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