1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
27 #include "opcode/arm.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
36 #include "elf/internal.h"
39 /* FIXME: Belongs in global header. */
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
50 unsigned long arch
; /* Architecture defining this insn. */
51 unsigned long value
; /* If arch == 0 then value is a sentinel. */
52 unsigned long mask
; /* Recognise insn if (op & mask) == value. */
53 const char * assembler
; /* How to disassemble this insn. */
58 unsigned long arch
; /* Architecture defining this insn. */
59 unsigned short value
, mask
; /* Recognise insn if (op & mask) == value. */
60 const char *assembler
; /* How to disassemble this insn. */
63 /* print_insn_coprocessor recognizes the following format control codes:
67 %c print condition code (always bits 28-31 in ARM mode)
68 %q print shifter argument
69 %u print condition code (unconditional in ARM mode)
70 %A print address for ldc/stc/ldf/stf instruction
71 %B print vstm/vldm register list
72 %I print cirrus signed shift immediate: bits 0..3|4..6
73 %F print the COUNT field of a LFM/SFM instruction.
74 %P print floating point precision in arithmetic insn
75 %Q print floating point precision in ldf/stf insn
76 %R print floating point rounding mode
78 %<bitfield>r print as an ARM register
79 %<bitfield>d print the bitfield in decimal
80 %<bitfield>k print immediate for VFPv3 conversion instruction
81 %<bitfield>x print the bitfield in hex
82 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
83 %<bitfield>f print a floating point constant if >7 else a
84 floating point register
85 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
86 %<bitfield>g print as an iWMMXt 64-bit register
87 %<bitfield>G print as an iWMMXt general purpose or control register
88 %<bitfield>D print as a NEON D register
89 %<bitfield>Q print as a NEON Q register
91 %y<code> print a single precision VFP reg.
92 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
93 %z<code> print a double precision VFP reg
94 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
96 %<bitfield>'c print specified char iff bitfield is all ones
97 %<bitfield>`c print specified char iff bitfield is all zeroes
98 %<bitfield>?ab... select from array of values in big endian order
100 %L print as an iWMMXt N/M width field.
101 %Z print the Immediate of a WSHUFH instruction.
102 %l like 'A' except use byte offsets for 'B' & 'H'
104 %i print 5-bit immediate in bits 8,3..0
106 %r print register offset address for wldt/wstr instruction. */
108 enum opcode_sentinel_enum
110 SENTINEL_IWMMXT_START
= 1,
112 SENTINEL_GENERIC_START
115 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
116 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
118 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
120 static const struct opcode32 coprocessor_opcodes
[] =
122 /* XScale instructions. */
123 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
124 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
125 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
126 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
127 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
129 /* Intel Wireless MMX technology instructions. */
130 { 0, SENTINEL_IWMMXT_START
, 0, "" },
131 {ARM_CEXT_IWMMXT
, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
132 {ARM_CEXT_XSCALE
, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
133 {ARM_CEXT_XSCALE
, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
134 {ARM_CEXT_XSCALE
, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
135 {ARM_CEXT_XSCALE
, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
136 {ARM_CEXT_XSCALE
, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
137 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
138 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
139 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
140 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
141 {ARM_CEXT_XSCALE
, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
142 {ARM_CEXT_XSCALE
, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
143 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
144 {ARM_CEXT_XSCALE
, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
145 {ARM_CEXT_XSCALE
, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
146 {ARM_CEXT_XSCALE
, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
147 {ARM_CEXT_XSCALE
, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
148 {ARM_CEXT_XSCALE
, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
149 {ARM_CEXT_XSCALE
, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
150 {ARM_CEXT_XSCALE
, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
151 {ARM_CEXT_XSCALE
, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
152 {ARM_CEXT_XSCALE
, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
153 {ARM_CEXT_XSCALE
, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
154 {ARM_CEXT_XSCALE
, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
155 {ARM_CEXT_XSCALE
, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
156 {ARM_CEXT_XSCALE
, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
157 {ARM_CEXT_XSCALE
, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
158 {ARM_CEXT_XSCALE
, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
159 {ARM_CEXT_XSCALE
, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
160 {ARM_CEXT_XSCALE
, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
161 {ARM_CEXT_XSCALE
, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
162 {ARM_CEXT_XSCALE
, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
163 {ARM_CEXT_XSCALE
, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
164 {ARM_CEXT_XSCALE
, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
165 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
166 {ARM_CEXT_XSCALE
, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
167 {ARM_CEXT_XSCALE
, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
168 {ARM_CEXT_XSCALE
, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
169 {ARM_CEXT_XSCALE
, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
170 {ARM_CEXT_XSCALE
, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
171 {ARM_CEXT_XSCALE
, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
172 {ARM_CEXT_XSCALE
, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
173 {ARM_CEXT_XSCALE
, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
174 {ARM_CEXT_XSCALE
, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
175 {ARM_CEXT_XSCALE
, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE
, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE
, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
178 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE
, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
180 {ARM_CEXT_XSCALE
, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE
, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
182 {ARM_CEXT_XSCALE
, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE
, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
184 {ARM_CEXT_XSCALE
, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
185 {ARM_CEXT_XSCALE
, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE
, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
187 {ARM_CEXT_XSCALE
, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
188 {ARM_CEXT_XSCALE
, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE
, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
190 {ARM_CEXT_XSCALE
, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
191 {ARM_CEXT_XSCALE
, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
192 {ARM_CEXT_XSCALE
, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
193 {ARM_CEXT_XSCALE
, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
194 {ARM_CEXT_XSCALE
, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
195 {ARM_CEXT_XSCALE
, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
196 {ARM_CEXT_XSCALE
, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
197 {ARM_CEXT_XSCALE
, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE
, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE
, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
200 {ARM_CEXT_XSCALE
, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
201 {ARM_CEXT_XSCALE
, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
202 {ARM_CEXT_XSCALE
, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
203 {ARM_CEXT_XSCALE
, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE
, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE
, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
206 { 0, SENTINEL_IWMMXT_END
, 0, "" },
208 /* Floating point coprocessor (FPA) instructions. */
209 {FPU_FPA_EXT_V1
, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
210 {FPU_FPA_EXT_V1
, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
211 {FPU_FPA_EXT_V1
, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
212 {FPU_FPA_EXT_V1
, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
213 {FPU_FPA_EXT_V1
, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
214 {FPU_FPA_EXT_V1
, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
215 {FPU_FPA_EXT_V1
, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
216 {FPU_FPA_EXT_V1
, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
217 {FPU_FPA_EXT_V1
, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
218 {FPU_FPA_EXT_V1
, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
219 {FPU_FPA_EXT_V1
, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
220 {FPU_FPA_EXT_V1
, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
221 {FPU_FPA_EXT_V1
, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
222 {FPU_FPA_EXT_V1
, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
223 {FPU_FPA_EXT_V1
, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
224 {FPU_FPA_EXT_V1
, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
225 {FPU_FPA_EXT_V1
, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
226 {FPU_FPA_EXT_V1
, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
227 {FPU_FPA_EXT_V1
, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
228 {FPU_FPA_EXT_V1
, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
229 {FPU_FPA_EXT_V1
, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
230 {FPU_FPA_EXT_V1
, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
231 {FPU_FPA_EXT_V1
, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
232 {FPU_FPA_EXT_V1
, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
233 {FPU_FPA_EXT_V1
, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
234 {FPU_FPA_EXT_V1
, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
235 {FPU_FPA_EXT_V1
, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
236 {FPU_FPA_EXT_V1
, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
237 {FPU_FPA_EXT_V1
, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
238 {FPU_FPA_EXT_V1
, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
239 {FPU_FPA_EXT_V1
, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
240 {FPU_FPA_EXT_V1
, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
241 {FPU_FPA_EXT_V1
, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
242 {FPU_FPA_EXT_V1
, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
243 {FPU_FPA_EXT_V1
, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
244 {FPU_FPA_EXT_V1
, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1
, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1
, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1
, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1
, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
249 {FPU_FPA_EXT_V1
, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
250 {FPU_FPA_EXT_V2
, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
251 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
253 /* Register load/store. */
254 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
255 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
256 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
257 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
258 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
259 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
260 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
261 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
262 {FPU_VFP_EXT_V1xD
, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
263 {FPU_VFP_EXT_V1xD
, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
264 {FPU_VFP_EXT_V1xD
, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
265 {FPU_VFP_EXT_V1xD
, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
266 {FPU_VFP_EXT_V1xD
, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
267 {FPU_VFP_EXT_V1xD
, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
268 {FPU_VFP_EXT_V1xD
, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
269 {FPU_VFP_EXT_V1xD
, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
271 {FPU_VFP_EXT_V1xD
, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
272 {FPU_VFP_EXT_V1xD
, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
273 {FPU_VFP_EXT_V1xD
, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
274 {FPU_VFP_EXT_V1xD
, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
276 /* Data transfer between ARM and NEON registers. */
277 {FPU_NEON_EXT_V1
, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
278 {FPU_NEON_EXT_V1
, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
279 {FPU_NEON_EXT_V1
, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
280 {FPU_NEON_EXT_V1
, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
281 {FPU_NEON_EXT_V1
, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
282 {FPU_NEON_EXT_V1
, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
283 {FPU_NEON_EXT_V1
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
284 {FPU_NEON_EXT_V1
, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
285 {FPU_NEON_EXT_V1
, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
286 {FPU_NEON_EXT_V1
, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
287 {FPU_NEON_EXT_V1
, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
288 {FPU_NEON_EXT_V1
, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
289 {FPU_NEON_EXT_V1
, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
290 {FPU_NEON_EXT_V1
, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
291 /* Half-precision conversion instructions. */
292 {FPU_VFP_EXT_FP16
, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
293 {FPU_VFP_EXT_FP16
, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
295 /* Floating point coprocessor (VFP) instructions. */
296 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
297 {FPU_VFP_EXT_V1xD
, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
298 {FPU_VFP_EXT_V1xD
, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
299 {FPU_VFP_EXT_V1xD
, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
300 {FPU_VFP_EXT_V1xD
, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
301 {FPU_VFP_EXT_V1xD
, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
302 {FPU_VFP_EXT_V1xD
, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
303 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
304 {FPU_VFP_EXT_V1xD
, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
305 {FPU_VFP_EXT_V1xD
, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
306 {FPU_VFP_EXT_V1xD
, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
307 {FPU_VFP_EXT_V1xD
, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
308 {FPU_VFP_EXT_V1xD
, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
309 {FPU_VFP_EXT_V1xD
, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
310 {FPU_VFP_EXT_V1xD
, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
311 {FPU_VFP_EXT_V1
, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
312 {FPU_VFP_EXT_V1
, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
313 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
314 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
315 {FPU_VFP_EXT_V1xD
, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
316 {FPU_VFP_EXT_V1xD
, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
317 {FPU_VFP_EXT_V1xD
, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
318 {FPU_VFP_EXT_V1
, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
319 {FPU_VFP_EXT_V1xD
, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
320 {FPU_VFP_EXT_V1xD
, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
321 {FPU_VFP_EXT_V1
, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
322 {FPU_VFP_EXT_V1
, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
323 {FPU_VFP_EXT_V1xD
, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
324 {FPU_VFP_EXT_V1xD
, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
325 {FPU_VFP_EXT_V1
, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
326 {FPU_VFP_EXT_V1
, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
327 {FPU_VFP_EXT_V1
, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
328 {FPU_VFP_EXT_V1
, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
329 {FPU_VFP_EXT_V1xD
, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
330 {FPU_VFP_EXT_V1
, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
331 {FPU_VFP_EXT_V1xD
, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
332 {FPU_VFP_EXT_V1
, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
333 {FPU_VFP_EXT_V3xD
, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
334 {FPU_VFP_EXT_V3
, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
335 {FPU_VFP_EXT_V1xD
, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
336 {FPU_VFP_EXT_V1
, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
337 {FPU_VFP_EXT_V3xD
, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
338 {FPU_VFP_EXT_V3
, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
339 {FPU_VFP_EXT_V1
, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
340 {FPU_VFP_EXT_V3xD
, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
341 {FPU_VFP_EXT_V3
, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
342 {FPU_VFP_EXT_V2
, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
343 {FPU_VFP_EXT_V2
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
344 {FPU_VFP_EXT_V2
, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
345 {FPU_VFP_EXT_V1xD
, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
346 {FPU_VFP_EXT_V1xD
, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
347 {FPU_VFP_EXT_V1
, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
348 {FPU_VFP_EXT_V1
, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
349 {FPU_VFP_EXT_V1xD
, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
350 {FPU_VFP_EXT_V1xD
, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
351 {FPU_VFP_EXT_V1
, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
352 {FPU_VFP_EXT_V1
, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
353 {FPU_VFP_EXT_V1xD
, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
354 {FPU_VFP_EXT_V1xD
, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
355 {FPU_VFP_EXT_V1
, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
356 {FPU_VFP_EXT_V1
, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
357 {FPU_VFP_EXT_V1xD
, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
358 {FPU_VFP_EXT_V1xD
, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
359 {FPU_VFP_EXT_V1
, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
360 {FPU_VFP_EXT_V1
, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
361 {FPU_VFP_EXT_V1xD
, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
362 {FPU_VFP_EXT_V1
, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
364 /* Cirrus coprocessor instructions. */
365 {ARM_CEXT_MAVERICK
, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
366 {ARM_CEXT_MAVERICK
, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
367 {ARM_CEXT_MAVERICK
, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
368 {ARM_CEXT_MAVERICK
, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
369 {ARM_CEXT_MAVERICK
, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
370 {ARM_CEXT_MAVERICK
, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
371 {ARM_CEXT_MAVERICK
, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
372 {ARM_CEXT_MAVERICK
, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
373 {ARM_CEXT_MAVERICK
, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
374 {ARM_CEXT_MAVERICK
, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
375 {ARM_CEXT_MAVERICK
, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
376 {ARM_CEXT_MAVERICK
, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
377 {ARM_CEXT_MAVERICK
, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
378 {ARM_CEXT_MAVERICK
, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
379 {ARM_CEXT_MAVERICK
, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
380 {ARM_CEXT_MAVERICK
, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
381 {ARM_CEXT_MAVERICK
, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
382 {ARM_CEXT_MAVERICK
, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
383 {ARM_CEXT_MAVERICK
, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
384 {ARM_CEXT_MAVERICK
, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
385 {ARM_CEXT_MAVERICK
, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
386 {ARM_CEXT_MAVERICK
, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
387 {ARM_CEXT_MAVERICK
, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
388 {ARM_CEXT_MAVERICK
, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
389 {ARM_CEXT_MAVERICK
, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
390 {ARM_CEXT_MAVERICK
, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
391 {ARM_CEXT_MAVERICK
, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
392 {ARM_CEXT_MAVERICK
, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
393 {ARM_CEXT_MAVERICK
, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
394 {ARM_CEXT_MAVERICK
, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
395 {ARM_CEXT_MAVERICK
, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
396 {ARM_CEXT_MAVERICK
, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
397 {ARM_CEXT_MAVERICK
, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
398 {ARM_CEXT_MAVERICK
, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
399 {ARM_CEXT_MAVERICK
, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
400 {ARM_CEXT_MAVERICK
, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
401 {ARM_CEXT_MAVERICK
, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
402 {ARM_CEXT_MAVERICK
, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
403 {ARM_CEXT_MAVERICK
, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
404 {ARM_CEXT_MAVERICK
, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
405 {ARM_CEXT_MAVERICK
, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
406 {ARM_CEXT_MAVERICK
, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
407 {ARM_CEXT_MAVERICK
, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
408 {ARM_CEXT_MAVERICK
, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
409 {ARM_CEXT_MAVERICK
, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
410 {ARM_CEXT_MAVERICK
, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
411 {ARM_CEXT_MAVERICK
, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
412 {ARM_CEXT_MAVERICK
, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
413 {ARM_CEXT_MAVERICK
, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
414 {ARM_CEXT_MAVERICK
, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
415 {ARM_CEXT_MAVERICK
, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
416 {ARM_CEXT_MAVERICK
, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
417 {ARM_CEXT_MAVERICK
, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
418 {ARM_CEXT_MAVERICK
, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
419 {ARM_CEXT_MAVERICK
, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
420 {ARM_CEXT_MAVERICK
, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
421 {ARM_CEXT_MAVERICK
, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
422 {ARM_CEXT_MAVERICK
, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
423 {ARM_CEXT_MAVERICK
, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
424 {ARM_CEXT_MAVERICK
, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
425 {ARM_CEXT_MAVERICK
, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
426 {ARM_CEXT_MAVERICK
, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
427 {ARM_CEXT_MAVERICK
, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
428 {ARM_CEXT_MAVERICK
, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
429 {ARM_CEXT_MAVERICK
, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
430 {ARM_CEXT_MAVERICK
, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
431 {ARM_CEXT_MAVERICK
, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
432 {ARM_CEXT_MAVERICK
, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
433 {ARM_CEXT_MAVERICK
, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
434 {ARM_CEXT_MAVERICK
, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
435 {ARM_CEXT_MAVERICK
, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
436 {ARM_CEXT_MAVERICK
, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
437 {ARM_CEXT_MAVERICK
, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
438 {ARM_CEXT_MAVERICK
, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
439 {ARM_CEXT_MAVERICK
, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
440 {ARM_CEXT_MAVERICK
, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
441 {ARM_CEXT_MAVERICK
, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
442 {ARM_CEXT_MAVERICK
, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
443 {ARM_CEXT_MAVERICK
, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
444 {ARM_CEXT_MAVERICK
, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
445 {ARM_CEXT_MAVERICK
, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
446 {ARM_CEXT_MAVERICK
, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
447 {ARM_CEXT_MAVERICK
, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
448 {ARM_CEXT_MAVERICK
, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
450 /* VFP Fused multiply add instructions. */
451 {FPU_VFP_EXT_FMA
, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
452 {FPU_VFP_EXT_FMA
, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
453 {FPU_VFP_EXT_FMA
, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
454 {FPU_VFP_EXT_FMA
, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
455 {FPU_VFP_EXT_FMA
, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
456 {FPU_VFP_EXT_FMA
, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
457 {FPU_VFP_EXT_FMA
, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
458 {FPU_VFP_EXT_FMA
, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
460 /* Generic coprocessor instructions. */
461 { 0, SENTINEL_GENERIC_START
, 0, "" },
462 {ARM_EXT_V5E
, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
463 {ARM_EXT_V5E
, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
464 {ARM_EXT_V2
, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
465 {ARM_EXT_V2
, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
466 {ARM_EXT_V2
, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
467 {ARM_EXT_V2
, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
468 {ARM_EXT_V2
, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
470 /* V6 coprocessor instructions. */
471 {ARM_EXT_V6
, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
472 {ARM_EXT_V6
, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
474 /* V5 coprocessor instructions. */
475 {ARM_EXT_V5
, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
476 {ARM_EXT_V5
, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
477 {ARM_EXT_V5
, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
478 {ARM_EXT_V5
, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
479 {ARM_EXT_V5
, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
484 /* Neon opcode table: This does not encode the top byte -- that is
485 checked by the print_insn_neon routine, as it depends on whether we are
486 doing thumb32 or arm32 disassembly. */
488 /* print_insn_neon recognizes the following format control codes:
492 %c print condition code
493 %A print v{st,ld}[1234] operands
494 %B print v{st,ld}[1234] any one operands
495 %C print v{st,ld}[1234] single->all operands
497 %E print vmov, vmvn, vorr, vbic encoded constant
498 %F print vtbl,vtbx register list
500 %<bitfield>r print as an ARM register
501 %<bitfield>d print the bitfield in decimal
502 %<bitfield>e print the 2^N - bitfield in decimal
503 %<bitfield>D print as a NEON D register
504 %<bitfield>Q print as a NEON Q register
505 %<bitfield>R print as a NEON D or Q register
506 %<bitfield>Sn print byte scaled width limited by n
507 %<bitfield>Tn print short scaled width limited by n
508 %<bitfield>Un print long scaled width limited by n
510 %<bitfield>'c print specified char iff bitfield is all ones
511 %<bitfield>`c print specified char iff bitfield is all zeroes
512 %<bitfield>?ab... select from array of values in big endian order. */
514 static const struct opcode32 neon_opcodes
[] =
517 {FPU_NEON_EXT_V1
, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
518 {FPU_NEON_EXT_V1
, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
520 /* Move data element to all lanes. */
521 {FPU_NEON_EXT_V1
, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
522 {FPU_NEON_EXT_V1
, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
523 {FPU_NEON_EXT_V1
, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
526 {FPU_NEON_EXT_V1
, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
527 {FPU_NEON_EXT_V1
, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
529 /* Half-precision conversions. */
530 {FPU_VFP_EXT_FP16
, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
531 {FPU_VFP_EXT_FP16
, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
533 /* NEON fused multiply add instructions. */
534 {FPU_NEON_EXT_FMA
, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
535 {FPU_NEON_EXT_FMA
, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
537 /* Two registers, miscellaneous. */
538 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
539 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
540 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
541 {FPU_NEON_EXT_V1
, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
542 {FPU_NEON_EXT_V1
, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
543 {FPU_NEON_EXT_V1
, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
544 {FPU_NEON_EXT_V1
, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
545 {FPU_NEON_EXT_V1
, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
546 {FPU_NEON_EXT_V1
, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
547 {FPU_NEON_EXT_V1
, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
548 {FPU_NEON_EXT_V1
, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
549 {FPU_NEON_EXT_V1
, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
550 {FPU_NEON_EXT_V1
, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
551 {FPU_NEON_EXT_V1
, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
552 {FPU_NEON_EXT_V1
, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
553 {FPU_NEON_EXT_V1
, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
554 {FPU_NEON_EXT_V1
, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
555 {FPU_NEON_EXT_V1
, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
556 {FPU_NEON_EXT_V1
, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
557 {FPU_NEON_EXT_V1
, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
558 {FPU_NEON_EXT_V1
, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
559 {FPU_NEON_EXT_V1
, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
560 {FPU_NEON_EXT_V1
, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
561 {FPU_NEON_EXT_V1
, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
562 {FPU_NEON_EXT_V1
, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
563 {FPU_NEON_EXT_V1
, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
564 {FPU_NEON_EXT_V1
, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
565 {FPU_NEON_EXT_V1
, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
566 {FPU_NEON_EXT_V1
, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
567 {FPU_NEON_EXT_V1
, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
568 {FPU_NEON_EXT_V1
, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
569 {FPU_NEON_EXT_V1
, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
570 {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"},
572 /* Three registers of the same length. */
573 {FPU_NEON_EXT_V1
, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
574 {FPU_NEON_EXT_V1
, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
575 {FPU_NEON_EXT_V1
, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
576 {FPU_NEON_EXT_V1
, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
577 {FPU_NEON_EXT_V1
, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
578 {FPU_NEON_EXT_V1
, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
579 {FPU_NEON_EXT_V1
, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
580 {FPU_NEON_EXT_V1
, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
581 {FPU_NEON_EXT_V1
, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
582 {FPU_NEON_EXT_V1
, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
583 {FPU_NEON_EXT_V1
, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
584 {FPU_NEON_EXT_V1
, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
585 {FPU_NEON_EXT_V1
, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
586 {FPU_NEON_EXT_V1
, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
587 {FPU_NEON_EXT_V1
, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
588 {FPU_NEON_EXT_V1
, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
589 {FPU_NEON_EXT_V1
, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
590 {FPU_NEON_EXT_V1
, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
591 {FPU_NEON_EXT_V1
, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
592 {FPU_NEON_EXT_V1
, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
593 {FPU_NEON_EXT_V1
, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
594 {FPU_NEON_EXT_V1
, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
595 {FPU_NEON_EXT_V1
, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
596 {FPU_NEON_EXT_V1
, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
597 {FPU_NEON_EXT_V1
, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
598 {FPU_NEON_EXT_V1
, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
599 {FPU_NEON_EXT_V1
, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
600 {FPU_NEON_EXT_V1
, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
601 {FPU_NEON_EXT_V1
, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1
, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1
, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1
, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1
, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1
, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1
, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1
, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1
, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1
, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1
, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1
, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1
, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1
, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1
, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
616 {FPU_NEON_EXT_V1
, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
617 {FPU_NEON_EXT_V1
, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
618 {FPU_NEON_EXT_V1
, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
619 {FPU_NEON_EXT_V1
, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1
, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1
, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1
, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1
, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1
, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1
, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 /* One register and an immediate value. */
628 {FPU_NEON_EXT_V1
, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
629 {FPU_NEON_EXT_V1
, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
630 {FPU_NEON_EXT_V1
, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
631 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
632 {FPU_NEON_EXT_V1
, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
633 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
634 {FPU_NEON_EXT_V1
, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
635 {FPU_NEON_EXT_V1
, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
636 {FPU_NEON_EXT_V1
, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
637 {FPU_NEON_EXT_V1
, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
638 {FPU_NEON_EXT_V1
, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
639 {FPU_NEON_EXT_V1
, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
640 {FPU_NEON_EXT_V1
, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
642 /* Two registers and a shift amount. */
643 {FPU_NEON_EXT_V1
, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
644 {FPU_NEON_EXT_V1
, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
645 {FPU_NEON_EXT_V1
, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
646 {FPU_NEON_EXT_V1
, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
647 {FPU_NEON_EXT_V1
, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
648 {FPU_NEON_EXT_V1
, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
649 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
650 {FPU_NEON_EXT_V1
, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
651 {FPU_NEON_EXT_V1
, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
652 {FPU_NEON_EXT_V1
, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
653 {FPU_NEON_EXT_V1
, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
654 {FPU_NEON_EXT_V1
, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
655 {FPU_NEON_EXT_V1
, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
656 {FPU_NEON_EXT_V1
, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
657 {FPU_NEON_EXT_V1
, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
658 {FPU_NEON_EXT_V1
, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
659 {FPU_NEON_EXT_V1
, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
660 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
661 {FPU_NEON_EXT_V1
, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
662 {FPU_NEON_EXT_V1
, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
663 {FPU_NEON_EXT_V1
, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
664 {FPU_NEON_EXT_V1
, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
665 {FPU_NEON_EXT_V1
, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
666 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
667 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
668 {FPU_NEON_EXT_V1
, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
669 {FPU_NEON_EXT_V1
, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
670 {FPU_NEON_EXT_V1
, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
671 {FPU_NEON_EXT_V1
, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
672 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
673 {FPU_NEON_EXT_V1
, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
674 {FPU_NEON_EXT_V1
, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
675 {FPU_NEON_EXT_V1
, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
676 {FPU_NEON_EXT_V1
, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
677 {FPU_NEON_EXT_V1
, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
678 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
679 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
680 {FPU_NEON_EXT_V1
, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
681 {FPU_NEON_EXT_V1
, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
682 {FPU_NEON_EXT_V1
, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
683 {FPU_NEON_EXT_V1
, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
684 {FPU_NEON_EXT_V1
, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
685 {FPU_NEON_EXT_V1
, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
686 {FPU_NEON_EXT_V1
, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
687 {FPU_NEON_EXT_V1
, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
688 {FPU_NEON_EXT_V1
, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
689 {FPU_NEON_EXT_V1
, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
690 {FPU_NEON_EXT_V1
, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
691 {FPU_NEON_EXT_V1
, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
692 {FPU_NEON_EXT_V1
, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
693 {FPU_NEON_EXT_V1
, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
694 {FPU_NEON_EXT_V1
, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
695 {FPU_NEON_EXT_V1
, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
696 {FPU_NEON_EXT_V1
, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
697 {FPU_NEON_EXT_V1
, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
698 {FPU_NEON_EXT_V1
, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
699 {FPU_NEON_EXT_V1
, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
700 {FPU_NEON_EXT_V1
, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
702 /* Three registers of different lengths. */
703 {FPU_NEON_EXT_V1
, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
704 {FPU_NEON_EXT_V1
, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
705 {FPU_NEON_EXT_V1
, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
706 {FPU_NEON_EXT_V1
, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
707 {FPU_NEON_EXT_V1
, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
708 {FPU_NEON_EXT_V1
, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
709 {FPU_NEON_EXT_V1
, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
710 {FPU_NEON_EXT_V1
, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
711 {FPU_NEON_EXT_V1
, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
712 {FPU_NEON_EXT_V1
, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
713 {FPU_NEON_EXT_V1
, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
714 {FPU_NEON_EXT_V1
, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
715 {FPU_NEON_EXT_V1
, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
716 {FPU_NEON_EXT_V1
, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
717 {FPU_NEON_EXT_V1
, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
718 {FPU_NEON_EXT_V1
, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
719 {FPU_NEON_EXT_V1
, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
721 /* Two registers and a scalar. */
722 {FPU_NEON_EXT_V1
, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
723 {FPU_NEON_EXT_V1
, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
724 {FPU_NEON_EXT_V1
, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
725 {FPU_NEON_EXT_V1
, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
726 {FPU_NEON_EXT_V1
, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
727 {FPU_NEON_EXT_V1
, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
728 {FPU_NEON_EXT_V1
, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
729 {FPU_NEON_EXT_V1
, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
730 {FPU_NEON_EXT_V1
, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
731 {FPU_NEON_EXT_V1
, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
732 {FPU_NEON_EXT_V1
, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
733 {FPU_NEON_EXT_V1
, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
734 {FPU_NEON_EXT_V1
, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
735 {FPU_NEON_EXT_V1
, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
736 {FPU_NEON_EXT_V1
, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
737 {FPU_NEON_EXT_V1
, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
738 {FPU_NEON_EXT_V1
, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
739 {FPU_NEON_EXT_V1
, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
740 {FPU_NEON_EXT_V1
, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
741 {FPU_NEON_EXT_V1
, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
742 {FPU_NEON_EXT_V1
, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
743 {FPU_NEON_EXT_V1
, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
745 /* Element and structure load/store. */
746 {FPU_NEON_EXT_V1
, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
747 {FPU_NEON_EXT_V1
, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
748 {FPU_NEON_EXT_V1
, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
749 {FPU_NEON_EXT_V1
, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
750 {FPU_NEON_EXT_V1
, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
751 {FPU_NEON_EXT_V1
, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
752 {FPU_NEON_EXT_V1
, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
753 {FPU_NEON_EXT_V1
, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
754 {FPU_NEON_EXT_V1
, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
755 {FPU_NEON_EXT_V1
, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
756 {FPU_NEON_EXT_V1
, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
757 {FPU_NEON_EXT_V1
, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
758 {FPU_NEON_EXT_V1
, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
759 {FPU_NEON_EXT_V1
, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
760 {FPU_NEON_EXT_V1
, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
761 {FPU_NEON_EXT_V1
, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
762 {FPU_NEON_EXT_V1
, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
763 {FPU_NEON_EXT_V1
, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
764 {FPU_NEON_EXT_V1
, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
769 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
770 ordered: they must be searched linearly from the top to obtain a correct
773 /* print_insn_arm recognizes the following format control codes:
777 %a print address for ldr/str instruction
778 %s print address for ldr/str halfword/signextend instruction
779 %S like %s but allow UNPREDICTABLE addressing
780 %b print branch destination
781 %c print condition code (always bits 28-31)
782 %m print register mask for ldm/stm instruction
783 %o print operand2 (immediate or register + shift)
784 %p print 'p' iff bits 12-15 are 15
785 %t print 't' iff bit 21 set and bit 24 clear
786 %B print arm BLX(1) destination
787 %C print the PSR sub type.
788 %U print barrier type.
789 %P print address for pli instruction.
791 %<bitfield>r print as an ARM register
792 %<bitfield>d print the bitfield in decimal
793 %<bitfield>W print the bitfield plus one in decimal
794 %<bitfield>x print the bitfield in hex
795 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
797 %<bitfield>'c print specified char iff bitfield is all ones
798 %<bitfield>`c print specified char iff bitfield is all zeroes
799 %<bitfield>?ab... select from array of values in big endian order
801 %e print arm SMI operand (bits 0..7,8..19).
802 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
803 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
805 static const struct opcode32 arm_opcodes
[] =
807 /* ARM instructions. */
808 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
809 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
810 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
811 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
812 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
813 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
814 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
816 /* V7 instructions. */
817 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
818 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
819 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
820 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
821 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
823 /* ARM V6T2 instructions. */
824 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
825 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
826 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
827 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
829 {ARM_EXT_V6T2
, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION
},
830 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %S"},
832 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
833 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
834 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
835 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
837 /* ARM V6Z instructions. */
838 {ARM_EXT_V6Z
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
840 /* ARM V6K instructions. */
841 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
842 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
843 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
844 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
845 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
846 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
847 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
849 /* ARM V6K NOP hints. */
850 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
851 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
852 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
853 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
854 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
856 /* ARM V6 instructions. */
857 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
858 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
859 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
860 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
861 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
862 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
863 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
864 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
865 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
866 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
867 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
869 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
870 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
871 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
900 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
901 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
902 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
903 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
904 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
905 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
906 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
907 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
908 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
909 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
910 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
911 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
912 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
913 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
914 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
915 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
916 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
917 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
918 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
919 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
920 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
921 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
922 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
923 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
924 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
925 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
926 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
927 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
928 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
929 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
930 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
931 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
932 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
933 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
934 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
935 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
936 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
937 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
938 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
939 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
940 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
941 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
942 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
943 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
944 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
945 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
946 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
947 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
948 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
949 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
950 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
951 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
952 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
953 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
954 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
955 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
956 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
957 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
958 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
959 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
960 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
961 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
962 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
963 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
964 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
965 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
966 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
967 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
968 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
969 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
970 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
971 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
972 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
973 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
974 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
975 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
976 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
977 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
978 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
980 /* V5J instruction. */
981 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
983 /* V5 Instructions. */
984 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
985 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
986 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
987 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
989 /* V5E "El Segundo" Instructions. */
990 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
991 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
992 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
993 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
994 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
995 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
996 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
998 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
999 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1001 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1002 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1003 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1004 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1006 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1007 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1009 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1011 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1012 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1014 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1015 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1016 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1017 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1019 /* ARM Instructions. */
1020 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1021 {ARM_EXT_V1
, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1022 {ARM_EXT_V1
, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1023 {ARM_EXT_V1
, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1024 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1025 {ARM_EXT_V1
, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
1026 {ARM_EXT_V1
, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
1027 {ARM_EXT_V1
, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
1029 {ARM_EXT_V1
, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION
},
1030 {ARM_EXT_V1
, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1031 {ARM_EXT_V1
, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION
},
1032 {ARM_EXT_V1
, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
1034 {ARM_EXT_V1
, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1035 {ARM_EXT_V1
, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1036 {ARM_EXT_V1
, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
1038 {ARM_EXT_V1
, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1039 {ARM_EXT_V1
, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1040 {ARM_EXT_V1
, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
1042 {ARM_EXT_V1
, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1043 {ARM_EXT_V1
, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1044 {ARM_EXT_V1
, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
1046 {ARM_EXT_V1
, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1047 {ARM_EXT_V1
, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1048 {ARM_EXT_V1
, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1050 {ARM_EXT_V1
, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1051 {ARM_EXT_V1
, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1052 {ARM_EXT_V1
, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
1054 {ARM_EXT_V1
, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1055 {ARM_EXT_V1
, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1
, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
1058 {ARM_EXT_V1
, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1059 {ARM_EXT_V1
, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1060 {ARM_EXT_V1
, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1062 {ARM_EXT_V1
, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1063 {ARM_EXT_V1
, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1064 {ARM_EXT_V1
, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1066 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1067 {ARM_EXT_V3
, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1069 {ARM_EXT_V1
, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1070 {ARM_EXT_V1
, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1071 {ARM_EXT_V1
, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
1073 {ARM_EXT_V1
, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1074 {ARM_EXT_V1
, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1075 {ARM_EXT_V1
, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
1077 {ARM_EXT_V1
, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1078 {ARM_EXT_V3
, 0x01400000, 0x0ff00010, "mrs%c\t%12-15r, %22?SCPSR"},
1079 {ARM_EXT_V1
, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1080 {ARM_EXT_V1
, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
1082 {ARM_EXT_V1
, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1083 {ARM_EXT_V1
, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1084 {ARM_EXT_V1
, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
1086 {ARM_EXT_V1
, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1087 {ARM_EXT_V1
, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1
, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
1090 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1091 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1092 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1093 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1094 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1095 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1096 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1098 {ARM_EXT_V1
, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1099 {ARM_EXT_V1
, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1100 {ARM_EXT_V1
, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
1102 {ARM_EXT_V1
, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1103 {ARM_EXT_V1
, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1104 {ARM_EXT_V1
, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
1106 {ARM_EXT_V1
, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION
},
1107 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1108 {ARM_EXT_V1
, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1109 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1110 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1111 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1112 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1113 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1114 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1115 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1116 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1119 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1120 {0, 0x00000000, 0x00000000, 0}
1123 /* print_insn_thumb16 recognizes the following format control codes:
1125 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1126 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1127 %<bitfield>I print bitfield as a signed decimal
1128 (top bit of range being the sign bit)
1129 %N print Thumb register mask (with LR)
1130 %O print Thumb register mask (with PC)
1131 %M print Thumb register mask
1132 %b print CZB's 6-bit unsigned branch destination
1133 %s print Thumb right-shift immediate (6..10; 0 == 32).
1134 %c print the condition code
1135 %C print the condition code, or "s" if not conditional
1136 %x print warning if conditional an not at end of IT block"
1137 %X print "\t; unpredictable <IT:code>" if conditional
1138 %I print IT instruction suffix and operands
1139 %<bitfield>r print bitfield as an ARM register
1140 %<bitfield>d print bitfield as a decimal
1141 %<bitfield>H print (bitfield * 2) as a decimal
1142 %<bitfield>W print (bitfield * 4) as a decimal
1143 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1144 %<bitfield>B print Thumb branch destination (signed displacement)
1145 %<bitfield>c print bitfield as a condition code
1146 %<bitnum>'c print specified char iff bit is one
1147 %<bitnum>?ab print a if bit is one else print b. */
1149 static const struct opcode16 thumb_opcodes
[] =
1151 /* Thumb instructions. */
1153 /* ARM V6K no-argument instructions. */
1154 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
1155 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
1156 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
1157 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
1158 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
1159 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1161 /* ARM V6T2 instructions. */
1162 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1163 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1164 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
1167 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1168 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1169 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1170 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1171 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1172 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1173 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1174 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1175 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1176 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1177 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1179 /* ARM V5 ISA extends Thumb. */
1180 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1181 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1182 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1183 /* ARM V4T ISA (Thumb v1). */
1184 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1186 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1187 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1188 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1189 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1190 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1191 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1192 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1193 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1194 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1195 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1196 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1197 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1198 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1199 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1200 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1201 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1203 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1204 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1206 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
1207 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
1208 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1209 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1211 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
1212 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
1214 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1215 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1216 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1217 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1219 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1220 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1221 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1223 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1224 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1226 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1227 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1228 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1230 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1231 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1232 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1233 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1235 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1237 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1238 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1239 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1240 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1242 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1243 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1245 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1246 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1248 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1249 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1251 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1252 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1254 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1256 {ARM_EXT_V4T
, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION
},
1257 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1259 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1261 /* The E800 .. FFFF range is unconditionally redirected to the
1262 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1263 are processed via that table. Thus, we can never encounter a
1264 bare "second half of BL/BLX(1)" instruction here. */
1265 {ARM_EXT_V1
, 0x0000, 0x0000, UNDEFINED_INSTRUCTION
},
1269 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1270 We adopt the convention that hw1 is the high 16 bits of .value and
1271 .mask, hw2 the low 16 bits.
1273 print_insn_thumb32 recognizes the following format control codes:
1277 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1278 %M print a modified 12-bit immediate (same location)
1279 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1280 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1281 %S print a possibly-shifted Rm
1283 %a print the address of a plain load/store
1284 %w print the width and signedness of a core load/store
1285 %m print register mask for ldm/stm
1287 %E print the lsb and width fields of a bfc/bfi instruction
1288 %F print the lsb and width fields of a sbfx/ubfx instruction
1289 %b print a conditional branch offset
1290 %B print an unconditional branch offset
1291 %s print the shift field of an SSAT instruction
1292 %R print the rotation field of an SXT instruction
1293 %U print barrier type.
1294 %P print address for pli instruction.
1295 %c print the condition code
1296 %x print warning if conditional an not at end of IT block"
1297 %X print "\t; unpredictable <IT:code>" if conditional
1299 %<bitfield>d print bitfield in decimal
1300 %<bitfield>W print bitfield*4 in decimal
1301 %<bitfield>r print bitfield as an ARM register
1302 %<bitfield>c print bitfield as a condition code
1304 %<bitfield>'c print specified char iff bitfield is all ones
1305 %<bitfield>`c print specified char iff bitfield is all zeroes
1306 %<bitfield>?ab... select from array of values in big endian order
1308 With one exception at the bottom (done because BL and BLX(1) need
1309 to come dead last), this table was machine-sorted first in
1310 decreasing order of number of bits set in the mask, then in
1311 increasing numeric order of mask, then in increasing numeric order
1312 of opcode. This order is not the clearest for a human reader, but
1313 is guaranteed never to catch a special-case bit pattern with a more
1314 general mask, which is important, because this instruction encoding
1315 makes heavy use of special-case bit patterns. */
1316 static const struct opcode32 thumb32_opcodes
[] =
1318 /* V7 instructions. */
1319 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1320 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1321 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1322 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1323 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1324 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1325 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1327 /* Instructions defined in the basic V6T2 set. */
1328 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
1329 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
1330 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1331 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1332 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
1333 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1335 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1336 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1337 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1338 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1339 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1340 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1341 {ARM_EXT_V6T2
, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1342 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1343 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1344 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1345 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1346 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1347 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1348 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1349 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1350 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1351 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1352 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1353 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1354 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1355 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1356 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1357 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1358 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1359 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1360 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1361 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1363 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1364 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1365 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1368 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1369 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1370 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1371 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1372 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1373 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1377 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1378 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1379 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1380 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1381 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1382 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1384 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1388 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1389 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1390 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1397 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1398 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1399 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1406 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1407 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1408 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1409 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1413 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1414 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1415 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1416 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1417 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1418 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1420 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1421 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1422 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1423 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1424 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1425 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1426 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1427 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1428 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1429 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1430 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1431 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1432 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1433 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1434 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1435 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1436 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1437 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1438 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1439 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1440 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1441 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1442 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1446 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1447 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1448 {ARM_EXT_V6T2
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1449 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1450 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1451 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1452 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1453 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1454 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1455 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1456 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1457 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1460 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1461 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1462 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1463 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1464 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1465 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1466 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1467 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1468 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1469 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1470 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1471 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1472 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1473 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1474 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1475 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1476 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1477 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1478 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1479 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1480 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1481 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1482 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1483 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1484 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1485 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1486 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1487 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1488 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1489 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1490 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1491 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1492 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1493 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1494 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1495 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1496 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1497 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1498 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1499 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1500 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1501 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1502 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1503 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1504 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1505 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1506 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1508 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1509 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1510 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1511 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1512 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1514 /* These have been 32-bit since the invention of Thumb. */
1515 {ARM_EXT_V4T
, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1516 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1519 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1523 static const char *const arm_conditional
[] =
1524 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1525 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1527 static const char *const arm_fp_const
[] =
1528 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1530 static const char *const arm_shift
[] =
1531 {"lsl", "lsr", "asr", "ror"};
1536 const char *description
;
1537 const char *reg_names
[16];
1541 static const arm_regname regnames
[] =
1543 { "raw" , "Select raw register names",
1544 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1545 { "gcc", "Select register names used by GCC",
1546 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1547 { "std", "Select register names used in ARM's ISA documentation",
1548 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1549 { "apcs", "Select register names used in the APCS",
1550 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1551 { "atpcs", "Select register names used in the ATPCS",
1552 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1553 { "special-atpcs", "Select special register names used in the ATPCS",
1554 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1557 static const char *const iwmmxt_wwnames
[] =
1558 {"b", "h", "w", "d"};
1560 static const char *const iwmmxt_wwssnames
[] =
1561 {"b", "bus", "bc", "bss",
1562 "h", "hus", "hc", "hss",
1563 "w", "wus", "wc", "wss",
1564 "d", "dus", "dc", "dss"
1567 static const char *const iwmmxt_regnames
[] =
1568 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1569 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1572 static const char *const iwmmxt_cregnames
[] =
1573 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1574 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1577 /* Default to GCC register name set. */
1578 static unsigned int regname_selected
= 1;
1580 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1581 #define arm_regnames regnames[regname_selected].reg_names
1583 static bfd_boolean force_thumb
= FALSE
;
1585 /* Current IT instruction state. This contains the same state as the IT
1586 bits in the CPSR. */
1587 static unsigned int ifthen_state
;
1588 /* IT state for the next instruction. */
1589 static unsigned int ifthen_next_state
;
1590 /* The address of the insn for which the IT state is valid. */
1591 static bfd_vma ifthen_address
;
1592 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1594 /* Cached mapping symbol state. */
1602 enum map_type last_type
;
1603 int last_mapping_sym
= -1;
1604 bfd_vma last_mapping_addr
= 0;
1609 get_arm_regname_num_options (void)
1611 return NUM_ARM_REGNAMES
;
1615 set_arm_regname_option (int option
)
1617 int old
= regname_selected
;
1618 regname_selected
= option
;
1623 get_arm_regnames (int option
,
1624 const char **setname
,
1625 const char **setdescription
,
1626 const char *const **register_names
)
1628 *setname
= regnames
[option
].name
;
1629 *setdescription
= regnames
[option
].description
;
1630 *register_names
= regnames
[option
].reg_names
;
1634 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1635 Returns pointer to following character of the format string and
1636 fills in *VALUEP and *WIDTHP with the extracted value and number of
1637 bits extracted. WIDTHP can be NULL. */
1640 arm_decode_bitfield (const char *ptr
,
1642 unsigned long *valuep
,
1645 unsigned long value
= 0;
1653 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1654 start
= start
* 10 + *ptr
- '0';
1656 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1657 end
= end
* 10 + *ptr
- '0';
1663 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
1666 while (*ptr
++ == ',');
1674 arm_decode_shift (long given
, fprintf_ftype func
, void *stream
,
1675 bfd_boolean print_shift
)
1677 func (stream
, "%s", arm_regnames
[given
& 0xf]);
1679 if ((given
& 0xff0) != 0)
1681 if ((given
& 0x10) == 0)
1683 int amount
= (given
& 0xf80) >> 7;
1684 int shift
= (given
& 0x60) >> 5;
1690 func (stream
, ", rrx");
1698 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
1700 func (stream
, ", #%d", amount
);
1702 else if ((given
& 0x80) == 0x80)
1703 func (stream
, "\t; <illegal shifter operand>");
1704 else if (print_shift
)
1705 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
1706 arm_regnames
[(given
& 0xf00) >> 8]);
1708 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
1717 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1718 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1719 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1720 #define PRE_BIT_SET (given & (1 << P_BIT))
1722 /* Print one coprocessor instruction on INFO->STREAM.
1723 Return TRUE if the instuction matched, FALSE if this is not a
1724 recognised coprocessor instruction. */
1727 print_insn_coprocessor (bfd_vma pc
,
1728 struct disassemble_info
*info
,
1732 const struct opcode32
*insn
;
1733 void *stream
= info
->stream
;
1734 fprintf_ftype func
= info
->fprintf_func
;
1736 unsigned long value
;
1737 unsigned long allowed_arches
= ((arm_feature_set
*) info
->private_data
)->coproc
;
1740 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
1742 signed long value_in_comment
= 0;
1745 if (insn
->arch
== 0)
1746 switch (insn
->value
)
1748 case SENTINEL_IWMMXT_START
:
1749 if (info
->mach
!= bfd_mach_arm_XScale
1750 && info
->mach
!= bfd_mach_arm_iWMMXt
1751 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
1754 while (insn
->arch
!= 0 && insn
->value
!= SENTINEL_IWMMXT_END
);
1757 case SENTINEL_IWMMXT_END
:
1760 case SENTINEL_GENERIC_START
:
1761 allowed_arches
= ((arm_feature_set
*) info
->private_data
)->core
;
1769 value
= insn
->value
;
1772 /* The high 4 bits are 0xe for Arm conditional instructions, and
1773 0xe for arm unconditional instructions. The rest of the
1774 encoding is the same. */
1776 value
|= 0xe0000000;
1784 /* Only match unconditional instuctions against unconditional
1786 if ((given
& 0xf0000000) == 0xf0000000)
1793 cond
= (given
>> 28) & 0xf;
1799 if ((given
& mask
) != value
)
1802 if ((insn
->arch
& allowed_arches
) == 0)
1805 for (c
= insn
->assembler
; *c
; c
++)
1812 func (stream
, "%%");
1817 int rn
= (given
>> 16) & 0xf;
1818 int offset
= given
& 0xff;
1820 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
1822 if (PRE_BIT_SET
|| WRITEBACK_BIT_SET
)
1824 /* Not unindexed. The offset is scaled. */
1825 offset
= offset
* 4;
1826 if (NEGATIVE_BIT_SET
)
1829 value_in_comment
= offset
;
1835 func (stream
, ", #%d]%s",
1837 WRITEBACK_BIT_SET
? "!" : "");
1845 if (WRITEBACK_BIT_SET
)
1848 func (stream
, ", #%d", offset
);
1852 func (stream
, ", {%d}", offset
);
1853 value_in_comment
= offset
;
1856 if (rn
== 15 && (PRE_BIT_SET
|| WRITEBACK_BIT_SET
))
1858 func (stream
, "\t; ");
1859 info
->print_address_func (offset
+ pc
1860 + info
->bytes_per_chunk
* 2, info
);
1867 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
1868 int offset
= (given
>> 1) & 0x3f;
1871 func (stream
, "{d%d}", regno
);
1872 else if (regno
+ offset
> 32)
1873 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
1875 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
1880 func (stream
, "%s", arm_conditional
[cond
]);
1884 /* Print a Cirrus/DSP shift immediate. */
1885 /* Immediates are 7bit signed ints with bits 0..3 in
1886 bits 0..3 of opcode and bits 4..6 in bits 5..7
1891 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
1893 /* Is ``imm'' a negative number? */
1897 func (stream
, "%d", imm
);
1903 switch (given
& 0x00408000)
1920 switch (given
& 0x00080080)
1932 func (stream
, _("<illegal precision>"));
1938 switch (given
& 0x00408000)
1956 switch (given
& 0x60)
1972 case '0': case '1': case '2': case '3': case '4':
1973 case '5': case '6': case '7': case '8': case '9':
1977 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
1982 func (stream
, "%s", arm_regnames
[value
]);
1985 func (stream
, "d%ld", value
);
1989 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
1991 func (stream
, "q%ld", value
>> 1);
1994 func (stream
, "%ld", value
);
1995 value_in_comment
= value
;
1999 int from
= (given
& (1 << 7)) ? 32 : 16;
2000 func (stream
, "%ld", from
- value
);
2006 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2008 func (stream
, "f%ld", value
);
2013 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2015 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2019 func (stream
, "%s", iwmmxt_regnames
[value
]);
2022 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2026 func (stream
, "0x%lx", (value
& 0xffffffffUL
));
2032 func (stream
, "%c", *c
);
2036 if (value
== ((1ul << width
) - 1))
2037 func (stream
, "%c", *c
);
2040 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2051 int single
= *c
++ == 'y';
2056 case '4': /* Sm pair */
2057 case '0': /* Sm, Dm */
2058 regno
= given
& 0x0000000f;
2062 regno
+= (given
>> 5) & 1;
2065 regno
+= ((given
>> 5) & 1) << 4;
2068 case '1': /* Sd, Dd */
2069 regno
= (given
>> 12) & 0x0000000f;
2073 regno
+= (given
>> 22) & 1;
2076 regno
+= ((given
>> 22) & 1) << 4;
2079 case '2': /* Sn, Dn */
2080 regno
= (given
>> 16) & 0x0000000f;
2084 regno
+= (given
>> 7) & 1;
2087 regno
+= ((given
>> 7) & 1) << 4;
2090 case '3': /* List */
2092 regno
= (given
>> 12) & 0x0000000f;
2096 regno
+= (given
>> 22) & 1;
2099 regno
+= ((given
>> 22) & 1) << 4;
2106 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2110 int count
= given
& 0xff;
2117 func (stream
, "-%c%d",
2125 func (stream
, ", %c%d", single
? 's' : 'd',
2131 switch (given
& 0x00400100)
2133 case 0x00000000: func (stream
, "b"); break;
2134 case 0x00400000: func (stream
, "h"); break;
2135 case 0x00000100: func (stream
, "w"); break;
2136 case 0x00400100: func (stream
, "d"); break;
2144 /* given (20, 23) | given (0, 3) */
2145 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
2146 func (stream
, "%d", value
);
2151 /* This is like the 'A' operator, except that if
2152 the width field "M" is zero, then the offset is
2153 *not* multiplied by four. */
2155 int offset
= given
& 0xff;
2156 int multiplier
= (given
& 0x00000100) ? 4 : 1;
2158 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2162 value_in_comment
= offset
* multiplier
;
2163 if (NEGATIVE_BIT_SET
)
2164 value_in_comment
= - value_in_comment
;
2170 func (stream
, ", #%s%d]%s",
2171 NEGATIVE_BIT_SET
? "-" : "",
2172 offset
* multiplier
,
2173 WRITEBACK_BIT_SET
? "!" : "");
2175 func (stream
, "], #%s%d",
2176 NEGATIVE_BIT_SET
? "-" : "",
2177 offset
* multiplier
);
2186 int imm4
= (given
>> 4) & 0xf;
2187 int puw_bits
= ((given
>> 22) & 6) | ((given
>> W_BIT
) & 1);
2188 int ubit
= ! NEGATIVE_BIT_SET
;
2189 const char *rm
= arm_regnames
[given
& 0xf];
2190 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
2196 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
2198 func (stream
, ", lsl #%d", imm4
);
2205 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
2207 func (stream
, ", lsl #%d", imm4
);
2209 if (puw_bits
== 5 || puw_bits
== 7)
2214 func (stream
, "INVALID");
2222 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
2223 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
2233 func (stream
, "%c", *c
);
2236 if (value_in_comment
> 32 || value_in_comment
< -16)
2237 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
2244 /* Decodes and prints ARM addressing modes. Returns the offset
2245 used in the address, if any, if it is worthwhile printing the
2246 offset as a hexadecimal value in a comment at the end of the
2247 line of disassembly. */
2250 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2252 void *stream
= info
->stream
;
2253 fprintf_ftype func
= info
->fprintf_func
;
2256 if (((given
& 0x000f0000) == 0x000f0000)
2257 && ((given
& 0x02000000) == 0))
2259 offset
= given
& 0xfff;
2261 func (stream
, "[pc");
2265 if (NEGATIVE_BIT_SET
)
2269 func (stream
, ", #%d]", offset
);
2273 /* Cope with the possibility of write-back
2274 being used. Probably a very dangerous thing
2275 for the programmer to do, but who are we to
2277 if (WRITEBACK_BIT_SET
)
2280 else /* Post indexed. */
2282 func (stream
, "], #%d", offset
);
2284 /* Ie ignore the offset. */
2288 func (stream
, "\t; ");
2289 info
->print_address_func (offset
, info
);
2294 func (stream
, "[%s",
2295 arm_regnames
[(given
>> 16) & 0xf]);
2299 if ((given
& 0x02000000) == 0)
2301 offset
= given
& 0xfff;
2303 func (stream
, ", #%s%d",
2304 NEGATIVE_BIT_SET
? "-" : "", offset
);
2308 func (stream
, ", %s",
2309 NEGATIVE_BIT_SET
? "-" : "");
2310 arm_decode_shift (given
, func
, stream
, TRUE
);
2313 func (stream
, "]%s",
2314 WRITEBACK_BIT_SET
? "!" : "");
2318 if ((given
& 0x02000000) == 0)
2320 offset
= given
& 0xfff;
2322 func (stream
, "], #%s%d",
2323 NEGATIVE_BIT_SET
? "-" : "", offset
);
2329 func (stream
, "], %s",
2330 NEGATIVE_BIT_SET
? "-" : "");
2331 arm_decode_shift (given
, func
, stream
, TRUE
);
2336 return (signed long) offset
;
2339 /* Print one neon instruction on INFO->STREAM.
2340 Return TRUE if the instuction matched, FALSE if this is not a
2341 recognised neon instruction. */
2344 print_insn_neon (struct disassemble_info
*info
, long given
, bfd_boolean thumb
)
2346 const struct opcode32
*insn
;
2347 void *stream
= info
->stream
;
2348 fprintf_ftype func
= info
->fprintf_func
;
2352 if ((given
& 0xef000000) == 0xef000000)
2354 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2355 unsigned long bit28
= given
& (1 << 28);
2357 given
&= 0x00ffffff;
2359 given
|= 0xf3000000;
2361 given
|= 0xf2000000;
2363 else if ((given
& 0xff000000) == 0xf9000000)
2364 given
^= 0xf9000000 ^ 0xf4000000;
2369 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
2371 if ((given
& insn
->mask
) == insn
->value
)
2373 signed long value_in_comment
= 0;
2376 for (c
= insn
->assembler
; *c
; c
++)
2383 func (stream
, "%%");
2387 if (thumb
&& ifthen_state
)
2388 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
2393 static const unsigned char enc
[16] =
2395 0x4, 0x14, /* st4 0,1 */
2407 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2408 int rn
= ((given
>> 16) & 0xf);
2409 int rm
= ((given
>> 0) & 0xf);
2410 int align
= ((given
>> 4) & 0x3);
2411 int type
= ((given
>> 8) & 0xf);
2412 int n
= enc
[type
] & 0xf;
2413 int stride
= (enc
[type
] >> 4) + 1;
2418 for (ix
= 0; ix
!= n
; ix
++)
2419 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
2421 func (stream
, "d%d", rd
);
2423 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
2424 func (stream
, "}, [%s", arm_regnames
[rn
]);
2426 func (stream
, ", :%d", 32 << align
);
2431 func (stream
, ", %s", arm_regnames
[rm
]);
2437 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2438 int rn
= ((given
>> 16) & 0xf);
2439 int rm
= ((given
>> 0) & 0xf);
2440 int idx_align
= ((given
>> 4) & 0xf);
2442 int size
= ((given
>> 10) & 0x3);
2443 int idx
= idx_align
>> (size
+ 1);
2444 int length
= ((given
>> 8) & 3) + 1;
2448 if (length
> 1 && size
> 0)
2449 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
2455 int amask
= (1 << size
) - 1;
2456 if ((idx_align
& (1 << size
)) != 0)
2460 if ((idx_align
& amask
) == amask
)
2462 else if ((idx_align
& amask
) != 0)
2469 if (size
== 2 && (idx_align
& 2) != 0)
2471 align
= (idx_align
& 1) ? 16 << size
: 0;
2475 if ((size
== 2 && (idx_align
& 3) != 0)
2476 || (idx_align
& 1) != 0)
2483 if ((idx_align
& 3) == 3)
2485 align
= (idx_align
& 3) * 64;
2488 align
= (idx_align
& 1) ? 32 << size
: 0;
2496 for (i
= 0; i
< length
; i
++)
2497 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
2498 rd
+ i
* stride
, idx
);
2499 func (stream
, "}, [%s", arm_regnames
[rn
]);
2501 func (stream
, ", :%d", align
);
2506 func (stream
, ", %s", arm_regnames
[rm
]);
2512 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2513 int rn
= ((given
>> 16) & 0xf);
2514 int rm
= ((given
>> 0) & 0xf);
2515 int align
= ((given
>> 4) & 0x1);
2516 int size
= ((given
>> 6) & 0x3);
2517 int type
= ((given
>> 8) & 0x3);
2519 int stride
= ((given
>> 5) & 0x1);
2522 if (stride
&& (n
== 1))
2529 for (ix
= 0; ix
!= n
; ix
++)
2530 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
2532 func (stream
, "d%d[]", rd
);
2534 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
2535 func (stream
, "}, [%s", arm_regnames
[rn
]);
2538 align
= (8 * (type
+ 1)) << size
;
2540 align
= (size
> 1) ? align
>> 1 : align
;
2541 if (type
== 2 || (type
== 0 && !size
))
2542 func (stream
, ", :<bad align %d>", align
);
2544 func (stream
, ", :%d", align
);
2550 func (stream
, ", %s", arm_regnames
[rm
]);
2556 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
2557 int size
= (given
>> 20) & 3;
2558 int reg
= raw_reg
& ((4 << size
) - 1);
2559 int ix
= raw_reg
>> size
>> 2;
2561 func (stream
, "d%d[%d]", reg
, ix
);
2566 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2569 int cmode
= (given
>> 8) & 0xf;
2570 int op
= (given
>> 5) & 0x1;
2571 unsigned long value
= 0, hival
= 0;
2576 bits
|= ((given
>> 24) & 1) << 7;
2577 bits
|= ((given
>> 16) & 7) << 4;
2578 bits
|= ((given
>> 0) & 15) << 0;
2582 shift
= (cmode
>> 1) & 3;
2583 value
= (unsigned long) bits
<< (8 * shift
);
2586 else if (cmode
< 12)
2588 shift
= (cmode
>> 1) & 1;
2589 value
= (unsigned long) bits
<< (8 * shift
);
2592 else if (cmode
< 14)
2594 shift
= (cmode
& 1) + 1;
2595 value
= (unsigned long) bits
<< (8 * shift
);
2596 value
|= (1ul << (8 * shift
)) - 1;
2599 else if (cmode
== 14)
2603 /* Bit replication into bytes. */
2609 for (ix
= 7; ix
>= 0; ix
--)
2611 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
2613 value
= (value
<< 8) | mask
;
2615 hival
= (hival
<< 8) | mask
;
2621 /* Byte replication. */
2622 value
= (unsigned long) bits
;
2628 /* Floating point encoding. */
2631 value
= (unsigned long) (bits
& 0x7f) << 19;
2632 value
|= (unsigned long) (bits
& 0x80) << 24;
2633 tmp
= bits
& 0x40 ? 0x3c : 0x40;
2634 value
|= (unsigned long) tmp
<< 24;
2640 func (stream
, "<illegal constant %.8x:%x:%x>",
2648 func (stream
, "#%ld\t; 0x%.2lx", value
, value
);
2652 func (stream
, "#%ld\t; 0x%.4lx", value
, value
);
2658 unsigned char valbytes
[4];
2661 /* Do this a byte at a time so we don't have to
2662 worry about the host's endianness. */
2663 valbytes
[0] = value
& 0xff;
2664 valbytes
[1] = (value
>> 8) & 0xff;
2665 valbytes
[2] = (value
>> 16) & 0xff;
2666 valbytes
[3] = (value
>> 24) & 0xff;
2668 floatformat_to_double
2669 (& floatformat_ieee_single_little
, valbytes
,
2672 func (stream
, "#%.7g\t; 0x%.8lx", fvalue
,
2676 func (stream
, "#%ld\t; 0x%.8lx",
2677 (long) (NEGATIVE_BIT_SET
? value
| ~0xffffffffL
: value
),
2682 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
2693 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
2694 int num
= (given
>> 8) & 0x3;
2697 func (stream
, "{d%d}", regno
);
2698 else if (num
+ regno
>= 32)
2699 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
2701 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
2706 case '0': case '1': case '2': case '3': case '4':
2707 case '5': case '6': case '7': case '8': case '9':
2710 unsigned long value
;
2712 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2717 func (stream
, "%s", arm_regnames
[value
]);
2720 func (stream
, "%ld", value
);
2721 value_in_comment
= value
;
2724 func (stream
, "%ld", (1ul << width
) - value
);
2730 /* Various width encodings. */
2732 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
2737 if (*c
>= '0' && *c
<= '9')
2739 else if (*c
>= 'a' && *c
<= 'f')
2740 limit
= *c
- 'a' + 10;
2746 if (value
< low
|| value
> high
)
2747 func (stream
, "<illegal width %d>", base
<< value
);
2749 func (stream
, "%d", base
<< value
);
2753 if (given
& (1 << 6))
2757 func (stream
, "d%ld", value
);
2762 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2764 func (stream
, "q%ld", value
>> 1);
2770 func (stream
, "%c", *c
);
2774 if (value
== ((1ul << width
) - 1))
2775 func (stream
, "%c", *c
);
2778 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2792 func (stream
, "%c", *c
);
2795 if (value_in_comment
> 32 || value_in_comment
< -16)
2796 func (stream
, "\t; 0x%lx", value_in_comment
);
2804 /* Print one ARM instruction from PC on INFO->STREAM. */
2807 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2809 const struct opcode32
*insn
;
2810 void *stream
= info
->stream
;
2811 fprintf_ftype func
= info
->fprintf_func
;
2813 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
2816 if (print_insn_neon (info
, given
, FALSE
))
2819 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
2821 if ((given
& insn
->mask
) != insn
->value
)
2824 if ((insn
->arch
& ((arm_feature_set
*) info
->private_data
)->core
) == 0)
2827 /* Special case: an instruction with all bits set in the condition field
2828 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2829 or by the catchall at the end of the table. */
2830 if ((given
& 0xF0000000) != 0xF0000000
2831 || (insn
->mask
& 0xF0000000) == 0xF0000000
2832 || (insn
->mask
== 0 && insn
->value
== 0))
2834 signed long value_in_comment
= 0;
2837 for (c
= insn
->assembler
; *c
; c
++)
2841 bfd_boolean allow_unpredictable
= FALSE
;
2846 func (stream
, "%%");
2850 value_in_comment
= print_arm_address (pc
, info
, given
);
2854 /* Set P address bit and use normal address
2855 printing routine. */
2856 value_in_comment
= print_arm_address (pc
, info
, given
| (1 << P_BIT
));
2860 allow_unpredictable
= TRUE
;
2862 if ((given
& 0x004f0000) == 0x004f0000)
2864 /* PC relative with immediate offset. */
2865 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2867 if (NEGATIVE_BIT_SET
)
2873 func (stream
, "[pc, #%d]\t; ", offset
);
2875 func (stream
, "[pc]\t; ");
2876 info
->print_address_func (offset
+ pc
+ 8, info
);
2880 func (stream
, "[pc], #%d", offset
);
2881 func (stream
, UNPREDICTABLE_INSTRUCTION
);
2886 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2888 if (NEGATIVE_BIT_SET
)
2891 func (stream
, "[%s",
2892 arm_regnames
[(given
>> 16) & 0xf]);
2896 if (IMMEDIATE_BIT_SET
)
2898 if (WRITEBACK_BIT_SET
)
2899 /* Immediate Pre-indexed. */
2900 /* PR 10924: Offset must be printed, even if it is zero. */
2901 func (stream
, ", #%d", offset
);
2903 /* Immediate Offset: printing zero offset is optional. */
2904 func (stream
, ", #%d", offset
);
2906 value_in_comment
= offset
;
2909 /* Register Offset or Register Pre-Indexed. */
2910 func (stream
, ", %s%s",
2911 NEGATIVE_BIT_SET
? "-" : "",
2912 arm_regnames
[given
& 0xf]);
2914 func (stream
, "]%s",
2915 WRITEBACK_BIT_SET
? "!" : "");
2919 if (IMMEDIATE_BIT_SET
)
2921 /* Immediate Post-indexed. */
2922 /* PR 10924: Offset must be printed, even if it is zero. */
2923 func (stream
, "], #%d", offset
);
2924 value_in_comment
= offset
;
2927 /* Register Post-indexed. */
2928 func (stream
, "], %s%s",
2929 NEGATIVE_BIT_SET
? "-" : "",
2930 arm_regnames
[given
& 0xf]);
2932 if (! allow_unpredictable
)
2934 /* Writeback is automatically implied by post- addressing.
2935 Setting the W bit is unnecessary and ARM specify it as
2936 being unpredictable. */
2937 if (WRITEBACK_BIT_SET
2938 /* Specifying the PC register as the post-indexed
2939 registers is also unpredictable. */
2940 || ((given
& 0xf) == 0xf))
2941 func (stream
, UNPREDICTABLE_INSTRUCTION
);
2949 int disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
2950 info
->print_address_func (disp
* 4 + pc
+ 8, info
);
2955 if (((given
>> 28) & 0xf) != 0xe)
2957 arm_conditional
[(given
>> 28) & 0xf]);
2966 for (reg
= 0; reg
< 16; reg
++)
2967 if ((given
& (1 << reg
)) != 0)
2970 func (stream
, ", ");
2972 func (stream
, "%s", arm_regnames
[reg
]);
2979 arm_decode_shift (given
, func
, stream
, FALSE
);
2983 if ((given
& 0x02000000) != 0)
2985 int rotate
= (given
& 0xf00) >> 7;
2986 int immed
= (given
& 0xff);
2988 immed
= (((immed
<< (32 - rotate
))
2989 | (immed
>> rotate
)) & 0xffffffff);
2990 func (stream
, "#%d", immed
);
2991 value_in_comment
= immed
;
2994 arm_decode_shift (given
, func
, stream
, TRUE
);
2998 if ((given
& 0x0000f000) == 0x0000f000)
3000 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3001 mechanism for setting PSR flag bits. They are
3002 obsolete in V6 onwards. */
3003 if (((((arm_feature_set
*) info
->private_data
)->core
) & ARM_EXT_V6
) == 0)
3009 if ((given
& 0x01200000) == 0x00200000)
3015 int offset
= given
& 0xff;
3017 value_in_comment
= offset
* 4;
3018 if (NEGATIVE_BIT_SET
)
3019 value_in_comment
= - value_in_comment
;
3021 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3026 func (stream
, ", #%d]%s",
3028 WRITEBACK_BIT_SET
? "!" : "");
3036 if (WRITEBACK_BIT_SET
)
3039 func (stream
, ", #%d", value_in_comment
);
3043 func (stream
, ", {%d}", offset
);
3044 value_in_comment
= offset
;
3051 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3056 if (! NEGATIVE_BIT_SET
)
3057 /* Is signed, hi bits should be ones. */
3058 offset
= (-1) ^ 0x00ffffff;
3060 /* Offset is (SignExtend(offset field)<<2). */
3061 offset
+= given
& 0x00ffffff;
3063 address
= offset
+ pc
+ 8;
3065 if (given
& 0x01000000)
3066 /* H bit allows addressing to 2-byte boundaries. */
3069 info
->print_address_func (address
, info
);
3075 if (given
& 0x80000)
3077 if (given
& 0x40000)
3079 if (given
& 0x20000)
3081 if (given
& 0x10000)
3086 switch (given
& 0xf)
3088 case 0xf: func (stream
, "sy"); break;
3089 case 0x7: func (stream
, "un"); break;
3090 case 0xe: func (stream
, "st"); break;
3091 case 0x6: func (stream
, "unst"); break;
3093 func (stream
, "#%d", (int) given
& 0xf);
3098 case '0': case '1': case '2': case '3': case '4':
3099 case '5': case '6': case '7': case '8': case '9':
3102 unsigned long value
;
3104 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3109 func (stream
, "%s", arm_regnames
[value
]);
3112 func (stream
, "%ld", value
);
3113 value_in_comment
= value
;
3116 func (stream
, "%ld", value
* 8);
3117 value_in_comment
= value
* 8;
3120 func (stream
, "%ld", value
+ 1);
3121 value_in_comment
= value
+ 1;
3124 func (stream
, "0x%08lx", value
);
3126 /* Some SWI instructions have special
3128 if ((given
& 0x0fffffff) == 0x0FF00000)
3129 func (stream
, "\t; IMB");
3130 else if ((given
& 0x0fffffff) == 0x0FF00001)
3131 func (stream
, "\t; IMBRange");
3134 func (stream
, "%01lx", value
& 0xf);
3135 value_in_comment
= value
;
3140 func (stream
, "%c", *c
);
3144 if (value
== ((1ul << width
) - 1))
3145 func (stream
, "%c", *c
);
3148 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3160 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3161 func (stream
, "%d", imm
);
3162 value_in_comment
= imm
;
3167 /* LSB and WIDTH fields of BFI or BFC. The machine-
3168 language instruction encodes LSB and MSB. */
3170 long msb
= (given
& 0x001f0000) >> 16;
3171 long lsb
= (given
& 0x00000f80) >> 7;
3172 long w
= msb
- lsb
+ 1;
3175 func (stream
, "#%lu, #%lu", lsb
, w
);
3177 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3182 /* 16-bit unsigned immediate from a MOVT or MOVW
3183 instruction, encoded in bits 0:11 and 15:19. */
3185 long hi
= (given
& 0x000f0000) >> 4;
3186 long lo
= (given
& 0x00000fff);
3187 long imm16
= hi
| lo
;
3189 func (stream
, "#%lu", imm16
);
3190 value_in_comment
= imm16
;
3200 func (stream
, "%c", *c
);
3203 if (value_in_comment
> 32 || value_in_comment
< -16)
3204 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3211 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3214 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3216 const struct opcode16
*insn
;
3217 void *stream
= info
->stream
;
3218 fprintf_ftype func
= info
->fprintf_func
;
3220 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3221 if ((given
& insn
->mask
) == insn
->value
)
3223 signed long value_in_comment
= 0;
3224 const char *c
= insn
->assembler
;
3233 func (stream
, "%c", *c
);
3240 func (stream
, "%%");
3245 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3250 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3259 ifthen_next_state
= given
& 0xff;
3260 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3261 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3262 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3267 if (ifthen_next_state
)
3268 func (stream
, "\t; unpredictable branch in IT block\n");
3273 func (stream
, "\t; unpredictable <IT:%s>",
3274 arm_conditional
[IFTHEN_COND
]);
3281 reg
= (given
>> 3) & 0x7;
3282 if (given
& (1 << 6))
3285 func (stream
, "%s", arm_regnames
[reg
]);
3294 if (given
& (1 << 7))
3297 func (stream
, "%s", arm_regnames
[reg
]);
3302 if (given
& (1 << 8))
3306 if (*c
== 'O' && (given
& (1 << 8)))
3316 /* It would be nice if we could spot
3317 ranges, and generate the rS-rE format: */
3318 for (reg
= 0; (reg
< 8); reg
++)
3319 if ((given
& (1 << reg
)) != 0)
3322 func (stream
, ", ");
3324 func (stream
, "%s", arm_regnames
[reg
]);
3330 func (stream
, ", ");
3332 func (stream
, arm_regnames
[14] /* "lr" */);
3338 func (stream
, ", ");
3339 func (stream
, arm_regnames
[15] /* "pc" */);
3347 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3349 bfd_vma address
= (pc
+ 4
3350 + ((given
& 0x00f8) >> 2)
3351 + ((given
& 0x0200) >> 3));
3352 info
->print_address_func (address
, info
);
3357 /* Right shift immediate -- bits 6..10; 1-31 print
3358 as themselves, 0 prints as 32. */
3360 long imm
= (given
& 0x07c0) >> 6;
3363 func (stream
, "#%ld", imm
);
3367 case '0': case '1': case '2': case '3': case '4':
3368 case '5': case '6': case '7': case '8': case '9':
3370 int bitstart
= *c
++ - '0';
3373 while (*c
>= '0' && *c
<= '9')
3374 bitstart
= (bitstart
* 10) + *c
++ - '0';
3383 while (*c
>= '0' && *c
<= '9')
3384 bitend
= (bitend
* 10) + *c
++ - '0';
3387 reg
= given
>> bitstart
;
3388 reg
&= (2 << (bitend
- bitstart
)) - 1;
3392 func (stream
, "%s", arm_regnames
[reg
]);
3396 func (stream
, "%ld", reg
);
3397 value_in_comment
= reg
;
3401 func (stream
, "%ld", reg
<< 1);
3402 value_in_comment
= reg
<< 1;
3406 func (stream
, "%ld", reg
<< 2);
3407 value_in_comment
= reg
<< 2;
3411 /* PC-relative address -- the bottom two
3412 bits of the address are dropped
3413 before the calculation. */
3414 info
->print_address_func
3415 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3416 value_in_comment
= 0;
3420 func (stream
, "0x%04lx", reg
);
3424 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3425 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3426 value_in_comment
= 0;
3430 func (stream
, "%s", arm_conditional
[reg
]);
3441 if ((given
& (1 << bitstart
)) != 0)
3442 func (stream
, "%c", *c
);
3447 if ((given
& (1 << bitstart
)) != 0)
3448 func (stream
, "%c", *c
++);
3450 func (stream
, "%c", *++c
);
3464 if (value_in_comment
> 32 || value_in_comment
< -16)
3465 func (stream
, "\t; 0x%lx", value_in_comment
);
3473 /* Return the name of an V7M special register. */
3476 psr_name (int regno
)
3480 case 0: return "APSR";
3481 case 1: return "IAPSR";
3482 case 2: return "EAPSR";
3483 case 3: return "PSR";
3484 case 5: return "IPSR";
3485 case 6: return "EPSR";
3486 case 7: return "IEPSR";
3487 case 8: return "MSP";
3488 case 9: return "PSP";
3489 case 16: return "PRIMASK";
3490 case 17: return "BASEPRI";
3491 case 18: return "BASEPRI_MASK";
3492 case 19: return "FAULTMASK";
3493 case 20: return "CONTROL";
3494 default: return "<unknown>";
3498 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3501 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3503 const struct opcode32
*insn
;
3504 void *stream
= info
->stream
;
3505 fprintf_ftype func
= info
->fprintf_func
;
3507 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3510 if (print_insn_neon (info
, given
, TRUE
))
3513 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3514 if ((given
& insn
->mask
) == insn
->value
)
3516 signed long value_in_comment
= 0;
3517 const char *c
= insn
->assembler
;
3523 func (stream
, "%c", *c
);
3530 func (stream
, "%%");
3535 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3539 if (ifthen_next_state
)
3540 func (stream
, "\t; unpredictable branch in IT block\n");
3545 func (stream
, "\t; unpredictable <IT:%s>",
3546 arm_conditional
[IFTHEN_COND
]);
3551 unsigned int imm12
= 0;
3553 imm12
|= (given
& 0x000000ffu
);
3554 imm12
|= (given
& 0x00007000u
) >> 4;
3555 imm12
|= (given
& 0x04000000u
) >> 15;
3556 func (stream
, "#%u", imm12
);
3557 value_in_comment
= imm12
;
3563 unsigned int bits
= 0, imm
, imm8
, mod
;
3565 bits
|= (given
& 0x000000ffu
);
3566 bits
|= (given
& 0x00007000u
) >> 4;
3567 bits
|= (given
& 0x04000000u
) >> 15;
3568 imm8
= (bits
& 0x0ff);
3569 mod
= (bits
& 0xf00) >> 8;
3572 case 0: imm
= imm8
; break;
3573 case 1: imm
= ((imm8
<< 16) | imm8
); break;
3574 case 2: imm
= ((imm8
<< 24) | (imm8
<< 8)); break;
3575 case 3: imm
= ((imm8
<< 24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3577 mod
= (bits
& 0xf80) >> 7;
3578 imm8
= (bits
& 0x07f) | 0x80;
3579 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3581 func (stream
, "#%u", imm
);
3582 value_in_comment
= imm
;
3588 unsigned int imm
= 0;
3590 imm
|= (given
& 0x000000ffu
);
3591 imm
|= (given
& 0x00007000u
) >> 4;
3592 imm
|= (given
& 0x04000000u
) >> 15;
3593 imm
|= (given
& 0x000f0000u
) >> 4;
3594 func (stream
, "#%u", imm
);
3595 value_in_comment
= imm
;
3601 unsigned int imm
= 0;
3603 imm
|= (given
& 0x000f0000u
) >> 16;
3604 imm
|= (given
& 0x00000ff0u
) >> 0;
3605 imm
|= (given
& 0x0000000fu
) << 12;
3606 func (stream
, "#%u", imm
);
3607 value_in_comment
= imm
;
3613 unsigned int reg
= (given
& 0x0000000fu
);
3614 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3615 unsigned int imm
= 0;
3616 imm
|= (given
& 0x000000c0u
) >> 6;
3617 imm
|= (given
& 0x00007000u
) >> 10;
3619 func (stream
, "%s", arm_regnames
[reg
]);
3624 func (stream
, ", lsl #%u", imm
);
3630 func (stream
, ", lsr #%u", imm
);
3636 func (stream
, ", asr #%u", imm
);
3641 func (stream
, ", rrx");
3643 func (stream
, ", ror #%u", imm
);
3650 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3651 unsigned int U
= ! NEGATIVE_BIT_SET
;
3652 unsigned int op
= (given
& 0x00000f00) >> 8;
3653 unsigned int i12
= (given
& 0x00000fff);
3654 unsigned int i8
= (given
& 0x000000ff);
3655 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3658 func (stream
, "[%s", arm_regnames
[Rn
]);
3659 if (U
) /* 12-bit positive immediate offset. */
3663 value_in_comment
= offset
;
3665 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3666 offset
= - (int) i12
;
3667 else if (op
== 0x0) /* Shifted register offset. */
3669 unsigned int Rm
= (i8
& 0x0f);
3670 unsigned int sh
= (i8
& 0x30) >> 4;
3672 func (stream
, ", %s", arm_regnames
[Rm
]);
3674 func (stream
, ", lsl #%u", sh
);
3680 case 0xE: /* 8-bit positive immediate offset. */
3684 case 0xC: /* 8-bit negative immediate offset. */
3688 case 0xF: /* 8-bit + preindex with wb. */
3693 case 0xD: /* 8-bit - preindex with wb. */
3698 case 0xB: /* 8-bit + postindex. */
3703 case 0x9: /* 8-bit - postindex. */
3709 func (stream
, ", <undefined>]");
3714 func (stream
, "], #%d", offset
);
3718 func (stream
, ", #%d", offset
);
3719 func (stream
, writeback
? "]!" : "]");
3724 func (stream
, "\t; ");
3725 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3733 unsigned int U
= ! NEGATIVE_BIT_SET
;
3734 unsigned int W
= WRITEBACK_BIT_SET
;
3735 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3736 unsigned int off
= (given
& 0x000000ff);
3738 func (stream
, "[%s", arm_regnames
[Rn
]);
3744 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
3745 value_in_comment
= off
* 4 * U
? 1 : -1;
3753 func (stream
, "], ");
3756 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
3757 value_in_comment
= off
* 4 * U
? 1 : -1;
3761 func (stream
, "{%u}", off
);
3762 value_in_comment
= off
;
3770 unsigned int Sbit
= (given
& 0x01000000) >> 24;
3771 unsigned int type
= (given
& 0x00600000) >> 21;
3775 case 0: func (stream
, Sbit
? "sb" : "b"); break;
3776 case 1: func (stream
, Sbit
? "sh" : "h"); break;
3779 func (stream
, "??");
3782 func (stream
, "??");
3794 for (reg
= 0; reg
< 16; reg
++)
3795 if ((given
& (1 << reg
)) != 0)
3798 func (stream
, ", ");
3800 func (stream
, "%s", arm_regnames
[reg
]);
3808 unsigned int msb
= (given
& 0x0000001f);
3809 unsigned int lsb
= 0;
3811 lsb
|= (given
& 0x000000c0u
) >> 6;
3812 lsb
|= (given
& 0x00007000u
) >> 10;
3813 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
3819 unsigned int width
= (given
& 0x0000001f) + 1;
3820 unsigned int lsb
= 0;
3822 lsb
|= (given
& 0x000000c0u
) >> 6;
3823 lsb
|= (given
& 0x00007000u
) >> 10;
3824 func (stream
, "#%u, #%u", lsb
, width
);
3830 unsigned int S
= (given
& 0x04000000u
) >> 26;
3831 unsigned int J1
= (given
& 0x00002000u
) >> 13;
3832 unsigned int J2
= (given
& 0x00000800u
) >> 11;
3838 offset
|= (given
& 0x003f0000) >> 4;
3839 offset
|= (given
& 0x000007ff) << 1;
3840 offset
-= (1 << 20);
3842 info
->print_address_func (pc
+ 4 + offset
, info
);
3848 unsigned int S
= (given
& 0x04000000u
) >> 26;
3849 unsigned int I1
= (given
& 0x00002000u
) >> 13;
3850 unsigned int I2
= (given
& 0x00000800u
) >> 11;
3854 offset
|= !(I1
^ S
) << 23;
3855 offset
|= !(I2
^ S
) << 22;
3856 offset
|= (given
& 0x03ff0000u
) >> 4;
3857 offset
|= (given
& 0x000007ffu
) << 1;
3858 offset
-= (1 << 24);
3861 /* BLX target addresses are always word aligned. */
3862 if ((given
& 0x00001000u
) == 0)
3865 info
->print_address_func (offset
, info
);
3871 unsigned int shift
= 0;
3873 shift
|= (given
& 0x000000c0u
) >> 6;
3874 shift
|= (given
& 0x00007000u
) >> 10;
3875 if (WRITEBACK_BIT_SET
)
3876 func (stream
, ", asr #%u", shift
);
3878 func (stream
, ", lsl #%u", shift
);
3879 /* else print nothing - lsl #0 */
3885 unsigned int rot
= (given
& 0x00000030) >> 4;
3888 func (stream
, ", ror #%u", rot
* 8);
3893 switch (given
& 0xf)
3895 case 0xf: func (stream
, "sy"); break;
3896 case 0x7: func (stream
, "un"); break;
3897 case 0xe: func (stream
, "st"); break;
3898 case 0x6: func (stream
, "unst"); break;
3900 func (stream
, "#%d", (int) given
& 0xf);
3906 if ((given
& 0xff) == 0)
3908 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
3920 func (stream
, psr_name (given
& 0xff));
3925 if ((given
& 0xff) == 0)
3926 func (stream
, "%cPSR", (given
& 0x100000) ? 'S' : 'C');
3928 func (stream
, psr_name (given
& 0xff));
3931 case '0': case '1': case '2': case '3': case '4':
3932 case '5': case '6': case '7': case '8': case '9':
3937 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
3942 func (stream
, "%lu", val
);
3943 value_in_comment
= val
;
3946 func (stream
, "%lu", val
* 4);
3947 value_in_comment
= val
* 4;
3949 case 'r': func (stream
, "%s", arm_regnames
[val
]); break;
3952 func (stream
, "%s", arm_conditional
[val
]);
3957 if (val
== ((1ul << width
) - 1))
3958 func (stream
, "%c", *c
);
3964 func (stream
, "%c", *c
);
3968 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
3973 func (stream
, "0x%lx", val
& 0xffffffffUL
);
3987 if (value_in_comment
> 32 || value_in_comment
< -16)
3988 func (stream
, "\t; 0x%lx", value_in_comment
);
3996 /* Print data bytes on INFO->STREAM. */
3999 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
4000 struct disassemble_info
*info
,
4003 switch (info
->bytes_per_chunk
)
4006 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4009 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4012 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4019 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4020 being displayed in symbol relative addresses. */
4023 arm_symbol_is_valid (asymbol
* sym
,
4024 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4031 name
= bfd_asymbol_name (sym
);
4033 return (name
&& *name
!= '$');
4036 /* Parse an individual disassembler option. */
4039 parse_arm_disassembler_option (char *option
)
4044 if (CONST_STRNEQ (option
, "reg-names-"))
4050 for (i
= NUM_ARM_REGNAMES
; i
--;)
4051 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4053 regname_selected
= i
;
4058 /* XXX - should break 'option' at following delimiter. */
4059 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4061 else if (CONST_STRNEQ (option
, "force-thumb"))
4063 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4066 /* XXX - should break 'option' at following delimiter. */
4067 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4072 /* Parse the string of disassembler options, spliting it at whitespaces
4073 or commas. (Whitespace separators supported for backwards compatibility). */
4076 parse_disassembler_options (char *options
)
4078 if (options
== NULL
)
4083 parse_arm_disassembler_option (options
);
4085 /* Skip forward to next seperator. */
4086 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4088 /* Skip forward past seperators. */
4089 while (ISSPACE (*options
) || (*options
== ','))
4094 /* Search back through the insn stream to determine if this instruction is
4095 conditionally executed. */
4098 find_ifthen_state (bfd_vma pc
,
4099 struct disassemble_info
*info
,
4105 /* COUNT is twice the number of instructions seen. It will be odd if we
4106 just crossed an instruction boundary. */
4109 unsigned int seen_it
;
4112 ifthen_address
= pc
;
4119 /* Scan backwards looking for IT instructions, keeping track of where
4120 instruction boundaries are. We don't know if something is actually an
4121 IT instruction until we find a definite instruction boundary. */
4124 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4126 /* A symbol must be on an instruction boundary, and will not
4127 be within an IT block. */
4128 if (seen_it
&& (count
& 1))
4134 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4139 insn
= (b
[0]) | (b
[1] << 8);
4141 insn
= (b
[1]) | (b
[0] << 8);
4144 if ((insn
& 0xf800) < 0xe800)
4146 /* Addr + 2 is an instruction boundary. See if this matches
4147 the expected boundary based on the position of the last
4154 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4156 /* This could be an IT instruction. */
4158 it_count
= count
>> 1;
4160 if ((insn
& 0xf800) >= 0xe800)
4163 count
= (count
+ 2) | 1;
4164 /* IT blocks contain at most 4 instructions. */
4165 if (count
>= 8 && !seen_it
)
4168 /* We found an IT instruction. */
4169 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4170 if ((ifthen_state
& 0xf) == 0)
4174 /* Try to infer the code type (Arm or Thumb) from a symbol.
4175 Returns nonzero if *MAP_TYPE was set. */
4178 get_sym_code_type (struct disassemble_info
*info
,
4180 enum map_type
*map_type
)
4182 elf_symbol_type
*es
;
4186 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4187 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4189 /* If the symbol has function type then use that. */
4190 if (type
== STT_FUNC
|| type
== STT_ARM_TFUNC
)
4192 *map_type
= (type
== STT_ARM_TFUNC
) ? MAP_THUMB
: MAP_ARM
;
4196 /* Check for mapping symbols. */
4197 name
= bfd_asymbol_name (info
->symtab
[n
]);
4198 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4199 && (name
[2] == 0 || name
[2] == '.'))
4201 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4202 : (name
[1] == 't') ? MAP_THUMB
4210 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4211 of the supplied arm_feature_set structure with bitmasks indicating
4212 the support base architectures and coprocessor extensions.
4214 FIXME: This could more efficiently implemented as a constant array,
4215 although it would also be less robust. */
4218 select_arm_features (unsigned long mach
,
4219 arm_feature_set
* features
)
4222 #define ARM_FEATURE(ARCH,CEXT) \
4223 features->core = (ARCH); \
4224 features->coproc = (CEXT) | FPU_FPA; \
4229 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4230 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4231 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4232 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4233 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4234 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4235 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4236 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4237 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4238 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4239 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4240 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4241 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4242 /* If the machine type is unknown allow all
4243 architecture types and all extensions. */
4244 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4251 /* NOTE: There are no checks in these routines that
4252 the relevant number of data bytes exist. */
4255 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4260 int is_thumb
= FALSE
;
4261 int is_data
= FALSE
;
4263 unsigned int size
= 4;
4264 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4265 bfd_boolean found
= FALSE
;
4267 if (info
->disassembler_options
)
4269 parse_disassembler_options (info
->disassembler_options
);
4271 /* To avoid repeated parsing of these options, we remove them here. */
4272 info
->disassembler_options
= NULL
;
4275 /* PR 10288: Control which instructions will be disassembled. */
4276 if (info
->private_data
== NULL
)
4278 static arm_feature_set features
;
4280 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4281 /* If the user did not use the -m command line switch then default to
4282 disassembling all types of ARM instruction.
4284 The info->mach value has to be ignored as this will be based on
4285 the default archictecture for the target and/or hints in the notes
4286 section, but it will never be greater than the current largest arm
4287 machine value (iWMMXt2), which is only equivalent to the V5TE
4288 architecture. ARM architectures have advanced beyond the machine
4289 value encoding, and these newer architectures would be ignored if
4290 the machine value was used.
4292 Ie the -m switch is used to restrict which instructions will be
4293 disassembled. If it is necessary to use the -m switch to tell
4294 objdump that an ARM binary is being disassembled, eg because the
4295 input is a raw binary file, but it is also desired to disassemble
4296 all ARM instructions then use "-marm". This will select the
4297 "unknown" arm architecture which is compatible with any ARM
4299 info
->mach
= bfd_mach_arm_unknown
;
4301 /* Compute the architecture bitmask from the machine number.
4302 Note: This assumes that the machine number will not change
4303 during disassembly.... */
4304 select_arm_features (info
->mach
, & features
);
4306 info
->private_data
= & features
;
4309 /* Decide if our code is going to be little-endian, despite what the
4310 function argument might say. */
4311 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4313 /* First check the full symtab for a mapping symbol, even if there
4314 are no usable non-mapping symbols for this address. */
4315 if (info
->symtab_size
!= 0
4316 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4321 enum map_type type
= MAP_ARM
;
4323 if (pc
<= last_mapping_addr
)
4324 last_mapping_sym
= -1;
4325 is_thumb
= (last_type
== MAP_THUMB
);
4327 /* Start scanning at the start of the function, or wherever
4328 we finished last time. */
4329 n
= info
->symtab_pos
+ 1;
4330 if (n
< last_mapping_sym
)
4331 n
= last_mapping_sym
;
4333 /* Scan up to the location being disassembled. */
4334 for (; n
< info
->symtab_size
; n
++)
4336 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4339 if ((info
->section
== NULL
4340 || info
->section
== info
->symtab
[n
]->section
)
4341 && get_sym_code_type (info
, n
, &type
))
4350 n
= info
->symtab_pos
;
4351 if (n
< last_mapping_sym
- 1)
4352 n
= last_mapping_sym
- 1;
4354 /* No mapping symbol found at this address. Look backwards
4355 for a preceeding one. */
4358 if ((info
->section
== NULL
4359 || info
->section
== info
->symtab
[n
]->section
)
4360 && get_sym_code_type (info
, n
, &type
))
4369 last_mapping_sym
= last_sym
;
4371 is_thumb
= (last_type
== MAP_THUMB
);
4372 is_data
= (last_type
== MAP_DATA
);
4374 /* Look a little bit ahead to see if we should print out
4375 two or four bytes of data. If there's a symbol,
4376 mapping or otherwise, after two bytes then don't
4380 size
= 4 - (pc
& 3);
4381 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4383 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4386 if (addr
- pc
< size
)
4391 /* If the next symbol is after three bytes, we need to
4392 print only part of the data, so that we can use either
4395 size
= (pc
& 1) ? 1 : 2;
4399 if (info
->symbols
!= NULL
)
4401 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4403 coff_symbol_type
* cs
;
4405 cs
= coffsymbol (*info
->symbols
);
4406 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4407 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4408 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4409 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4410 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4412 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4415 /* If no mapping symbol has been found then fall back to the type
4416 of the function symbol. */
4417 elf_symbol_type
* es
;
4420 es
= *(elf_symbol_type
**)(info
->symbols
);
4421 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4423 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
4431 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4433 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4435 info
->bytes_per_line
= 4;
4437 /* PR 10263: Disassemble data if requested to do so by the user. */
4438 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4442 /* Size was already set above. */
4443 info
->bytes_per_chunk
= size
;
4444 printer
= print_insn_data
;
4446 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4449 for (i
= size
- 1; i
>= 0; i
--)
4450 given
= b
[i
] | (given
<< 8);
4452 for (i
= 0; i
< (int) size
; i
++)
4453 given
= b
[i
] | (given
<< 8);
4457 /* In ARM mode endianness is a straightforward issue: the instruction
4458 is four bytes long and is either ordered 0123 or 3210. */
4459 printer
= print_insn_arm
;
4460 info
->bytes_per_chunk
= 4;
4463 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4465 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4467 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4471 /* In Thumb mode we have the additional wrinkle of two
4472 instruction lengths. Fortunately, the bits that determine
4473 the length of the current instruction are always to be found
4474 in the first two bytes. */
4475 printer
= print_insn_thumb16
;
4476 info
->bytes_per_chunk
= 2;
4479 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4481 given
= (b
[0]) | (b
[1] << 8);
4483 given
= (b
[1]) | (b
[0] << 8);
4487 /* These bit patterns signal a four-byte Thumb
4489 if ((given
& 0xF800) == 0xF800
4490 || (given
& 0xF800) == 0xF000
4491 || (given
& 0xF800) == 0xE800)
4493 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4495 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4497 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4499 printer
= print_insn_thumb32
;
4504 if (ifthen_address
!= pc
)
4505 find_ifthen_state (pc
, info
, little_code
);
4509 if ((ifthen_state
& 0xf) == 0x8)
4510 ifthen_next_state
= 0;
4512 ifthen_next_state
= (ifthen_state
& 0xe0)
4513 | ((ifthen_state
& 0xf) << 1);
4519 info
->memory_error_func (status
, pc
, info
);
4522 if (info
->flags
& INSN_HAS_RELOC
)
4523 /* If the instruction has a reloc associated with it, then
4524 the offset field in the instruction will actually be the
4525 addend for the reloc. (We are using REL type relocs).
4526 In such cases, we can ignore the pc when computing
4527 addresses, since the addend is not currently pc-relative. */
4530 printer (pc
, info
, given
);
4534 ifthen_state
= ifthen_next_state
;
4535 ifthen_address
+= size
;
4541 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4543 /* Detect BE8-ness and record it in the disassembler info. */
4544 if (info
->flavour
== bfd_target_elf_flavour
4545 && info
->section
!= NULL
4546 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4547 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4549 return print_insn (pc
, info
, FALSE
);
4553 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4555 return print_insn (pc
, info
, TRUE
);
4559 print_arm_disassembler_options (FILE *stream
)
4563 fprintf (stream
, _("\n\
4564 The following ARM specific disassembler options are supported for use with\n\
4565 the -M switch:\n"));
4567 for (i
= NUM_ARM_REGNAMES
; i
--;)
4568 fprintf (stream
, " reg-names-%s %*c%s\n",
4570 (int)(14 - strlen (regnames
[i
].name
)), ' ',
4571 regnames
[i
].description
);
4573 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
4574 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");