arm-dis.c revision 1.1.1.1.2.1 1 1.1 christos /* Instruction printing code for the ARM
2 1.1 christos Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 1.1.1.1.2.1 yamt 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
4 1.1.1.1.2.1 yamt Free Software Foundation, Inc.
5 1.1 christos Contributed by Richard Earnshaw (rwe (at) pegasus.esprit.ec.org)
6 1.1 christos Modification by James G. Smith (jsmith (at) cygnus.co.uk)
7 1.1 christos
8 1.1 christos This file is part of libopcodes.
9 1.1 christos
10 1.1 christos This library is free software; you can redistribute it and/or modify
11 1.1 christos it under the terms of the GNU General Public License as published by
12 1.1 christos the Free Software Foundation; either version 3 of the License, or
13 1.1 christos (at your option) any later version.
14 1.1 christos
15 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
16 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 1.1 christos License for more details.
19 1.1 christos
20 1.1 christos You should have received a copy of the GNU General Public License
21 1.1 christos along with this program; if not, write to the Free Software
22 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 1.1 christos MA 02110-1301, USA. */
24 1.1 christos
25 1.1 christos #include "sysdep.h"
26 1.1 christos
27 1.1 christos #include "dis-asm.h"
28 1.1 christos #include "opcode/arm.h"
29 1.1 christos #include "opintl.h"
30 1.1 christos #include "safe-ctype.h"
31 1.1 christos #include "floatformat.h"
32 1.1 christos
33 1.1 christos /* FIXME: This shouldn't be done here. */
34 1.1 christos #include "coff/internal.h"
35 1.1 christos #include "libcoff.h"
36 1.1 christos #include "elf-bfd.h"
37 1.1 christos #include "elf/internal.h"
38 1.1 christos #include "elf/arm.h"
39 1.1 christos
40 1.1 christos /* FIXME: Belongs in global header. */
41 1.1 christos #ifndef strneq
42 1.1 christos #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
43 1.1 christos #endif
44 1.1 christos
45 1.1 christos #ifndef NUM_ELEM
46 1.1 christos #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
47 1.1 christos #endif
48 1.1 christos
49 1.1.1.1.2.1 yamt /* Cached mapping symbol state. */
50 1.1.1.1.2.1 yamt enum map_type
51 1.1.1.1.2.1 yamt {
52 1.1.1.1.2.1 yamt MAP_ARM,
53 1.1.1.1.2.1 yamt MAP_THUMB,
54 1.1.1.1.2.1 yamt MAP_DATA
55 1.1.1.1.2.1 yamt };
56 1.1.1.1.2.1 yamt
57 1.1 christos struct arm_private_data
58 1.1 christos {
59 1.1 christos /* The features to use when disassembling optional instructions. */
60 1.1 christos arm_feature_set features;
61 1.1 christos
62 1.1 christos /* Whether any mapping symbols are present in the provided symbol
63 1.1 christos table. -1 if we do not know yet, otherwise 0 or 1. */
64 1.1 christos int has_mapping_symbols;
65 1.1.1.1.2.1 yamt
66 1.1.1.1.2.1 yamt /* Track the last type (although this doesn't seem to be useful) */
67 1.1.1.1.2.1 yamt enum map_type last_type;
68 1.1.1.1.2.1 yamt
69 1.1.1.1.2.1 yamt /* Tracking symbol table information */
70 1.1.1.1.2.1 yamt int last_mapping_sym;
71 1.1.1.1.2.1 yamt bfd_vma last_mapping_addr;
72 1.1 christos };
73 1.1 christos
74 1.1 christos struct opcode32
75 1.1 christos {
76 1.1 christos unsigned long arch; /* Architecture defining this insn. */
77 1.1 christos unsigned long value; /* If arch == 0 then value is a sentinel. */
78 1.1 christos unsigned long mask; /* Recognise insn if (op & mask) == value. */
79 1.1 christos const char * assembler; /* How to disassemble this insn. */
80 1.1 christos };
81 1.1 christos
82 1.1 christos struct opcode16
83 1.1 christos {
84 1.1 christos unsigned long arch; /* Architecture defining this insn. */
85 1.1 christos unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
86 1.1 christos const char *assembler; /* How to disassemble this insn. */
87 1.1 christos };
88 1.1 christos
89 1.1 christos /* print_insn_coprocessor recognizes the following format control codes:
90 1.1 christos
91 1.1 christos %% %
92 1.1 christos
93 1.1 christos %c print condition code (always bits 28-31 in ARM mode)
94 1.1 christos %q print shifter argument
95 1.1.1.1.2.1 yamt %u print condition code (unconditional in ARM mode,
96 1.1.1.1.2.1 yamt UNPREDICTABLE if not AL in Thumb)
97 1.1 christos %A print address for ldc/stc/ldf/stf instruction
98 1.1 christos %B print vstm/vldm register list
99 1.1 christos %I print cirrus signed shift immediate: bits 0..3|4..6
100 1.1 christos %F print the COUNT field of a LFM/SFM instruction.
101 1.1 christos %P print floating point precision in arithmetic insn
102 1.1 christos %Q print floating point precision in ldf/stf insn
103 1.1 christos %R print floating point rounding mode
104 1.1 christos
105 1.1.1.1.2.1 yamt %<bitfield>c print as a condition code (for vsel)
106 1.1 christos %<bitfield>r print as an ARM register
107 1.1 christos %<bitfield>R as %<>r but r15 is UNPREDICTABLE
108 1.1 christos %<bitfield>ru as %<>r but each u register must be unique.
109 1.1 christos %<bitfield>d print the bitfield in decimal
110 1.1 christos %<bitfield>k print immediate for VFPv3 conversion instruction
111 1.1 christos %<bitfield>x print the bitfield in hex
112 1.1 christos %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
113 1.1 christos %<bitfield>f print a floating point constant if >7 else a
114 1.1 christos floating point register
115 1.1 christos %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
116 1.1 christos %<bitfield>g print as an iWMMXt 64-bit register
117 1.1 christos %<bitfield>G print as an iWMMXt general purpose or control register
118 1.1 christos %<bitfield>D print as a NEON D register
119 1.1 christos %<bitfield>Q print as a NEON Q register
120 1.1 christos
121 1.1 christos %y<code> print a single precision VFP reg.
122 1.1 christos Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
123 1.1 christos %z<code> print a double precision VFP reg
124 1.1 christos Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
125 1.1 christos
126 1.1 christos %<bitfield>'c print specified char iff bitfield is all ones
127 1.1 christos %<bitfield>`c print specified char iff bitfield is all zeroes
128 1.1 christos %<bitfield>?ab... select from array of values in big endian order
129 1.1 christos
130 1.1 christos %L print as an iWMMXt N/M width field.
131 1.1 christos %Z print the Immediate of a WSHUFH instruction.
132 1.1 christos %l like 'A' except use byte offsets for 'B' & 'H'
133 1.1 christos versions.
134 1.1 christos %i print 5-bit immediate in bits 8,3..0
135 1.1 christos (print "32" when 0)
136 1.1 christos %r print register offset address for wldt/wstr instruction. */
137 1.1 christos
138 1.1 christos enum opcode_sentinel_enum
139 1.1 christos {
140 1.1 christos SENTINEL_IWMMXT_START = 1,
141 1.1 christos SENTINEL_IWMMXT_END,
142 1.1 christos SENTINEL_GENERIC_START
143 1.1 christos } opcode_sentinels;
144 1.1 christos
145 1.1 christos #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
146 1.1 christos #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
147 1.1 christos
148 1.1 christos /* Common coprocessor opcodes shared between Arm and Thumb-2. */
149 1.1 christos
150 1.1 christos static const struct opcode32 coprocessor_opcodes[] =
151 1.1 christos {
152 1.1 christos /* XScale instructions. */
153 1.1 christos {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
154 1.1 christos {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
155 1.1 christos {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
156 1.1 christos {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
157 1.1 christos {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
158 1.1 christos
159 1.1 christos /* Intel Wireless MMX technology instructions. */
160 1.1 christos { 0, SENTINEL_IWMMXT_START, 0, "" },
161 1.1 christos {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
162 1.1 christos {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
163 1.1 christos {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
164 1.1 christos {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
165 1.1 christos {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
166 1.1 christos {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
167 1.1 christos {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
168 1.1 christos {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
169 1.1 christos {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
170 1.1 christos {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
171 1.1 christos {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
172 1.1 christos {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
173 1.1 christos {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
174 1.1 christos {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
175 1.1 christos {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
176 1.1 christos {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
177 1.1 christos {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
178 1.1 christos {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
179 1.1 christos {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
180 1.1 christos {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
181 1.1 christos {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
182 1.1 christos {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
183 1.1 christos {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
184 1.1 christos {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
185 1.1 christos {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
186 1.1 christos {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
187 1.1 christos {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
188 1.1 christos {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
189 1.1 christos {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
190 1.1 christos {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
191 1.1 christos {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
192 1.1 christos {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
193 1.1 christos {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
194 1.1 christos {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
195 1.1 christos {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
196 1.1 christos {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
197 1.1 christos {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
198 1.1 christos {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
199 1.1 christos {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
200 1.1 christos {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
201 1.1 christos {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
202 1.1 christos {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
203 1.1 christos {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
204 1.1 christos {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
205 1.1 christos {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
206 1.1 christos {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
207 1.1 christos {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
208 1.1 christos {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
209 1.1 christos {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
210 1.1 christos {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
211 1.1 christos {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
212 1.1 christos {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
213 1.1 christos {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
214 1.1 christos {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
215 1.1 christos {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
216 1.1 christos {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
217 1.1 christos {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
218 1.1 christos {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
219 1.1 christos {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
220 1.1 christos {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
221 1.1 christos {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
222 1.1 christos {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
223 1.1 christos {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
224 1.1 christos {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
225 1.1 christos {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
226 1.1 christos {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
227 1.1 christos {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
228 1.1 christos {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
229 1.1 christos {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
230 1.1 christos {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
231 1.1 christos {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
232 1.1 christos {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
233 1.1 christos {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
234 1.1 christos {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
235 1.1 christos {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
236 1.1 christos { 0, SENTINEL_IWMMXT_END, 0, "" },
237 1.1 christos
238 1.1 christos /* Floating point coprocessor (FPA) instructions. */
239 1.1 christos {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 1.1 christos {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 1.1 christos {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 1.1 christos {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 1.1 christos {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 1.1 christos {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 1.1 christos {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 1.1 christos {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 1.1 christos {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 1.1 christos {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 1.1 christos {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
250 1.1 christos {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
251 1.1 christos {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
252 1.1 christos {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
253 1.1 christos {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
254 1.1 christos {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
255 1.1 christos {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
256 1.1 christos {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
257 1.1 christos {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
258 1.1 christos {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
259 1.1 christos {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
260 1.1 christos {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
261 1.1 christos {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
262 1.1 christos {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
263 1.1 christos {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
264 1.1 christos {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
265 1.1 christos {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
266 1.1 christos {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
267 1.1 christos {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
268 1.1 christos {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
269 1.1 christos {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
270 1.1 christos {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
271 1.1 christos {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
272 1.1 christos {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
273 1.1 christos {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
274 1.1 christos {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
275 1.1 christos {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
276 1.1 christos {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
277 1.1 christos {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
278 1.1 christos {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
279 1.1 christos {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
280 1.1 christos {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
281 1.1 christos {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
282 1.1 christos
283 1.1 christos /* Register load/store. */
284 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
285 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
286 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
287 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
288 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
289 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
290 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
291 1.1 christos {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
292 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
293 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
294 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
295 1.1 christos {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
296 1.1 christos {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
297 1.1 christos {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
298 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
299 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
300 1.1 christos
301 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
302 1.1 christos {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
303 1.1 christos {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
304 1.1 christos {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
305 1.1 christos
306 1.1 christos /* Data transfer between ARM and NEON registers. */
307 1.1 christos {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
308 1.1 christos {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
309 1.1 christos {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
310 1.1 christos {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
311 1.1 christos {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
312 1.1 christos {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
313 1.1 christos {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
314 1.1 christos {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
315 1.1 christos {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
316 1.1 christos {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
317 1.1 christos {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
318 1.1 christos {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
319 1.1 christos {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
320 1.1 christos {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
321 1.1 christos /* Half-precision conversion instructions. */
322 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0x0eb20b40, 0x0fbf0f50, "vcvt%7?tb%c.f64.f16\t%z1, %y0"},
323 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0x0eb30b40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f64\t%y1, %z0"},
324 1.1 christos {FPU_VFP_EXT_FP16, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
325 1.1 christos {FPU_VFP_EXT_FP16, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
326 1.1 christos
327 1.1 christos /* Floating point coprocessor (VFP) instructions. */
328 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
329 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
330 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
331 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
332 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
333 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
334 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
335 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
336 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
337 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
338 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
339 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
340 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
341 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
342 1.1 christos {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
343 1.1 christos {FPU_VFP_EXT_V1, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
344 1.1 christos {FPU_VFP_EXT_V1, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
345 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
346 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
347 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
348 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
349 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
350 1.1 christos {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
351 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
352 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
353 1.1 christos {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
354 1.1 christos {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
355 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
356 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
357 1.1 christos {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
358 1.1 christos {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
359 1.1 christos {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
360 1.1 christos {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
361 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
362 1.1 christos {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
363 1.1 christos {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
364 1.1 christos {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
365 1.1 christos {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
366 1.1 christos {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
367 1.1 christos {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
368 1.1 christos {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
369 1.1 christos {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
370 1.1 christos {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
371 1.1 christos {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
372 1.1 christos {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
373 1.1 christos {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
374 1.1 christos {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
375 1.1 christos {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
376 1.1 christos {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
377 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
378 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
379 1.1 christos {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
380 1.1 christos {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
381 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
382 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
383 1.1 christos {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
384 1.1 christos {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
385 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
386 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
387 1.1 christos {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
388 1.1 christos {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
389 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
390 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
391 1.1 christos {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
392 1.1 christos {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
393 1.1 christos {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
394 1.1 christos {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
395 1.1 christos
396 1.1 christos /* Cirrus coprocessor instructions. */
397 1.1 christos {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
398 1.1 christos {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
399 1.1 christos {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
400 1.1 christos {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
401 1.1 christos {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
402 1.1 christos {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
403 1.1 christos {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
404 1.1 christos {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
405 1.1 christos {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
406 1.1 christos {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
407 1.1 christos {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
408 1.1 christos {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
409 1.1 christos {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
410 1.1 christos {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
411 1.1 christos {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
412 1.1 christos {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
413 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
414 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
415 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
416 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
417 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
418 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
419 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
420 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
421 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
422 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
423 1.1 christos {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
424 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
425 1.1 christos {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
426 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
427 1.1 christos {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
428 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
429 1.1 christos {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
430 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
431 1.1 christos {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
432 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
433 1.1 christos {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
434 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
435 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
436 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
437 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
438 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
439 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
440 1.1 christos {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
441 1.1 christos {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
442 1.1 christos {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
443 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
444 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
445 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
446 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
447 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
448 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
449 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
450 1.1 christos {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
451 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
452 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
453 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
454 1.1 christos {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
455 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
456 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
457 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
458 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
459 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
460 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
461 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
462 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
463 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
464 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
465 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
466 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
467 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
468 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
469 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
470 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
471 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 1.1 christos {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
473 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
475 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
476 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
477 1.1 christos {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
478 1.1 christos {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
479 1.1 christos {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
480 1.1 christos {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
481 1.1 christos
482 1.1 christos /* VFP Fused multiply add instructions. */
483 1.1 christos {FPU_VFP_EXT_FMA, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
484 1.1 christos {FPU_VFP_EXT_FMA, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
485 1.1 christos {FPU_VFP_EXT_FMA, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
486 1.1 christos {FPU_VFP_EXT_FMA, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
487 1.1 christos {FPU_VFP_EXT_FMA, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
488 1.1 christos {FPU_VFP_EXT_FMA, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
489 1.1 christos {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
490 1.1 christos {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
491 1.1 christos
492 1.1.1.1.2.1 yamt /* FP v5. */
493 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe000a00, 0xff800f00, "vsel%20-21c%u.f32\t%y1, %y2, %y0"},
494 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe000b00, 0xff800f00, "vsel%20-21c%u.f64\t%z1, %z2, %z0"},
495 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe800a00, 0xffb00f40, "vmaxnm%u.f32\t%y1, %y2, %y0"},
496 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe800b00, 0xffb00f40, "vmaxnm%u.f64\t%z1, %z2, %z0"},
497 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe800a40, 0xffb00f40, "vminnm%u.f32\t%y1, %y2, %y0"},
498 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfe800b40, 0xffb00f40, "vminnm%u.f64\t%z1, %z2, %z0"},
499 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfebc0a40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f32\t%y1, %y0"},
500 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfebc0b40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f64\t%y1, %z0"},
501 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0x0eb60a40, 0x0fbe0f50, "vrint%7,16??xzr%c.f32\t%y1, %y0"},
502 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0x0eb60b40, 0x0fbe0f50, "vrint%7,16??xzr%c.f64\t%z1, %z0"},
503 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfeb80a40, 0xffbc0f50, "vrint%16-17?mpna%u.f32\t%y1, %y0"},
504 1.1.1.1.2.1 yamt {FPU_VFP_EXT_ARMV8, 0xfeb80b40, 0xffbc0f50, "vrint%16-17?mpna%u.f64\t%z1, %z0"},
505 1.1.1.1.2.1 yamt
506 1.1 christos /* Generic coprocessor instructions. */
507 1.1 christos { 0, SENTINEL_GENERIC_START, 0, "" },
508 1.1 christos {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
509 1.1 christos {ARM_EXT_V5E, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
510 1.1 christos {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
511 1.1 christos {ARM_EXT_V2, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
512 1.1 christos {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
513 1.1 christos {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
514 1.1 christos {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
515 1.1 christos {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
516 1.1 christos
517 1.1 christos /* V6 coprocessor instructions. */
518 1.1 christos {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
519 1.1 christos {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
520 1.1 christos
521 1.1 christos /* V5 coprocessor instructions. */
522 1.1 christos {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
523 1.1 christos {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
524 1.1 christos {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
525 1.1 christos {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
526 1.1 christos {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
527 1.1 christos
528 1.1 christos {0, 0, 0, 0}
529 1.1 christos };
530 1.1 christos
531 1.1 christos /* Neon opcode table: This does not encode the top byte -- that is
532 1.1 christos checked by the print_insn_neon routine, as it depends on whether we are
533 1.1 christos doing thumb32 or arm32 disassembly. */
534 1.1 christos
535 1.1 christos /* print_insn_neon recognizes the following format control codes:
536 1.1 christos
537 1.1 christos %% %
538 1.1 christos
539 1.1 christos %c print condition code
540 1.1.1.1.2.1 yamt %u print condition code (unconditional in ARM mode,
541 1.1.1.1.2.1 yamt UNPREDICTABLE if not AL in Thumb)
542 1.1 christos %A print v{st,ld}[1234] operands
543 1.1 christos %B print v{st,ld}[1234] any one operands
544 1.1 christos %C print v{st,ld}[1234] single->all operands
545 1.1 christos %D print scalar
546 1.1 christos %E print vmov, vmvn, vorr, vbic encoded constant
547 1.1 christos %F print vtbl,vtbx register list
548 1.1 christos
549 1.1 christos %<bitfield>r print as an ARM register
550 1.1 christos %<bitfield>d print the bitfield in decimal
551 1.1 christos %<bitfield>e print the 2^N - bitfield in decimal
552 1.1 christos %<bitfield>D print as a NEON D register
553 1.1 christos %<bitfield>Q print as a NEON Q register
554 1.1 christos %<bitfield>R print as a NEON D or Q register
555 1.1 christos %<bitfield>Sn print byte scaled width limited by n
556 1.1 christos %<bitfield>Tn print short scaled width limited by n
557 1.1 christos %<bitfield>Un print long scaled width limited by n
558 1.1 christos
559 1.1 christos %<bitfield>'c print specified char iff bitfield is all ones
560 1.1 christos %<bitfield>`c print specified char iff bitfield is all zeroes
561 1.1 christos %<bitfield>?ab... select from array of values in big endian order. */
562 1.1 christos
563 1.1 christos static const struct opcode32 neon_opcodes[] =
564 1.1 christos {
565 1.1 christos /* Extract. */
566 1.1 christos {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
567 1.1 christos {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
568 1.1 christos
569 1.1 christos /* Move data element to all lanes. */
570 1.1 christos {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
571 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
572 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
573 1.1 christos
574 1.1 christos /* Table lookup. */
575 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
576 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
577 1.1 christos
578 1.1 christos /* Half-precision conversions. */
579 1.1 christos {FPU_VFP_EXT_FP16, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
580 1.1 christos {FPU_VFP_EXT_FP16, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
581 1.1 christos
582 1.1 christos /* NEON fused multiply add instructions. */
583 1.1 christos {FPU_NEON_EXT_FMA, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
584 1.1 christos {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
585 1.1 christos
586 1.1 christos /* Two registers, miscellaneous. */
587 1.1.1.1.2.1 yamt {FPU_NEON_EXT_ARMV8, 0xf3ba0400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f32\t%12-15,22R, %0-3,5R"},
588 1.1.1.1.2.1 yamt {FPU_NEON_EXT_ARMV8, 0xf3bb0000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us32.f32\t%12-15,22R, %0-3,5R"},
589 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3b00300, 0xffbf0fd0, "aese%u.8\t%12-15,22Q, %0-3,5Q"},
590 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3b00340, 0xffbf0fd0, "aesd%u.8\t%12-15,22Q, %0-3,5Q"},
591 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3b00380, 0xffbf0fd0, "aesmc%u.8\t%12-15,22Q, %0-3,5Q"},
592 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3b003c0, 0xffbf0fd0, "aesimc%u.8\t%12-15,22Q, %0-3,5Q"},
593 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3b902c0, 0xffbf0fd0, "sha1h%u.32\t%12-15,22Q, %0-3,5Q"},
594 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3ba0380, 0xffbf0fd0, "sha1su1%u.32\t%12-15,22Q, %0-3,5Q"},
595 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3ba03c0, 0xffbf0fd0, "sha256su0%u.32\t%12-15,22Q, %0-3,5Q"},
596 1.1 christos {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
597 1.1 christos {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
598 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
599 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
600 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
601 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
602 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
603 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
604 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
605 1.1 christos {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
606 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
607 1.1 christos {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
608 1.1 christos {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
609 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
610 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
611 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
612 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
613 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
614 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
615 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
616 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
617 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
618 1.1 christos {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
619 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
620 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
621 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
622 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
623 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
624 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
625 1.1 christos {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
626 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
627 1.1 christos {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
628 1.1 christos {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
629 1.1 christos
630 1.1 christos /* Three registers of the same length. */
631 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf2000c40, 0xffb00f50, "sha1c%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
632 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf2100c40, 0xffb00f50, "sha1p%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
633 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf2200c40, 0xffb00f50, "sha1m%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
634 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf2300c40, 0xffb00f50, "sha1su0%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
635 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3000c40, 0xffb00f50, "sha256h%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
636 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3100c40, 0xffb00f50, "sha256h2%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
637 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf3200c40, 0xffb00f50, "sha256su1%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
638 1.1.1.1.2.1 yamt {FPU_NEON_EXT_ARMV8, 0xf3000f10, 0xffa00f10, "vmaxnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
639 1.1.1.1.2.1 yamt {FPU_NEON_EXT_ARMV8, 0xf3200f10, 0xffa00f10, "vminnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 1.1 christos {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
641 1.1 christos {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
642 1.1 christos {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
643 1.1 christos {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
644 1.1 christos {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
645 1.1 christos {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
646 1.1 christos {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
647 1.1 christos {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
648 1.1 christos {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
649 1.1 christos {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
650 1.1 christos {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
651 1.1 christos {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
652 1.1 christos {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
653 1.1 christos {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
654 1.1 christos {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
655 1.1 christos {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
656 1.1 christos {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
657 1.1 christos {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
658 1.1 christos {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
659 1.1 christos {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
660 1.1 christos {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
661 1.1 christos {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
662 1.1 christos {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
663 1.1 christos {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
664 1.1 christos {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
665 1.1 christos {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
666 1.1 christos {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
667 1.1 christos {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
668 1.1 christos {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
669 1.1 christos {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
670 1.1 christos {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
671 1.1 christos {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
672 1.1 christos {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
673 1.1 christos {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
674 1.1 christos {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
675 1.1 christos {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
676 1.1 christos {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
677 1.1 christos {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
678 1.1 christos {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
679 1.1 christos {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
680 1.1 christos {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
681 1.1 christos {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
682 1.1 christos {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
683 1.1 christos {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
684 1.1 christos {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
685 1.1 christos {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
686 1.1 christos {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
687 1.1 christos {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
688 1.1 christos {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
689 1.1 christos {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
690 1.1 christos {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
691 1.1 christos {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
692 1.1 christos {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
693 1.1 christos
694 1.1 christos /* One register and an immediate value. */
695 1.1 christos {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
696 1.1 christos {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
697 1.1 christos {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
698 1.1 christos {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
699 1.1 christos {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
700 1.1 christos {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
701 1.1 christos {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
702 1.1 christos {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
703 1.1 christos {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
704 1.1 christos {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
705 1.1 christos {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
706 1.1 christos {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
707 1.1 christos {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
708 1.1 christos
709 1.1 christos /* Two registers and a shift amount. */
710 1.1 christos {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
711 1.1 christos {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
712 1.1 christos {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
713 1.1 christos {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
714 1.1 christos {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
715 1.1 christos {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
716 1.1 christos {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
717 1.1 christos {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
718 1.1 christos {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
719 1.1 christos {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
720 1.1 christos {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
721 1.1 christos {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
722 1.1 christos {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
723 1.1 christos {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
724 1.1 christos {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
725 1.1 christos {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
726 1.1 christos {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
727 1.1 christos {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
728 1.1 christos {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
729 1.1 christos {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
730 1.1 christos {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
731 1.1 christos {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
732 1.1 christos {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
733 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
734 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
735 1.1 christos {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
736 1.1 christos {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
737 1.1 christos {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
738 1.1 christos {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
739 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
740 1.1 christos {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
741 1.1 christos {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
742 1.1 christos {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
743 1.1 christos {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
744 1.1 christos {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
745 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
746 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
747 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
748 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
749 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
750 1.1 christos {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
751 1.1 christos {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
752 1.1 christos {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
753 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
754 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
755 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
756 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
757 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
758 1.1 christos {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
759 1.1 christos {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
760 1.1 christos {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
761 1.1 christos {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
762 1.1 christos {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
763 1.1 christos {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
764 1.1 christos {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
765 1.1 christos {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
766 1.1 christos {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
767 1.1 christos {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
768 1.1 christos
769 1.1 christos /* Three registers of different lengths. */
770 1.1.1.1.2.1 yamt {FPU_CRYPTO_EXT_ARMV8, 0xf2a00e00, 0xfeb00f50, "vmull%c.p64\t%12-15,22Q, %16-19,7D, %0-3,5D"},
771 1.1 christos {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
772 1.1 christos {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
773 1.1 christos {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
774 1.1 christos {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
775 1.1 christos {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
776 1.1 christos {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
777 1.1 christos {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
778 1.1 christos {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
779 1.1 christos {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
780 1.1 christos {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
781 1.1 christos {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
782 1.1 christos {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
783 1.1 christos {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
784 1.1 christos {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
785 1.1 christos {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
786 1.1 christos {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
787 1.1 christos {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
788 1.1 christos
789 1.1 christos /* Two registers and a scalar. */
790 1.1 christos {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
791 1.1 christos {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
792 1.1 christos {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
793 1.1 christos {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
794 1.1 christos {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
795 1.1 christos {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
796 1.1 christos {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
797 1.1 christos {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
798 1.1 christos {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
799 1.1 christos {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
800 1.1 christos {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
801 1.1 christos {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
802 1.1 christos {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
803 1.1 christos {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
804 1.1 christos {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
805 1.1 christos {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
806 1.1 christos {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
807 1.1 christos {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
808 1.1 christos {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
809 1.1 christos {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
810 1.1 christos {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
811 1.1 christos {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
812 1.1 christos
813 1.1 christos /* Element and structure load/store. */
814 1.1 christos {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
815 1.1 christos {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
816 1.1 christos {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
817 1.1 christos {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
818 1.1 christos {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
819 1.1 christos {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
820 1.1 christos {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
821 1.1 christos {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
822 1.1 christos {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
823 1.1 christos {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
824 1.1 christos {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
825 1.1 christos {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
826 1.1 christos {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
827 1.1 christos {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
828 1.1 christos {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
829 1.1 christos {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
830 1.1 christos {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
831 1.1 christos {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
832 1.1 christos {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
833 1.1 christos
834 1.1 christos {0,0 ,0, 0}
835 1.1 christos };
836 1.1 christos
837 1.1 christos /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
838 1.1 christos ordered: they must be searched linearly from the top to obtain a correct
839 1.1 christos match. */
840 1.1 christos
841 1.1 christos /* print_insn_arm recognizes the following format control codes:
842 1.1 christos
843 1.1 christos %% %
844 1.1 christos
845 1.1 christos %a print address for ldr/str instruction
846 1.1 christos %s print address for ldr/str halfword/signextend instruction
847 1.1 christos %S like %s but allow UNPREDICTABLE addressing
848 1.1 christos %b print branch destination
849 1.1 christos %c print condition code (always bits 28-31)
850 1.1 christos %m print register mask for ldm/stm instruction
851 1.1 christos %o print operand2 (immediate or register + shift)
852 1.1 christos %p print 'p' iff bits 12-15 are 15
853 1.1 christos %t print 't' iff bit 21 set and bit 24 clear
854 1.1 christos %B print arm BLX(1) destination
855 1.1 christos %C print the PSR sub type.
856 1.1 christos %U print barrier type.
857 1.1 christos %P print address for pli instruction.
858 1.1 christos
859 1.1 christos %<bitfield>r print as an ARM register
860 1.1.1.1.2.1 yamt %<bitfield>T print as an ARM register + 1
861 1.1 christos %<bitfield>R as %r but r15 is UNPREDICTABLE
862 1.1 christos %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
863 1.1 christos %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
864 1.1 christos %<bitfield>d print the bitfield in decimal
865 1.1 christos %<bitfield>W print the bitfield plus one in decimal
866 1.1 christos %<bitfield>x print the bitfield in hex
867 1.1 christos %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
868 1.1 christos
869 1.1 christos %<bitfield>'c print specified char iff bitfield is all ones
870 1.1 christos %<bitfield>`c print specified char iff bitfield is all zeroes
871 1.1 christos %<bitfield>?ab... select from array of values in big endian order
872 1.1 christos
873 1.1 christos %e print arm SMI operand (bits 0..7,8..19).
874 1.1 christos %E print the LSB and WIDTH fields of a BFI or BFC instruction.
875 1.1 christos %V print the 16-bit immediate field of a MOVT or MOVW instruction.
876 1.1 christos %R print the SPSR/CPSR or banked register of an MRS. */
877 1.1 christos
878 1.1 christos static const struct opcode32 arm_opcodes[] =
879 1.1 christos {
880 1.1 christos /* ARM instructions. */
881 1.1 christos {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
882 1.1 christos {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
883 1.1 christos {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
884 1.1 christos {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
885 1.1 christos {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
886 1.1 christos {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
887 1.1 christos {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
888 1.1 christos
889 1.1.1.1.2.1 yamt /* V8 instructions. */
890 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x0320f005, 0x0fffffff, "sevl"},
891 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe1000070, 0xfff000f0, "hlt\t0x%16-19X%12-15X%8-11X%0-3X"},
892 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01800e90, 0x0ff00ff0, "stlex%c\t%12-15r, %0-3r, [%16-19R]"},
893 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01900e9f, 0x0ff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
894 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01a00e90, 0x0ff00ff0, "stlexd%c\t%12-15r, %0-3r, %0-3T, [%16-19R]"},
895 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01b00e9f, 0x0ff00fff, "ldaexd%c\t%12-15r, %12-15T, [%16-19R]"},
896 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01c00e90, 0x0ff00ff0, "stlexb%c\t%12-15r, %0-3r, [%16-19R]"},
897 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01d00e9f, 0x0ff00fff, "ldaexb%c\t%12-15r, [%16-19R]"},
898 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01e00e90, 0x0ff00ff0, "stlexh%c\t%12-15r, %0-3r, [%16-19R]"},
899 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01f00e9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
900 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x0180fc90, 0x0ff0fff0, "stl%c\t%0-3r, [%16-19R]"},
901 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01900c9f, 0x0ff00fff, "lda%c\t%12-15r, [%16-19R]"},
902 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01c0fc90, 0x0ff0fff0, "stlb%c\t%0-3r, [%16-19R]"},
903 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01d00c9f, 0x0ff00fff, "ldab%c\t%12-15r, [%16-19R]"},
904 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01e0fc90, 0x0ff0fff0, "stlh%c\t%0-3r, [%16-19R]"},
905 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0x01f00c9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
906 1.1.1.1.2.1 yamt /* CRC32 instructions. */
907 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1000040, 0xfff00ff0, "crc32b\t%12-15R, %16-19R, %0-3R"},
908 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1200040, 0xfff00ff0, "crc32h\t%12-15R, %16-19R, %0-3R"},
909 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1400040, 0xfff00ff0, "crc32w\t%12-15R, %16-19R, %0-3R"},
910 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1000240, 0xfff00ff0, "crc32cb\t%12-15R, %16-19R, %0-3R"},
911 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1200240, 0xfff00ff0, "crc32ch\t%12-15R, %16-19R, %0-3R"},
912 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xe1400240, 0xfff00ff0, "crc32cw\t%12-15R, %16-19R, %0-3R"},
913 1.1.1.1.2.1 yamt
914 1.1 christos /* Virtualization Extension instructions. */
915 1.1 christos {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
916 1.1 christos {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
917 1.1 christos
918 1.1 christos /* Integer Divide Extension instructions. */
919 1.1 christos {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
920 1.1 christos {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
921 1.1 christos
922 1.1 christos /* MP Extension instructions. */
923 1.1 christos {ARM_EXT_MP, 0xf410f000, 0xfc70f000, "pldw\t%a"},
924 1.1 christos
925 1.1 christos /* V7 instructions. */
926 1.1 christos {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
927 1.1 christos {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
928 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf57ff051, 0xfffffff3, "dmb\t%U"},
929 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf57ff041, 0xfffffff3, "dsb\t%U"},
930 1.1 christos {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
931 1.1 christos {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
932 1.1 christos {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
933 1.1 christos
934 1.1 christos /* ARM V6T2 instructions. */
935 1.1 christos {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
936 1.1 christos {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
937 1.1 christos {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
938 1.1.1.1.2.1 yamt {ARM_EXT_V6T2, 0x002000b0, 0x0f3000f0, "strht%c\t%12-15R, %S"},
939 1.1.1.1.2.1 yamt
940 1.1 christos {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
941 1.1 christos {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
942 1.1 christos
943 1.1 christos {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
944 1.1 christos {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
945 1.1 christos {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
946 1.1 christos {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
947 1.1 christos
948 1.1 christos /* ARM Security extension instructions. */
949 1.1 christos {ARM_EXT_SEC, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
950 1.1 christos
951 1.1 christos /* ARM V6K instructions. */
952 1.1 christos {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
953 1.1 christos {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
954 1.1 christos {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
955 1.1 christos {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
956 1.1 christos {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
957 1.1 christos {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
958 1.1 christos {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
959 1.1 christos
960 1.1 christos /* ARM V6K NOP hints. */
961 1.1 christos {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
962 1.1 christos {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
963 1.1 christos {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
964 1.1 christos {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
965 1.1 christos {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
966 1.1 christos
967 1.1 christos /* ARM V6 instructions. */
968 1.1 christos {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
969 1.1 christos {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
970 1.1 christos {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
971 1.1 christos {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
972 1.1 christos {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
973 1.1 christos {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
974 1.1 christos {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
975 1.1 christos {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
976 1.1 christos {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
977 1.1 christos {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
978 1.1 christos {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
979 1.1 christos {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
980 1.1 christos {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
981 1.1 christos {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
982 1.1 christos {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
983 1.1 christos {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
984 1.1 christos {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
985 1.1 christos {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
986 1.1 christos {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
987 1.1 christos {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
988 1.1 christos {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
989 1.1 christos {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
990 1.1 christos {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
991 1.1 christos {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
992 1.1 christos {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
993 1.1 christos {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
994 1.1 christos {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
995 1.1 christos {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
996 1.1 christos {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
997 1.1 christos {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
998 1.1 christos {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
999 1.1 christos {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
1000 1.1 christos {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
1001 1.1 christos {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
1002 1.1 christos {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
1003 1.1 christos {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
1004 1.1 christos {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
1005 1.1 christos {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
1006 1.1 christos {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
1007 1.1 christos {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
1008 1.1 christos {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
1009 1.1 christos {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
1010 1.1 christos {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
1011 1.1 christos {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
1012 1.1 christos {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
1013 1.1 christos {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
1014 1.1 christos {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
1015 1.1 christos {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
1016 1.1 christos {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
1017 1.1 christos {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
1018 1.1 christos {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
1019 1.1 christos {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
1020 1.1 christos {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
1021 1.1 christos {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
1022 1.1 christos {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
1023 1.1 christos {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
1024 1.1 christos {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
1025 1.1 christos {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
1026 1.1 christos {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
1027 1.1 christos {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
1028 1.1 christos {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
1029 1.1 christos {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
1030 1.1 christos {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
1031 1.1 christos {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
1032 1.1 christos {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
1033 1.1 christos {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
1034 1.1 christos {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
1035 1.1 christos {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
1036 1.1 christos {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
1037 1.1 christos {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
1038 1.1 christos {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
1039 1.1 christos {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
1040 1.1 christos {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
1041 1.1 christos {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
1042 1.1 christos {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
1043 1.1 christos {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1044 1.1 christos {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1045 1.1 christos {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1046 1.1 christos {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
1047 1.1 christos {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1048 1.1 christos {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1049 1.1 christos {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1050 1.1 christos {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
1051 1.1 christos {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1052 1.1 christos {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1053 1.1 christos {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1054 1.1 christos {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
1055 1.1 christos {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1056 1.1 christos {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1057 1.1 christos {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1058 1.1 christos {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
1059 1.1 christos {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1060 1.1 christos {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1061 1.1 christos {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
1062 1.1 christos {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
1063 1.1 christos {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1064 1.1 christos {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1065 1.1 christos {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1066 1.1 christos {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
1067 1.1 christos {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1068 1.1 christos {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
1069 1.1 christos {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
1070 1.1 christos {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1071 1.1 christos {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1072 1.1 christos {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1073 1.1 christos {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1074 1.1 christos {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
1075 1.1 christos {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1076 1.1 christos {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1077 1.1 christos {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1078 1.1 christos {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
1079 1.1 christos {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
1080 1.1 christos {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
1081 1.1 christos {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1082 1.1 christos {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1083 1.1 christos {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1084 1.1 christos {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1085 1.1 christos {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1086 1.1 christos {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1087 1.1 christos {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1088 1.1 christos {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1089 1.1 christos {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1090 1.1 christos
1091 1.1 christos /* V5J instruction. */
1092 1.1 christos {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1093 1.1 christos
1094 1.1 christos /* V5 Instructions. */
1095 1.1 christos {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1096 1.1 christos {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1097 1.1 christos {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1098 1.1 christos {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1099 1.1 christos
1100 1.1 christos /* V5E "El Segundo" Instructions. */
1101 1.1 christos {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1102 1.1 christos {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1103 1.1 christos {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1104 1.1 christos {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1105 1.1 christos {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1106 1.1 christos {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1107 1.1 christos {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1108 1.1 christos
1109 1.1 christos {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1110 1.1 christos {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1111 1.1 christos
1112 1.1 christos {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1113 1.1 christos {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1114 1.1 christos {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1115 1.1 christos {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1116 1.1 christos
1117 1.1 christos {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1118 1.1 christos {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1119 1.1 christos {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1120 1.1 christos {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1121 1.1 christos
1122 1.1 christos {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1123 1.1 christos {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1124 1.1 christos
1125 1.1 christos {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1126 1.1 christos {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1127 1.1 christos {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1128 1.1 christos {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1129 1.1 christos
1130 1.1 christos /* ARM Instructions. */
1131 1.1 christos {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1132 1.1 christos
1133 1.1 christos {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1134 1.1 christos {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1135 1.1 christos {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1136 1.1 christos {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1137 1.1 christos {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1138 1.1 christos {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1139 1.1 christos
1140 1.1 christos {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1141 1.1 christos {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1142 1.1 christos {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1143 1.1 christos {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1144 1.1 christos
1145 1.1 christos {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1146 1.1 christos {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1147 1.1 christos {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1148 1.1 christos {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1149 1.1 christos
1150 1.1 christos {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1151 1.1 christos {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1152 1.1 christos {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1153 1.1 christos
1154 1.1 christos {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1155 1.1 christos {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1156 1.1 christos {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1157 1.1 christos
1158 1.1 christos {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1159 1.1 christos {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1160 1.1 christos {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1161 1.1 christos
1162 1.1 christos {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1163 1.1 christos {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1164 1.1 christos {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1165 1.1 christos
1166 1.1 christos {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1167 1.1 christos {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1168 1.1 christos {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1169 1.1 christos
1170 1.1 christos {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1171 1.1 christos {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1172 1.1 christos {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1173 1.1 christos
1174 1.1 christos {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1175 1.1 christos {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1176 1.1 christos {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1177 1.1 christos
1178 1.1 christos {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1179 1.1 christos {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1180 1.1 christos {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1181 1.1 christos
1182 1.1 christos {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1183 1.1 christos {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1184 1.1 christos {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1185 1.1 christos
1186 1.1 christos {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1187 1.1 christos {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1188 1.1 christos {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1189 1.1 christos
1190 1.1 christos {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1191 1.1 christos {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1192 1.1 christos {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1193 1.1 christos
1194 1.1 christos {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1195 1.1 christos {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1196 1.1 christos {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1197 1.1 christos
1198 1.1 christos {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1199 1.1 christos {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1200 1.1 christos {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1201 1.1 christos
1202 1.1 christos {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1203 1.1 christos {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1204 1.1 christos {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1205 1.1 christos
1206 1.1 christos {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1207 1.1 christos {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1208 1.1 christos {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1209 1.1 christos {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1210 1.1 christos {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1211 1.1 christos {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1212 1.1 christos {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1213 1.1 christos
1214 1.1 christos {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1215 1.1 christos {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1216 1.1 christos {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1217 1.1 christos
1218 1.1 christos {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1219 1.1 christos {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1220 1.1 christos {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1221 1.1 christos
1222 1.1 christos {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1223 1.1 christos {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1224 1.1 christos
1225 1.1 christos {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1226 1.1 christos
1227 1.1 christos {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1228 1.1 christos {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1229 1.1 christos
1230 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0001, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1231 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0002, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1232 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0004, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1233 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0008, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1234 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0010, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1235 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0020, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1236 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0040, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1237 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0080, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1238 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0100, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1239 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0200, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1240 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0400, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1241 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d0800, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1242 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d1000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1243 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d2000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1244 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d4000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1245 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x092d8000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1246 1.1 christos {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1247 1.1 christos {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1248 1.1 christos {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1249 1.1.1.1.2.1 yamt
1250 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0001, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1251 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0002, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1252 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0004, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1253 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0008, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1254 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0010, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1255 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0020, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1256 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0040, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1257 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0080, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1258 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0100, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1259 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0200, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1260 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0400, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1261 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd0800, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1262 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd1000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1263 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd2000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1264 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd4000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1265 1.1.1.1.2.1 yamt {ARM_EXT_V1, 0x08bd8000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1266 1.1 christos {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1267 1.1 christos {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1268 1.1 christos {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1269 1.1.1.1.2.1 yamt
1270 1.1 christos {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1271 1.1 christos {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1272 1.1 christos
1273 1.1 christos /* The rest. */
1274 1.1 christos {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1275 1.1 christos {0, 0x00000000, 0x00000000, 0}
1276 1.1 christos };
1277 1.1 christos
1278 1.1 christos /* print_insn_thumb16 recognizes the following format control codes:
1279 1.1 christos
1280 1.1 christos %S print Thumb register (bits 3..5 as high number if bit 6 set)
1281 1.1 christos %D print Thumb register (bits 0..2 as high number if bit 7 set)
1282 1.1 christos %<bitfield>I print bitfield as a signed decimal
1283 1.1 christos (top bit of range being the sign bit)
1284 1.1 christos %N print Thumb register mask (with LR)
1285 1.1 christos %O print Thumb register mask (with PC)
1286 1.1 christos %M print Thumb register mask
1287 1.1 christos %b print CZB's 6-bit unsigned branch destination
1288 1.1 christos %s print Thumb right-shift immediate (6..10; 0 == 32).
1289 1.1 christos %c print the condition code
1290 1.1 christos %C print the condition code, or "s" if not conditional
1291 1.1 christos %x print warning if conditional an not at end of IT block"
1292 1.1 christos %X print "\t; unpredictable <IT:code>" if conditional
1293 1.1 christos %I print IT instruction suffix and operands
1294 1.1 christos %W print Thumb Writeback indicator for LDMIA
1295 1.1 christos %<bitfield>r print bitfield as an ARM register
1296 1.1 christos %<bitfield>d print bitfield as a decimal
1297 1.1 christos %<bitfield>H print (bitfield * 2) as a decimal
1298 1.1 christos %<bitfield>W print (bitfield * 4) as a decimal
1299 1.1 christos %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1300 1.1 christos %<bitfield>B print Thumb branch destination (signed displacement)
1301 1.1 christos %<bitfield>c print bitfield as a condition code
1302 1.1 christos %<bitnum>'c print specified char iff bit is one
1303 1.1 christos %<bitnum>?ab print a if bit is one else print b. */
1304 1.1 christos
1305 1.1 christos static const struct opcode16 thumb_opcodes[] =
1306 1.1 christos {
1307 1.1 christos /* Thumb instructions. */
1308 1.1 christos
1309 1.1.1.1.2.1 yamt /* ARM V8 instructions. */
1310 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xbf50, 0xffff, "sevl%c"},
1311 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xba80, 0xffc0, "hlt\t%0-5x"},
1312 1.1.1.1.2.1 yamt
1313 1.1 christos /* ARM V6K no-argument instructions. */
1314 1.1 christos {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1315 1.1 christos {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1316 1.1 christos {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1317 1.1 christos {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1318 1.1 christos {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1319 1.1 christos {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1320 1.1 christos
1321 1.1 christos /* ARM V6T2 instructions. */
1322 1.1 christos {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1323 1.1 christos {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1324 1.1 christos {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1325 1.1 christos
1326 1.1 christos /* ARM V6. */
1327 1.1 christos {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1328 1.1 christos {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1329 1.1 christos {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1330 1.1 christos {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1331 1.1 christos {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1332 1.1 christos {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1333 1.1 christos {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1334 1.1 christos {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1335 1.1 christos {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1336 1.1 christos {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1337 1.1 christos {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1338 1.1 christos
1339 1.1 christos /* ARM V5 ISA extends Thumb. */
1340 1.1 christos {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1341 1.1 christos /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1342 1.1 christos {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1343 1.1 christos /* ARM V4T ISA (Thumb v1). */
1344 1.1 christos {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1345 1.1 christos /* Format 4. */
1346 1.1 christos {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1347 1.1 christos {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1348 1.1 christos {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1349 1.1 christos {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1350 1.1 christos {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1351 1.1 christos {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1352 1.1 christos {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1353 1.1 christos {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1354 1.1 christos {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1355 1.1 christos {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1356 1.1 christos {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1357 1.1 christos {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1358 1.1 christos {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1359 1.1 christos {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1360 1.1 christos {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1361 1.1 christos {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1362 1.1 christos /* format 13 */
1363 1.1 christos {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1364 1.1 christos {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1365 1.1 christos /* format 5 */
1366 1.1 christos {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1367 1.1 christos {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1368 1.1 christos {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1369 1.1 christos {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1370 1.1 christos /* format 14 */
1371 1.1 christos {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1372 1.1 christos {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1373 1.1 christos /* format 2 */
1374 1.1 christos {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1375 1.1 christos {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1376 1.1 christos {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1377 1.1 christos {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1378 1.1 christos /* format 8 */
1379 1.1 christos {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1380 1.1 christos {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1381 1.1 christos {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1382 1.1 christos /* format 7 */
1383 1.1 christos {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1384 1.1 christos {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1385 1.1 christos /* format 1 */
1386 1.1 christos {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1387 1.1 christos {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1388 1.1 christos {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1389 1.1 christos {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1390 1.1 christos /* format 3 */
1391 1.1 christos {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1392 1.1 christos {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1393 1.1 christos {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1394 1.1 christos {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1395 1.1 christos /* format 6 */
1396 1.1 christos {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1397 1.1 christos /* format 9 */
1398 1.1 christos {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1399 1.1 christos {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1400 1.1 christos {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1401 1.1 christos {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1402 1.1 christos /* format 10 */
1403 1.1 christos {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1404 1.1 christos {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1405 1.1 christos /* format 11 */
1406 1.1 christos {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1407 1.1 christos {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1408 1.1 christos /* format 12 */
1409 1.1 christos {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1410 1.1 christos {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1411 1.1 christos /* format 15 */
1412 1.1 christos {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1413 1.1 christos {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1414 1.1 christos /* format 17 */
1415 1.1 christos {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1416 1.1 christos /* format 16 */
1417 1.1 christos {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1418 1.1 christos {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1419 1.1 christos /* format 18 */
1420 1.1 christos {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1421 1.1 christos
1422 1.1 christos /* The E800 .. FFFF range is unconditionally redirected to the
1423 1.1 christos 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1424 1.1 christos are processed via that table. Thus, we can never encounter a
1425 1.1 christos bare "second half of BL/BLX(1)" instruction here. */
1426 1.1 christos {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1427 1.1 christos {0, 0, 0, 0}
1428 1.1 christos };
1429 1.1 christos
1430 1.1 christos /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1431 1.1 christos We adopt the convention that hw1 is the high 16 bits of .value and
1432 1.1 christos .mask, hw2 the low 16 bits.
1433 1.1 christos
1434 1.1 christos print_insn_thumb32 recognizes the following format control codes:
1435 1.1 christos
1436 1.1 christos %% %
1437 1.1 christos
1438 1.1 christos %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1439 1.1 christos %M print a modified 12-bit immediate (same location)
1440 1.1 christos %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1441 1.1 christos %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1442 1.1 christos %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1443 1.1 christos %S print a possibly-shifted Rm
1444 1.1 christos
1445 1.1.1.1.2.1 yamt %L print address for a ldrd/strd instruction
1446 1.1 christos %a print the address of a plain load/store
1447 1.1 christos %w print the width and signedness of a core load/store
1448 1.1 christos %m print register mask for ldm/stm
1449 1.1 christos
1450 1.1 christos %E print the lsb and width fields of a bfc/bfi instruction
1451 1.1 christos %F print the lsb and width fields of a sbfx/ubfx instruction
1452 1.1 christos %b print a conditional branch offset
1453 1.1 christos %B print an unconditional branch offset
1454 1.1 christos %s print the shift field of an SSAT instruction
1455 1.1 christos %R print the rotation field of an SXT instruction
1456 1.1 christos %U print barrier type.
1457 1.1 christos %P print address for pli instruction.
1458 1.1 christos %c print the condition code
1459 1.1 christos %x print warning if conditional an not at end of IT block"
1460 1.1 christos %X print "\t; unpredictable <IT:code>" if conditional
1461 1.1 christos
1462 1.1 christos %<bitfield>d print bitfield in decimal
1463 1.1 christos %<bitfield>W print bitfield*4 in decimal
1464 1.1 christos %<bitfield>r print bitfield as an ARM register
1465 1.1.1.1.2.1 yamt %<bitfield>R as %<>r but r15 is UNPREDICTABLE
1466 1.1.1.1.2.1 yamt %<bitfield>S as %<>R but r13 is UNPREDICTABLE
1467 1.1 christos %<bitfield>c print bitfield as a condition code
1468 1.1 christos
1469 1.1 christos %<bitfield>'c print specified char iff bitfield is all ones
1470 1.1 christos %<bitfield>`c print specified char iff bitfield is all zeroes
1471 1.1 christos %<bitfield>?ab... select from array of values in big endian order
1472 1.1 christos
1473 1.1 christos With one exception at the bottom (done because BL and BLX(1) need
1474 1.1 christos to come dead last), this table was machine-sorted first in
1475 1.1 christos decreasing order of number of bits set in the mask, then in
1476 1.1 christos increasing numeric order of mask, then in increasing numeric order
1477 1.1 christos of opcode. This order is not the clearest for a human reader, but
1478 1.1 christos is guaranteed never to catch a special-case bit pattern with a more
1479 1.1 christos general mask, which is important, because this instruction encoding
1480 1.1 christos makes heavy use of special-case bit patterns. */
1481 1.1 christos static const struct opcode32 thumb32_opcodes[] =
1482 1.1 christos {
1483 1.1.1.1.2.1 yamt /* V8 instructions. */
1484 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf3af8005, 0xffffffff, "sevl%c.w"},
1485 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf78f8000, 0xfffffffc, "dcps%0-1d"},
1486 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00f8f, 0xfff00fff, "stlb%c\t%12-15r, [%16-19R]"},
1487 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00f9f, 0xfff00fff, "stlh%c\t%12-15r, [%16-19R]"},
1488 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00faf, 0xfff00fff, "stl%c\t%12-15r, [%16-19R]"},
1489 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00fc0, 0xfff00ff0, "stlexb%c\t%0-3r, %12-15r, [%16-19R]"},
1490 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00fd0, 0xfff00ff0, "stlexh%c\t%0-3r, %12-15r, [%16-19R]"},
1491 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c00fe0, 0xfff00ff0, "stlex%c\t%0-3r, %12-15r, [%16-19R]"},
1492 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8c000f0, 0xfff000f0, "stlexd%c\t%0-3r, %12-15r, %8-11r, [%16-19R]"},
1493 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00f8f, 0xfff00fff, "ldab%c\t%12-15r, [%16-19R]"},
1494 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00f9f, 0xfff00fff, "ldah%c\t%12-15r, [%16-19R]"},
1495 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00faf, 0xfff00fff, "lda%c\t%12-15r, [%16-19R]"},
1496 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00fcf, 0xfff00fff, "ldaexb%c\t%12-15r, [%16-19R]"},
1497 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00fdf, 0xfff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
1498 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d00fef, 0xfff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
1499 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xe8d000ff, 0xfff000ff, "ldaexd%c\t%12-15r, %8-11r, [%16-19R]"},
1500 1.1.1.1.2.1 yamt
1501 1.1.1.1.2.1 yamt /* CRC32 instructions. */
1502 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11S, %16-19S, %0-3S"},
1503 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11S, %16-19S, %0-3S"},
1504 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11S, %16-19S, %0-3S"},
1505 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11S, %16-19S, %0-3S"},
1506 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11S, %16-19S, %0-3S"},
1507 1.1.1.1.2.1 yamt {CRC_EXT_ARMV8, 0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11S, %16-19S, %0-3S"},
1508 1.1.1.1.2.1 yamt
1509 1.1 christos /* V7 instructions. */
1510 1.1 christos {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1511 1.1 christos {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1512 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf3bf8f51, 0xfffffff3, "dmb%c\t%U"},
1513 1.1.1.1.2.1 yamt {ARM_EXT_V8, 0xf3bf8f41, 0xfffffff3, "dsb%c\t%U"},
1514 1.1 christos {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1515 1.1 christos {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1516 1.1 christos {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1517 1.1 christos {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1518 1.1 christos {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1519 1.1 christos
1520 1.1 christos /* Virtualization Extension instructions. */
1521 1.1 christos {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1522 1.1 christos /* We skip ERET as that is SUBS pc, lr, #0. */
1523 1.1 christos
1524 1.1 christos /* MP Extension instructions. */
1525 1.1 christos {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1526 1.1 christos
1527 1.1 christos /* Security extension instructions. */
1528 1.1 christos {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1529 1.1 christos
1530 1.1 christos /* Instructions defined in the basic V6T2 set. */
1531 1.1 christos {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1532 1.1 christos {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1533 1.1 christos {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1534 1.1 christos {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1535 1.1 christos {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1536 1.1 christos {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1537 1.1 christos
1538 1.1 christos {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1539 1.1 christos {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1540 1.1 christos {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1541 1.1 christos {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1542 1.1 christos {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1543 1.1 christos {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1544 1.1 christos {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1545 1.1 christos {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1546 1.1 christos {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1547 1.1 christos {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1548 1.1 christos {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1549 1.1 christos {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1550 1.1 christos {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1551 1.1 christos {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1552 1.1 christos {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1553 1.1 christos {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1554 1.1 christos {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1555 1.1 christos {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1556 1.1 christos {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1557 1.1 christos {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1558 1.1 christos {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1559 1.1 christos {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1560 1.1 christos {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1561 1.1 christos {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1562 1.1 christos {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1563 1.1 christos {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1564 1.1 christos {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1565 1.1 christos {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1566 1.1 christos {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1567 1.1 christos {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1568 1.1 christos {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1569 1.1 christos {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1570 1.1 christos {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1571 1.1 christos {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1572 1.1 christos {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1573 1.1 christos {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1574 1.1 christos {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1575 1.1 christos {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1576 1.1 christos {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1577 1.1 christos {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1578 1.1 christos {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1579 1.1 christos {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1580 1.1 christos {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1581 1.1 christos {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1582 1.1 christos {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1583 1.1 christos {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1584 1.1 christos {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1585 1.1 christos {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1586 1.1 christos {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1587 1.1 christos {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1588 1.1 christos {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1589 1.1 christos {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1590 1.1 christos {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1591 1.1 christos {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1592 1.1 christos {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1593 1.1 christos {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1594 1.1 christos {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1595 1.1 christos {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1596 1.1 christos {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1597 1.1 christos {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1598 1.1 christos {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1599 1.1 christos {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1600 1.1 christos {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1601 1.1 christos {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1602 1.1 christos {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1603 1.1 christos {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1604 1.1 christos {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1605 1.1 christos {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1606 1.1 christos {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1607 1.1 christos {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1608 1.1 christos {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1609 1.1 christos {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1610 1.1 christos {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1611 1.1 christos {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1612 1.1 christos {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1613 1.1 christos {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1614 1.1 christos {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1615 1.1 christos {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1616 1.1 christos {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1617 1.1 christos {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1618 1.1 christos {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1619 1.1 christos {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1620 1.1 christos {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1621 1.1 christos {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1622 1.1 christos {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1623 1.1 christos {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1624 1.1 christos {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1625 1.1 christos {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1626 1.1 christos {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1627 1.1 christos {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1628 1.1 christos {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1629 1.1 christos {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1630 1.1 christos {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1631 1.1 christos {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1632 1.1 christos {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1633 1.1 christos {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1634 1.1 christos {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1635 1.1 christos {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1636 1.1 christos {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1637 1.1 christos {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1638 1.1 christos {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1639 1.1 christos {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1640 1.1 christos {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1641 1.1 christos {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1642 1.1 christos {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1643 1.1 christos {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1644 1.1 christos {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1645 1.1 christos {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1646 1.1 christos {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1647 1.1 christos {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1648 1.1 christos {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1649 1.1 christos {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1650 1.1 christos {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1651 1.1 christos {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1652 1.1 christos {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1653 1.1 christos {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1654 1.1 christos {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1655 1.1 christos {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1656 1.1 christos {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1657 1.1 christos {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1658 1.1 christos {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1659 1.1 christos {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1660 1.1 christos {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1661 1.1 christos {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1662 1.1 christos {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1663 1.1 christos {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1664 1.1 christos {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1665 1.1 christos {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1666 1.1 christos {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1667 1.1 christos {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1668 1.1 christos {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1669 1.1 christos {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1670 1.1 christos {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1671 1.1 christos {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1672 1.1 christos {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1673 1.1 christos {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1674 1.1 christos {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1675 1.1 christos {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1676 1.1 christos {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1677 1.1 christos {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1678 1.1 christos {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1679 1.1 christos {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1680 1.1 christos {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1681 1.1 christos {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1682 1.1 christos {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1683 1.1 christos {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1684 1.1 christos {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1685 1.1 christos {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1686 1.1 christos {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1687 1.1 christos {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1688 1.1 christos {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1689 1.1 christos {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1690 1.1 christos {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1691 1.1 christos {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1692 1.1 christos {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1693 1.1 christos {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1694 1.1 christos {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1695 1.1 christos {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1696 1.1 christos {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1697 1.1 christos {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1698 1.1 christos {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1699 1.1 christos {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1700 1.1 christos {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1701 1.1 christos {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1702 1.1 christos {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1703 1.1.1.1.2.1 yamt {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1704 1.1.1.1.2.1 yamt {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1705 1.1.1.1.2.1 yamt {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1706 1.1.1.1.2.1 yamt {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1707 1.1 christos {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1708 1.1 christos {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1709 1.1 christos
1710 1.1 christos /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1711 1.1 christos {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1712 1.1 christos {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1713 1.1 christos {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1714 1.1 christos {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1715 1.1 christos
1716 1.1 christos /* These have been 32-bit since the invention of Thumb. */
1717 1.1 christos {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1718 1.1 christos {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1719 1.1 christos
1720 1.1 christos /* Fallback. */
1721 1.1 christos {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1722 1.1 christos {0, 0, 0, 0}
1723 1.1 christos };
1724 1.1 christos
1725 1.1 christos static const char *const arm_conditional[] =
1726 1.1 christos {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1727 1.1 christos "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1728 1.1 christos
1729 1.1 christos static const char *const arm_fp_const[] =
1730 1.1 christos {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1731 1.1 christos
1732 1.1 christos static const char *const arm_shift[] =
1733 1.1 christos {"lsl", "lsr", "asr", "ror"};
1734 1.1 christos
1735 1.1 christos typedef struct
1736 1.1 christos {
1737 1.1 christos const char *name;
1738 1.1 christos const char *description;
1739 1.1 christos const char *reg_names[16];
1740 1.1 christos }
1741 1.1 christos arm_regname;
1742 1.1 christos
1743 1.1 christos static const arm_regname regnames[] =
1744 1.1 christos {
1745 1.1 christos { "raw" , "Select raw register names",
1746 1.1 christos { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1747 1.1 christos { "gcc", "Select register names used by GCC",
1748 1.1 christos { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1749 1.1 christos { "std", "Select register names used in ARM's ISA documentation",
1750 1.1 christos { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1751 1.1 christos { "apcs", "Select register names used in the APCS",
1752 1.1 christos { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1753 1.1 christos { "atpcs", "Select register names used in the ATPCS",
1754 1.1 christos { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1755 1.1 christos { "special-atpcs", "Select special register names used in the ATPCS",
1756 1.1 christos { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1757 1.1 christos };
1758 1.1 christos
1759 1.1 christos static const char *const iwmmxt_wwnames[] =
1760 1.1 christos {"b", "h", "w", "d"};
1761 1.1 christos
1762 1.1 christos static const char *const iwmmxt_wwssnames[] =
1763 1.1 christos {"b", "bus", "bc", "bss",
1764 1.1 christos "h", "hus", "hc", "hss",
1765 1.1 christos "w", "wus", "wc", "wss",
1766 1.1 christos "d", "dus", "dc", "dss"
1767 1.1 christos };
1768 1.1 christos
1769 1.1 christos static const char *const iwmmxt_regnames[] =
1770 1.1 christos { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1771 1.1 christos "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1772 1.1 christos };
1773 1.1 christos
1774 1.1 christos static const char *const iwmmxt_cregnames[] =
1775 1.1 christos { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1776 1.1 christos "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1777 1.1 christos };
1778 1.1 christos
1779 1.1 christos /* Default to GCC register name set. */
1780 1.1 christos static unsigned int regname_selected = 1;
1781 1.1 christos
1782 1.1 christos #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1783 1.1 christos #define arm_regnames regnames[regname_selected].reg_names
1784 1.1 christos
1785 1.1 christos static bfd_boolean force_thumb = FALSE;
1786 1.1 christos
1787 1.1 christos /* Current IT instruction state. This contains the same state as the IT
1788 1.1 christos bits in the CPSR. */
1789 1.1 christos static unsigned int ifthen_state;
1790 1.1 christos /* IT state for the next instruction. */
1791 1.1 christos static unsigned int ifthen_next_state;
1792 1.1 christos /* The address of the insn for which the IT state is valid. */
1793 1.1 christos static bfd_vma ifthen_address;
1794 1.1 christos #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1795 1.1.1.1.2.1 yamt /* Indicates that the current Conditional state is unconditional or outside
1796 1.1.1.1.2.1 yamt an IT block. */
1797 1.1.1.1.2.1 yamt #define COND_UNCOND 16
1798 1.1 christos
1799 1.1 christos
1800 1.1 christos /* Functions. */
1802 1.1 christos int
1803 1.1 christos get_arm_regname_num_options (void)
1804 1.1 christos {
1805 1.1 christos return NUM_ARM_REGNAMES;
1806 1.1 christos }
1807 1.1 christos
1808 1.1 christos int
1809 1.1 christos set_arm_regname_option (int option)
1810 1.1 christos {
1811 1.1 christos int old = regname_selected;
1812 1.1 christos regname_selected = option;
1813 1.1 christos return old;
1814 1.1 christos }
1815 1.1 christos
1816 1.1 christos int
1817 1.1 christos get_arm_regnames (int option,
1818 1.1 christos const char **setname,
1819 1.1 christos const char **setdescription,
1820 1.1 christos const char *const **register_names)
1821 1.1 christos {
1822 1.1 christos *setname = regnames[option].name;
1823 1.1 christos *setdescription = regnames[option].description;
1824 1.1 christos *register_names = regnames[option].reg_names;
1825 1.1 christos return 16;
1826 1.1 christos }
1827 1.1 christos
1828 1.1 christos /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1829 1.1 christos Returns pointer to following character of the format string and
1830 1.1 christos fills in *VALUEP and *WIDTHP with the extracted value and number of
1831 1.1 christos bits extracted. WIDTHP can be NULL. */
1832 1.1 christos
1833 1.1 christos static const char *
1834 1.1 christos arm_decode_bitfield (const char *ptr,
1835 1.1 christos unsigned long insn,
1836 1.1 christos unsigned long *valuep,
1837 1.1 christos int *widthp)
1838 1.1 christos {
1839 1.1 christos unsigned long value = 0;
1840 1.1 christos int width = 0;
1841 1.1 christos
1842 1.1 christos do
1843 1.1 christos {
1844 1.1 christos int start, end;
1845 1.1 christos int bits;
1846 1.1 christos
1847 1.1 christos for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1848 1.1 christos start = start * 10 + *ptr - '0';
1849 1.1 christos if (*ptr == '-')
1850 1.1 christos for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1851 1.1 christos end = end * 10 + *ptr - '0';
1852 1.1 christos else
1853 1.1 christos end = start;
1854 1.1 christos bits = end - start;
1855 1.1 christos if (bits < 0)
1856 1.1 christos abort ();
1857 1.1 christos value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1858 1.1 christos width += bits + 1;
1859 1.1 christos }
1860 1.1 christos while (*ptr++ == ',');
1861 1.1 christos *valuep = value;
1862 1.1 christos if (widthp)
1863 1.1 christos *widthp = width;
1864 1.1 christos return ptr - 1;
1865 1.1 christos }
1866 1.1 christos
1867 1.1 christos static void
1868 1.1 christos arm_decode_shift (long given, fprintf_ftype func, void *stream,
1869 1.1 christos bfd_boolean print_shift)
1870 1.1 christos {
1871 1.1 christos func (stream, "%s", arm_regnames[given & 0xf]);
1872 1.1 christos
1873 1.1 christos if ((given & 0xff0) != 0)
1874 1.1 christos {
1875 1.1 christos if ((given & 0x10) == 0)
1876 1.1 christos {
1877 1.1 christos int amount = (given & 0xf80) >> 7;
1878 1.1 christos int shift = (given & 0x60) >> 5;
1879 1.1 christos
1880 1.1 christos if (amount == 0)
1881 1.1 christos {
1882 1.1 christos if (shift == 3)
1883 1.1 christos {
1884 1.1 christos func (stream, ", rrx");
1885 1.1 christos return;
1886 1.1 christos }
1887 1.1 christos
1888 1.1 christos amount = 32;
1889 1.1 christos }
1890 1.1 christos
1891 1.1 christos if (print_shift)
1892 1.1 christos func (stream, ", %s #%d", arm_shift[shift], amount);
1893 1.1 christos else
1894 1.1 christos func (stream, ", #%d", amount);
1895 1.1 christos }
1896 1.1 christos else if ((given & 0x80) == 0x80)
1897 1.1 christos func (stream, "\t; <illegal shifter operand>");
1898 1.1 christos else if (print_shift)
1899 1.1 christos func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1900 1.1 christos arm_regnames[(given & 0xf00) >> 8]);
1901 1.1 christos else
1902 1.1 christos func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1903 1.1 christos }
1904 1.1 christos }
1905 1.1 christos
1906 1.1 christos #define W_BIT 21
1907 1.1 christos #define I_BIT 22
1908 1.1 christos #define U_BIT 23
1909 1.1 christos #define P_BIT 24
1910 1.1 christos
1911 1.1 christos #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1912 1.1 christos #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1913 1.1 christos #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1914 1.1 christos #define PRE_BIT_SET (given & (1 << P_BIT))
1915 1.1 christos
1916 1.1 christos /* Print one coprocessor instruction on INFO->STREAM.
1917 1.1 christos Return TRUE if the instuction matched, FALSE if this is not a
1918 1.1 christos recognised coprocessor instruction. */
1919 1.1 christos
1920 1.1 christos static bfd_boolean
1921 1.1 christos print_insn_coprocessor (bfd_vma pc,
1922 1.1 christos struct disassemble_info *info,
1923 1.1 christos long given,
1924 1.1 christos bfd_boolean thumb)
1925 1.1 christos {
1926 1.1 christos const struct opcode32 *insn;
1927 1.1 christos void *stream = info->stream;
1928 1.1 christos fprintf_ftype func = info->fprintf_func;
1929 1.1 christos unsigned long mask;
1930 1.1 christos unsigned long value = 0;
1931 1.1 christos struct arm_private_data *private_data = info->private_data;
1932 1.1 christos unsigned long allowed_arches = private_data->features.coproc;
1933 1.1 christos int cond;
1934 1.1 christos
1935 1.1 christos for (insn = coprocessor_opcodes; insn->assembler; insn++)
1936 1.1 christos {
1937 1.1 christos unsigned long u_reg = 16;
1938 1.1 christos bfd_boolean is_unpredictable = FALSE;
1939 1.1 christos signed long value_in_comment = 0;
1940 1.1 christos const char *c;
1941 1.1 christos
1942 1.1 christos if (insn->arch == 0)
1943 1.1 christos switch (insn->value)
1944 1.1 christos {
1945 1.1 christos case SENTINEL_IWMMXT_START:
1946 1.1 christos if (info->mach != bfd_mach_arm_XScale
1947 1.1 christos && info->mach != bfd_mach_arm_iWMMXt
1948 1.1 christos && info->mach != bfd_mach_arm_iWMMXt2)
1949 1.1 christos do
1950 1.1 christos insn++;
1951 1.1 christos while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1952 1.1 christos continue;
1953 1.1 christos
1954 1.1 christos case SENTINEL_IWMMXT_END:
1955 1.1 christos continue;
1956 1.1 christos
1957 1.1 christos case SENTINEL_GENERIC_START:
1958 1.1 christos allowed_arches = private_data->features.core;
1959 1.1 christos continue;
1960 1.1 christos
1961 1.1 christos default:
1962 1.1 christos abort ();
1963 1.1 christos }
1964 1.1 christos
1965 1.1 christos mask = insn->mask;
1966 1.1 christos value = insn->value;
1967 1.1 christos if (thumb)
1968 1.1 christos {
1969 1.1 christos /* The high 4 bits are 0xe for Arm conditional instructions, and
1970 1.1 christos 0xe for arm unconditional instructions. The rest of the
1971 1.1 christos encoding is the same. */
1972 1.1 christos mask |= 0xf0000000;
1973 1.1 christos value |= 0xe0000000;
1974 1.1 christos if (ifthen_state)
1975 1.1 christos cond = IFTHEN_COND;
1976 1.1.1.1.2.1 yamt else
1977 1.1 christos cond = COND_UNCOND;
1978 1.1 christos }
1979 1.1 christos else
1980 1.1 christos {
1981 1.1 christos /* Only match unconditional instuctions against unconditional
1982 1.1 christos patterns. */
1983 1.1 christos if ((given & 0xf0000000) == 0xf0000000)
1984 1.1 christos {
1985 1.1.1.1.2.1 yamt mask |= 0xf0000000;
1986 1.1 christos cond = COND_UNCOND;
1987 1.1 christos }
1988 1.1 christos else
1989 1.1 christos {
1990 1.1 christos cond = (given >> 28) & 0xf;
1991 1.1.1.1.2.1 yamt if (cond == 0xe)
1992 1.1 christos cond = COND_UNCOND;
1993 1.1 christos }
1994 1.1 christos }
1995 1.1 christos
1996 1.1 christos if ((given & mask) != value)
1997 1.1 christos continue;
1998 1.1 christos
1999 1.1 christos if ((insn->arch & allowed_arches) == 0)
2000 1.1 christos continue;
2001 1.1 christos
2002 1.1 christos for (c = insn->assembler; *c; c++)
2003 1.1 christos {
2004 1.1 christos if (*c == '%')
2005 1.1 christos {
2006 1.1 christos switch (*++c)
2007 1.1 christos {
2008 1.1 christos case '%':
2009 1.1 christos func (stream, "%%");
2010 1.1 christos break;
2011 1.1 christos
2012 1.1 christos case 'A':
2013 1.1 christos {
2014 1.1.1.1.2.1 yamt int rn = (given >> 16) & 0xf;
2015 1.1 christos bfd_vma offset = given & 0xff;
2016 1.1 christos
2017 1.1 christos func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2018 1.1 christos
2019 1.1 christos if (PRE_BIT_SET || WRITEBACK_BIT_SET)
2020 1.1 christos {
2021 1.1 christos /* Not unindexed. The offset is scaled. */
2022 1.1 christos offset = offset * 4;
2023 1.1 christos if (NEGATIVE_BIT_SET)
2024 1.1 christos offset = - offset;
2025 1.1 christos if (rn != 15)
2026 1.1 christos value_in_comment = offset;
2027 1.1 christos }
2028 1.1 christos
2029 1.1 christos if (PRE_BIT_SET)
2030 1.1 christos {
2031 1.1 christos if (offset)
2032 1.1.1.1.2.1 yamt func (stream, ", #%d]%s",
2033 1.1 christos (int) offset,
2034 1.1.1.1.2.1 yamt WRITEBACK_BIT_SET ? "!" : "");
2035 1.1.1.1.2.1 yamt else if (NEGATIVE_BIT_SET)
2036 1.1 christos func (stream, ", #-0]");
2037 1.1 christos else
2038 1.1 christos func (stream, "]");
2039 1.1 christos }
2040 1.1 christos else
2041 1.1 christos {
2042 1.1 christos func (stream, "]");
2043 1.1 christos
2044 1.1 christos if (WRITEBACK_BIT_SET)
2045 1.1 christos {
2046 1.1.1.1.2.1 yamt if (offset)
2047 1.1.1.1.2.1 yamt func (stream, ", #%d", (int) offset);
2048 1.1.1.1.2.1 yamt else if (NEGATIVE_BIT_SET)
2049 1.1 christos func (stream, ", #-0");
2050 1.1 christos }
2051 1.1 christos else
2052 1.1.1.1.2.1 yamt {
2053 1.1.1.1.2.1 yamt func (stream, ", {%s%d}",
2054 1.1.1.1.2.1 yamt (NEGATIVE_BIT_SET && !offset) ? "-" : "",
2055 1.1 christos (int) offset);
2056 1.1 christos value_in_comment = offset;
2057 1.1 christos }
2058 1.1 christos }
2059 1.1 christos if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
2060 1.1 christos {
2061 1.1 christos func (stream, "\t; ");
2062 1.1 christos /* For unaligned PCs, apply off-by-alignment
2063 1.1 christos correction. */
2064 1.1 christos info->print_address_func (offset + pc
2065 1.1 christos + info->bytes_per_chunk * 2
2066 1.1 christos - (pc & 3),
2067 1.1 christos info);
2068 1.1 christos }
2069 1.1 christos }
2070 1.1 christos break;
2071 1.1 christos
2072 1.1 christos case 'B':
2073 1.1 christos {
2074 1.1 christos int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
2075 1.1 christos int offset = (given >> 1) & 0x3f;
2076 1.1 christos
2077 1.1 christos if (offset == 1)
2078 1.1 christos func (stream, "{d%d}", regno);
2079 1.1 christos else if (regno + offset > 32)
2080 1.1 christos func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
2081 1.1 christos else
2082 1.1 christos func (stream, "{d%d-d%d}", regno, regno + offset - 1);
2083 1.1 christos }
2084 1.1 christos break;
2085 1.1.1.1.2.1 yamt
2086 1.1.1.1.2.1 yamt case 'u':
2087 1.1.1.1.2.1 yamt if (cond != COND_UNCOND)
2088 1.1.1.1.2.1 yamt is_unpredictable = TRUE;
2089 1.1.1.1.2.1 yamt
2090 1.1 christos /* Fall through. */
2091 1.1 christos case 'c':
2092 1.1 christos func (stream, "%s", arm_conditional[cond]);
2093 1.1 christos break;
2094 1.1 christos
2095 1.1 christos case 'I':
2096 1.1 christos /* Print a Cirrus/DSP shift immediate. */
2097 1.1 christos /* Immediates are 7bit signed ints with bits 0..3 in
2098 1.1 christos bits 0..3 of opcode and bits 4..6 in bits 5..7
2099 1.1 christos of opcode. */
2100 1.1 christos {
2101 1.1 christos int imm;
2102 1.1 christos
2103 1.1 christos imm = (given & 0xf) | ((given & 0xe0) >> 1);
2104 1.1 christos
2105 1.1 christos /* Is ``imm'' a negative number? */
2106 1.1 christos if (imm & 0x40)
2107 1.1 christos imm |= (-1 << 7);
2108 1.1 christos
2109 1.1 christos func (stream, "%d", imm);
2110 1.1 christos }
2111 1.1 christos
2112 1.1 christos break;
2113 1.1 christos
2114 1.1 christos case 'F':
2115 1.1 christos switch (given & 0x00408000)
2116 1.1 christos {
2117 1.1 christos case 0:
2118 1.1 christos func (stream, "4");
2119 1.1 christos break;
2120 1.1 christos case 0x8000:
2121 1.1 christos func (stream, "1");
2122 1.1 christos break;
2123 1.1 christos case 0x00400000:
2124 1.1 christos func (stream, "2");
2125 1.1 christos break;
2126 1.1 christos default:
2127 1.1 christos func (stream, "3");
2128 1.1 christos }
2129 1.1 christos break;
2130 1.1 christos
2131 1.1 christos case 'P':
2132 1.1 christos switch (given & 0x00080080)
2133 1.1 christos {
2134 1.1 christos case 0:
2135 1.1 christos func (stream, "s");
2136 1.1 christos break;
2137 1.1 christos case 0x80:
2138 1.1 christos func (stream, "d");
2139 1.1 christos break;
2140 1.1 christos case 0x00080000:
2141 1.1 christos func (stream, "e");
2142 1.1 christos break;
2143 1.1 christos default:
2144 1.1 christos func (stream, _("<illegal precision>"));
2145 1.1 christos break;
2146 1.1 christos }
2147 1.1 christos break;
2148 1.1 christos
2149 1.1 christos case 'Q':
2150 1.1 christos switch (given & 0x00408000)
2151 1.1 christos {
2152 1.1 christos case 0:
2153 1.1 christos func (stream, "s");
2154 1.1 christos break;
2155 1.1 christos case 0x8000:
2156 1.1 christos func (stream, "d");
2157 1.1 christos break;
2158 1.1 christos case 0x00400000:
2159 1.1 christos func (stream, "e");
2160 1.1 christos break;
2161 1.1 christos default:
2162 1.1 christos func (stream, "p");
2163 1.1 christos break;
2164 1.1 christos }
2165 1.1 christos break;
2166 1.1 christos
2167 1.1 christos case 'R':
2168 1.1 christos switch (given & 0x60)
2169 1.1 christos {
2170 1.1 christos case 0:
2171 1.1 christos break;
2172 1.1 christos case 0x20:
2173 1.1 christos func (stream, "p");
2174 1.1 christos break;
2175 1.1 christos case 0x40:
2176 1.1 christos func (stream, "m");
2177 1.1 christos break;
2178 1.1 christos default:
2179 1.1 christos func (stream, "z");
2180 1.1 christos break;
2181 1.1 christos }
2182 1.1 christos break;
2183 1.1 christos
2184 1.1 christos case '0': case '1': case '2': case '3': case '4':
2185 1.1 christos case '5': case '6': case '7': case '8': case '9':
2186 1.1 christos {
2187 1.1 christos int width;
2188 1.1 christos
2189 1.1 christos c = arm_decode_bitfield (c, given, &value, &width);
2190 1.1 christos
2191 1.1 christos switch (*c)
2192 1.1 christos {
2193 1.1 christos case 'R':
2194 1.1 christos if (value == 15)
2195 1.1 christos is_unpredictable = TRUE;
2196 1.1 christos /* Fall through. */
2197 1.1 christos case 'r':
2198 1.1 christos if (c[1] == 'u')
2199 1.1 christos {
2200 1.1 christos /* Eat the 'u' character. */
2201 1.1 christos ++ c;
2202 1.1 christos
2203 1.1 christos if (u_reg == value)
2204 1.1 christos is_unpredictable = TRUE;
2205 1.1 christos u_reg = value;
2206 1.1 christos }
2207 1.1 christos func (stream, "%s", arm_regnames[value]);
2208 1.1 christos break;
2209 1.1 christos case 'D':
2210 1.1 christos func (stream, "d%ld", value);
2211 1.1 christos break;
2212 1.1 christos case 'Q':
2213 1.1 christos if (value & 1)
2214 1.1 christos func (stream, "<illegal reg q%ld.5>", value >> 1);
2215 1.1 christos else
2216 1.1 christos func (stream, "q%ld", value >> 1);
2217 1.1 christos break;
2218 1.1 christos case 'd':
2219 1.1 christos func (stream, "%ld", value);
2220 1.1 christos value_in_comment = value;
2221 1.1 christos break;
2222 1.1 christos case 'k':
2223 1.1 christos {
2224 1.1 christos int from = (given & (1 << 7)) ? 32 : 16;
2225 1.1 christos func (stream, "%ld", from - value);
2226 1.1 christos }
2227 1.1 christos break;
2228 1.1 christos
2229 1.1 christos case 'f':
2230 1.1 christos if (value > 7)
2231 1.1 christos func (stream, "#%s", arm_fp_const[value & 7]);
2232 1.1 christos else
2233 1.1 christos func (stream, "f%ld", value);
2234 1.1 christos break;
2235 1.1 christos
2236 1.1 christos case 'w':
2237 1.1 christos if (width == 2)
2238 1.1 christos func (stream, "%s", iwmmxt_wwnames[value]);
2239 1.1 christos else
2240 1.1 christos func (stream, "%s", iwmmxt_wwssnames[value]);
2241 1.1 christos break;
2242 1.1 christos
2243 1.1 christos case 'g':
2244 1.1 christos func (stream, "%s", iwmmxt_regnames[value]);
2245 1.1 christos break;
2246 1.1 christos case 'G':
2247 1.1 christos func (stream, "%s", iwmmxt_cregnames[value]);
2248 1.1 christos break;
2249 1.1 christos
2250 1.1 christos case 'x':
2251 1.1 christos func (stream, "0x%lx", (value & 0xffffffffUL));
2252 1.1 christos break;
2253 1.1.1.1.2.1 yamt
2254 1.1.1.1.2.1 yamt case 'c':
2255 1.1.1.1.2.1 yamt switch (value)
2256 1.1.1.1.2.1 yamt {
2257 1.1.1.1.2.1 yamt case 0:
2258 1.1.1.1.2.1 yamt func (stream, "eq");
2259 1.1.1.1.2.1 yamt break;
2260 1.1.1.1.2.1 yamt
2261 1.1.1.1.2.1 yamt case 1:
2262 1.1.1.1.2.1 yamt func (stream, "vs");
2263 1.1.1.1.2.1 yamt break;
2264 1.1.1.1.2.1 yamt
2265 1.1.1.1.2.1 yamt case 2:
2266 1.1.1.1.2.1 yamt func (stream, "ge");
2267 1.1.1.1.2.1 yamt break;
2268 1.1.1.1.2.1 yamt
2269 1.1.1.1.2.1 yamt case 3:
2270 1.1.1.1.2.1 yamt func (stream, "gt");
2271 1.1.1.1.2.1 yamt break;
2272 1.1.1.1.2.1 yamt
2273 1.1.1.1.2.1 yamt default:
2274 1.1.1.1.2.1 yamt func (stream, "??");
2275 1.1.1.1.2.1 yamt break;
2276 1.1.1.1.2.1 yamt }
2277 1.1.1.1.2.1 yamt break;
2278 1.1 christos
2279 1.1 christos case '`':
2280 1.1 christos c++;
2281 1.1 christos if (value == 0)
2282 1.1 christos func (stream, "%c", *c);
2283 1.1 christos break;
2284 1.1 christos case '\'':
2285 1.1 christos c++;
2286 1.1 christos if (value == ((1ul << width) - 1))
2287 1.1 christos func (stream, "%c", *c);
2288 1.1 christos break;
2289 1.1 christos case '?':
2290 1.1 christos func (stream, "%c", c[(1 << width) - (int) value]);
2291 1.1 christos c += 1 << width;
2292 1.1 christos break;
2293 1.1 christos default:
2294 1.1 christos abort ();
2295 1.1 christos }
2296 1.1 christos break;
2297 1.1 christos
2298 1.1 christos case 'y':
2299 1.1 christos case 'z':
2300 1.1 christos {
2301 1.1 christos int single = *c++ == 'y';
2302 1.1 christos int regno;
2303 1.1 christos
2304 1.1 christos switch (*c)
2305 1.1 christos {
2306 1.1 christos case '4': /* Sm pair */
2307 1.1 christos case '0': /* Sm, Dm */
2308 1.1 christos regno = given & 0x0000000f;
2309 1.1 christos if (single)
2310 1.1 christos {
2311 1.1 christos regno <<= 1;
2312 1.1 christos regno += (given >> 5) & 1;
2313 1.1 christos }
2314 1.1 christos else
2315 1.1 christos regno += ((given >> 5) & 1) << 4;
2316 1.1 christos break;
2317 1.1 christos
2318 1.1 christos case '1': /* Sd, Dd */
2319 1.1 christos regno = (given >> 12) & 0x0000000f;
2320 1.1 christos if (single)
2321 1.1 christos {
2322 1.1 christos regno <<= 1;
2323 1.1 christos regno += (given >> 22) & 1;
2324 1.1 christos }
2325 1.1 christos else
2326 1.1 christos regno += ((given >> 22) & 1) << 4;
2327 1.1 christos break;
2328 1.1 christos
2329 1.1 christos case '2': /* Sn, Dn */
2330 1.1 christos regno = (given >> 16) & 0x0000000f;
2331 1.1 christos if (single)
2332 1.1 christos {
2333 1.1 christos regno <<= 1;
2334 1.1 christos regno += (given >> 7) & 1;
2335 1.1 christos }
2336 1.1 christos else
2337 1.1 christos regno += ((given >> 7) & 1) << 4;
2338 1.1 christos break;
2339 1.1 christos
2340 1.1 christos case '3': /* List */
2341 1.1 christos func (stream, "{");
2342 1.1 christos regno = (given >> 12) & 0x0000000f;
2343 1.1 christos if (single)
2344 1.1 christos {
2345 1.1 christos regno <<= 1;
2346 1.1 christos regno += (given >> 22) & 1;
2347 1.1 christos }
2348 1.1 christos else
2349 1.1 christos regno += ((given >> 22) & 1) << 4;
2350 1.1 christos break;
2351 1.1 christos
2352 1.1 christos default:
2353 1.1 christos abort ();
2354 1.1 christos }
2355 1.1 christos
2356 1.1 christos func (stream, "%c%d", single ? 's' : 'd', regno);
2357 1.1 christos
2358 1.1 christos if (*c == '3')
2359 1.1 christos {
2360 1.1 christos int count = given & 0xff;
2361 1.1 christos
2362 1.1 christos if (single == 0)
2363 1.1 christos count >>= 1;
2364 1.1 christos
2365 1.1 christos if (--count)
2366 1.1 christos {
2367 1.1 christos func (stream, "-%c%d",
2368 1.1 christos single ? 's' : 'd',
2369 1.1 christos regno + count);
2370 1.1 christos }
2371 1.1 christos
2372 1.1 christos func (stream, "}");
2373 1.1 christos }
2374 1.1 christos else if (*c == '4')
2375 1.1 christos func (stream, ", %c%d", single ? 's' : 'd',
2376 1.1 christos regno + 1);
2377 1.1 christos }
2378 1.1 christos break;
2379 1.1 christos
2380 1.1 christos case 'L':
2381 1.1 christos switch (given & 0x00400100)
2382 1.1 christos {
2383 1.1 christos case 0x00000000: func (stream, "b"); break;
2384 1.1 christos case 0x00400000: func (stream, "h"); break;
2385 1.1 christos case 0x00000100: func (stream, "w"); break;
2386 1.1 christos case 0x00400100: func (stream, "d"); break;
2387 1.1 christos default:
2388 1.1 christos break;
2389 1.1 christos }
2390 1.1 christos break;
2391 1.1 christos
2392 1.1 christos case 'Z':
2393 1.1 christos {
2394 1.1 christos /* given (20, 23) | given (0, 3) */
2395 1.1.1.1.2.1 yamt value = ((given >> 16) & 0xf0) | (given & 0xf);
2396 1.1 christos func (stream, "%d", (int) value);
2397 1.1 christos }
2398 1.1 christos break;
2399 1.1 christos
2400 1.1 christos case 'l':
2401 1.1 christos /* This is like the 'A' operator, except that if
2402 1.1 christos the width field "M" is zero, then the offset is
2403 1.1 christos *not* multiplied by four. */
2404 1.1 christos {
2405 1.1 christos int offset = given & 0xff;
2406 1.1 christos int multiplier = (given & 0x00000100) ? 4 : 1;
2407 1.1 christos
2408 1.1 christos func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2409 1.1 christos
2410 1.1 christos if (multiplier > 1)
2411 1.1 christos {
2412 1.1 christos value_in_comment = offset * multiplier;
2413 1.1 christos if (NEGATIVE_BIT_SET)
2414 1.1 christos value_in_comment = - value_in_comment;
2415 1.1 christos }
2416 1.1 christos
2417 1.1 christos if (offset)
2418 1.1 christos {
2419 1.1 christos if (PRE_BIT_SET)
2420 1.1 christos func (stream, ", #%s%d]%s",
2421 1.1 christos NEGATIVE_BIT_SET ? "-" : "",
2422 1.1 christos offset * multiplier,
2423 1.1 christos WRITEBACK_BIT_SET ? "!" : "");
2424 1.1 christos else
2425 1.1 christos func (stream, "], #%s%d",
2426 1.1 christos NEGATIVE_BIT_SET ? "-" : "",
2427 1.1 christos offset * multiplier);
2428 1.1 christos }
2429 1.1 christos else
2430 1.1 christos func (stream, "]");
2431 1.1 christos }
2432 1.1 christos break;
2433 1.1 christos
2434 1.1 christos case 'r':
2435 1.1 christos {
2436 1.1 christos int imm4 = (given >> 4) & 0xf;
2437 1.1 christos int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2438 1.1 christos int ubit = ! NEGATIVE_BIT_SET;
2439 1.1 christos const char *rm = arm_regnames [given & 0xf];
2440 1.1 christos const char *rn = arm_regnames [(given >> 16) & 0xf];
2441 1.1 christos
2442 1.1 christos switch (puw_bits)
2443 1.1 christos {
2444 1.1 christos case 1:
2445 1.1 christos case 3:
2446 1.1 christos func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2447 1.1 christos if (imm4)
2448 1.1 christos func (stream, ", lsl #%d", imm4);
2449 1.1 christos break;
2450 1.1 christos
2451 1.1 christos case 4:
2452 1.1 christos case 5:
2453 1.1 christos case 6:
2454 1.1 christos case 7:
2455 1.1 christos func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2456 1.1 christos if (imm4 > 0)
2457 1.1 christos func (stream, ", lsl #%d", imm4);
2458 1.1 christos func (stream, "]");
2459 1.1 christos if (puw_bits == 5 || puw_bits == 7)
2460 1.1 christos func (stream, "!");
2461 1.1 christos break;
2462 1.1 christos
2463 1.1 christos default:
2464 1.1 christos func (stream, "INVALID");
2465 1.1 christos }
2466 1.1 christos }
2467 1.1 christos break;
2468 1.1 christos
2469 1.1 christos case 'i':
2470 1.1 christos {
2471 1.1 christos long imm5;
2472 1.1 christos imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2473 1.1 christos func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2474 1.1 christos }
2475 1.1 christos break;
2476 1.1 christos
2477 1.1 christos default:
2478 1.1 christos abort ();
2479 1.1 christos }
2480 1.1 christos }
2481 1.1 christos }
2482 1.1 christos else
2483 1.1 christos func (stream, "%c", *c);
2484 1.1 christos }
2485 1.1 christos
2486 1.1 christos if (value_in_comment > 32 || value_in_comment < -16)
2487 1.1 christos func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2488 1.1 christos
2489 1.1 christos if (is_unpredictable)
2490 1.1 christos func (stream, UNPREDICTABLE_INSTRUCTION);
2491 1.1 christos
2492 1.1 christos return TRUE;
2493 1.1 christos }
2494 1.1 christos return FALSE;
2495 1.1 christos }
2496 1.1 christos
2497 1.1 christos /* Decodes and prints ARM addressing modes. Returns the offset
2498 1.1 christos used in the address, if any, if it is worthwhile printing the
2499 1.1 christos offset as a hexadecimal value in a comment at the end of the
2500 1.1 christos line of disassembly. */
2501 1.1 christos
2502 1.1 christos static signed long
2503 1.1 christos print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2504 1.1 christos {
2505 1.1 christos void *stream = info->stream;
2506 1.1.1.1.2.1 yamt fprintf_ftype func = info->fprintf_func;
2507 1.1 christos bfd_vma offset = 0;
2508 1.1 christos
2509 1.1 christos if (((given & 0x000f0000) == 0x000f0000)
2510 1.1 christos && ((given & 0x02000000) == 0))
2511 1.1 christos {
2512 1.1 christos offset = given & 0xfff;
2513 1.1 christos
2514 1.1 christos func (stream, "[pc");
2515 1.1 christos
2516 1.1 christos if (PRE_BIT_SET)
2517 1.1.1.1.2.1 yamt {
2518 1.1.1.1.2.1 yamt /* Pre-indexed. Elide offset of positive zero when
2519 1.1.1.1.2.1 yamt non-writeback. */
2520 1.1.1.1.2.1 yamt if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2521 1.1.1.1.2.1 yamt func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2522 1.1.1.1.2.1 yamt
2523 1.1.1.1.2.1 yamt if (NEGATIVE_BIT_SET)
2524 1.1 christos offset = -offset;
2525 1.1 christos
2526 1.1 christos offset += pc + 8;
2527 1.1 christos
2528 1.1 christos /* Cope with the possibility of write-back
2529 1.1 christos being used. Probably a very dangerous thing
2530 1.1 christos for the programmer to do, but who are we to
2531 1.1.1.1.2.1 yamt argue ? */
2532 1.1 christos func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2533 1.1 christos }
2534 1.1 christos else /* Post indexed. */
2535 1.1.1.1.2.1 yamt {
2536 1.1 christos func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2537 1.1 christos
2538 1.1 christos /* Ie ignore the offset. */
2539 1.1 christos offset = pc + 8;
2540 1.1 christos }
2541 1.1 christos
2542 1.1 christos func (stream, "\t; ");
2543 1.1 christos info->print_address_func (offset, info);
2544 1.1 christos offset = 0;
2545 1.1 christos }
2546 1.1 christos else
2547 1.1 christos {
2548 1.1 christos func (stream, "[%s",
2549 1.1 christos arm_regnames[(given >> 16) & 0xf]);
2550 1.1 christos
2551 1.1 christos if (PRE_BIT_SET)
2552 1.1 christos {
2553 1.1 christos if ((given & 0x02000000) == 0)
2554 1.1.1.1.2.1 yamt {
2555 1.1 christos /* Elide offset of positive zero when non-writeback. */
2556 1.1.1.1.2.1 yamt offset = given & 0xfff;
2557 1.1.1.1.2.1 yamt if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2558 1.1 christos func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2559 1.1 christos }
2560 1.1 christos else
2561 1.1.1.1.2.1 yamt {
2562 1.1 christos func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2563 1.1 christos arm_decode_shift (given, func, stream, TRUE);
2564 1.1 christos }
2565 1.1 christos
2566 1.1 christos func (stream, "]%s",
2567 1.1 christos WRITEBACK_BIT_SET ? "!" : "");
2568 1.1 christos }
2569 1.1 christos else
2570 1.1 christos {
2571 1.1 christos if ((given & 0x02000000) == 0)
2572 1.1.1.1.2.1 yamt {
2573 1.1 christos /* Always show offset. */
2574 1.1.1.1.2.1 yamt offset = given & 0xfff;
2575 1.1.1.1.2.1 yamt func (stream, "], #%s%d",
2576 1.1 christos NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2577 1.1 christos }
2578 1.1 christos else
2579 1.1 christos {
2580 1.1 christos func (stream, "], %s",
2581 1.1 christos NEGATIVE_BIT_SET ? "-" : "");
2582 1.1 christos arm_decode_shift (given, func, stream, TRUE);
2583 1.1 christos }
2584 1.1 christos }
2585 1.1 christos }
2586 1.1 christos
2587 1.1 christos return (signed long) offset;
2588 1.1 christos }
2589 1.1 christos
2590 1.1 christos /* Print one neon instruction on INFO->STREAM.
2591 1.1 christos Return TRUE if the instuction matched, FALSE if this is not a
2592 1.1 christos recognised neon instruction. */
2593 1.1 christos
2594 1.1 christos static bfd_boolean
2595 1.1 christos print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2596 1.1 christos {
2597 1.1 christos const struct opcode32 *insn;
2598 1.1 christos void *stream = info->stream;
2599 1.1 christos fprintf_ftype func = info->fprintf_func;
2600 1.1 christos
2601 1.1 christos if (thumb)
2602 1.1 christos {
2603 1.1 christos if ((given & 0xef000000) == 0xef000000)
2604 1.1 christos {
2605 1.1 christos /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2606 1.1 christos unsigned long bit28 = given & (1 << 28);
2607 1.1 christos
2608 1.1 christos given &= 0x00ffffff;
2609 1.1 christos if (bit28)
2610 1.1 christos given |= 0xf3000000;
2611 1.1 christos else
2612 1.1 christos given |= 0xf2000000;
2613 1.1 christos }
2614 1.1 christos else if ((given & 0xff000000) == 0xf9000000)
2615 1.1 christos given ^= 0xf9000000 ^ 0xf4000000;
2616 1.1 christos else
2617 1.1 christos return FALSE;
2618 1.1 christos }
2619 1.1 christos
2620 1.1 christos for (insn = neon_opcodes; insn->assembler; insn++)
2621 1.1 christos {
2622 1.1 christos if ((given & insn->mask) == insn->value)
2623 1.1 christos {
2624 1.1.1.1.2.1 yamt signed long value_in_comment = 0;
2625 1.1 christos bfd_boolean is_unpredictable = FALSE;
2626 1.1 christos const char *c;
2627 1.1 christos
2628 1.1 christos for (c = insn->assembler; *c; c++)
2629 1.1 christos {
2630 1.1 christos if (*c == '%')
2631 1.1 christos {
2632 1.1 christos switch (*++c)
2633 1.1 christos {
2634 1.1 christos case '%':
2635 1.1 christos func (stream, "%%");
2636 1.1 christos break;
2637 1.1.1.1.2.1 yamt
2638 1.1.1.1.2.1 yamt case 'u':
2639 1.1.1.1.2.1 yamt if (thumb && ifthen_state)
2640 1.1.1.1.2.1 yamt is_unpredictable = TRUE;
2641 1.1.1.1.2.1 yamt
2642 1.1 christos /* Fall through. */
2643 1.1 christos case 'c':
2644 1.1 christos if (thumb && ifthen_state)
2645 1.1 christos func (stream, "%s", arm_conditional[IFTHEN_COND]);
2646 1.1 christos break;
2647 1.1 christos
2648 1.1 christos case 'A':
2649 1.1 christos {
2650 1.1 christos static const unsigned char enc[16] =
2651 1.1 christos {
2652 1.1 christos 0x4, 0x14, /* st4 0,1 */
2653 1.1 christos 0x4, /* st1 2 */
2654 1.1 christos 0x4, /* st2 3 */
2655 1.1 christos 0x3, /* st3 4 */
2656 1.1 christos 0x13, /* st3 5 */
2657 1.1 christos 0x3, /* st1 6 */
2658 1.1 christos 0x1, /* st1 7 */
2659 1.1 christos 0x2, /* st2 8 */
2660 1.1 christos 0x12, /* st2 9 */
2661 1.1 christos 0x2, /* st1 10 */
2662 1.1 christos 0, 0, 0, 0, 0
2663 1.1 christos };
2664 1.1 christos int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2665 1.1 christos int rn = ((given >> 16) & 0xf);
2666 1.1 christos int rm = ((given >> 0) & 0xf);
2667 1.1 christos int align = ((given >> 4) & 0x3);
2668 1.1 christos int type = ((given >> 8) & 0xf);
2669 1.1 christos int n = enc[type] & 0xf;
2670 1.1 christos int stride = (enc[type] >> 4) + 1;
2671 1.1 christos int ix;
2672 1.1 christos
2673 1.1 christos func (stream, "{");
2674 1.1 christos if (stride > 1)
2675 1.1 christos for (ix = 0; ix != n; ix++)
2676 1.1 christos func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2677 1.1 christos else if (n == 1)
2678 1.1 christos func (stream, "d%d", rd);
2679 1.1 christos else
2680 1.1 christos func (stream, "d%d-d%d", rd, rd + n - 1);
2681 1.1 christos func (stream, "}, [%s", arm_regnames[rn]);
2682 1.1 christos if (align)
2683 1.1 christos func (stream, " :%d", 32 << align);
2684 1.1 christos func (stream, "]");
2685 1.1 christos if (rm == 0xd)
2686 1.1 christos func (stream, "!");
2687 1.1 christos else if (rm != 0xf)
2688 1.1 christos func (stream, ", %s", arm_regnames[rm]);
2689 1.1 christos }
2690 1.1 christos break;
2691 1.1 christos
2692 1.1 christos case 'B':
2693 1.1 christos {
2694 1.1 christos int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2695 1.1 christos int rn = ((given >> 16) & 0xf);
2696 1.1 christos int rm = ((given >> 0) & 0xf);
2697 1.1 christos int idx_align = ((given >> 4) & 0xf);
2698 1.1 christos int align = 0;
2699 1.1 christos int size = ((given >> 10) & 0x3);
2700 1.1 christos int idx = idx_align >> (size + 1);
2701 1.1 christos int length = ((given >> 8) & 3) + 1;
2702 1.1 christos int stride = 1;
2703 1.1 christos int i;
2704 1.1 christos
2705 1.1 christos if (length > 1 && size > 0)
2706 1.1 christos stride = (idx_align & (1 << size)) ? 2 : 1;
2707 1.1 christos
2708 1.1 christos switch (length)
2709 1.1 christos {
2710 1.1 christos case 1:
2711 1.1 christos {
2712 1.1 christos int amask = (1 << size) - 1;
2713 1.1 christos if ((idx_align & (1 << size)) != 0)
2714 1.1 christos return FALSE;
2715 1.1 christos if (size > 0)
2716 1.1 christos {
2717 1.1 christos if ((idx_align & amask) == amask)
2718 1.1 christos align = 8 << size;
2719 1.1 christos else if ((idx_align & amask) != 0)
2720 1.1 christos return FALSE;
2721 1.1 christos }
2722 1.1 christos }
2723 1.1 christos break;
2724 1.1 christos
2725 1.1 christos case 2:
2726 1.1 christos if (size == 2 && (idx_align & 2) != 0)
2727 1.1 christos return FALSE;
2728 1.1 christos align = (idx_align & 1) ? 16 << size : 0;
2729 1.1 christos break;
2730 1.1 christos
2731 1.1 christos case 3:
2732 1.1 christos if ((size == 2 && (idx_align & 3) != 0)
2733 1.1 christos || (idx_align & 1) != 0)
2734 1.1 christos return FALSE;
2735 1.1 christos break;
2736 1.1 christos
2737 1.1 christos case 4:
2738 1.1 christos if (size == 2)
2739 1.1 christos {
2740 1.1 christos if ((idx_align & 3) == 3)
2741 1.1 christos return FALSE;
2742 1.1 christos align = (idx_align & 3) * 64;
2743 1.1 christos }
2744 1.1 christos else
2745 1.1 christos align = (idx_align & 1) ? 32 << size : 0;
2746 1.1 christos break;
2747 1.1 christos
2748 1.1 christos default:
2749 1.1 christos abort ();
2750 1.1 christos }
2751 1.1 christos
2752 1.1 christos func (stream, "{");
2753 1.1 christos for (i = 0; i < length; i++)
2754 1.1 christos func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2755 1.1 christos rd + i * stride, idx);
2756 1.1 christos func (stream, "}, [%s", arm_regnames[rn]);
2757 1.1 christos if (align)
2758 1.1 christos func (stream, " :%d", align);
2759 1.1 christos func (stream, "]");
2760 1.1 christos if (rm == 0xd)
2761 1.1 christos func (stream, "!");
2762 1.1 christos else if (rm != 0xf)
2763 1.1 christos func (stream, ", %s", arm_regnames[rm]);
2764 1.1 christos }
2765 1.1 christos break;
2766 1.1 christos
2767 1.1 christos case 'C':
2768 1.1 christos {
2769 1.1 christos int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2770 1.1 christos int rn = ((given >> 16) & 0xf);
2771 1.1 christos int rm = ((given >> 0) & 0xf);
2772 1.1 christos int align = ((given >> 4) & 0x1);
2773 1.1 christos int size = ((given >> 6) & 0x3);
2774 1.1 christos int type = ((given >> 8) & 0x3);
2775 1.1 christos int n = type + 1;
2776 1.1 christos int stride = ((given >> 5) & 0x1);
2777 1.1 christos int ix;
2778 1.1 christos
2779 1.1 christos if (stride && (n == 1))
2780 1.1 christos n++;
2781 1.1 christos else
2782 1.1 christos stride++;
2783 1.1 christos
2784 1.1 christos func (stream, "{");
2785 1.1 christos if (stride > 1)
2786 1.1 christos for (ix = 0; ix != n; ix++)
2787 1.1 christos func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2788 1.1 christos else if (n == 1)
2789 1.1 christos func (stream, "d%d[]", rd);
2790 1.1 christos else
2791 1.1 christos func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2792 1.1 christos func (stream, "}, [%s", arm_regnames[rn]);
2793 1.1 christos if (align)
2794 1.1 christos {
2795 1.1 christos align = (8 * (type + 1)) << size;
2796 1.1 christos if (type == 3)
2797 1.1 christos align = (size > 1) ? align >> 1 : align;
2798 1.1 christos if (type == 2 || (type == 0 && !size))
2799 1.1 christos func (stream, " :<bad align %d>", align);
2800 1.1 christos else
2801 1.1 christos func (stream, " :%d", align);
2802 1.1 christos }
2803 1.1 christos func (stream, "]");
2804 1.1 christos if (rm == 0xd)
2805 1.1 christos func (stream, "!");
2806 1.1 christos else if (rm != 0xf)
2807 1.1 christos func (stream, ", %s", arm_regnames[rm]);
2808 1.1 christos }
2809 1.1 christos break;
2810 1.1 christos
2811 1.1 christos case 'D':
2812 1.1 christos {
2813 1.1 christos int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2814 1.1 christos int size = (given >> 20) & 3;
2815 1.1 christos int reg = raw_reg & ((4 << size) - 1);
2816 1.1 christos int ix = raw_reg >> size >> 2;
2817 1.1 christos
2818 1.1 christos func (stream, "d%d[%d]", reg, ix);
2819 1.1 christos }
2820 1.1 christos break;
2821 1.1 christos
2822 1.1 christos case 'E':
2823 1.1 christos /* Neon encoded constant for mov, mvn, vorr, vbic. */
2824 1.1 christos {
2825 1.1 christos int bits = 0;
2826 1.1 christos int cmode = (given >> 8) & 0xf;
2827 1.1 christos int op = (given >> 5) & 0x1;
2828 1.1 christos unsigned long value = 0, hival = 0;
2829 1.1 christos unsigned shift;
2830 1.1 christos int size = 0;
2831 1.1 christos int isfloat = 0;
2832 1.1 christos
2833 1.1 christos bits |= ((given >> 24) & 1) << 7;
2834 1.1 christos bits |= ((given >> 16) & 7) << 4;
2835 1.1 christos bits |= ((given >> 0) & 15) << 0;
2836 1.1 christos
2837 1.1 christos if (cmode < 8)
2838 1.1 christos {
2839 1.1 christos shift = (cmode >> 1) & 3;
2840 1.1 christos value = (unsigned long) bits << (8 * shift);
2841 1.1 christos size = 32;
2842 1.1 christos }
2843 1.1 christos else if (cmode < 12)
2844 1.1 christos {
2845 1.1 christos shift = (cmode >> 1) & 1;
2846 1.1 christos value = (unsigned long) bits << (8 * shift);
2847 1.1 christos size = 16;
2848 1.1 christos }
2849 1.1 christos else if (cmode < 14)
2850 1.1 christos {
2851 1.1 christos shift = (cmode & 1) + 1;
2852 1.1 christos value = (unsigned long) bits << (8 * shift);
2853 1.1 christos value |= (1ul << (8 * shift)) - 1;
2854 1.1 christos size = 32;
2855 1.1 christos }
2856 1.1 christos else if (cmode == 14)
2857 1.1 christos {
2858 1.1 christos if (op)
2859 1.1 christos {
2860 1.1 christos /* Bit replication into bytes. */
2861 1.1 christos int ix;
2862 1.1 christos unsigned long mask;
2863 1.1 christos
2864 1.1 christos value = 0;
2865 1.1 christos hival = 0;
2866 1.1 christos for (ix = 7; ix >= 0; ix--)
2867 1.1 christos {
2868 1.1 christos mask = ((bits >> ix) & 1) ? 0xff : 0;
2869 1.1 christos if (ix <= 3)
2870 1.1 christos value = (value << 8) | mask;
2871 1.1 christos else
2872 1.1 christos hival = (hival << 8) | mask;
2873 1.1 christos }
2874 1.1 christos size = 64;
2875 1.1 christos }
2876 1.1 christos else
2877 1.1 christos {
2878 1.1 christos /* Byte replication. */
2879 1.1 christos value = (unsigned long) bits;
2880 1.1 christos size = 8;
2881 1.1 christos }
2882 1.1 christos }
2883 1.1 christos else if (!op)
2884 1.1 christos {
2885 1.1 christos /* Floating point encoding. */
2886 1.1 christos int tmp;
2887 1.1 christos
2888 1.1 christos value = (unsigned long) (bits & 0x7f) << 19;
2889 1.1 christos value |= (unsigned long) (bits & 0x80) << 24;
2890 1.1 christos tmp = bits & 0x40 ? 0x3c : 0x40;
2891 1.1 christos value |= (unsigned long) tmp << 24;
2892 1.1 christos size = 32;
2893 1.1 christos isfloat = 1;
2894 1.1 christos }
2895 1.1 christos else
2896 1.1 christos {
2897 1.1 christos func (stream, "<illegal constant %.8x:%x:%x>",
2898 1.1 christos bits, cmode, op);
2899 1.1 christos size = 32;
2900 1.1 christos break;
2901 1.1 christos }
2902 1.1 christos switch (size)
2903 1.1 christos {
2904 1.1 christos case 8:
2905 1.1 christos func (stream, "#%ld\t; 0x%.2lx", value, value);
2906 1.1 christos break;
2907 1.1 christos
2908 1.1 christos case 16:
2909 1.1 christos func (stream, "#%ld\t; 0x%.4lx", value, value);
2910 1.1 christos break;
2911 1.1 christos
2912 1.1 christos case 32:
2913 1.1 christos if (isfloat)
2914 1.1 christos {
2915 1.1 christos unsigned char valbytes[4];
2916 1.1 christos double fvalue;
2917 1.1 christos
2918 1.1 christos /* Do this a byte at a time so we don't have to
2919 1.1 christos worry about the host's endianness. */
2920 1.1 christos valbytes[0] = value & 0xff;
2921 1.1 christos valbytes[1] = (value >> 8) & 0xff;
2922 1.1 christos valbytes[2] = (value >> 16) & 0xff;
2923 1.1 christos valbytes[3] = (value >> 24) & 0xff;
2924 1.1 christos
2925 1.1 christos floatformat_to_double
2926 1.1 christos (& floatformat_ieee_single_little, valbytes,
2927 1.1 christos & fvalue);
2928 1.1 christos
2929 1.1 christos func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2930 1.1 christos value);
2931 1.1 christos }
2932 1.1 christos else
2933 1.1 christos func (stream, "#%ld\t; 0x%.8lx",
2934 1.1 christos (long) (((value & 0x80000000L) != 0)
2935 1.1 christos ? value | ~0xffffffffL : value),
2936 1.1 christos value);
2937 1.1 christos break;
2938 1.1 christos
2939 1.1 christos case 64:
2940 1.1 christos func (stream, "#0x%.8lx%.8lx", hival, value);
2941 1.1 christos break;
2942 1.1 christos
2943 1.1 christos default:
2944 1.1 christos abort ();
2945 1.1 christos }
2946 1.1 christos }
2947 1.1 christos break;
2948 1.1 christos
2949 1.1 christos case 'F':
2950 1.1 christos {
2951 1.1 christos int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2952 1.1 christos int num = (given >> 8) & 0x3;
2953 1.1 christos
2954 1.1 christos if (!num)
2955 1.1 christos func (stream, "{d%d}", regno);
2956 1.1 christos else if (num + regno >= 32)
2957 1.1 christos func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2958 1.1 christos else
2959 1.1 christos func (stream, "{d%d-d%d}", regno, regno + num);
2960 1.1 christos }
2961 1.1.1.1.2.1 yamt break;
2962 1.1 christos
2963 1.1 christos
2964 1.1 christos case '0': case '1': case '2': case '3': case '4':
2965 1.1 christos case '5': case '6': case '7': case '8': case '9':
2966 1.1 christos {
2967 1.1 christos int width;
2968 1.1 christos unsigned long value;
2969 1.1 christos
2970 1.1 christos c = arm_decode_bitfield (c, given, &value, &width);
2971 1.1 christos
2972 1.1 christos switch (*c)
2973 1.1 christos {
2974 1.1 christos case 'r':
2975 1.1 christos func (stream, "%s", arm_regnames[value]);
2976 1.1 christos break;
2977 1.1 christos case 'd':
2978 1.1 christos func (stream, "%ld", value);
2979 1.1 christos value_in_comment = value;
2980 1.1 christos break;
2981 1.1 christos case 'e':
2982 1.1 christos func (stream, "%ld", (1ul << width) - value);
2983 1.1 christos break;
2984 1.1 christos
2985 1.1 christos case 'S':
2986 1.1 christos case 'T':
2987 1.1 christos case 'U':
2988 1.1 christos /* Various width encodings. */
2989 1.1 christos {
2990 1.1 christos int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2991 1.1 christos int limit;
2992 1.1 christos unsigned low, high;
2993 1.1 christos
2994 1.1 christos c++;
2995 1.1 christos if (*c >= '0' && *c <= '9')
2996 1.1 christos limit = *c - '0';
2997 1.1 christos else if (*c >= 'a' && *c <= 'f')
2998 1.1 christos limit = *c - 'a' + 10;
2999 1.1 christos else
3000 1.1 christos abort ();
3001 1.1 christos low = limit >> 2;
3002 1.1 christos high = limit & 3;
3003 1.1 christos
3004 1.1 christos if (value < low || value > high)
3005 1.1 christos func (stream, "<illegal width %d>", base << value);
3006 1.1 christos else
3007 1.1 christos func (stream, "%d", base << value);
3008 1.1 christos }
3009 1.1 christos break;
3010 1.1 christos case 'R':
3011 1.1 christos if (given & (1 << 6))
3012 1.1 christos goto Q;
3013 1.1 christos /* FALLTHROUGH */
3014 1.1 christos case 'D':
3015 1.1 christos func (stream, "d%ld", value);
3016 1.1 christos break;
3017 1.1 christos case 'Q':
3018 1.1 christos Q:
3019 1.1 christos if (value & 1)
3020 1.1 christos func (stream, "<illegal reg q%ld.5>", value >> 1);
3021 1.1 christos else
3022 1.1 christos func (stream, "q%ld", value >> 1);
3023 1.1 christos break;
3024 1.1 christos
3025 1.1 christos case '`':
3026 1.1 christos c++;
3027 1.1 christos if (value == 0)
3028 1.1 christos func (stream, "%c", *c);
3029 1.1 christos break;
3030 1.1 christos case '\'':
3031 1.1 christos c++;
3032 1.1 christos if (value == ((1ul << width) - 1))
3033 1.1 christos func (stream, "%c", *c);
3034 1.1 christos break;
3035 1.1 christos case '?':
3036 1.1 christos func (stream, "%c", c[(1 << width) - (int) value]);
3037 1.1 christos c += 1 << width;
3038 1.1 christos break;
3039 1.1 christos default:
3040 1.1 christos abort ();
3041 1.1 christos }
3042 1.1 christos break;
3043 1.1 christos
3044 1.1 christos default:
3045 1.1 christos abort ();
3046 1.1 christos }
3047 1.1 christos }
3048 1.1 christos }
3049 1.1 christos else
3050 1.1 christos func (stream, "%c", *c);
3051 1.1 christos }
3052 1.1 christos
3053 1.1 christos if (value_in_comment > 32 || value_in_comment < -16)
3054 1.1 christos func (stream, "\t; 0x%lx", value_in_comment);
3055 1.1.1.1.2.1 yamt
3056 1.1.1.1.2.1 yamt if (is_unpredictable)
3057 1.1.1.1.2.1 yamt func (stream, UNPREDICTABLE_INSTRUCTION);
3058 1.1 christos
3059 1.1 christos return TRUE;
3060 1.1 christos }
3061 1.1 christos }
3062 1.1 christos return FALSE;
3063 1.1 christos }
3064 1.1 christos
3065 1.1 christos /* Return the name of a v7A special register. */
3066 1.1 christos
3067 1.1 christos static const char *
3068 1.1 christos banked_regname (unsigned reg)
3069 1.1 christos {
3070 1.1 christos switch (reg)
3071 1.1 christos {
3072 1.1 christos case 15: return "CPSR";
3073 1.1 christos case 32: return "R8_usr";
3074 1.1 christos case 33: return "R9_usr";
3075 1.1 christos case 34: return "R10_usr";
3076 1.1 christos case 35: return "R11_usr";
3077 1.1 christos case 36: return "R12_usr";
3078 1.1 christos case 37: return "SP_usr";
3079 1.1 christos case 38: return "LR_usr";
3080 1.1 christos case 40: return "R8_fiq";
3081 1.1 christos case 41: return "R9_fiq";
3082 1.1 christos case 42: return "R10_fiq";
3083 1.1 christos case 43: return "R11_fiq";
3084 1.1 christos case 44: return "R12_fiq";
3085 1.1 christos case 45: return "SP_fiq";
3086 1.1 christos case 46: return "LR_fiq";
3087 1.1 christos case 48: return "LR_irq";
3088 1.1 christos case 49: return "SP_irq";
3089 1.1 christos case 50: return "LR_svc";
3090 1.1 christos case 51: return "SP_svc";
3091 1.1 christos case 52: return "LR_abt";
3092 1.1 christos case 53: return "SP_abt";
3093 1.1 christos case 54: return "LR_und";
3094 1.1 christos case 55: return "SP_und";
3095 1.1 christos case 60: return "LR_mon";
3096 1.1 christos case 61: return "SP_mon";
3097 1.1 christos case 62: return "ELR_hyp";
3098 1.1 christos case 63: return "SP_hyp";
3099 1.1 christos case 79: return "SPSR";
3100 1.1 christos case 110: return "SPSR_fiq";
3101 1.1 christos case 112: return "SPSR_irq";
3102 1.1 christos case 114: return "SPSR_svc";
3103 1.1 christos case 116: return "SPSR_abt";
3104 1.1 christos case 118: return "SPSR_und";
3105 1.1 christos case 124: return "SPSR_mon";
3106 1.1 christos case 126: return "SPSR_hyp";
3107 1.1 christos default: return NULL;
3108 1.1 christos }
3109 1.1 christos }
3110 1.1.1.1.2.1 yamt
3111 1.1.1.1.2.1 yamt /* Return the name of the DMB/DSB option. */
3112 1.1.1.1.2.1 yamt static const char *
3113 1.1.1.1.2.1 yamt data_barrier_option (unsigned option)
3114 1.1.1.1.2.1 yamt {
3115 1.1.1.1.2.1 yamt switch (option & 0xf)
3116 1.1.1.1.2.1 yamt {
3117 1.1.1.1.2.1 yamt case 0xf: return "sy";
3118 1.1.1.1.2.1 yamt case 0xe: return "st";
3119 1.1.1.1.2.1 yamt case 0xd: return "ld";
3120 1.1.1.1.2.1 yamt case 0xb: return "ish";
3121 1.1.1.1.2.1 yamt case 0xa: return "ishst";
3122 1.1.1.1.2.1 yamt case 0x9: return "ishld";
3123 1.1.1.1.2.1 yamt case 0x7: return "un";
3124 1.1.1.1.2.1 yamt case 0x6: return "unst";
3125 1.1.1.1.2.1 yamt case 0x5: return "nshld";
3126 1.1.1.1.2.1 yamt case 0x3: return "osh";
3127 1.1.1.1.2.1 yamt case 0x2: return "oshst";
3128 1.1.1.1.2.1 yamt case 0x1: return "oshld";
3129 1.1.1.1.2.1 yamt default: return NULL;
3130 1.1.1.1.2.1 yamt }
3131 1.1.1.1.2.1 yamt }
3132 1.1 christos
3133 1.1 christos /* Print one ARM instruction from PC on INFO->STREAM. */
3134 1.1 christos
3135 1.1 christos static void
3136 1.1 christos print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
3137 1.1 christos {
3138 1.1 christos const struct opcode32 *insn;
3139 1.1 christos void *stream = info->stream;
3140 1.1 christos fprintf_ftype func = info->fprintf_func;
3141 1.1 christos struct arm_private_data *private_data = info->private_data;
3142 1.1 christos
3143 1.1 christos if (print_insn_coprocessor (pc, info, given, FALSE))
3144 1.1 christos return;
3145 1.1 christos
3146 1.1 christos if (print_insn_neon (info, given, FALSE))
3147 1.1 christos return;
3148 1.1 christos
3149 1.1 christos for (insn = arm_opcodes; insn->assembler; insn++)
3150 1.1 christos {
3151 1.1 christos if ((given & insn->mask) != insn->value)
3152 1.1 christos continue;
3153 1.1 christos
3154 1.1 christos if ((insn->arch & private_data->features.core) == 0)
3155 1.1 christos continue;
3156 1.1 christos
3157 1.1 christos /* Special case: an instruction with all bits set in the condition field
3158 1.1 christos (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
3159 1.1 christos or by the catchall at the end of the table. */
3160 1.1 christos if ((given & 0xF0000000) != 0xF0000000
3161 1.1 christos || (insn->mask & 0xF0000000) == 0xF0000000
3162 1.1 christos || (insn->mask == 0 && insn->value == 0))
3163 1.1 christos {
3164 1.1 christos unsigned long u_reg = 16;
3165 1.1 christos unsigned long U_reg = 16;
3166 1.1 christos bfd_boolean is_unpredictable = FALSE;
3167 1.1 christos signed long value_in_comment = 0;
3168 1.1 christos const char *c;
3169 1.1 christos
3170 1.1 christos for (c = insn->assembler; *c; c++)
3171 1.1 christos {
3172 1.1 christos if (*c == '%')
3173 1.1 christos {
3174 1.1 christos bfd_boolean allow_unpredictable = FALSE;
3175 1.1 christos
3176 1.1 christos switch (*++c)
3177 1.1 christos {
3178 1.1 christos case '%':
3179 1.1 christos func (stream, "%%");
3180 1.1 christos break;
3181 1.1 christos
3182 1.1 christos case 'a':
3183 1.1 christos value_in_comment = print_arm_address (pc, info, given);
3184 1.1 christos break;
3185 1.1 christos
3186 1.1 christos case 'P':
3187 1.1 christos /* Set P address bit and use normal address
3188 1.1 christos printing routine. */
3189 1.1 christos value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3190 1.1 christos break;
3191 1.1 christos
3192 1.1 christos case 'S':
3193 1.1 christos allow_unpredictable = TRUE;
3194 1.1 christos case 's':
3195 1.1 christos if ((given & 0x004f0000) == 0x004f0000)
3196 1.1 christos {
3197 1.1.1.1.2.1 yamt /* PC relative with immediate offset. */
3198 1.1 christos bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3199 1.1 christos
3200 1.1 christos if (PRE_BIT_SET)
3201 1.1.1.1.2.1 yamt {
3202 1.1.1.1.2.1 yamt /* Elide positive zero offset. */
3203 1.1.1.1.2.1 yamt if (offset || NEGATIVE_BIT_SET)
3204 1.1.1.1.2.1 yamt func (stream, "[pc, #%s%d]\t; ",
3205 1.1 christos NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3206 1.1.1.1.2.1 yamt else
3207 1.1.1.1.2.1 yamt func (stream, "[pc]\t; ");
3208 1.1.1.1.2.1 yamt if (NEGATIVE_BIT_SET)
3209 1.1 christos offset = -offset;
3210 1.1 christos info->print_address_func (offset + pc + 8, info);
3211 1.1 christos }
3212 1.1 christos else
3213 1.1.1.1.2.1 yamt {
3214 1.1.1.1.2.1 yamt /* Always show the offset. */
3215 1.1.1.1.2.1 yamt func (stream, "[pc], #%s%d",
3216 1.1 christos NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3217 1.1 christos if (! allow_unpredictable)
3218 1.1 christos is_unpredictable = TRUE;
3219 1.1 christos }
3220 1.1 christos }
3221 1.1 christos else
3222 1.1 christos {
3223 1.1 christos int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3224 1.1 christos
3225 1.1 christos func (stream, "[%s",
3226 1.1 christos arm_regnames[(given >> 16) & 0xf]);
3227 1.1 christos
3228 1.1 christos if (PRE_BIT_SET)
3229 1.1 christos {
3230 1.1 christos if (IMMEDIATE_BIT_SET)
3231 1.1.1.1.2.1 yamt {
3232 1.1.1.1.2.1 yamt /* Elide offset for non-writeback
3233 1.1.1.1.2.1 yamt positive zero. */
3234 1.1.1.1.2.1 yamt if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3235 1.1.1.1.2.1 yamt || offset)
3236 1.1.1.1.2.1 yamt func (stream, ", #%s%d",
3237 1.1.1.1.2.1 yamt NEGATIVE_BIT_SET ? "-" : "", offset);
3238 1.1.1.1.2.1 yamt
3239 1.1.1.1.2.1 yamt if (NEGATIVE_BIT_SET)
3240 1.1 christos offset = -offset;
3241 1.1 christos
3242 1.1 christos value_in_comment = offset;
3243 1.1 christos }
3244 1.1 christos else
3245 1.1 christos {
3246 1.1 christos /* Register Offset or Register Pre-Indexed. */
3247 1.1 christos func (stream, ", %s%s",
3248 1.1 christos NEGATIVE_BIT_SET ? "-" : "",
3249 1.1 christos arm_regnames[given & 0xf]);
3250 1.1 christos
3251 1.1 christos /* Writing back to the register that is the source/
3252 1.1 christos destination of the load/store is unpredictable. */
3253 1.1 christos if (! allow_unpredictable
3254 1.1 christos && WRITEBACK_BIT_SET
3255 1.1 christos && ((given & 0xf) == ((given >> 12) & 0xf)))
3256 1.1 christos is_unpredictable = TRUE;
3257 1.1 christos }
3258 1.1 christos
3259 1.1 christos func (stream, "]%s",
3260 1.1 christos WRITEBACK_BIT_SET ? "!" : "");
3261 1.1 christos }
3262 1.1 christos else
3263 1.1 christos {
3264 1.1 christos if (IMMEDIATE_BIT_SET)
3265 1.1 christos {
3266 1.1 christos /* Immediate Post-indexed. */
3267 1.1.1.1.2.1 yamt /* PR 10924: Offset must be printed, even if it is zero. */
3268 1.1.1.1.2.1 yamt func (stream, "], #%s%d",
3269 1.1.1.1.2.1 yamt NEGATIVE_BIT_SET ? "-" : "", offset);
3270 1.1.1.1.2.1 yamt if (NEGATIVE_BIT_SET)
3271 1.1 christos offset = -offset;
3272 1.1 christos value_in_comment = offset;
3273 1.1 christos }
3274 1.1 christos else
3275 1.1 christos {
3276 1.1 christos /* Register Post-indexed. */
3277 1.1 christos func (stream, "], %s%s",
3278 1.1 christos NEGATIVE_BIT_SET ? "-" : "",
3279 1.1 christos arm_regnames[given & 0xf]);
3280 1.1 christos
3281 1.1 christos /* Writing back to the register that is the source/
3282 1.1 christos destination of the load/store is unpredictable. */
3283 1.1 christos if (! allow_unpredictable
3284 1.1 christos && (given & 0xf) == ((given >> 12) & 0xf))
3285 1.1 christos is_unpredictable = TRUE;
3286 1.1 christos }
3287 1.1 christos
3288 1.1 christos if (! allow_unpredictable)
3289 1.1 christos {
3290 1.1 christos /* Writeback is automatically implied by post- addressing.
3291 1.1 christos Setting the W bit is unnecessary and ARM specify it as
3292 1.1 christos being unpredictable. */
3293 1.1 christos if (WRITEBACK_BIT_SET
3294 1.1 christos /* Specifying the PC register as the post-indexed
3295 1.1 christos registers is also unpredictable. */
3296 1.1 christos || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3297 1.1 christos is_unpredictable = TRUE;
3298 1.1 christos }
3299 1.1 christos }
3300 1.1 christos }
3301 1.1 christos break;
3302 1.1 christos
3303 1.1 christos case 'b':
3304 1.1.1.1.2.1 yamt {
3305 1.1 christos bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3306 1.1 christos info->print_address_func (disp * 4 + pc + 8, info);
3307 1.1 christos }
3308 1.1 christos break;
3309 1.1 christos
3310 1.1 christos case 'c':
3311 1.1 christos if (((given >> 28) & 0xf) != 0xe)
3312 1.1 christos func (stream, "%s",
3313 1.1 christos arm_conditional [(given >> 28) & 0xf]);
3314 1.1 christos break;
3315 1.1 christos
3316 1.1 christos case 'm':
3317 1.1 christos {
3318 1.1 christos int started = 0;
3319 1.1 christos int reg;
3320 1.1 christos
3321 1.1 christos func (stream, "{");
3322 1.1 christos for (reg = 0; reg < 16; reg++)
3323 1.1 christos if ((given & (1 << reg)) != 0)
3324 1.1 christos {
3325 1.1 christos if (started)
3326 1.1 christos func (stream, ", ");
3327 1.1 christos started = 1;
3328 1.1 christos func (stream, "%s", arm_regnames[reg]);
3329 1.1 christos }
3330 1.1 christos func (stream, "}");
3331 1.1 christos if (! started)
3332 1.1 christos is_unpredictable = TRUE;
3333 1.1 christos }
3334 1.1 christos break;
3335 1.1 christos
3336 1.1 christos case 'q':
3337 1.1 christos arm_decode_shift (given, func, stream, FALSE);
3338 1.1 christos break;
3339 1.1 christos
3340 1.1 christos case 'o':
3341 1.1 christos if ((given & 0x02000000) != 0)
3342 1.1.1.1.2.1 yamt {
3343 1.1.1.1.2.1 yamt unsigned int rotate = (given & 0xf00) >> 7;
3344 1.1.1.1.2.1 yamt unsigned int immed = (given & 0xff);
3345 1.1.1.1.2.1 yamt unsigned int a, i;
3346 1.1.1.1.2.1 yamt
3347 1.1.1.1.2.1 yamt a = (((immed << (32 - rotate))
3348 1.1.1.1.2.1 yamt | (immed >> rotate)) & 0xffffffff);
3349 1.1.1.1.2.1 yamt /* If there is another encoding with smaller rotate,
3350 1.1.1.1.2.1 yamt the rotate should be specified directly. */
3351 1.1.1.1.2.1 yamt for (i = 0; i < 32; i += 2)
3352 1.1.1.1.2.1 yamt if ((a << i | a >> (32 - i)) <= 0xff)
3353 1.1 christos break;
3354 1.1.1.1.2.1 yamt
3355 1.1.1.1.2.1 yamt if (i != rotate)
3356 1.1.1.1.2.1 yamt func (stream, "#%d, %d", immed, rotate);
3357 1.1.1.1.2.1 yamt else
3358 1.1.1.1.2.1 yamt func (stream, "#%d", a);
3359 1.1 christos value_in_comment = a;
3360 1.1 christos }
3361 1.1 christos else
3362 1.1 christos arm_decode_shift (given, func, stream, TRUE);
3363 1.1 christos break;
3364 1.1 christos
3365 1.1 christos case 'p':
3366 1.1 christos if ((given & 0x0000f000) == 0x0000f000)
3367 1.1 christos {
3368 1.1 christos /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3369 1.1 christos mechanism for setting PSR flag bits. They are
3370 1.1 christos obsolete in V6 onwards. */
3371 1.1 christos if ((private_data->features.core & ARM_EXT_V6) == 0)
3372 1.1 christos func (stream, "p");
3373 1.1 christos }
3374 1.1 christos break;
3375 1.1 christos
3376 1.1 christos case 't':
3377 1.1 christos if ((given & 0x01200000) == 0x00200000)
3378 1.1 christos func (stream, "t");
3379 1.1 christos break;
3380 1.1 christos
3381 1.1 christos case 'A':
3382 1.1 christos {
3383 1.1 christos int offset = given & 0xff;
3384 1.1 christos
3385 1.1 christos value_in_comment = offset * 4;
3386 1.1 christos if (NEGATIVE_BIT_SET)
3387 1.1 christos value_in_comment = - value_in_comment;
3388 1.1 christos
3389 1.1 christos func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3390 1.1 christos
3391 1.1 christos if (PRE_BIT_SET)
3392 1.1 christos {
3393 1.1 christos if (offset)
3394 1.1.1.1.2.1 yamt func (stream, ", #%d]%s",
3395 1.1 christos (int) value_in_comment,
3396 1.1 christos WRITEBACK_BIT_SET ? "!" : "");
3397 1.1 christos else
3398 1.1 christos func (stream, "]");
3399 1.1 christos }
3400 1.1 christos else
3401 1.1 christos {
3402 1.1 christos func (stream, "]");
3403 1.1 christos
3404 1.1 christos if (WRITEBACK_BIT_SET)
3405 1.1 christos {
3406 1.1.1.1.2.1 yamt if (offset)
3407 1.1 christos func (stream, ", #%d", (int) value_in_comment);
3408 1.1 christos }
3409 1.1 christos else
3410 1.1.1.1.2.1 yamt {
3411 1.1 christos func (stream, ", {%d}", (int) offset);
3412 1.1 christos value_in_comment = offset;
3413 1.1 christos }
3414 1.1 christos }
3415 1.1 christos }
3416 1.1 christos break;
3417 1.1 christos
3418 1.1 christos case 'B':
3419 1.1 christos /* Print ARM V5 BLX(1) address: pc+25 bits. */
3420 1.1 christos {
3421 1.1 christos bfd_vma address;
3422 1.1 christos bfd_vma offset = 0;
3423 1.1 christos
3424 1.1 christos if (! NEGATIVE_BIT_SET)
3425 1.1 christos /* Is signed, hi bits should be ones. */
3426 1.1 christos offset = (-1) ^ 0x00ffffff;
3427 1.1 christos
3428 1.1 christos /* Offset is (SignExtend(offset field)<<2). */
3429 1.1 christos offset += given & 0x00ffffff;
3430 1.1 christos offset <<= 2;
3431 1.1 christos address = offset + pc + 8;
3432 1.1 christos
3433 1.1 christos if (given & 0x01000000)
3434 1.1 christos /* H bit allows addressing to 2-byte boundaries. */
3435 1.1 christos address += 2;
3436 1.1 christos
3437 1.1 christos info->print_address_func (address, info);
3438 1.1 christos }
3439 1.1 christos break;
3440 1.1 christos
3441 1.1 christos case 'C':
3442 1.1 christos if ((given & 0x02000200) == 0x200)
3443 1.1 christos {
3444 1.1 christos const char * name;
3445 1.1 christos unsigned sysm = (given & 0x004f0000) >> 16;
3446 1.1 christos
3447 1.1 christos sysm |= (given & 0x300) >> 4;
3448 1.1 christos name = banked_regname (sysm);
3449 1.1 christos
3450 1.1 christos if (name != NULL)
3451 1.1 christos func (stream, "%s", name);
3452 1.1.1.1.2.1 yamt else
3453 1.1 christos func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3454 1.1 christos }
3455 1.1 christos else
3456 1.1 christos {
3457 1.1 christos func (stream, "%cPSR_",
3458 1.1 christos (given & 0x00400000) ? 'S' : 'C');
3459 1.1 christos if (given & 0x80000)
3460 1.1 christos func (stream, "f");
3461 1.1 christos if (given & 0x40000)
3462 1.1 christos func (stream, "s");
3463 1.1 christos if (given & 0x20000)
3464 1.1 christos func (stream, "x");
3465 1.1 christos if (given & 0x10000)
3466 1.1 christos func (stream, "c");
3467 1.1 christos }
3468 1.1 christos break;
3469 1.1 christos
3470 1.1 christos case 'U':
3471 1.1 christos if ((given & 0xf0) == 0x60)
3472 1.1 christos {
3473 1.1 christos switch (given & 0xf)
3474 1.1 christos {
3475 1.1 christos case 0xf: func (stream, "sy"); break;
3476 1.1 christos default:
3477 1.1 christos func (stream, "#%d", (int) given & 0xf);
3478 1.1 christos break;
3479 1.1 christos }
3480 1.1 christos }
3481 1.1 christos else
3482 1.1.1.1.2.1 yamt {
3483 1.1.1.1.2.1 yamt const char * opt = data_barrier_option (given & 0xf);
3484 1.1.1.1.2.1 yamt if (opt != NULL)
3485 1.1.1.1.2.1 yamt func (stream, "%s", opt);
3486 1.1 christos else
3487 1.1 christos func (stream, "#%d", (int) given & 0xf);
3488 1.1 christos }
3489 1.1 christos break;
3490 1.1 christos
3491 1.1 christos case '0': case '1': case '2': case '3': case '4':
3492 1.1 christos case '5': case '6': case '7': case '8': case '9':
3493 1.1 christos {
3494 1.1 christos int width;
3495 1.1 christos unsigned long value;
3496 1.1 christos
3497 1.1 christos c = arm_decode_bitfield (c, given, &value, &width);
3498 1.1 christos
3499 1.1 christos switch (*c)
3500 1.1 christos {
3501 1.1 christos case 'R':
3502 1.1 christos if (value == 15)
3503 1.1 christos is_unpredictable = TRUE;
3504 1.1 christos /* Fall through. */
3505 1.1.1.1.2.1 yamt case 'r':
3506 1.1.1.1.2.1 yamt case 'T':
3507 1.1.1.1.2.1 yamt /* We want register + 1 when decoding T. */
3508 1.1.1.1.2.1 yamt if (*c == 'T')
3509 1.1.1.1.2.1 yamt ++value;
3510 1.1 christos
3511 1.1 christos if (c[1] == 'u')
3512 1.1 christos {
3513 1.1 christos /* Eat the 'u' character. */
3514 1.1 christos ++ c;
3515 1.1 christos
3516 1.1 christos if (u_reg == value)
3517 1.1 christos is_unpredictable = TRUE;
3518 1.1 christos u_reg = value;
3519 1.1 christos }
3520 1.1 christos if (c[1] == 'U')
3521 1.1 christos {
3522 1.1 christos /* Eat the 'U' character. */
3523 1.1 christos ++ c;
3524 1.1 christos
3525 1.1 christos if (U_reg == value)
3526 1.1 christos is_unpredictable = TRUE;
3527 1.1 christos U_reg = value;
3528 1.1 christos }
3529 1.1 christos func (stream, "%s", arm_regnames[value]);
3530 1.1 christos break;
3531 1.1 christos case 'd':
3532 1.1 christos func (stream, "%ld", value);
3533 1.1 christos value_in_comment = value;
3534 1.1 christos break;
3535 1.1 christos case 'b':
3536 1.1 christos func (stream, "%ld", value * 8);
3537 1.1 christos value_in_comment = value * 8;
3538 1.1 christos break;
3539 1.1 christos case 'W':
3540 1.1 christos func (stream, "%ld", value + 1);
3541 1.1 christos value_in_comment = value + 1;
3542 1.1 christos break;
3543 1.1 christos case 'x':
3544 1.1 christos func (stream, "0x%08lx", value);
3545 1.1 christos
3546 1.1 christos /* Some SWI instructions have special
3547 1.1 christos meanings. */
3548 1.1 christos if ((given & 0x0fffffff) == 0x0FF00000)
3549 1.1 christos func (stream, "\t; IMB");
3550 1.1 christos else if ((given & 0x0fffffff) == 0x0FF00001)
3551 1.1 christos func (stream, "\t; IMBRange");
3552 1.1 christos break;
3553 1.1 christos case 'X':
3554 1.1 christos func (stream, "%01lx", value & 0xf);
3555 1.1 christos value_in_comment = value;
3556 1.1 christos break;
3557 1.1 christos case '`':
3558 1.1 christos c++;
3559 1.1 christos if (value == 0)
3560 1.1 christos func (stream, "%c", *c);
3561 1.1 christos break;
3562 1.1 christos case '\'':
3563 1.1 christos c++;
3564 1.1 christos if (value == ((1ul << width) - 1))
3565 1.1 christos func (stream, "%c", *c);
3566 1.1 christos break;
3567 1.1 christos case '?':
3568 1.1 christos func (stream, "%c", c[(1 << width) - (int) value]);
3569 1.1 christos c += 1 << width;
3570 1.1 christos break;
3571 1.1 christos default:
3572 1.1 christos abort ();
3573 1.1 christos }
3574 1.1 christos break;
3575 1.1 christos
3576 1.1 christos case 'e':
3577 1.1 christos {
3578 1.1 christos int imm;
3579 1.1 christos
3580 1.1 christos imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3581 1.1 christos func (stream, "%d", imm);
3582 1.1 christos value_in_comment = imm;
3583 1.1 christos }
3584 1.1 christos break;
3585 1.1 christos
3586 1.1 christos case 'E':
3587 1.1 christos /* LSB and WIDTH fields of BFI or BFC. The machine-
3588 1.1 christos language instruction encodes LSB and MSB. */
3589 1.1 christos {
3590 1.1 christos long msb = (given & 0x001f0000) >> 16;
3591 1.1 christos long lsb = (given & 0x00000f80) >> 7;
3592 1.1 christos long w = msb - lsb + 1;
3593 1.1 christos
3594 1.1 christos if (w > 0)
3595 1.1 christos func (stream, "#%lu, #%lu", lsb, w);
3596 1.1 christos else
3597 1.1 christos func (stream, "(invalid: %lu:%lu)", lsb, msb);
3598 1.1 christos }
3599 1.1 christos break;
3600 1.1 christos
3601 1.1 christos case 'R':
3602 1.1 christos /* Get the PSR/banked register name. */
3603 1.1 christos {
3604 1.1 christos const char * name;
3605 1.1 christos unsigned sysm = (given & 0x004f0000) >> 16;
3606 1.1 christos
3607 1.1 christos sysm |= (given & 0x300) >> 4;
3608 1.1 christos name = banked_regname (sysm);
3609 1.1 christos
3610 1.1 christos if (name != NULL)
3611 1.1 christos func (stream, "%s", name);
3612 1.1.1.1.2.1 yamt else
3613 1.1 christos func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3614 1.1 christos }
3615 1.1 christos break;
3616 1.1 christos
3617 1.1 christos case 'V':
3618 1.1 christos /* 16-bit unsigned immediate from a MOVT or MOVW
3619 1.1 christos instruction, encoded in bits 0:11 and 15:19. */
3620 1.1 christos {
3621 1.1 christos long hi = (given & 0x000f0000) >> 4;
3622 1.1 christos long lo = (given & 0x00000fff);
3623 1.1 christos long imm16 = hi | lo;
3624 1.1 christos
3625 1.1 christos func (stream, "#%lu", imm16);
3626 1.1 christos value_in_comment = imm16;
3627 1.1 christos }
3628 1.1 christos break;
3629 1.1 christos
3630 1.1 christos default:
3631 1.1 christos abort ();
3632 1.1 christos }
3633 1.1 christos }
3634 1.1 christos }
3635 1.1 christos else
3636 1.1 christos func (stream, "%c", *c);
3637 1.1 christos }
3638 1.1 christos
3639 1.1 christos if (value_in_comment > 32 || value_in_comment < -16)
3640 1.1 christos func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3641 1.1 christos
3642 1.1 christos if (is_unpredictable)
3643 1.1 christos func (stream, UNPREDICTABLE_INSTRUCTION);
3644 1.1 christos
3645 1.1 christos return;
3646 1.1 christos }
3647 1.1 christos }
3648 1.1 christos abort ();
3649 1.1 christos }
3650 1.1 christos
3651 1.1 christos /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3652 1.1 christos
3653 1.1 christos static void
3654 1.1 christos print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3655 1.1 christos {
3656 1.1 christos const struct opcode16 *insn;
3657 1.1 christos void *stream = info->stream;
3658 1.1 christos fprintf_ftype func = info->fprintf_func;
3659 1.1 christos
3660 1.1 christos for (insn = thumb_opcodes; insn->assembler; insn++)
3661 1.1 christos if ((given & insn->mask) == insn->value)
3662 1.1 christos {
3663 1.1 christos signed long value_in_comment = 0;
3664 1.1 christos const char *c = insn->assembler;
3665 1.1 christos
3666 1.1 christos for (; *c; c++)
3667 1.1 christos {
3668 1.1 christos int domaskpc = 0;
3669 1.1 christos int domasklr = 0;
3670 1.1 christos
3671 1.1 christos if (*c != '%')
3672 1.1 christos {
3673 1.1 christos func (stream, "%c", *c);
3674 1.1 christos continue;
3675 1.1 christos }
3676 1.1 christos
3677 1.1 christos switch (*++c)
3678 1.1 christos {
3679 1.1 christos case '%':
3680 1.1 christos func (stream, "%%");
3681 1.1 christos break;
3682 1.1 christos
3683 1.1 christos case 'c':
3684 1.1 christos if (ifthen_state)
3685 1.1 christos func (stream, "%s", arm_conditional[IFTHEN_COND]);
3686 1.1 christos break;
3687 1.1 christos
3688 1.1 christos case 'C':
3689 1.1 christos if (ifthen_state)
3690 1.1 christos func (stream, "%s", arm_conditional[IFTHEN_COND]);
3691 1.1 christos else
3692 1.1 christos func (stream, "s");
3693 1.1 christos break;
3694 1.1 christos
3695 1.1 christos case 'I':
3696 1.1 christos {
3697 1.1 christos unsigned int tmp;
3698 1.1 christos
3699 1.1 christos ifthen_next_state = given & 0xff;
3700 1.1 christos for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3701 1.1 christos func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3702 1.1 christos func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3703 1.1 christos }
3704 1.1 christos break;
3705 1.1 christos
3706 1.1 christos case 'x':
3707 1.1 christos if (ifthen_next_state)
3708 1.1 christos func (stream, "\t; unpredictable branch in IT block\n");
3709 1.1 christos break;
3710 1.1 christos
3711 1.1 christos case 'X':
3712 1.1 christos if (ifthen_state)
3713 1.1 christos func (stream, "\t; unpredictable <IT:%s>",
3714 1.1 christos arm_conditional[IFTHEN_COND]);
3715 1.1 christos break;
3716 1.1 christos
3717 1.1 christos case 'S':
3718 1.1 christos {
3719 1.1 christos long reg;
3720 1.1 christos
3721 1.1 christos reg = (given >> 3) & 0x7;
3722 1.1 christos if (given & (1 << 6))
3723 1.1 christos reg += 8;
3724 1.1 christos
3725 1.1 christos func (stream, "%s", arm_regnames[reg]);
3726 1.1 christos }
3727 1.1 christos break;
3728 1.1 christos
3729 1.1 christos case 'D':
3730 1.1 christos {
3731 1.1 christos long reg;
3732 1.1 christos
3733 1.1 christos reg = given & 0x7;
3734 1.1 christos if (given & (1 << 7))
3735 1.1 christos reg += 8;
3736 1.1 christos
3737 1.1 christos func (stream, "%s", arm_regnames[reg]);
3738 1.1 christos }
3739 1.1 christos break;
3740 1.1 christos
3741 1.1 christos case 'N':
3742 1.1 christos if (given & (1 << 8))
3743 1.1 christos domasklr = 1;
3744 1.1 christos /* Fall through. */
3745 1.1 christos case 'O':
3746 1.1 christos if (*c == 'O' && (given & (1 << 8)))
3747 1.1 christos domaskpc = 1;
3748 1.1 christos /* Fall through. */
3749 1.1 christos case 'M':
3750 1.1 christos {
3751 1.1 christos int started = 0;
3752 1.1 christos int reg;
3753 1.1 christos
3754 1.1 christos func (stream, "{");
3755 1.1 christos
3756 1.1 christos /* It would be nice if we could spot
3757 1.1 christos ranges, and generate the rS-rE format: */
3758 1.1 christos for (reg = 0; (reg < 8); reg++)
3759 1.1 christos if ((given & (1 << reg)) != 0)
3760 1.1 christos {
3761 1.1 christos if (started)
3762 1.1 christos func (stream, ", ");
3763 1.1 christos started = 1;
3764 1.1 christos func (stream, "%s", arm_regnames[reg]);
3765 1.1 christos }
3766 1.1 christos
3767 1.1 christos if (domasklr)
3768 1.1 christos {
3769 1.1 christos if (started)
3770 1.1 christos func (stream, ", ");
3771 1.1.1.1.2.1 yamt started = 1;
3772 1.1 christos func (stream, "%s", arm_regnames[14] /* "lr" */);
3773 1.1 christos }
3774 1.1 christos
3775 1.1 christos if (domaskpc)
3776 1.1 christos {
3777 1.1 christos if (started)
3778 1.1.1.1.2.1 yamt func (stream, ", ");
3779 1.1 christos func (stream, "%s", arm_regnames[15] /* "pc" */);
3780 1.1 christos }
3781 1.1 christos
3782 1.1 christos func (stream, "}");
3783 1.1 christos }
3784 1.1 christos break;
3785 1.1 christos
3786 1.1 christos case 'W':
3787 1.1 christos /* Print writeback indicator for a LDMIA. We are doing a
3788 1.1 christos writeback if the base register is not in the register
3789 1.1 christos mask. */
3790 1.1 christos if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3791 1.1 christos func (stream, "!");
3792 1.1 christos break;
3793 1.1 christos
3794 1.1 christos case 'b':
3795 1.1 christos /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3796 1.1 christos {
3797 1.1 christos bfd_vma address = (pc + 4
3798 1.1 christos + ((given & 0x00f8) >> 2)
3799 1.1 christos + ((given & 0x0200) >> 3));
3800 1.1 christos info->print_address_func (address, info);
3801 1.1 christos }
3802 1.1 christos break;
3803 1.1 christos
3804 1.1 christos case 's':
3805 1.1 christos /* Right shift immediate -- bits 6..10; 1-31 print
3806 1.1 christos as themselves, 0 prints as 32. */
3807 1.1 christos {
3808 1.1 christos long imm = (given & 0x07c0) >> 6;
3809 1.1 christos if (imm == 0)
3810 1.1 christos imm = 32;
3811 1.1 christos func (stream, "#%ld", imm);
3812 1.1 christos }
3813 1.1 christos break;
3814 1.1 christos
3815 1.1 christos case '0': case '1': case '2': case '3': case '4':
3816 1.1 christos case '5': case '6': case '7': case '8': case '9':
3817 1.1 christos {
3818 1.1 christos int bitstart = *c++ - '0';
3819 1.1 christos int bitend = 0;
3820 1.1 christos
3821 1.1 christos while (*c >= '0' && *c <= '9')
3822 1.1 christos bitstart = (bitstart * 10) + *c++ - '0';
3823 1.1 christos
3824 1.1 christos switch (*c)
3825 1.1 christos {
3826 1.1 christos case '-':
3827 1.1.1.1.2.1 yamt {
3828 1.1 christos bfd_vma reg;
3829 1.1 christos
3830 1.1 christos c++;
3831 1.1 christos while (*c >= '0' && *c <= '9')
3832 1.1 christos bitend = (bitend * 10) + *c++ - '0';
3833 1.1 christos if (!bitend)
3834 1.1 christos abort ();
3835 1.1 christos reg = given >> bitstart;
3836 1.1 christos reg &= (2 << (bitend - bitstart)) - 1;
3837 1.1 christos
3838 1.1 christos switch (*c)
3839 1.1 christos {
3840 1.1 christos case 'r':
3841 1.1 christos func (stream, "%s", arm_regnames[reg]);
3842 1.1 christos break;
3843 1.1 christos
3844 1.1.1.1.2.1 yamt case 'd':
3845 1.1 christos func (stream, "%ld", (long) reg);
3846 1.1 christos value_in_comment = reg;
3847 1.1 christos break;
3848 1.1 christos
3849 1.1.1.1.2.1 yamt case 'H':
3850 1.1 christos func (stream, "%ld", (long) (reg << 1));
3851 1.1 christos value_in_comment = reg << 1;
3852 1.1 christos break;
3853 1.1 christos
3854 1.1.1.1.2.1 yamt case 'W':
3855 1.1 christos func (stream, "%ld", (long) (reg << 2));
3856 1.1 christos value_in_comment = reg << 2;
3857 1.1 christos break;
3858 1.1 christos
3859 1.1 christos case 'a':
3860 1.1 christos /* PC-relative address -- the bottom two
3861 1.1 christos bits of the address are dropped
3862 1.1 christos before the calculation. */
3863 1.1 christos info->print_address_func
3864 1.1 christos (((pc + 4) & ~3) + (reg << 2), info);
3865 1.1 christos value_in_comment = 0;
3866 1.1 christos break;
3867 1.1 christos
3868 1.1.1.1.2.1 yamt case 'x':
3869 1.1 christos func (stream, "0x%04lx", (long) reg);
3870 1.1 christos break;
3871 1.1 christos
3872 1.1 christos case 'B':
3873 1.1 christos reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3874 1.1 christos info->print_address_func (reg * 2 + pc + 4, info);
3875 1.1 christos value_in_comment = 0;
3876 1.1 christos break;
3877 1.1 christos
3878 1.1 christos case 'c':
3879 1.1 christos func (stream, "%s", arm_conditional [reg]);
3880 1.1 christos break;
3881 1.1 christos
3882 1.1 christos default:
3883 1.1 christos abort ();
3884 1.1 christos }
3885 1.1 christos }
3886 1.1 christos break;
3887 1.1 christos
3888 1.1 christos case '\'':
3889 1.1 christos c++;
3890 1.1 christos if ((given & (1 << bitstart)) != 0)
3891 1.1 christos func (stream, "%c", *c);
3892 1.1 christos break;
3893 1.1 christos
3894 1.1 christos case '?':
3895 1.1 christos ++c;
3896 1.1 christos if ((given & (1 << bitstart)) != 0)
3897 1.1 christos func (stream, "%c", *c++);
3898 1.1 christos else
3899 1.1 christos func (stream, "%c", *++c);
3900 1.1 christos break;
3901 1.1 christos
3902 1.1 christos default:
3903 1.1 christos abort ();
3904 1.1 christos }
3905 1.1 christos }
3906 1.1 christos break;
3907 1.1 christos
3908 1.1 christos default:
3909 1.1 christos abort ();
3910 1.1 christos }
3911 1.1 christos }
3912 1.1 christos
3913 1.1 christos if (value_in_comment > 32 || value_in_comment < -16)
3914 1.1 christos func (stream, "\t; 0x%lx", value_in_comment);
3915 1.1 christos return;
3916 1.1 christos }
3917 1.1 christos
3918 1.1 christos /* No match. */
3919 1.1 christos abort ();
3920 1.1 christos }
3921 1.1 christos
3922 1.1 christos /* Return the name of an V7M special register. */
3923 1.1 christos
3924 1.1 christos static const char *
3925 1.1 christos psr_name (int regno)
3926 1.1 christos {
3927 1.1 christos switch (regno)
3928 1.1 christos {
3929 1.1 christos case 0: return "APSR";
3930 1.1 christos case 1: return "IAPSR";
3931 1.1 christos case 2: return "EAPSR";
3932 1.1 christos case 3: return "PSR";
3933 1.1 christos case 5: return "IPSR";
3934 1.1 christos case 6: return "EPSR";
3935 1.1 christos case 7: return "IEPSR";
3936 1.1 christos case 8: return "MSP";
3937 1.1 christos case 9: return "PSP";
3938 1.1 christos case 16: return "PRIMASK";
3939 1.1.1.1.2.1 yamt case 17: return "BASEPRI";
3940 1.1 christos case 18: return "BASEPRI_MAX";
3941 1.1 christos case 19: return "FAULTMASK";
3942 1.1 christos case 20: return "CONTROL";
3943 1.1 christos default: return "<unknown>";
3944 1.1 christos }
3945 1.1 christos }
3946 1.1 christos
3947 1.1 christos /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3948 1.1 christos
3949 1.1 christos static void
3950 1.1 christos print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3951 1.1 christos {
3952 1.1 christos const struct opcode32 *insn;
3953 1.1 christos void *stream = info->stream;
3954 1.1 christos fprintf_ftype func = info->fprintf_func;
3955 1.1 christos
3956 1.1 christos if (print_insn_coprocessor (pc, info, given, TRUE))
3957 1.1 christos return;
3958 1.1 christos
3959 1.1 christos if (print_insn_neon (info, given, TRUE))
3960 1.1 christos return;
3961 1.1 christos
3962 1.1 christos for (insn = thumb32_opcodes; insn->assembler; insn++)
3963 1.1 christos if ((given & insn->mask) == insn->value)
3964 1.1 christos {
3965 1.1 christos bfd_boolean is_unpredictable = FALSE;
3966 1.1 christos signed long value_in_comment = 0;
3967 1.1 christos const char *c = insn->assembler;
3968 1.1 christos
3969 1.1 christos for (; *c; c++)
3970 1.1 christos {
3971 1.1 christos if (*c != '%')
3972 1.1 christos {
3973 1.1 christos func (stream, "%c", *c);
3974 1.1 christos continue;
3975 1.1 christos }
3976 1.1 christos
3977 1.1 christos switch (*++c)
3978 1.1 christos {
3979 1.1 christos case '%':
3980 1.1 christos func (stream, "%%");
3981 1.1 christos break;
3982 1.1 christos
3983 1.1 christos case 'c':
3984 1.1 christos if (ifthen_state)
3985 1.1 christos func (stream, "%s", arm_conditional[IFTHEN_COND]);
3986 1.1 christos break;
3987 1.1 christos
3988 1.1 christos case 'x':
3989 1.1 christos if (ifthen_next_state)
3990 1.1 christos func (stream, "\t; unpredictable branch in IT block\n");
3991 1.1 christos break;
3992 1.1 christos
3993 1.1 christos case 'X':
3994 1.1 christos if (ifthen_state)
3995 1.1 christos func (stream, "\t; unpredictable <IT:%s>",
3996 1.1 christos arm_conditional[IFTHEN_COND]);
3997 1.1 christos break;
3998 1.1 christos
3999 1.1 christos case 'I':
4000 1.1 christos {
4001 1.1 christos unsigned int imm12 = 0;
4002 1.1 christos
4003 1.1 christos imm12 |= (given & 0x000000ffu);
4004 1.1 christos imm12 |= (given & 0x00007000u) >> 4;
4005 1.1 christos imm12 |= (given & 0x04000000u) >> 15;
4006 1.1 christos func (stream, "#%u", imm12);
4007 1.1 christos value_in_comment = imm12;
4008 1.1 christos }
4009 1.1 christos break;
4010 1.1 christos
4011 1.1 christos case 'M':
4012 1.1 christos {
4013 1.1 christos unsigned int bits = 0, imm, imm8, mod;
4014 1.1 christos
4015 1.1 christos bits |= (given & 0x000000ffu);
4016 1.1 christos bits |= (given & 0x00007000u) >> 4;
4017 1.1 christos bits |= (given & 0x04000000u) >> 15;
4018 1.1 christos imm8 = (bits & 0x0ff);
4019 1.1 christos mod = (bits & 0xf00) >> 8;
4020 1.1 christos switch (mod)
4021 1.1 christos {
4022 1.1 christos case 0: imm = imm8; break;
4023 1.1 christos case 1: imm = ((imm8 << 16) | imm8); break;
4024 1.1 christos case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
4025 1.1 christos case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
4026 1.1 christos default:
4027 1.1 christos mod = (bits & 0xf80) >> 7;
4028 1.1 christos imm8 = (bits & 0x07f) | 0x80;
4029 1.1 christos imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
4030 1.1 christos }
4031 1.1 christos func (stream, "#%u", imm);
4032 1.1 christos value_in_comment = imm;
4033 1.1 christos }
4034 1.1 christos break;
4035 1.1 christos
4036 1.1 christos case 'J':
4037 1.1 christos {
4038 1.1 christos unsigned int imm = 0;
4039 1.1 christos
4040 1.1 christos imm |= (given & 0x000000ffu);
4041 1.1 christos imm |= (given & 0x00007000u) >> 4;
4042 1.1 christos imm |= (given & 0x04000000u) >> 15;
4043 1.1 christos imm |= (given & 0x000f0000u) >> 4;
4044 1.1 christos func (stream, "#%u", imm);
4045 1.1 christos value_in_comment = imm;
4046 1.1 christos }
4047 1.1 christos break;
4048 1.1 christos
4049 1.1 christos case 'K':
4050 1.1 christos {
4051 1.1 christos unsigned int imm = 0;
4052 1.1 christos
4053 1.1 christos imm |= (given & 0x000f0000u) >> 16;
4054 1.1 christos imm |= (given & 0x00000ff0u) >> 0;
4055 1.1 christos imm |= (given & 0x0000000fu) << 12;
4056 1.1 christos func (stream, "#%u", imm);
4057 1.1 christos value_in_comment = imm;
4058 1.1 christos }
4059 1.1 christos break;
4060 1.1 christos
4061 1.1 christos case 'V':
4062 1.1 christos {
4063 1.1 christos unsigned int imm = 0;
4064 1.1 christos
4065 1.1 christos imm |= (given & 0x00000fffu);
4066 1.1 christos imm |= (given & 0x000f0000u) >> 4;
4067 1.1 christos func (stream, "#%u", imm);
4068 1.1 christos value_in_comment = imm;
4069 1.1 christos }
4070 1.1 christos break;
4071 1.1 christos
4072 1.1 christos case 'S':
4073 1.1 christos {
4074 1.1 christos unsigned int reg = (given & 0x0000000fu);
4075 1.1 christos unsigned int stp = (given & 0x00000030u) >> 4;
4076 1.1 christos unsigned int imm = 0;
4077 1.1 christos imm |= (given & 0x000000c0u) >> 6;
4078 1.1 christos imm |= (given & 0x00007000u) >> 10;
4079 1.1 christos
4080 1.1 christos func (stream, "%s", arm_regnames[reg]);
4081 1.1 christos switch (stp)
4082 1.1 christos {
4083 1.1 christos case 0:
4084 1.1 christos if (imm > 0)
4085 1.1 christos func (stream, ", lsl #%u", imm);
4086 1.1 christos break;
4087 1.1 christos
4088 1.1 christos case 1:
4089 1.1 christos if (imm == 0)
4090 1.1 christos imm = 32;
4091 1.1 christos func (stream, ", lsr #%u", imm);
4092 1.1 christos break;
4093 1.1 christos
4094 1.1 christos case 2:
4095 1.1 christos if (imm == 0)
4096 1.1 christos imm = 32;
4097 1.1 christos func (stream, ", asr #%u", imm);
4098 1.1 christos break;
4099 1.1 christos
4100 1.1 christos case 3:
4101 1.1 christos if (imm == 0)
4102 1.1 christos func (stream, ", rrx");
4103 1.1 christos else
4104 1.1 christos func (stream, ", ror #%u", imm);
4105 1.1 christos }
4106 1.1 christos }
4107 1.1 christos break;
4108 1.1 christos
4109 1.1 christos case 'a':
4110 1.1 christos {
4111 1.1 christos unsigned int Rn = (given & 0x000f0000) >> 16;
4112 1.1 christos unsigned int U = ! NEGATIVE_BIT_SET;
4113 1.1 christos unsigned int op = (given & 0x00000f00) >> 8;
4114 1.1 christos unsigned int i12 = (given & 0x00000fff);
4115 1.1 christos unsigned int i8 = (given & 0x000000ff);
4116 1.1.1.1.2.1 yamt bfd_boolean writeback = FALSE, postind = FALSE;
4117 1.1 christos bfd_vma offset = 0;
4118 1.1 christos
4119 1.1 christos func (stream, "[%s", arm_regnames[Rn]);
4120 1.1 christos if (U) /* 12-bit positive immediate offset. */
4121 1.1 christos {
4122 1.1 christos offset = i12;
4123 1.1 christos if (Rn != 15)
4124 1.1 christos value_in_comment = offset;
4125 1.1 christos }
4126 1.1 christos else if (Rn == 15) /* 12-bit negative immediate offset. */
4127 1.1 christos offset = - (int) i12;
4128 1.1 christos else if (op == 0x0) /* Shifted register offset. */
4129 1.1 christos {
4130 1.1 christos unsigned int Rm = (i8 & 0x0f);
4131 1.1 christos unsigned int sh = (i8 & 0x30) >> 4;
4132 1.1 christos
4133 1.1 christos func (stream, ", %s", arm_regnames[Rm]);
4134 1.1 christos if (sh)
4135 1.1 christos func (stream, ", lsl #%u", sh);
4136 1.1 christos func (stream, "]");
4137 1.1 christos break;
4138 1.1 christos }
4139 1.1 christos else switch (op)
4140 1.1 christos {
4141 1.1 christos case 0xE: /* 8-bit positive immediate offset. */
4142 1.1 christos offset = i8;
4143 1.1 christos break;
4144 1.1 christos
4145 1.1 christos case 0xC: /* 8-bit negative immediate offset. */
4146 1.1 christos offset = -i8;
4147 1.1 christos break;
4148 1.1 christos
4149 1.1 christos case 0xF: /* 8-bit + preindex with wb. */
4150 1.1 christos offset = i8;
4151 1.1 christos writeback = TRUE;
4152 1.1 christos break;
4153 1.1 christos
4154 1.1 christos case 0xD: /* 8-bit - preindex with wb. */
4155 1.1 christos offset = -i8;
4156 1.1 christos writeback = TRUE;
4157 1.1 christos break;
4158 1.1 christos
4159 1.1 christos case 0xB: /* 8-bit + postindex. */
4160 1.1 christos offset = i8;
4161 1.1 christos postind = TRUE;
4162 1.1 christos break;
4163 1.1 christos
4164 1.1 christos case 0x9: /* 8-bit - postindex. */
4165 1.1 christos offset = -i8;
4166 1.1 christos postind = TRUE;
4167 1.1 christos break;
4168 1.1 christos
4169 1.1 christos default:
4170 1.1 christos func (stream, ", <undefined>]");
4171 1.1 christos goto skip;
4172 1.1 christos }
4173 1.1 christos
4174 1.1.1.1.2.1 yamt if (postind)
4175 1.1 christos func (stream, "], #%d", (int) offset);
4176 1.1 christos else
4177 1.1 christos {
4178 1.1.1.1.2.1 yamt if (offset)
4179 1.1 christos func (stream, ", #%d", (int) offset);
4180 1.1 christos func (stream, writeback ? "]!" : "]");
4181 1.1 christos }
4182 1.1 christos
4183 1.1 christos if (Rn == 15)
4184 1.1 christos {
4185 1.1 christos func (stream, "\t; ");
4186 1.1 christos info->print_address_func (((pc + 4) & ~3) + offset, info);
4187 1.1 christos }
4188 1.1 christos }
4189 1.1 christos skip:
4190 1.1 christos break;
4191 1.1 christos
4192 1.1 christos case 'A':
4193 1.1 christos {
4194 1.1 christos unsigned int U = ! NEGATIVE_BIT_SET;
4195 1.1 christos unsigned int W = WRITEBACK_BIT_SET;
4196 1.1 christos unsigned int Rn = (given & 0x000f0000) >> 16;
4197 1.1 christos unsigned int off = (given & 0x000000ff);
4198 1.1 christos
4199 1.1 christos func (stream, "[%s", arm_regnames[Rn]);
4200 1.1 christos
4201 1.1 christos if (PRE_BIT_SET)
4202 1.1 christos {
4203 1.1 christos if (off || !U)
4204 1.1 christos {
4205 1.1 christos func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4206 1.1 christos value_in_comment = off * 4 * U ? 1 : -1;
4207 1.1 christos }
4208 1.1 christos func (stream, "]");
4209 1.1 christos if (W)
4210 1.1 christos func (stream, "!");
4211 1.1 christos }
4212 1.1 christos else
4213 1.1 christos {
4214 1.1 christos func (stream, "], ");
4215 1.1 christos if (W)
4216 1.1 christos {
4217 1.1 christos func (stream, "#%c%u", U ? '+' : '-', off * 4);
4218 1.1 christos value_in_comment = off * 4 * U ? 1 : -1;
4219 1.1 christos }
4220 1.1 christos else
4221 1.1 christos {
4222 1.1 christos func (stream, "{%u}", off);
4223 1.1 christos value_in_comment = off;
4224 1.1 christos }
4225 1.1 christos }
4226 1.1 christos }
4227 1.1 christos break;
4228 1.1 christos
4229 1.1 christos case 'w':
4230 1.1 christos {
4231 1.1 christos unsigned int Sbit = (given & 0x01000000) >> 24;
4232 1.1 christos unsigned int type = (given & 0x00600000) >> 21;
4233 1.1 christos
4234 1.1 christos switch (type)
4235 1.1 christos {
4236 1.1 christos case 0: func (stream, Sbit ? "sb" : "b"); break;
4237 1.1 christos case 1: func (stream, Sbit ? "sh" : "h"); break;
4238 1.1 christos case 2:
4239 1.1 christos if (Sbit)
4240 1.1 christos func (stream, "??");
4241 1.1 christos break;
4242 1.1 christos case 3:
4243 1.1 christos func (stream, "??");
4244 1.1 christos break;
4245 1.1 christos }
4246 1.1 christos }
4247 1.1 christos break;
4248 1.1 christos
4249 1.1 christos case 'm':
4250 1.1 christos {
4251 1.1 christos int started = 0;
4252 1.1 christos int reg;
4253 1.1 christos
4254 1.1 christos func (stream, "{");
4255 1.1 christos for (reg = 0; reg < 16; reg++)
4256 1.1 christos if ((given & (1 << reg)) != 0)
4257 1.1 christos {
4258 1.1 christos if (started)
4259 1.1 christos func (stream, ", ");
4260 1.1 christos started = 1;
4261 1.1 christos func (stream, "%s", arm_regnames[reg]);
4262 1.1 christos }
4263 1.1 christos func (stream, "}");
4264 1.1 christos }
4265 1.1 christos break;
4266 1.1 christos
4267 1.1 christos case 'E':
4268 1.1 christos {
4269 1.1 christos unsigned int msb = (given & 0x0000001f);
4270 1.1 christos unsigned int lsb = 0;
4271 1.1 christos
4272 1.1 christos lsb |= (given & 0x000000c0u) >> 6;
4273 1.1 christos lsb |= (given & 0x00007000u) >> 10;
4274 1.1 christos func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4275 1.1 christos }
4276 1.1 christos break;
4277 1.1 christos
4278 1.1 christos case 'F':
4279 1.1 christos {
4280 1.1 christos unsigned int width = (given & 0x0000001f) + 1;
4281 1.1 christos unsigned int lsb = 0;
4282 1.1 christos
4283 1.1 christos lsb |= (given & 0x000000c0u) >> 6;
4284 1.1 christos lsb |= (given & 0x00007000u) >> 10;
4285 1.1 christos func (stream, "#%u, #%u", lsb, width);
4286 1.1 christos }
4287 1.1 christos break;
4288 1.1 christos
4289 1.1 christos case 'b':
4290 1.1 christos {
4291 1.1 christos unsigned int S = (given & 0x04000000u) >> 26;
4292 1.1 christos unsigned int J1 = (given & 0x00002000u) >> 13;
4293 1.1.1.1.2.1 yamt unsigned int J2 = (given & 0x00000800u) >> 11;
4294 1.1 christos bfd_vma offset = 0;
4295 1.1 christos
4296 1.1 christos offset |= !S << 20;
4297 1.1 christos offset |= J2 << 19;
4298 1.1 christos offset |= J1 << 18;
4299 1.1 christos offset |= (given & 0x003f0000) >> 4;
4300 1.1 christos offset |= (given & 0x000007ff) << 1;
4301 1.1 christos offset -= (1 << 20);
4302 1.1 christos
4303 1.1 christos info->print_address_func (pc + 4 + offset, info);
4304 1.1 christos }
4305 1.1 christos break;
4306 1.1 christos
4307 1.1 christos case 'B':
4308 1.1 christos {
4309 1.1 christos unsigned int S = (given & 0x04000000u) >> 26;
4310 1.1 christos unsigned int I1 = (given & 0x00002000u) >> 13;
4311 1.1.1.1.2.1 yamt unsigned int I2 = (given & 0x00000800u) >> 11;
4312 1.1 christos bfd_vma offset = 0;
4313 1.1 christos
4314 1.1 christos offset |= !S << 24;
4315 1.1 christos offset |= !(I1 ^ S) << 23;
4316 1.1 christos offset |= !(I2 ^ S) << 22;
4317 1.1 christos offset |= (given & 0x03ff0000u) >> 4;
4318 1.1 christos offset |= (given & 0x000007ffu) << 1;
4319 1.1 christos offset -= (1 << 24);
4320 1.1 christos offset += pc + 4;
4321 1.1 christos
4322 1.1 christos /* BLX target addresses are always word aligned. */
4323 1.1 christos if ((given & 0x00001000u) == 0)
4324 1.1 christos offset &= ~2u;
4325 1.1 christos
4326 1.1 christos info->print_address_func (offset, info);
4327 1.1 christos }
4328 1.1 christos break;
4329 1.1 christos
4330 1.1 christos case 's':
4331 1.1 christos {
4332 1.1 christos unsigned int shift = 0;
4333 1.1 christos
4334 1.1 christos shift |= (given & 0x000000c0u) >> 6;
4335 1.1 christos shift |= (given & 0x00007000u) >> 10;
4336 1.1 christos if (WRITEBACK_BIT_SET)
4337 1.1 christos func (stream, ", asr #%u", shift);
4338 1.1 christos else if (shift)
4339 1.1 christos func (stream, ", lsl #%u", shift);
4340 1.1 christos /* else print nothing - lsl #0 */
4341 1.1 christos }
4342 1.1 christos break;
4343 1.1 christos
4344 1.1 christos case 'R':
4345 1.1 christos {
4346 1.1 christos unsigned int rot = (given & 0x00000030) >> 4;
4347 1.1 christos
4348 1.1 christos if (rot)
4349 1.1 christos func (stream, ", ror #%u", rot * 8);
4350 1.1 christos }
4351 1.1 christos break;
4352 1.1 christos
4353 1.1 christos case 'U':
4354 1.1 christos if ((given & 0xf0) == 0x60)
4355 1.1 christos {
4356 1.1 christos switch (given & 0xf)
4357 1.1 christos {
4358 1.1 christos case 0xf: func (stream, "sy"); break;
4359 1.1 christos default:
4360 1.1 christos func (stream, "#%d", (int) given & 0xf);
4361 1.1 christos break;
4362 1.1 christos }
4363 1.1 christos }
4364 1.1 christos else
4365 1.1.1.1.2.1 yamt {
4366 1.1.1.1.2.1 yamt const char * opt = data_barrier_option (given & 0xf);
4367 1.1.1.1.2.1 yamt if (opt != NULL)
4368 1.1.1.1.2.1 yamt func (stream, "%s", opt);
4369 1.1.1.1.2.1 yamt else
4370 1.1 christos func (stream, "#%d", (int) given & 0xf);
4371 1.1 christos }
4372 1.1 christos break;
4373 1.1 christos
4374 1.1 christos case 'C':
4375 1.1 christos if ((given & 0xff) == 0)
4376 1.1 christos {
4377 1.1 christos func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4378 1.1 christos if (given & 0x800)
4379 1.1 christos func (stream, "f");
4380 1.1 christos if (given & 0x400)
4381 1.1 christos func (stream, "s");
4382 1.1 christos if (given & 0x200)
4383 1.1 christos func (stream, "x");
4384 1.1 christos if (given & 0x100)
4385 1.1 christos func (stream, "c");
4386 1.1 christos }
4387 1.1 christos else if ((given & 0x20) == 0x20)
4388 1.1 christos {
4389 1.1 christos char const* name;
4390 1.1 christos unsigned sysm = (given & 0xf00) >> 8;
4391 1.1 christos
4392 1.1 christos sysm |= (given & 0x30);
4393 1.1 christos sysm |= (given & 0x00100000) >> 14;
4394 1.1 christos name = banked_regname (sysm);
4395 1.1 christos
4396 1.1 christos if (name != NULL)
4397 1.1 christos func (stream, "%s", name);
4398 1.1.1.1.2.1 yamt else
4399 1.1 christos func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
4400 1.1 christos }
4401 1.1 christos else
4402 1.1.1.1.2.1 yamt {
4403 1.1 christos func (stream, "%s", psr_name (given & 0xff));
4404 1.1 christos }
4405 1.1 christos break;
4406 1.1 christos
4407 1.1 christos case 'D':
4408 1.1 christos if (((given & 0xff) == 0)
4409 1.1 christos || ((given & 0x20) == 0x20))
4410 1.1 christos {
4411 1.1 christos char const* name;
4412 1.1 christos unsigned sm = (given & 0xf0000) >> 16;
4413 1.1 christos
4414 1.1 christos sm |= (given & 0x30);
4415 1.1 christos sm |= (given & 0x00100000) >> 14;
4416 1.1 christos name = banked_regname (sm);
4417 1.1 christos
4418 1.1 christos if (name != NULL)
4419 1.1 christos func (stream, "%s", name);
4420 1.1.1.1.2.1 yamt else
4421 1.1 christos func (stream, "(UNDEF: %lu)", (unsigned long) sm);
4422 1.1 christos }
4423 1.1.1.1.2.1 yamt else
4424 1.1 christos func (stream, "%s", psr_name (given & 0xff));
4425 1.1 christos break;
4426 1.1 christos
4427 1.1 christos case '0': case '1': case '2': case '3': case '4':
4428 1.1 christos case '5': case '6': case '7': case '8': case '9':
4429 1.1 christos {
4430 1.1 christos int width;
4431 1.1 christos unsigned long val;
4432 1.1 christos
4433 1.1 christos c = arm_decode_bitfield (c, given, &val, &width);
4434 1.1 christos
4435 1.1 christos switch (*c)
4436 1.1 christos {
4437 1.1 christos case 'd':
4438 1.1 christos func (stream, "%lu", val);
4439 1.1 christos value_in_comment = val;
4440 1.1 christos break;
4441 1.1 christos
4442 1.1 christos case 'W':
4443 1.1 christos func (stream, "%lu", val * 4);
4444 1.1 christos value_in_comment = val * 4;
4445 1.1 christos break;
4446 1.1.1.1.2.1 yamt
4447 1.1.1.1.2.1 yamt case 'S':
4448 1.1.1.1.2.1 yamt if (val == 13)
4449 1.1.1.1.2.1 yamt is_unpredictable = TRUE;
4450 1.1 christos /* Fall through. */
4451 1.1 christos case 'R':
4452 1.1 christos if (val == 15)
4453 1.1 christos is_unpredictable = TRUE;
4454 1.1 christos /* Fall through. */
4455 1.1 christos case 'r':
4456 1.1 christos func (stream, "%s", arm_regnames[val]);
4457 1.1 christos break;
4458 1.1 christos
4459 1.1 christos case 'c':
4460 1.1 christos func (stream, "%s", arm_conditional[val]);
4461 1.1 christos break;
4462 1.1 christos
4463 1.1 christos case '\'':
4464 1.1 christos c++;
4465 1.1 christos if (val == ((1ul << width) - 1))
4466 1.1 christos func (stream, "%c", *c);
4467 1.1 christos break;
4468 1.1 christos
4469 1.1 christos case '`':
4470 1.1 christos c++;
4471 1.1 christos if (val == 0)
4472 1.1 christos func (stream, "%c", *c);
4473 1.1 christos break;
4474 1.1 christos
4475 1.1 christos case '?':
4476 1.1 christos func (stream, "%c", c[(1 << width) - (int) val]);
4477 1.1 christos c += 1 << width;
4478 1.1 christos break;
4479 1.1 christos
4480 1.1 christos case 'x':
4481 1.1 christos func (stream, "0x%lx", val & 0xffffffffUL);
4482 1.1 christos break;
4483 1.1 christos
4484 1.1 christos default:
4485 1.1 christos abort ();
4486 1.1 christos }
4487 1.1 christos }
4488 1.1 christos break;
4489 1.1.1.1.2.1 yamt
4490 1.1.1.1.2.1 yamt case 'L':
4491 1.1.1.1.2.1 yamt /* PR binutils/12534
4492 1.1.1.1.2.1 yamt If we have a PC relative offset in an LDRD or STRD
4493 1.1.1.1.2.1 yamt instructions then display the decoded address. */
4494 1.1.1.1.2.1 yamt if (((given >> 16) & 0xf) == 0xf)
4495 1.1.1.1.2.1 yamt {
4496 1.1.1.1.2.1 yamt bfd_vma offset = (given & 0xff) * 4;
4497 1.1.1.1.2.1 yamt
4498 1.1.1.1.2.1 yamt if ((given & (1 << 23)) == 0)
4499 1.1.1.1.2.1 yamt offset = - offset;
4500 1.1.1.1.2.1 yamt func (stream, "\t; ");
4501 1.1.1.1.2.1 yamt info->print_address_func ((pc & ~3) + 4 + offset, info);
4502 1.1.1.1.2.1 yamt }
4503 1.1.1.1.2.1 yamt break;
4504 1.1 christos
4505 1.1 christos default:
4506 1.1 christos abort ();
4507 1.1 christos }
4508 1.1 christos }
4509 1.1 christos
4510 1.1 christos if (value_in_comment > 32 || value_in_comment < -16)
4511 1.1 christos func (stream, "\t; 0x%lx", value_in_comment);
4512 1.1 christos
4513 1.1 christos if (is_unpredictable)
4514 1.1 christos func (stream, UNPREDICTABLE_INSTRUCTION);
4515 1.1 christos
4516 1.1 christos return;
4517 1.1 christos }
4518 1.1 christos
4519 1.1 christos /* No match. */
4520 1.1 christos abort ();
4521 1.1 christos }
4522 1.1 christos
4523 1.1 christos /* Print data bytes on INFO->STREAM. */
4524 1.1 christos
4525 1.1 christos static void
4526 1.1 christos print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4527 1.1 christos struct disassemble_info *info,
4528 1.1 christos long given)
4529 1.1 christos {
4530 1.1 christos switch (info->bytes_per_chunk)
4531 1.1 christos {
4532 1.1 christos case 1:
4533 1.1 christos info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4534 1.1 christos break;
4535 1.1 christos case 2:
4536 1.1 christos info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4537 1.1 christos break;
4538 1.1 christos case 4:
4539 1.1 christos info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4540 1.1 christos break;
4541 1.1 christos default:
4542 1.1 christos abort ();
4543 1.1 christos }
4544 1.1 christos }
4545 1.1 christos
4546 1.1 christos /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4547 1.1 christos being displayed in symbol relative addresses. */
4548 1.1 christos
4549 1.1 christos bfd_boolean
4550 1.1 christos arm_symbol_is_valid (asymbol * sym,
4551 1.1 christos struct disassemble_info * info ATTRIBUTE_UNUSED)
4552 1.1 christos {
4553 1.1 christos const char * name;
4554 1.1 christos
4555 1.1 christos if (sym == NULL)
4556 1.1 christos return FALSE;
4557 1.1 christos
4558 1.1 christos name = bfd_asymbol_name (sym);
4559 1.1 christos
4560 1.1 christos return (name && *name != '$');
4561 1.1 christos }
4562 1.1 christos
4563 1.1 christos /* Parse an individual disassembler option. */
4564 1.1 christos
4565 1.1 christos void
4566 1.1 christos parse_arm_disassembler_option (char *option)
4567 1.1 christos {
4568 1.1 christos if (option == NULL)
4569 1.1 christos return;
4570 1.1 christos
4571 1.1 christos if (CONST_STRNEQ (option, "reg-names-"))
4572 1.1 christos {
4573 1.1 christos int i;
4574 1.1 christos
4575 1.1 christos option += 10;
4576 1.1 christos
4577 1.1 christos for (i = NUM_ARM_REGNAMES; i--;)
4578 1.1 christos if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4579 1.1 christos {
4580 1.1 christos regname_selected = i;
4581 1.1 christos break;
4582 1.1 christos }
4583 1.1 christos
4584 1.1 christos if (i < 0)
4585 1.1 christos /* XXX - should break 'option' at following delimiter. */
4586 1.1 christos fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4587 1.1 christos }
4588 1.1 christos else if (CONST_STRNEQ (option, "force-thumb"))
4589 1.1 christos force_thumb = 1;
4590 1.1 christos else if (CONST_STRNEQ (option, "no-force-thumb"))
4591 1.1 christos force_thumb = 0;
4592 1.1 christos else
4593 1.1 christos /* XXX - should break 'option' at following delimiter. */
4594 1.1 christos fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4595 1.1 christos
4596 1.1 christos return;
4597 1.1 christos }
4598 1.1 christos
4599 1.1 christos /* Parse the string of disassembler options, spliting it at whitespaces
4600 1.1 christos or commas. (Whitespace separators supported for backwards compatibility). */
4601 1.1 christos
4602 1.1 christos static void
4603 1.1 christos parse_disassembler_options (char *options)
4604 1.1 christos {
4605 1.1 christos if (options == NULL)
4606 1.1 christos return;
4607 1.1 christos
4608 1.1 christos while (*options)
4609 1.1 christos {
4610 1.1 christos parse_arm_disassembler_option (options);
4611 1.1 christos
4612 1.1 christos /* Skip forward to next seperator. */
4613 1.1 christos while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4614 1.1 christos ++ options;
4615 1.1 christos /* Skip forward past seperators. */
4616 1.1 christos while (ISSPACE (*options) || (*options == ','))
4617 1.1 christos ++ options;
4618 1.1 christos }
4619 1.1 christos }
4620 1.1 christos
4621 1.1 christos /* Search back through the insn stream to determine if this instruction is
4622 1.1 christos conditionally executed. */
4623 1.1 christos
4624 1.1 christos static void
4625 1.1 christos find_ifthen_state (bfd_vma pc,
4626 1.1 christos struct disassemble_info *info,
4627 1.1 christos bfd_boolean little)
4628 1.1 christos {
4629 1.1 christos unsigned char b[2];
4630 1.1 christos unsigned int insn;
4631 1.1 christos int status;
4632 1.1 christos /* COUNT is twice the number of instructions seen. It will be odd if we
4633 1.1 christos just crossed an instruction boundary. */
4634 1.1 christos int count;
4635 1.1 christos int it_count;
4636 1.1 christos unsigned int seen_it;
4637 1.1 christos bfd_vma addr;
4638 1.1 christos
4639 1.1 christos ifthen_address = pc;
4640 1.1 christos ifthen_state = 0;
4641 1.1 christos
4642 1.1 christos addr = pc;
4643 1.1 christos count = 1;
4644 1.1 christos it_count = 0;
4645 1.1 christos seen_it = 0;
4646 1.1 christos /* Scan backwards looking for IT instructions, keeping track of where
4647 1.1 christos instruction boundaries are. We don't know if something is actually an
4648 1.1 christos IT instruction until we find a definite instruction boundary. */
4649 1.1 christos for (;;)
4650 1.1 christos {
4651 1.1 christos if (addr == 0 || info->symbol_at_address_func (addr, info))
4652 1.1 christos {
4653 1.1 christos /* A symbol must be on an instruction boundary, and will not
4654 1.1 christos be within an IT block. */
4655 1.1 christos if (seen_it && (count & 1))
4656 1.1 christos break;
4657 1.1 christos
4658 1.1 christos return;
4659 1.1 christos }
4660 1.1 christos addr -= 2;
4661 1.1 christos status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4662 1.1 christos if (status)
4663 1.1 christos return;
4664 1.1 christos
4665 1.1 christos if (little)
4666 1.1 christos insn = (b[0]) | (b[1] << 8);
4667 1.1 christos else
4668 1.1 christos insn = (b[1]) | (b[0] << 8);
4669 1.1 christos if (seen_it)
4670 1.1 christos {
4671 1.1 christos if ((insn & 0xf800) < 0xe800)
4672 1.1 christos {
4673 1.1 christos /* Addr + 2 is an instruction boundary. See if this matches
4674 1.1 christos the expected boundary based on the position of the last
4675 1.1 christos IT candidate. */
4676 1.1 christos if (count & 1)
4677 1.1 christos break;
4678 1.1 christos seen_it = 0;
4679 1.1 christos }
4680 1.1 christos }
4681 1.1 christos if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4682 1.1 christos {
4683 1.1 christos /* This could be an IT instruction. */
4684 1.1 christos seen_it = insn;
4685 1.1 christos it_count = count >> 1;
4686 1.1 christos }
4687 1.1 christos if ((insn & 0xf800) >= 0xe800)
4688 1.1 christos count++;
4689 1.1 christos else
4690 1.1 christos count = (count + 2) | 1;
4691 1.1 christos /* IT blocks contain at most 4 instructions. */
4692 1.1 christos if (count >= 8 && !seen_it)
4693 1.1 christos return;
4694 1.1 christos }
4695 1.1 christos /* We found an IT instruction. */
4696 1.1 christos ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4697 1.1 christos if ((ifthen_state & 0xf) == 0)
4698 1.1 christos ifthen_state = 0;
4699 1.1 christos }
4700 1.1 christos
4701 1.1 christos /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4702 1.1 christos mapping symbol. */
4703 1.1 christos
4704 1.1 christos static int
4705 1.1 christos is_mapping_symbol (struct disassemble_info *info, int n,
4706 1.1 christos enum map_type *map_type)
4707 1.1 christos {
4708 1.1 christos const char *name;
4709 1.1 christos
4710 1.1 christos name = bfd_asymbol_name (info->symtab[n]);
4711 1.1 christos if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4712 1.1 christos && (name[2] == 0 || name[2] == '.'))
4713 1.1 christos {
4714 1.1 christos *map_type = ((name[1] == 'a') ? MAP_ARM
4715 1.1 christos : (name[1] == 't') ? MAP_THUMB
4716 1.1 christos : MAP_DATA);
4717 1.1 christos return TRUE;
4718 1.1 christos }
4719 1.1 christos
4720 1.1 christos return FALSE;
4721 1.1 christos }
4722 1.1 christos
4723 1.1 christos /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4724 1.1 christos Returns nonzero if *MAP_TYPE was set. */
4725 1.1 christos
4726 1.1 christos static int
4727 1.1 christos get_map_sym_type (struct disassemble_info *info,
4728 1.1 christos int n,
4729 1.1 christos enum map_type *map_type)
4730 1.1 christos {
4731 1.1 christos /* If the symbol is in a different section, ignore it. */
4732 1.1 christos if (info->section != NULL && info->section != info->symtab[n]->section)
4733 1.1 christos return FALSE;
4734 1.1 christos
4735 1.1 christos return is_mapping_symbol (info, n, map_type);
4736 1.1 christos }
4737 1.1 christos
4738 1.1 christos /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4739 1.1 christos Returns nonzero if *MAP_TYPE was set. */
4740 1.1 christos
4741 1.1 christos static int
4742 1.1 christos get_sym_code_type (struct disassemble_info *info,
4743 1.1 christos int n,
4744 1.1 christos enum map_type *map_type)
4745 1.1 christos {
4746 1.1 christos elf_symbol_type *es;
4747 1.1 christos unsigned int type;
4748 1.1 christos
4749 1.1 christos /* If the symbol is in a different section, ignore it. */
4750 1.1 christos if (info->section != NULL && info->section != info->symtab[n]->section)
4751 1.1 christos return FALSE;
4752 1.1 christos
4753 1.1 christos es = *(elf_symbol_type **)(info->symtab + n);
4754 1.1 christos type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4755 1.1 christos
4756 1.1 christos /* If the symbol has function type then use that. */
4757 1.1 christos if (type == STT_FUNC || type == STT_GNU_IFUNC)
4758 1.1 christos {
4759 1.1 christos if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4760 1.1 christos *map_type = MAP_THUMB;
4761 1.1 christos else
4762 1.1 christos *map_type = MAP_ARM;
4763 1.1 christos return TRUE;
4764 1.1 christos }
4765 1.1 christos
4766 1.1 christos return FALSE;
4767 1.1 christos }
4768 1.1 christos
4769 1.1 christos /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4770 1.1 christos of the supplied arm_feature_set structure with bitmasks indicating
4771 1.1 christos the support base architectures and coprocessor extensions.
4772 1.1 christos
4773 1.1 christos FIXME: This could more efficiently implemented as a constant array,
4774 1.1 christos although it would also be less robust. */
4775 1.1 christos
4776 1.1 christos static void
4777 1.1 christos select_arm_features (unsigned long mach,
4778 1.1 christos arm_feature_set * features)
4779 1.1 christos {
4780 1.1 christos #undef ARM_FEATURE
4781 1.1 christos #define ARM_FEATURE(ARCH,CEXT) \
4782 1.1 christos features->core = (ARCH); \
4783 1.1 christos features->coproc = (CEXT) | FPU_FPA; \
4784 1.1 christos return
4785 1.1 christos
4786 1.1 christos switch (mach)
4787 1.1 christos {
4788 1.1 christos case bfd_mach_arm_2: ARM_ARCH_V2;
4789 1.1 christos case bfd_mach_arm_2a: ARM_ARCH_V2S;
4790 1.1 christos case bfd_mach_arm_3: ARM_ARCH_V3;
4791 1.1 christos case bfd_mach_arm_3M: ARM_ARCH_V3M;
4792 1.1 christos case bfd_mach_arm_4: ARM_ARCH_V4;
4793 1.1 christos case bfd_mach_arm_4T: ARM_ARCH_V4T;
4794 1.1 christos case bfd_mach_arm_5: ARM_ARCH_V5;
4795 1.1 christos case bfd_mach_arm_5T: ARM_ARCH_V5T;
4796 1.1 christos case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4797 1.1 christos case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4798 1.1 christos case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4799 1.1 christos case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4800 1.1 christos case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4801 1.1 christos /* If the machine type is unknown allow all
4802 1.1 christos architecture types and all extensions. */
4803 1.1 christos case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4804 1.1 christos default:
4805 1.1 christos abort ();
4806 1.1 christos }
4807 1.1 christos }
4808 1.1 christos
4809 1.1 christos
4810 1.1 christos /* NOTE: There are no checks in these routines that
4811 1.1 christos the relevant number of data bytes exist. */
4812 1.1 christos
4813 1.1 christos static int
4814 1.1 christos print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4815 1.1 christos {
4816 1.1 christos unsigned char b[4];
4817 1.1 christos long given;
4818 1.1 christos int status;
4819 1.1 christos int is_thumb = FALSE;
4820 1.1 christos int is_data = FALSE;
4821 1.1 christos int little_code;
4822 1.1 christos unsigned int size = 4;
4823 1.1 christos void (*printer) (bfd_vma, struct disassemble_info *, long);
4824 1.1 christos bfd_boolean found = FALSE;
4825 1.1 christos struct arm_private_data *private_data;
4826 1.1 christos
4827 1.1 christos if (info->disassembler_options)
4828 1.1 christos {
4829 1.1 christos parse_disassembler_options (info->disassembler_options);
4830 1.1 christos
4831 1.1 christos /* To avoid repeated parsing of these options, we remove them here. */
4832 1.1 christos info->disassembler_options = NULL;
4833 1.1 christos }
4834 1.1 christos
4835 1.1 christos /* PR 10288: Control which instructions will be disassembled. */
4836 1.1 christos if (info->private_data == NULL)
4837 1.1 christos {
4838 1.1 christos static struct arm_private_data private;
4839 1.1 christos
4840 1.1 christos if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4841 1.1 christos /* If the user did not use the -m command line switch then default to
4842 1.1 christos disassembling all types of ARM instruction.
4843 1.1 christos
4844 1.1 christos The info->mach value has to be ignored as this will be based on
4845 1.1 christos the default archictecture for the target and/or hints in the notes
4846 1.1 christos section, but it will never be greater than the current largest arm
4847 1.1 christos machine value (iWMMXt2), which is only equivalent to the V5TE
4848 1.1 christos architecture. ARM architectures have advanced beyond the machine
4849 1.1 christos value encoding, and these newer architectures would be ignored if
4850 1.1 christos the machine value was used.
4851 1.1 christos
4852 1.1 christos Ie the -m switch is used to restrict which instructions will be
4853 1.1 christos disassembled. If it is necessary to use the -m switch to tell
4854 1.1 christos objdump that an ARM binary is being disassembled, eg because the
4855 1.1 christos input is a raw binary file, but it is also desired to disassemble
4856 1.1 christos all ARM instructions then use "-marm". This will select the
4857 1.1 christos "unknown" arm architecture which is compatible with any ARM
4858 1.1 christos instruction. */
4859 1.1 christos info->mach = bfd_mach_arm_unknown;
4860 1.1 christos
4861 1.1 christos /* Compute the architecture bitmask from the machine number.
4862 1.1 christos Note: This assumes that the machine number will not change
4863 1.1 christos during disassembly.... */
4864 1.1 christos select_arm_features (info->mach, & private.features);
4865 1.1 christos
4866 1.1.1.1.2.1 yamt private.has_mapping_symbols = -1;
4867 1.1.1.1.2.1 yamt private.last_mapping_sym = -1;
4868 1.1 christos private.last_mapping_addr = 0;
4869 1.1 christos
4870 1.1 christos info->private_data = & private;
4871 1.1 christos }
4872 1.1 christos
4873 1.1 christos private_data = info->private_data;
4874 1.1 christos
4875 1.1 christos /* Decide if our code is going to be little-endian, despite what the
4876 1.1 christos function argument might say. */
4877 1.1 christos little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4878 1.1 christos
4879 1.1 christos /* For ELF, consult the symbol table to determine what kind of code
4880 1.1 christos or data we have. */
4881 1.1 christos if (info->symtab_size != 0
4882 1.1 christos && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4883 1.1 christos {
4884 1.1 christos bfd_vma addr;
4885 1.1 christos int n, start;
4886 1.1 christos int last_sym = -1;
4887 1.1 christos enum map_type type = MAP_ARM;
4888 1.1 christos
4889 1.1 christos /* Start scanning at the start of the function, or wherever
4890 1.1.1.1.2.1 yamt we finished last time. */
4891 1.1.1.1.2.1 yamt /* PR 14006. When the address is 0 we are either at the start of the
4892 1.1.1.1.2.1 yamt very first function, or else the first function in a new, unlinked
4893 1.1.1.1.2.1 yamt executable section (eg because uf -ffunction-sections). Either way
4894 1.1.1.1.2.1 yamt start scanning from the beginning of the symbol table, not where we
4895 1.1.1.1.2.1 yamt left off last time. */
4896 1.1.1.1.2.1 yamt if (pc == 0)
4897 1.1.1.1.2.1 yamt start = 0;
4898 1.1.1.1.2.1 yamt else
4899 1.1.1.1.2.1 yamt {
4900 1.1.1.1.2.1 yamt start = info->symtab_pos + 1;
4901 1.1.1.1.2.1 yamt if (start < private_data->last_mapping_sym)
4902 1.1.1.1.2.1 yamt start = private_data->last_mapping_sym;
4903 1.1 christos }
4904 1.1 christos found = FALSE;
4905 1.1 christos
4906 1.1 christos /* First, look for mapping symbols. */
4907 1.1 christos if (private_data->has_mapping_symbols != 0)
4908 1.1 christos {
4909 1.1 christos /* Scan up to the location being disassembled. */
4910 1.1 christos for (n = start; n < info->symtab_size; n++)
4911 1.1 christos {
4912 1.1 christos addr = bfd_asymbol_value (info->symtab[n]);
4913 1.1 christos if (addr > pc)
4914 1.1 christos break;
4915 1.1 christos if (get_map_sym_type (info, n, &type))
4916 1.1 christos {
4917 1.1 christos last_sym = n;
4918 1.1 christos found = TRUE;
4919 1.1 christos }
4920 1.1 christos }
4921 1.1 christos
4922 1.1 christos if (!found)
4923 1.1 christos {
4924 1.1.1.1.2.1 yamt /* No mapping symbol found at this address. Look backwards
4925 1.1 christos for a preceding one. */
4926 1.1 christos for (n = start - 1; n >= 0; n--)
4927 1.1 christos {
4928 1.1 christos if (get_map_sym_type (info, n, &type))
4929 1.1 christos {
4930 1.1 christos last_sym = n;
4931 1.1 christos found = TRUE;
4932 1.1 christos break;
4933 1.1 christos }
4934 1.1 christos }
4935 1.1 christos }
4936 1.1 christos
4937 1.1 christos if (found)
4938 1.1 christos private_data->has_mapping_symbols = 1;
4939 1.1 christos
4940 1.1 christos /* No mapping symbols were found. A leading $d may be
4941 1.1 christos omitted for sections which start with data; but for
4942 1.1 christos compatibility with legacy and stripped binaries, only
4943 1.1 christos assume the leading $d if there is at least one mapping
4944 1.1 christos symbol in the file. */
4945 1.1 christos if (!found && private_data->has_mapping_symbols == -1)
4946 1.1 christos {
4947 1.1 christos /* Look for mapping symbols, in any section. */
4948 1.1 christos for (n = 0; n < info->symtab_size; n++)
4949 1.1 christos if (is_mapping_symbol (info, n, &type))
4950 1.1 christos {
4951 1.1 christos private_data->has_mapping_symbols = 1;
4952 1.1 christos break;
4953 1.1 christos }
4954 1.1 christos if (private_data->has_mapping_symbols == -1)
4955 1.1 christos private_data->has_mapping_symbols = 0;
4956 1.1 christos }
4957 1.1 christos
4958 1.1 christos if (!found && private_data->has_mapping_symbols == 1)
4959 1.1 christos {
4960 1.1 christos type = MAP_DATA;
4961 1.1 christos found = TRUE;
4962 1.1 christos }
4963 1.1 christos }
4964 1.1 christos
4965 1.1 christos /* Next search for function symbols to separate ARM from Thumb
4966 1.1 christos in binaries without mapping symbols. */
4967 1.1 christos if (!found)
4968 1.1 christos {
4969 1.1 christos /* Scan up to the location being disassembled. */
4970 1.1 christos for (n = start; n < info->symtab_size; n++)
4971 1.1 christos {
4972 1.1 christos addr = bfd_asymbol_value (info->symtab[n]);
4973 1.1 christos if (addr > pc)
4974 1.1 christos break;
4975 1.1 christos if (get_sym_code_type (info, n, &type))
4976 1.1 christos {
4977 1.1 christos last_sym = n;
4978 1.1 christos found = TRUE;
4979 1.1 christos }
4980 1.1 christos }
4981 1.1 christos
4982 1.1 christos if (!found)
4983 1.1 christos {
4984 1.1.1.1.2.1 yamt /* No mapping symbol found at this address. Look backwards
4985 1.1 christos for a preceding one. */
4986 1.1 christos for (n = start - 1; n >= 0; n--)
4987 1.1 christos {
4988 1.1 christos if (get_sym_code_type (info, n, &type))
4989 1.1 christos {
4990 1.1 christos last_sym = n;
4991 1.1 christos found = TRUE;
4992 1.1 christos break;
4993 1.1 christos }
4994 1.1 christos }
4995 1.1 christos }
4996 1.1 christos }
4997 1.1.1.1.2.1 yamt
4998 1.1.1.1.2.1 yamt private_data->last_mapping_sym = last_sym;
4999 1.1.1.1.2.1 yamt private_data->last_type = type;
5000 1.1.1.1.2.1 yamt is_thumb = (private_data->last_type == MAP_THUMB);
5001 1.1 christos is_data = (private_data->last_type == MAP_DATA);
5002 1.1 christos
5003 1.1 christos /* Look a little bit ahead to see if we should print out
5004 1.1 christos two or four bytes of data. If there's a symbol,
5005 1.1 christos mapping or otherwise, after two bytes then don't
5006 1.1 christos print more. */
5007 1.1 christos if (is_data)
5008 1.1 christos {
5009 1.1 christos size = 4 - (pc & 3);
5010 1.1 christos for (n = last_sym + 1; n < info->symtab_size; n++)
5011 1.1 christos {
5012 1.1 christos addr = bfd_asymbol_value (info->symtab[n]);
5013 1.1 christos if (addr > pc
5014 1.1 christos && (info->section == NULL
5015 1.1 christos || info->section == info->symtab[n]->section))
5016 1.1 christos {
5017 1.1 christos if (addr - pc < size)
5018 1.1 christos size = addr - pc;
5019 1.1 christos break;
5020 1.1 christos }
5021 1.1 christos }
5022 1.1 christos /* If the next symbol is after three bytes, we need to
5023 1.1 christos print only part of the data, so that we can use either
5024 1.1 christos .byte or .short. */
5025 1.1 christos if (size == 3)
5026 1.1 christos size = (pc & 1) ? 1 : 2;
5027 1.1 christos }
5028 1.1 christos }
5029 1.1 christos
5030 1.1 christos if (info->symbols != NULL)
5031 1.1 christos {
5032 1.1 christos if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
5033 1.1 christos {
5034 1.1 christos coff_symbol_type * cs;
5035 1.1 christos
5036 1.1 christos cs = coffsymbol (*info->symbols);
5037 1.1 christos is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
5038 1.1 christos || cs->native->u.syment.n_sclass == C_THUMBSTAT
5039 1.1 christos || cs->native->u.syment.n_sclass == C_THUMBLABEL
5040 1.1 christos || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
5041 1.1 christos || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
5042 1.1 christos }
5043 1.1 christos else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
5044 1.1 christos && !found)
5045 1.1 christos {
5046 1.1 christos /* If no mapping symbol has been found then fall back to the type
5047 1.1 christos of the function symbol. */
5048 1.1 christos elf_symbol_type * es;
5049 1.1 christos unsigned int type;
5050 1.1 christos
5051 1.1 christos es = *(elf_symbol_type **)(info->symbols);
5052 1.1 christos type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
5053 1.1 christos
5054 1.1 christos is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
5055 1.1 christos == ST_BRANCH_TO_THUMB)
5056 1.1 christos || type == STT_ARM_16BIT);
5057 1.1 christos }
5058 1.1 christos }
5059 1.1 christos
5060 1.1 christos if (force_thumb)
5061 1.1 christos is_thumb = TRUE;
5062 1.1 christos
5063 1.1 christos if (is_data)
5064 1.1 christos info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5065 1.1 christos else
5066 1.1 christos info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5067 1.1 christos
5068 1.1 christos info->bytes_per_line = 4;
5069 1.1 christos
5070 1.1 christos /* PR 10263: Disassemble data if requested to do so by the user. */
5071 1.1 christos if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
5072 1.1 christos {
5073 1.1 christos int i;
5074 1.1 christos
5075 1.1 christos /* Size was already set above. */
5076 1.1 christos info->bytes_per_chunk = size;
5077 1.1 christos printer = print_insn_data;
5078 1.1 christos
5079 1.1 christos status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
5080 1.1 christos given = 0;
5081 1.1 christos if (little)
5082 1.1 christos for (i = size - 1; i >= 0; i--)
5083 1.1 christos given = b[i] | (given << 8);
5084 1.1 christos else
5085 1.1 christos for (i = 0; i < (int) size; i++)
5086 1.1 christos given = b[i] | (given << 8);
5087 1.1 christos }
5088 1.1 christos else if (!is_thumb)
5089 1.1 christos {
5090 1.1 christos /* In ARM mode endianness is a straightforward issue: the instruction
5091 1.1 christos is four bytes long and is either ordered 0123 or 3210. */
5092 1.1 christos printer = print_insn_arm;
5093 1.1 christos info->bytes_per_chunk = 4;
5094 1.1 christos size = 4;
5095 1.1 christos
5096 1.1 christos status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
5097 1.1 christos if (little_code)
5098 1.1 christos given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
5099 1.1 christos else
5100 1.1 christos given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
5101 1.1 christos }
5102 1.1 christos else
5103 1.1 christos {
5104 1.1 christos /* In Thumb mode we have the additional wrinkle of two
5105 1.1 christos instruction lengths. Fortunately, the bits that determine
5106 1.1 christos the length of the current instruction are always to be found
5107 1.1 christos in the first two bytes. */
5108 1.1 christos printer = print_insn_thumb16;
5109 1.1 christos info->bytes_per_chunk = 2;
5110 1.1 christos size = 2;
5111 1.1 christos
5112 1.1 christos status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
5113 1.1 christos if (little_code)
5114 1.1 christos given = (b[0]) | (b[1] << 8);
5115 1.1 christos else
5116 1.1 christos given = (b[1]) | (b[0] << 8);
5117 1.1 christos
5118 1.1 christos if (!status)
5119 1.1 christos {
5120 1.1 christos /* These bit patterns signal a four-byte Thumb
5121 1.1 christos instruction. */
5122 1.1 christos if ((given & 0xF800) == 0xF800
5123 1.1 christos || (given & 0xF800) == 0xF000
5124 1.1 christos || (given & 0xF800) == 0xE800)
5125 1.1 christos {
5126 1.1 christos status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
5127 1.1 christos if (little_code)
5128 1.1 christos given = (b[0]) | (b[1] << 8) | (given << 16);
5129 1.1 christos else
5130 1.1 christos given = (b[1]) | (b[0] << 8) | (given << 16);
5131 1.1 christos
5132 1.1 christos printer = print_insn_thumb32;
5133 1.1 christos size = 4;
5134 1.1 christos }
5135 1.1 christos }
5136 1.1 christos
5137 1.1 christos if (ifthen_address != pc)
5138 1.1 christos find_ifthen_state (pc, info, little_code);
5139 1.1 christos
5140 1.1 christos if (ifthen_state)
5141 1.1 christos {
5142 1.1 christos if ((ifthen_state & 0xf) == 0x8)
5143 1.1 christos ifthen_next_state = 0;
5144 1.1 christos else
5145 1.1 christos ifthen_next_state = (ifthen_state & 0xe0)
5146 1.1 christos | ((ifthen_state & 0xf) << 1);
5147 1.1 christos }
5148 1.1 christos }
5149 1.1 christos
5150 1.1 christos if (status)
5151 1.1 christos {
5152 1.1 christos info->memory_error_func (status, pc, info);
5153 1.1 christos return -1;
5154 1.1 christos }
5155 1.1 christos if (info->flags & INSN_HAS_RELOC)
5156 1.1 christos /* If the instruction has a reloc associated with it, then
5157 1.1 christos the offset field in the instruction will actually be the
5158 1.1 christos addend for the reloc. (We are using REL type relocs).
5159 1.1 christos In such cases, we can ignore the pc when computing
5160 1.1 christos addresses, since the addend is not currently pc-relative. */
5161 1.1 christos pc = 0;
5162 1.1 christos
5163 1.1 christos printer (pc, info, given);
5164 1.1 christos
5165 1.1 christos if (is_thumb)
5166 1.1 christos {
5167 1.1 christos ifthen_state = ifthen_next_state;
5168 1.1 christos ifthen_address += size;
5169 1.1 christos }
5170 1.1 christos return size;
5171 1.1 christos }
5172 1.1 christos
5173 1.1 christos int
5174 1.1 christos print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5175 1.1 christos {
5176 1.1 christos /* Detect BE8-ness and record it in the disassembler info. */
5177 1.1 christos if (info->flavour == bfd_target_elf_flavour
5178 1.1 christos && info->section != NULL
5179 1.1 christos && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5180 1.1 christos info->endian_code = BFD_ENDIAN_LITTLE;
5181 1.1 christos
5182 1.1 christos return print_insn (pc, info, FALSE);
5183 1.1 christos }
5184 1.1 christos
5185 1.1 christos int
5186 1.1 christos print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5187 1.1 christos {
5188 1.1 christos return print_insn (pc, info, TRUE);
5189 1.1 christos }
5190 1.1 christos
5191 1.1 christos void
5192 1.1 christos print_arm_disassembler_options (FILE *stream)
5193 1.1 christos {
5194 1.1 christos int i;
5195 1.1 christos
5196 1.1 christos fprintf (stream, _("\n\
5197 1.1 christos The following ARM specific disassembler options are supported for use with\n\
5198 1.1 christos the -M switch:\n"));
5199 1.1 christos
5200 1.1 christos for (i = NUM_ARM_REGNAMES; i--;)
5201 1.1 christos fprintf (stream, " reg-names-%s %*c%s\n",
5202 1.1 christos regnames[i].name,
5203 1.1 christos (int)(14 - strlen (regnames[i].name)), ' ',
5204 1.1 christos regnames[i].description);
5205 1.1 christos
5206 1.1.1.1.2.1 yamt fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5207 1.1 christos fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");
5208 }
5209