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