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 %C print vstr/vldr address operand
73 %I print cirrus signed shift immediate: bits 0..3|4..6
74 %F print the COUNT field of a LFM/SFM instruction.
75 %P print floating point precision in arithmetic insn
76 %Q print floating point precision in ldf/stf insn
77 %R print floating point rounding mode
79 %<bitfield>r print as an ARM register
80 %<bitfield>d print the bitfield in decimal
81 %<bitfield>k print immediate for VFPv3 conversion instruction
82 %<bitfield>x print the bitfield in hex
83 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
84 %<bitfield>f print a floating point constant if >7 else a
85 floating point register
86 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
87 %<bitfield>g print as an iWMMXt 64-bit register
88 %<bitfield>G print as an iWMMXt general purpose or control register
89 %<bitfield>D print as a NEON D register
90 %<bitfield>Q print as a NEON Q register
92 %y<code> print a single precision VFP reg.
93 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
94 %z<code> print a double precision VFP reg
95 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
97 %<bitfield>'c print specified char iff bitfield is all ones
98 %<bitfield>`c print specified char iff bitfield is all zeroes
99 %<bitfield>?ab... select from array of values in big endian order
101 %L print as an iWMMXt N/M width field.
102 %Z print the Immediate of a WSHUFH instruction.
103 %l like 'A' except use byte offsets for 'B' & 'H'
105 %i print 5-bit immediate in bits 8,3..0
107 %r print register offset address for wldt/wstr instruction. */
109 enum opcode_sentinel_enum
111 SENTINEL_IWMMXT_START
= 1,
113 SENTINEL_GENERIC_START
116 #define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
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\t; (stc%22'l%c %8-11d, cr%12-15d, %A)"},
251 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A\t; (ldc%22'l%c %8-11d, cr%12-15d, %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, %C"},
261 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
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 %b print branch destination
780 %c print condition code (always bits 28-31)
781 %m print register mask for ldm/stm instruction
782 %o print operand2 (immediate or register + shift)
783 %p print 'p' iff bits 12-15 are 15
784 %t print 't' iff bit 21 set and bit 24 clear
785 %B print arm BLX(1) destination
786 %C print the PSR sub type.
787 %U print barrier type.
788 %P print address for pli instruction.
790 %<bitfield>r print as an ARM register
791 %<bitfield>d print the bitfield in decimal
792 %<bitfield>W print the bitfield plus one in decimal
793 %<bitfield>x print the bitfield in hex
794 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
796 %<bitfield>'c print specified char iff bitfield is all ones
797 %<bitfield>`c print specified char iff bitfield is all zeroes
798 %<bitfield>?ab... select from array of values in big endian order
800 %e print arm SMI operand (bits 0..7,8..19).
801 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
802 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
804 static const struct opcode32 arm_opcodes
[] =
806 /* ARM instructions. */
807 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
808 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
809 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
810 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
811 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
812 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
813 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
815 /* V7 instructions. */
816 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
817 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
818 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
819 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
820 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
822 /* ARM V6T2 instructions. */
823 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
824 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
825 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
826 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
827 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
828 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
829 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
830 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
831 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
833 /* ARM V6Z instructions. */
834 {ARM_EXT_V6Z
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
836 /* ARM V6K instructions. */
837 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
838 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
839 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
840 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
841 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
842 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
843 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
845 /* ARM V6K NOP hints. */
846 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
847 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
848 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
849 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
850 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
852 /* ARM V6 instructions. */
853 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
854 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
855 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
856 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
857 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
858 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
859 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
860 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
861 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
862 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
863 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
864 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
865 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
866 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
867 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
869 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
870 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
871 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
900 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
901 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
902 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
903 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
904 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
905 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
906 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
907 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
908 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
909 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
910 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
911 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
912 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
913 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
914 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
915 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
916 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
917 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
918 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
919 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
920 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
921 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
922 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
923 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
924 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
925 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
926 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
927 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
928 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
929 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
930 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
931 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
932 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
933 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
934 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
935 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
936 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
937 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
938 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
939 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
940 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
941 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
942 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
943 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
944 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
945 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
946 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
947 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
948 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
949 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
950 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
951 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
952 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
953 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
954 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
955 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
956 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
957 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
958 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
959 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
960 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
961 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
962 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
963 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
964 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
965 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
966 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
967 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
968 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
969 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
970 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
971 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
972 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
973 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
974 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
976 /* V5J instruction. */
977 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
979 /* V5 Instructions. */
980 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
981 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
982 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
983 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
985 /* V5E "El Segundo" Instructions. */
986 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
987 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
988 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
989 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
990 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
991 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
992 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
994 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
995 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
997 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
998 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
999 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1000 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1002 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1003 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1004 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1005 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1007 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1010 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1011 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1012 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1013 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1015 /* ARM Instructions. */
1016 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1017 {ARM_EXT_V1
, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1018 {ARM_EXT_V1
, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1019 {ARM_EXT_V1
, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1020 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1021 {ARM_EXT_V1
, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
1022 {ARM_EXT_V1
, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
1023 {ARM_EXT_V1
, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
1024 {ARM_EXT_V1
, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1025 {ARM_EXT_V1
, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
1027 {ARM_EXT_V1
, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1028 {ARM_EXT_V1
, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1029 {ARM_EXT_V1
, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
1031 {ARM_EXT_V1
, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1
, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1
, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
1035 {ARM_EXT_V1
, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1036 {ARM_EXT_V1
, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1037 {ARM_EXT_V1
, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
1039 {ARM_EXT_V1
, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1040 {ARM_EXT_V1
, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1041 {ARM_EXT_V1
, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1043 {ARM_EXT_V1
, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1044 {ARM_EXT_V1
, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1045 {ARM_EXT_V1
, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
1047 {ARM_EXT_V1
, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1048 {ARM_EXT_V1
, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1049 {ARM_EXT_V1
, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
1051 {ARM_EXT_V1
, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1052 {ARM_EXT_V1
, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1053 {ARM_EXT_V1
, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1055 {ARM_EXT_V1
, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1
, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1057 {ARM_EXT_V1
, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1059 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1060 {ARM_EXT_V3
, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1062 {ARM_EXT_V1
, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1063 {ARM_EXT_V1
, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1064 {ARM_EXT_V1
, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
1066 {ARM_EXT_V1
, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1067 {ARM_EXT_V1
, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1068 {ARM_EXT_V1
, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
1070 {ARM_EXT_V1
, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1071 {ARM_EXT_V1
, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1072 {ARM_EXT_V1
, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
1074 {ARM_EXT_V1
, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1075 {ARM_EXT_V1
, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1076 {ARM_EXT_V1
, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
1078 {ARM_EXT_V1
, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1079 {ARM_EXT_V1
, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1
, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
1082 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1083 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1084 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1085 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1086 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1087 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1088 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1090 {ARM_EXT_V1
, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1091 {ARM_EXT_V1
, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1
, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
1094 {ARM_EXT_V1
, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1095 {ARM_EXT_V1
, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1096 {ARM_EXT_V1
, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
1098 {ARM_EXT_V1
, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION
},
1099 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1100 {ARM_EXT_V1
, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1101 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1102 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1103 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1104 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1105 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1106 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1107 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1108 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1111 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1112 {0, 0x00000000, 0x00000000, 0}
1115 /* print_insn_thumb16 recognizes the following format control codes:
1117 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1118 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1119 %<bitfield>I print bitfield as a signed decimal
1120 (top bit of range being the sign bit)
1121 %N print Thumb register mask (with LR)
1122 %O print Thumb register mask (with PC)
1123 %M print Thumb register mask
1124 %b print CZB's 6-bit unsigned branch destination
1125 %s print Thumb right-shift immediate (6..10; 0 == 32).
1126 %c print the condition code
1127 %C print the condition code, or "s" if not conditional
1128 %x print warning if conditional an not at end of IT block"
1129 %X print "\t; unpredictable <IT:code>" if conditional
1130 %I print IT instruction suffix and operands
1131 %<bitfield>r print bitfield as an ARM register
1132 %<bitfield>d print bitfield as a decimal
1133 %<bitfield>H print (bitfield * 2) as a decimal
1134 %<bitfield>W print (bitfield * 4) as a decimal
1135 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1136 %<bitfield>B print Thumb branch destination (signed displacement)
1137 %<bitfield>c print bitfield as a condition code
1138 %<bitnum>'c print specified char iff bit is one
1139 %<bitnum>?ab print a if bit is one else print b. */
1141 static const struct opcode16 thumb_opcodes
[] =
1143 /* Thumb instructions. */
1145 /* ARM V6K no-argument instructions. */
1146 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
1147 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
1148 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
1149 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
1150 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
1151 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1153 /* ARM V6T2 instructions. */
1154 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1155 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1156 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
1159 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1160 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1161 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1162 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1163 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1164 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1165 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1166 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1167 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1168 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1169 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1171 /* ARM V5 ISA extends Thumb. */
1172 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1173 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1174 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1175 /* ARM V4T ISA (Thumb v1). */
1176 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1178 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1179 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1180 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1181 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1182 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1183 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1184 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1185 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1186 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1187 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1188 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1189 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1190 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1191 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1192 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1193 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1195 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1196 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1198 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
1199 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
1200 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1201 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1203 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
1204 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
1206 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1207 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1208 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1209 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1211 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1212 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1213 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1215 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1216 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1218 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1219 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1220 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1222 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1223 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1224 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1225 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1227 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1229 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1230 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1231 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1232 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1234 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1235 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1237 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1238 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1240 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1241 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1243 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1244 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1246 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1248 {ARM_EXT_V4T
, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION
},
1249 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1251 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1253 /* The E800 .. FFFF range is unconditionally redirected to the
1254 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1255 are processed via that table. Thus, we can never encounter a
1256 bare "second half of BL/BLX(1)" instruction here. */
1257 {ARM_EXT_V1
, 0x0000, 0x0000, UNDEFINED_INSTRUCTION
},
1261 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1262 We adopt the convention that hw1 is the high 16 bits of .value and
1263 .mask, hw2 the low 16 bits.
1265 print_insn_thumb32 recognizes the following format control codes:
1269 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1270 %M print a modified 12-bit immediate (same location)
1271 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1272 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1273 %S print a possibly-shifted Rm
1275 %a print the address of a plain load/store
1276 %w print the width and signedness of a core load/store
1277 %m print register mask for ldm/stm
1279 %E print the lsb and width fields of a bfc/bfi instruction
1280 %F print the lsb and width fields of a sbfx/ubfx instruction
1281 %b print a conditional branch offset
1282 %B print an unconditional branch offset
1283 %s print the shift field of an SSAT instruction
1284 %R print the rotation field of an SXT instruction
1285 %U print barrier type.
1286 %P print address for pli instruction.
1287 %c print the condition code
1288 %x print warning if conditional an not at end of IT block"
1289 %X print "\t; unpredictable <IT:code>" if conditional
1291 %<bitfield>d print bitfield in decimal
1292 %<bitfield>W print bitfield*4 in decimal
1293 %<bitfield>r print bitfield as an ARM register
1294 %<bitfield>c print bitfield as a condition code
1296 %<bitfield>'c print specified char iff bitfield is all ones
1297 %<bitfield>`c print specified char iff bitfield is all zeroes
1298 %<bitfield>?ab... select from array of values in big endian order
1300 With one exception at the bottom (done because BL and BLX(1) need
1301 to come dead last), this table was machine-sorted first in
1302 decreasing order of number of bits set in the mask, then in
1303 increasing numeric order of mask, then in increasing numeric order
1304 of opcode. This order is not the clearest for a human reader, but
1305 is guaranteed never to catch a special-case bit pattern with a more
1306 general mask, which is important, because this instruction encoding
1307 makes heavy use of special-case bit patterns. */
1308 static const struct opcode32 thumb32_opcodes
[] =
1310 /* V7 instructions. */
1311 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1312 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1313 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1314 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1315 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1316 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1317 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1319 /* Instructions defined in the basic V6T2 set. */
1320 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
1321 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
1322 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1323 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1324 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
1325 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1327 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1328 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1329 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1330 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1331 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1332 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1333 {ARM_EXT_V6T2
, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1334 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1335 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1336 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1337 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1338 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1339 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1340 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1341 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1342 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1343 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1344 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1345 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1346 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1347 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1348 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1349 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1350 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1351 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1352 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1353 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1356 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1358 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1359 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1360 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1361 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1363 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1364 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1365 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1368 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1369 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1370 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1371 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1372 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1373 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1377 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1378 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1379 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1380 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1381 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1382 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1384 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1388 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1389 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1390 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1397 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1398 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1399 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1406 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1407 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1408 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1409 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1413 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1414 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1415 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1416 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1417 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1418 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1420 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1421 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1422 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1423 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1424 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1425 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1426 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1427 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1428 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1429 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1430 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1431 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1432 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1433 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1434 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1440 {ARM_EXT_V6T2
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1441 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1442 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1443 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1444 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1445 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1446 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1447 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1448 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1449 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1452 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1453 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1454 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1455 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1456 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1457 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1459 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1460 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1461 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1462 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1463 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1464 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1465 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1466 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1467 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1468 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1469 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1470 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1471 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1472 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1473 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1474 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1475 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1476 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1477 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1478 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1479 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1480 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1481 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1482 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1483 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1484 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1485 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1486 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1487 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1488 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1489 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1490 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1491 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1492 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1493 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1494 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1495 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1496 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1497 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1498 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1500 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1501 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1502 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1503 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1504 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1506 /* These have been 32-bit since the invention of Thumb. */
1507 {ARM_EXT_V4T
, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1508 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1511 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1515 static const char *const arm_conditional
[] =
1516 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1517 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1519 static const char *const arm_fp_const
[] =
1520 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1522 static const char *const arm_shift
[] =
1523 {"lsl", "lsr", "asr", "ror"};
1528 const char *description
;
1529 const char *reg_names
[16];
1533 static const arm_regname regnames
[] =
1535 { "raw" , "Select raw register names",
1536 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1537 { "gcc", "Select register names used by GCC",
1538 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1539 { "std", "Select register names used in ARM's ISA documentation",
1540 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1541 { "apcs", "Select register names used in the APCS",
1542 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1543 { "atpcs", "Select register names used in the ATPCS",
1544 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1545 { "special-atpcs", "Select special register names used in the ATPCS",
1546 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1549 static const char *const iwmmxt_wwnames
[] =
1550 {"b", "h", "w", "d"};
1552 static const char *const iwmmxt_wwssnames
[] =
1553 {"b", "bus", "bc", "bss",
1554 "h", "hus", "hc", "hss",
1555 "w", "wus", "wc", "wss",
1556 "d", "dus", "dc", "dss"
1559 static const char *const iwmmxt_regnames
[] =
1560 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1561 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1564 static const char *const iwmmxt_cregnames
[] =
1565 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1566 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1569 /* Default to GCC register name set. */
1570 static unsigned int regname_selected
= 1;
1572 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1573 #define arm_regnames regnames[regname_selected].reg_names
1575 static bfd_boolean force_thumb
= FALSE
;
1577 /* Current IT instruction state. This contains the same state as the IT
1578 bits in the CPSR. */
1579 static unsigned int ifthen_state
;
1580 /* IT state for the next instruction. */
1581 static unsigned int ifthen_next_state
;
1582 /* The address of the insn for which the IT state is valid. */
1583 static bfd_vma ifthen_address
;
1584 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1586 /* Cached mapping symbol state. */
1594 enum map_type last_type
;
1595 int last_mapping_sym
= -1;
1596 bfd_vma last_mapping_addr
= 0;
1601 get_arm_regname_num_options (void)
1603 return NUM_ARM_REGNAMES
;
1607 set_arm_regname_option (int option
)
1609 int old
= regname_selected
;
1610 regname_selected
= option
;
1615 get_arm_regnames (int option
,
1616 const char **setname
,
1617 const char **setdescription
,
1618 const char *const **register_names
)
1620 *setname
= regnames
[option
].name
;
1621 *setdescription
= regnames
[option
].description
;
1622 *register_names
= regnames
[option
].reg_names
;
1626 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1627 Returns pointer to following character of the format string and
1628 fills in *VALUEP and *WIDTHP with the extracted value and number of
1629 bits extracted. WIDTHP can be NULL. */
1632 arm_decode_bitfield (const char *ptr
,
1634 unsigned long *valuep
,
1637 unsigned long value
= 0;
1645 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1646 start
= start
* 10 + *ptr
- '0';
1648 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1649 end
= end
* 10 + *ptr
- '0';
1655 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
1658 while (*ptr
++ == ',');
1666 arm_decode_shift (long given
, fprintf_ftype func
, void *stream
,
1667 bfd_boolean print_shift
)
1669 func (stream
, "%s", arm_regnames
[given
& 0xf]);
1671 if ((given
& 0xff0) != 0)
1673 if ((given
& 0x10) == 0)
1675 int amount
= (given
& 0xf80) >> 7;
1676 int shift
= (given
& 0x60) >> 5;
1682 func (stream
, ", rrx");
1690 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
1692 func (stream
, ", #%d", amount
);
1694 else if ((given
& 0x80) == 0x80)
1695 func (stream
, ", <illegal shifter operand>");
1696 else if (print_shift
)
1697 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
1698 arm_regnames
[(given
& 0xf00) >> 8]);
1700 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
1704 /* Print one coprocessor instruction on INFO->STREAM.
1705 Return TRUE if the instuction matched, FALSE if this is not a
1706 recognised coprocessor instruction. */
1709 print_insn_coprocessor (bfd_vma pc
,
1710 struct disassemble_info
*info
,
1714 const struct opcode32
*insn
;
1715 void *stream
= info
->stream
;
1716 fprintf_ftype func
= info
->fprintf_func
;
1718 unsigned long value
;
1719 unsigned long allowed_arches
= ((arm_feature_set
*) info
->private_data
)->coproc
;
1722 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
1724 signed long value_in_comment
= 0;
1727 if (insn
->arch
== 0)
1728 switch (insn
->value
)
1730 case SENTINEL_IWMMXT_START
:
1731 if (info
->mach
!= bfd_mach_arm_XScale
1732 && info
->mach
!= bfd_mach_arm_iWMMXt
1733 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
1736 while (insn
->arch
!= 0 && insn
->value
!= SENTINEL_IWMMXT_END
);
1739 case SENTINEL_IWMMXT_END
:
1742 case SENTINEL_GENERIC_START
:
1743 allowed_arches
= ((arm_feature_set
*) info
->private_data
)->core
;
1751 value
= insn
->value
;
1754 /* The high 4 bits are 0xe for Arm conditional instructions, and
1755 0xe for arm unconditional instructions. The rest of the
1756 encoding is the same. */
1758 value
|= 0xe0000000;
1766 /* Only match unconditional instuctions against unconditional
1768 if ((given
& 0xf0000000) == 0xf0000000)
1775 cond
= (given
>> 28) & 0xf;
1781 if ((given
& mask
) != value
)
1784 if ((insn
->arch
& allowed_arches
) == 0)
1787 for (c
= insn
->assembler
; *c
; c
++)
1794 func (stream
, "%%");
1799 int offset
= given
& 0xff;
1801 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
1803 value_in_comment
= offset
* 4;
1804 if ((given
& 0x00800000) == 0)
1805 value_in_comment
= - value_in_comment
;
1807 if ((given
& (1 << 24)) != 0)
1810 func (stream
, ", #%d]%s",
1812 ((given
& 0x00200000) != 0 ? "!" : ""));
1820 if (given
& (1 << 21))
1823 func (stream
, ", #%d", value_in_comment
);
1827 func (stream
, ", {%d}", offset
);
1828 value_in_comment
= offset
;
1836 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
1837 int offset
= (given
>> 1) & 0x3f;
1840 func (stream
, "{d%d}", regno
);
1841 else if (regno
+ offset
> 32)
1842 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
1844 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
1850 int rn
= (given
>> 16) & 0xf;
1851 int offset
= (given
& 0xff) * 4;
1852 int add
= (given
>> 23) & 1;
1854 func (stream
, "[%s", arm_regnames
[rn
]);
1860 func (stream
, ", #%d", offset
);
1862 value_in_comment
= offset
;
1867 func (stream
, "\t; ");
1868 /* FIXME: Unsure if info->bytes_per_chunk is the
1869 right thing to use here. */
1870 info
->print_address_func (offset
+ pc
1871 + info
->bytes_per_chunk
* 2, info
);
1877 func (stream
, "%s", arm_conditional
[cond
]);
1881 /* Print a Cirrus/DSP shift immediate. */
1882 /* Immediates are 7bit signed ints with bits 0..3 in
1883 bits 0..3 of opcode and bits 4..6 in bits 5..7
1888 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
1890 /* Is ``imm'' a negative number? */
1894 func (stream
, "%d", imm
);
1900 switch (given
& 0x00408000)
1917 switch (given
& 0x00080080)
1929 func (stream
, _("<illegal precision>"));
1935 switch (given
& 0x00408000)
1953 switch (given
& 0x60)
1969 case '0': case '1': case '2': case '3': case '4':
1970 case '5': case '6': case '7': case '8': case '9':
1973 unsigned long value
;
1975 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
1980 func (stream
, "%s", arm_regnames
[value
]);
1983 func (stream
, "d%ld", value
);
1987 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
1989 func (stream
, "q%ld", value
>> 1);
1992 func (stream
, "%ld", value
);
1993 value_in_comment
= value
;
1997 int from
= (given
& (1 << 7)) ? 32 : 16;
1998 func (stream
, "%ld", from
- value
);
2004 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2006 func (stream
, "f%ld", value
);
2011 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2013 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2017 func (stream
, "%s", iwmmxt_regnames
[value
]);
2020 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2024 func (stream
, "0x%lx", (value
& 0xffffffffUL
));
2030 func (stream
, "%c", *c
);
2034 if (value
== ((1ul << width
) - 1))
2035 func (stream
, "%c", *c
);
2038 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2049 int single
= *c
++ == 'y';
2054 case '4': /* Sm pair */
2055 case '0': /* Sm, Dm */
2056 regno
= given
& 0x0000000f;
2060 regno
+= (given
>> 5) & 1;
2063 regno
+= ((given
>> 5) & 1) << 4;
2066 case '1': /* Sd, Dd */
2067 regno
= (given
>> 12) & 0x0000000f;
2071 regno
+= (given
>> 22) & 1;
2074 regno
+= ((given
>> 22) & 1) << 4;
2077 case '2': /* Sn, Dn */
2078 regno
= (given
>> 16) & 0x0000000f;
2082 regno
+= (given
>> 7) & 1;
2085 regno
+= ((given
>> 7) & 1) << 4;
2088 case '3': /* List */
2090 regno
= (given
>> 12) & 0x0000000f;
2094 regno
+= (given
>> 22) & 1;
2097 regno
+= ((given
>> 22) & 1) << 4;
2104 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2108 int count
= given
& 0xff;
2115 func (stream
, "-%c%d",
2123 func (stream
, ", %c%d", single
? 's' : 'd',
2129 switch (given
& 0x00400100)
2131 case 0x00000000: func (stream
, "b"); break;
2132 case 0x00400000: func (stream
, "h"); break;
2133 case 0x00000100: func (stream
, "w"); break;
2134 case 0x00400100: func (stream
, "d"); break;
2143 /* given (20, 23) | given (0, 3) */
2144 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
2145 func (stream
, "%d", value
);
2150 /* This is like the 'A' operator, except that if
2151 the width field "M" is zero, then the offset is
2152 *not* multiplied by four. */
2154 int offset
= given
& 0xff;
2155 int multiplier
= (given
& 0x00000100) ? 4 : 1;
2157 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2161 value_in_comment
= offset
* multiplier
;
2162 if ((given
& 0x00800000) == 0)
2163 value_in_comment
= - value_in_comment
;
2168 if ((given
& 0x01000000) != 0)
2169 func (stream
, ", #%s%d]%s",
2170 ((given
& 0x00800000) == 0 ? "-" : ""),
2171 offset
* multiplier
,
2172 ((given
& 0x00200000) != 0 ? "!" : ""));
2174 func (stream
, "], #%s%d",
2175 ((given
& 0x00800000) == 0 ? "-" : ""),
2176 offset
* multiplier
);
2185 int imm4
= (given
>> 4) & 0xf;
2186 int puw_bits
= ((given
>> 22) & 6) | ((given
>> 21) & 1);
2187 int ubit
= (given
>> 23) & 1;
2188 const char *rm
= arm_regnames
[given
& 0xf];
2189 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
2195 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
2197 func (stream
, ", lsl #%d", imm4
);
2204 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
2206 func (stream
, ", lsl #%d", imm4
);
2208 if (puw_bits
== 5 || puw_bits
== 7)
2213 func (stream
, "INVALID");
2221 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
2222 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
2232 func (stream
, "%c", *c
);
2235 if (value_in_comment
> 32 || value_in_comment
< -16)
2236 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
2243 /* Decodes and prints ARM addressing modes. Returns the offset
2244 used in the address, if any, if it is worthwhile printing the
2245 offset as a hexadecimal value in a comment at the end of the
2246 line of disassembly. */
2249 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2251 void *stream
= info
->stream
;
2252 fprintf_ftype func
= info
->fprintf_func
;
2255 if (((given
& 0x000f0000) == 0x000f0000)
2256 && ((given
& 0x02000000) == 0))
2258 offset
= given
& 0xfff;
2260 func (stream
, "[pc");
2262 if (given
& 0x01000000)
2264 if ((given
& 0x00800000) == 0)
2268 func (stream
, ", #%d]", offset
);
2272 /* Cope with the possibility of write-back
2273 being used. Probably a very dangerous thing
2274 for the programmer to do, but who are we to
2276 if (given
& 0x00200000)
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]);
2296 if ((given
& 0x01000000) != 0)
2298 if ((given
& 0x02000000) == 0)
2300 offset
= given
& 0xfff;
2302 func (stream
, ", #%s%d",
2303 (((given
& 0x00800000) == 0)
2304 ? "-" : ""), offset
);
2308 func (stream
, ", %s",
2309 (((given
& 0x00800000) == 0)
2311 arm_decode_shift (given
, func
, stream
, TRUE
);
2314 func (stream
, "]%s",
2315 ((given
& 0x00200000) != 0) ? "!" : "");
2319 if ((given
& 0x02000000) == 0)
2321 offset
= given
& 0xfff;
2323 func (stream
, "], #%s%d",
2324 (((given
& 0x00800000) == 0)
2325 ? "-" : ""), offset
);
2331 func (stream
, "], %s",
2332 (((given
& 0x00800000) == 0)
2334 arm_decode_shift (given
, func
, stream
, TRUE
);
2339 return (signed long) offset
;
2342 /* Print one neon instruction on INFO->STREAM.
2343 Return TRUE if the instuction matched, FALSE if this is not a
2344 recognised neon instruction. */
2347 print_insn_neon (struct disassemble_info
*info
, long given
, bfd_boolean thumb
)
2349 const struct opcode32
*insn
;
2350 void *stream
= info
->stream
;
2351 fprintf_ftype func
= info
->fprintf_func
;
2355 if ((given
& 0xef000000) == 0xef000000)
2357 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2358 unsigned long bit28
= given
& (1 << 28);
2360 given
&= 0x00ffffff;
2362 given
|= 0xf3000000;
2364 given
|= 0xf2000000;
2366 else if ((given
& 0xff000000) == 0xf9000000)
2367 given
^= 0xf9000000 ^ 0xf4000000;
2372 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
2374 if ((given
& insn
->mask
) == insn
->value
)
2376 signed long value_in_comment
= 0;
2379 for (c
= insn
->assembler
; *c
; c
++)
2386 func (stream
, "%%");
2390 if (thumb
&& ifthen_state
)
2391 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
2396 static const unsigned char enc
[16] =
2398 0x4, 0x14, /* st4 0,1 */
2410 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2411 int rn
= ((given
>> 16) & 0xf);
2412 int rm
= ((given
>> 0) & 0xf);
2413 int align
= ((given
>> 4) & 0x3);
2414 int type
= ((given
>> 8) & 0xf);
2415 int n
= enc
[type
] & 0xf;
2416 int stride
= (enc
[type
] >> 4) + 1;
2421 for (ix
= 0; ix
!= n
; ix
++)
2422 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
2424 func (stream
, "d%d", rd
);
2426 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
2427 func (stream
, "}, [%s", arm_regnames
[rn
]);
2429 func (stream
, ", :%d", 32 << align
);
2434 func (stream
, ", %s", arm_regnames
[rm
]);
2440 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2441 int rn
= ((given
>> 16) & 0xf);
2442 int rm
= ((given
>> 0) & 0xf);
2443 int idx_align
= ((given
>> 4) & 0xf);
2445 int size
= ((given
>> 10) & 0x3);
2446 int idx
= idx_align
>> (size
+ 1);
2447 int length
= ((given
>> 8) & 3) + 1;
2451 if (length
> 1 && size
> 0)
2452 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
2458 int amask
= (1 << size
) - 1;
2459 if ((idx_align
& (1 << size
)) != 0)
2463 if ((idx_align
& amask
) == amask
)
2465 else if ((idx_align
& amask
) != 0)
2472 if (size
== 2 && (idx_align
& 2) != 0)
2474 align
= (idx_align
& 1) ? 16 << size
: 0;
2478 if ((size
== 2 && (idx_align
& 3) != 0)
2479 || (idx_align
& 1) != 0)
2486 if ((idx_align
& 3) == 3)
2488 align
= (idx_align
& 3) * 64;
2491 align
= (idx_align
& 1) ? 32 << size
: 0;
2499 for (i
= 0; i
< length
; i
++)
2500 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
2501 rd
+ i
* stride
, idx
);
2502 func (stream
, "}, [%s", arm_regnames
[rn
]);
2504 func (stream
, ", :%d", align
);
2509 func (stream
, ", %s", arm_regnames
[rm
]);
2515 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2516 int rn
= ((given
>> 16) & 0xf);
2517 int rm
= ((given
>> 0) & 0xf);
2518 int align
= ((given
>> 4) & 0x1);
2519 int size
= ((given
>> 6) & 0x3);
2520 int type
= ((given
>> 8) & 0x3);
2522 int stride
= ((given
>> 5) & 0x1);
2525 if (stride
&& (n
== 1))
2532 for (ix
= 0; ix
!= n
; ix
++)
2533 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
2535 func (stream
, "d%d[]", rd
);
2537 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
2538 func (stream
, "}, [%s", arm_regnames
[rn
]);
2541 int align
= (8 * (type
+ 1)) << size
;
2543 align
= (size
> 1) ? align
>> 1 : align
;
2544 if (type
== 2 || (type
== 0 && !size
))
2545 func (stream
, ", :<bad align %d>", align
);
2547 func (stream
, ", :%d", align
);
2553 func (stream
, ", %s", arm_regnames
[rm
]);
2559 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
2560 int size
= (given
>> 20) & 3;
2561 int reg
= raw_reg
& ((4 << size
) - 1);
2562 int ix
= raw_reg
>> size
>> 2;
2564 func (stream
, "d%d[%d]", reg
, ix
);
2569 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2572 int cmode
= (given
>> 8) & 0xf;
2573 int op
= (given
>> 5) & 0x1;
2574 unsigned long value
= 0, hival
= 0;
2579 bits
|= ((given
>> 24) & 1) << 7;
2580 bits
|= ((given
>> 16) & 7) << 4;
2581 bits
|= ((given
>> 0) & 15) << 0;
2585 shift
= (cmode
>> 1) & 3;
2586 value
= (unsigned long) bits
<< (8 * shift
);
2589 else if (cmode
< 12)
2591 shift
= (cmode
>> 1) & 1;
2592 value
= (unsigned long) bits
<< (8 * shift
);
2595 else if (cmode
< 14)
2597 shift
= (cmode
& 1) + 1;
2598 value
= (unsigned long) bits
<< (8 * shift
);
2599 value
|= (1ul << (8 * shift
)) - 1;
2602 else if (cmode
== 14)
2606 /* Bit replication into bytes. */
2612 for (ix
= 7; ix
>= 0; ix
--)
2614 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
2616 value
= (value
<< 8) | mask
;
2618 hival
= (hival
<< 8) | mask
;
2624 /* Byte replication. */
2625 value
= (unsigned long) bits
;
2631 /* Floating point encoding. */
2634 value
= (unsigned long) (bits
& 0x7f) << 19;
2635 value
|= (unsigned long) (bits
& 0x80) << 24;
2636 tmp
= bits
& 0x40 ? 0x3c : 0x40;
2637 value
|= (unsigned long) tmp
<< 24;
2643 func (stream
, "<illegal constant %.8x:%x:%x>",
2651 func (stream
, "#%ld\t; 0x%.2lx", value
, value
);
2655 func (stream
, "#%ld\t; 0x%.4lx", value
, value
);
2661 unsigned char valbytes
[4];
2664 /* Do this a byte at a time so we don't have to
2665 worry about the host's endianness. */
2666 valbytes
[0] = value
& 0xff;
2667 valbytes
[1] = (value
>> 8) & 0xff;
2668 valbytes
[2] = (value
>> 16) & 0xff;
2669 valbytes
[3] = (value
>> 24) & 0xff;
2671 floatformat_to_double
2672 (&floatformat_ieee_single_little
, valbytes
,
2675 func (stream
, "#%.7g\t; 0x%.8lx", fvalue
,
2679 func (stream
, "#%ld\t; 0x%.8lx",
2680 (long) ((value
& 0x80000000)
2681 ? value
| ~0xffffffffl
: value
), value
);
2685 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
2696 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
2697 int num
= (given
>> 8) & 0x3;
2700 func (stream
, "{d%d}", regno
);
2701 else if (num
+ regno
>= 32)
2702 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
2704 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
2709 case '0': case '1': case '2': case '3': case '4':
2710 case '5': case '6': case '7': case '8': case '9':
2713 unsigned long value
;
2715 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2720 func (stream
, "%s", arm_regnames
[value
]);
2723 func (stream
, "%ld", value
);
2724 value_in_comment
= value
;
2727 func (stream
, "%ld", (1ul << width
) - value
);
2733 /* Various width encodings. */
2735 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
2740 if (*c
>= '0' && *c
<= '9')
2742 else if (*c
>= 'a' && *c
<= 'f')
2743 limit
= *c
- 'a' + 10;
2749 if (value
< low
|| value
> high
)
2750 func (stream
, "<illegal width %d>", base
<< value
);
2752 func (stream
, "%d", base
<< value
);
2756 if (given
& (1 << 6))
2760 func (stream
, "d%ld", value
);
2765 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2767 func (stream
, "q%ld", value
>> 1);
2773 func (stream
, "%c", *c
);
2777 if (value
== ((1ul << width
) - 1))
2778 func (stream
, "%c", *c
);
2781 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2795 func (stream
, "%c", *c
);
2798 if (value_in_comment
> 32 || value_in_comment
< -16)
2799 func (stream
, "\t; 0x%lx", value_in_comment
);
2807 /* Print one ARM instruction from PC on INFO->STREAM. */
2810 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2812 const struct opcode32
*insn
;
2813 void *stream
= info
->stream
;
2814 fprintf_ftype func
= info
->fprintf_func
;
2816 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
2819 if (print_insn_neon (info
, given
, FALSE
))
2822 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
2824 if ((given
& insn
->mask
) != insn
->value
)
2827 if ((insn
->arch
& ((arm_feature_set
*) info
->private_data
)->core
) == 0)
2830 /* Special case: an instruction with all bits set in the condition field
2831 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2832 or by the catchall at the end of the table. */
2833 if ((given
& 0xF0000000) != 0xF0000000
2834 || (insn
->mask
& 0xF0000000) == 0xF0000000
2835 || (insn
->mask
== 0 && insn
->value
== 0))
2837 signed long value_in_comment
= 0;
2840 for (c
= insn
->assembler
; *c
; c
++)
2847 func (stream
, "%%");
2851 value_in_comment
= print_arm_address (pc
, info
, given
);
2855 /* Set P address bit and use normal address
2856 printing routine. */
2857 value_in_comment
= print_arm_address (pc
, info
, given
| (1 << 24));
2861 if ((given
& 0x004f0000) == 0x004f0000)
2863 /* PC relative with immediate offset. */
2864 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2866 if ((given
& 0x00800000) == 0)
2869 func (stream
, "[pc, #%d]\t; ", offset
);
2870 info
->print_address_func (offset
+ pc
+ 8, info
);
2874 bfd_boolean negative
= (given
& 0x00800000) == 0;
2875 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2880 func (stream
, "[%s",
2881 arm_regnames
[(given
>> 16) & 0xf]);
2883 if ((given
& 0x01000000) != 0)
2886 if ((given
& 0x00400000) == 0x00400000)
2890 func (stream
, ", #%d", offset
);
2891 value_in_comment
= offset
;
2896 func (stream
, ", %s%s", negative
? "-" : "",
2897 arm_regnames
[given
& 0xf]);
2900 func (stream
, "]%s",
2901 ((given
& 0x00200000) != 0) ? "!" : "");
2906 if ((given
& 0x00400000) == 0x00400000)
2910 func (stream
, "], #%d", offset
);
2914 value_in_comment
= offset
;
2919 func (stream
, "], %s%s", negative
? "-" : "",
2920 arm_regnames
[given
& 0xf]);
2928 int disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
2929 info
->print_address_func (disp
* 4 + pc
+ 8, info
);
2934 if (((given
>> 28) & 0xf) != 0xe)
2936 arm_conditional
[(given
>> 28) & 0xf]);
2945 for (reg
= 0; reg
< 16; reg
++)
2946 if ((given
& (1 << reg
)) != 0)
2949 func (stream
, ", ");
2951 func (stream
, "%s", arm_regnames
[reg
]);
2958 arm_decode_shift (given
, func
, stream
, FALSE
);
2962 if ((given
& 0x02000000) != 0)
2964 int rotate
= (given
& 0xf00) >> 7;
2965 int immed
= (given
& 0xff);
2967 immed
= (((immed
<< (32 - rotate
))
2968 | (immed
>> rotate
)) & 0xffffffff);
2969 func (stream
, "#%d", immed
);
2970 value_in_comment
= immed
;
2973 arm_decode_shift (given
, func
, stream
, TRUE
);
2977 if ((given
& 0x0000f000) == 0x0000f000)
2982 if ((given
& 0x01200000) == 0x00200000)
2988 int offset
= given
& 0xff;
2990 value_in_comment
= offset
* 4;
2991 if ((given
& 0x00800000) == 0)
2992 value_in_comment
= - value_in_comment
;
2994 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2996 if ((given
& (1 << 24)) != 0)
2999 func (stream
, ", #%d]%s",
3001 ((given
& 0x00200000) != 0 ? "!" : ""));
3009 if (given
& (1 << 21))
3012 func (stream
, ", #%d", value_in_comment
);
3016 func (stream
, ", {%d}", offset
);
3017 value_in_comment
= offset
;
3024 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3029 if (given
& 0x00800000)
3030 /* Is signed, hi bits should be ones. */
3031 offset
= (-1) ^ 0x00ffffff;
3033 /* Offset is (SignExtend(offset field)<<2). */
3034 offset
+= given
& 0x00ffffff;
3036 address
= offset
+ pc
+ 8;
3038 if (given
& 0x01000000)
3039 /* H bit allows addressing to 2-byte boundaries. */
3042 info
->print_address_func (address
, info
);
3048 if (given
& 0x80000)
3050 if (given
& 0x40000)
3052 if (given
& 0x20000)
3054 if (given
& 0x10000)
3059 switch (given
& 0xf)
3061 case 0xf: func (stream
, "sy"); break;
3062 case 0x7: func (stream
, "un"); break;
3063 case 0xe: func (stream
, "st"); break;
3064 case 0x6: func (stream
, "unst"); break;
3066 func (stream
, "#%d", (int) given
& 0xf);
3071 case '0': case '1': case '2': case '3': case '4':
3072 case '5': case '6': case '7': case '8': case '9':
3075 unsigned long value
;
3077 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3082 func (stream
, "%s", arm_regnames
[value
]);
3085 func (stream
, "%ld", value
);
3086 value_in_comment
= value
;
3089 func (stream
, "%ld", value
* 8);
3090 value_in_comment
= value
* 8;
3093 func (stream
, "%ld", value
+ 1);
3094 value_in_comment
= value
+ 1;
3097 func (stream
, "0x%08lx", value
);
3099 /* Some SWI instructions have special
3101 if ((given
& 0x0fffffff) == 0x0FF00000)
3102 func (stream
, "\t; IMB");
3103 else if ((given
& 0x0fffffff) == 0x0FF00001)
3104 func (stream
, "\t; IMBRange");
3107 func (stream
, "%01lx", value
& 0xf);
3108 value_in_comment
= value
;
3113 func (stream
, "%c", *c
);
3117 if (value
== ((1ul << width
) - 1))
3118 func (stream
, "%c", *c
);
3121 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3133 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3134 func (stream
, "%d", imm
);
3135 value_in_comment
= imm
;
3140 /* LSB and WIDTH fields of BFI or BFC. The machine-
3141 language instruction encodes LSB and MSB. */
3143 long msb
= (given
& 0x001f0000) >> 16;
3144 long lsb
= (given
& 0x00000f80) >> 7;
3145 long width
= msb
- lsb
+ 1;
3148 func (stream
, "#%lu, #%lu", lsb
, width
);
3150 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3155 /* 16-bit unsigned immediate from a MOVT or MOVW
3156 instruction, encoded in bits 0:11 and 15:19. */
3158 long hi
= (given
& 0x000f0000) >> 4;
3159 long lo
= (given
& 0x00000fff);
3160 long imm16
= hi
| lo
;
3162 func (stream
, "#%lu", imm16
);
3163 value_in_comment
= imm16
;
3173 func (stream
, "%c", *c
);
3176 if (value_in_comment
> 32 || value_in_comment
< -16)
3177 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3184 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3187 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3189 const struct opcode16
*insn
;
3190 void *stream
= info
->stream
;
3191 fprintf_ftype func
= info
->fprintf_func
;
3193 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3194 if ((given
& insn
->mask
) == insn
->value
)
3196 signed long value_in_comment
= 0;
3197 const char *c
= insn
->assembler
;
3206 func (stream
, "%c", *c
);
3213 func (stream
, "%%");
3218 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3223 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3232 ifthen_next_state
= given
& 0xff;
3233 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3234 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3235 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3240 if (ifthen_next_state
)
3241 func (stream
, "\t; unpredictable branch in IT block\n");
3246 func (stream
, "\t; unpredictable <IT:%s>",
3247 arm_conditional
[IFTHEN_COND
]);
3254 reg
= (given
>> 3) & 0x7;
3255 if (given
& (1 << 6))
3258 func (stream
, "%s", arm_regnames
[reg
]);
3267 if (given
& (1 << 7))
3270 func (stream
, "%s", arm_regnames
[reg
]);
3275 if (given
& (1 << 8))
3279 if (*c
== 'O' && (given
& (1 << 8)))
3289 /* It would be nice if we could spot
3290 ranges, and generate the rS-rE format: */
3291 for (reg
= 0; (reg
< 8); reg
++)
3292 if ((given
& (1 << reg
)) != 0)
3295 func (stream
, ", ");
3297 func (stream
, "%s", arm_regnames
[reg
]);
3303 func (stream
, ", ");
3305 func (stream
, arm_regnames
[14] /* "lr" */);
3311 func (stream
, ", ");
3312 func (stream
, arm_regnames
[15] /* "pc" */);
3320 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3322 bfd_vma address
= (pc
+ 4
3323 + ((given
& 0x00f8) >> 2)
3324 + ((given
& 0x0200) >> 3));
3325 info
->print_address_func (address
, info
);
3330 /* Right shift immediate -- bits 6..10; 1-31 print
3331 as themselves, 0 prints as 32. */
3333 long imm
= (given
& 0x07c0) >> 6;
3336 func (stream
, "#%ld", imm
);
3340 case '0': case '1': case '2': case '3': case '4':
3341 case '5': case '6': case '7': case '8': case '9':
3343 int bitstart
= *c
++ - '0';
3346 while (*c
>= '0' && *c
<= '9')
3347 bitstart
= (bitstart
* 10) + *c
++ - '0';
3356 while (*c
>= '0' && *c
<= '9')
3357 bitend
= (bitend
* 10) + *c
++ - '0';
3360 reg
= given
>> bitstart
;
3361 reg
&= (2 << (bitend
- bitstart
)) - 1;
3365 func (stream
, "%s", arm_regnames
[reg
]);
3369 func (stream
, "%ld", reg
);
3370 value_in_comment
= reg
;
3374 func (stream
, "%ld", reg
<< 1);
3375 value_in_comment
= reg
<< 1;
3379 func (stream
, "%ld", reg
<< 2);
3380 value_in_comment
= reg
<< 2;
3384 /* PC-relative address -- the bottom two
3385 bits of the address are dropped
3386 before the calculation. */
3387 info
->print_address_func
3388 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3389 value_in_comment
= 0;
3393 func (stream
, "0x%04lx", reg
);
3397 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3398 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3399 value_in_comment
= 0;
3403 func (stream
, "%s", arm_conditional
[reg
]);
3414 if ((given
& (1 << bitstart
)) != 0)
3415 func (stream
, "%c", *c
);
3420 if ((given
& (1 << bitstart
)) != 0)
3421 func (stream
, "%c", *c
++);
3423 func (stream
, "%c", *++c
);
3437 if (value_in_comment
> 32 || value_in_comment
< -16)
3438 func (stream
, "\t; 0x%lx", value_in_comment
);
3446 /* Return the name of an V7M special register. */
3449 psr_name (int regno
)
3453 case 0: return "APSR";
3454 case 1: return "IAPSR";
3455 case 2: return "EAPSR";
3456 case 3: return "PSR";
3457 case 5: return "IPSR";
3458 case 6: return "EPSR";
3459 case 7: return "IEPSR";
3460 case 8: return "MSP";
3461 case 9: return "PSP";
3462 case 16: return "PRIMASK";
3463 case 17: return "BASEPRI";
3464 case 18: return "BASEPRI_MASK";
3465 case 19: return "FAULTMASK";
3466 case 20: return "CONTROL";
3467 default: return "<unknown>";
3471 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3474 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3476 const struct opcode32
*insn
;
3477 void *stream
= info
->stream
;
3478 fprintf_ftype func
= info
->fprintf_func
;
3480 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3483 if (print_insn_neon (info
, given
, TRUE
))
3486 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3487 if ((given
& insn
->mask
) == insn
->value
)
3489 signed long value_in_comment
= 0;
3490 const char *c
= insn
->assembler
;
3496 func (stream
, "%c", *c
);
3503 func (stream
, "%%");
3508 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3512 if (ifthen_next_state
)
3513 func (stream
, "\t; unpredictable branch in IT block\n");
3518 func (stream
, "\t; unpredictable <IT:%s>",
3519 arm_conditional
[IFTHEN_COND
]);
3524 unsigned int imm12
= 0;
3526 imm12
|= (given
& 0x000000ffu
);
3527 imm12
|= (given
& 0x00007000u
) >> 4;
3528 imm12
|= (given
& 0x04000000u
) >> 15;
3529 func (stream
, "#%u", imm12
);
3530 value_in_comment
= imm12
;
3536 unsigned int bits
= 0, imm
, imm8
, mod
;
3538 bits
|= (given
& 0x000000ffu
);
3539 bits
|= (given
& 0x00007000u
) >> 4;
3540 bits
|= (given
& 0x04000000u
) >> 15;
3541 imm8
= (bits
& 0x0ff);
3542 mod
= (bits
& 0xf00) >> 8;
3545 case 0: imm
= imm8
; break;
3546 case 1: imm
= ((imm8
<<16) | imm8
); break;
3547 case 2: imm
= ((imm8
<<24) | (imm8
<< 8)); break;
3548 case 3: imm
= ((imm8
<<24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3550 mod
= (bits
& 0xf80) >> 7;
3551 imm8
= (bits
& 0x07f) | 0x80;
3552 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3554 func (stream
, "#%u", imm
);
3555 value_in_comment
= imm
;
3561 unsigned int imm
= 0;
3563 imm
|= (given
& 0x000000ffu
);
3564 imm
|= (given
& 0x00007000u
) >> 4;
3565 imm
|= (given
& 0x04000000u
) >> 15;
3566 imm
|= (given
& 0x000f0000u
) >> 4;
3567 func (stream
, "#%u", imm
);
3568 value_in_comment
= imm
;
3574 unsigned int imm
= 0;
3576 imm
|= (given
& 0x000f0000u
) >> 16;
3577 imm
|= (given
& 0x00000ff0u
) >> 0;
3578 imm
|= (given
& 0x0000000fu
) << 12;
3579 func (stream
, "#%u", imm
);
3580 value_in_comment
= imm
;
3586 unsigned int reg
= (given
& 0x0000000fu
);
3587 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3588 unsigned int imm
= 0;
3589 imm
|= (given
& 0x000000c0u
) >> 6;
3590 imm
|= (given
& 0x00007000u
) >> 10;
3592 func (stream
, "%s", arm_regnames
[reg
]);
3597 func (stream
, ", lsl #%u", imm
);
3603 func (stream
, ", lsr #%u", imm
);
3609 func (stream
, ", asr #%u", imm
);
3614 func (stream
, ", rrx");
3616 func (stream
, ", ror #%u", imm
);
3623 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3624 unsigned int U
= (given
& 0x00800000) >> 23;
3625 unsigned int op
= (given
& 0x00000f00) >> 8;
3626 unsigned int i12
= (given
& 0x00000fff);
3627 unsigned int i8
= (given
& 0x000000ff);
3628 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3631 func (stream
, "[%s", arm_regnames
[Rn
]);
3632 if (U
) /* 12-bit positive immediate offset. */
3636 value_in_comment
= offset
;
3638 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3639 offset
= - (int) i12
;
3640 else if (op
== 0x0) /* Shifted register offset. */
3642 unsigned int Rm
= (i8
& 0x0f);
3643 unsigned int sh
= (i8
& 0x30) >> 4;
3645 func (stream
, ", %s", arm_regnames
[Rm
]);
3647 func (stream
, ", lsl #%u", sh
);
3653 case 0xE: /* 8-bit positive immediate offset. */
3657 case 0xC: /* 8-bit negative immediate offset. */
3661 case 0xF: /* 8-bit + preindex with wb. */
3666 case 0xD: /* 8-bit - preindex with wb. */
3671 case 0xB: /* 8-bit + postindex. */
3676 case 0x9: /* 8-bit - postindex. */
3682 func (stream
, ", <undefined>]");
3687 func (stream
, "], #%d", offset
);
3691 func (stream
, ", #%d", offset
);
3692 func (stream
, writeback
? "]!" : "]");
3697 func (stream
, "\t; ");
3698 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3706 unsigned int P
= (given
& 0x01000000) >> 24;
3707 unsigned int U
= (given
& 0x00800000) >> 23;
3708 unsigned int W
= (given
& 0x00400000) >> 21;
3709 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3710 unsigned int off
= (given
& 0x000000ff);
3712 func (stream
, "[%s", arm_regnames
[Rn
]);
3717 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
3718 value_in_comment
= off
* 4 * U
? 1 : -1;
3726 func (stream
, "], ");
3729 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
3730 value_in_comment
= off
* 4 * U
? 1 : -1;
3734 func (stream
, "{%u}", off
);
3735 value_in_comment
= off
;
3743 unsigned int Sbit
= (given
& 0x01000000) >> 24;
3744 unsigned int type
= (given
& 0x00600000) >> 21;
3748 case 0: func (stream
, Sbit
? "sb" : "b"); break;
3749 case 1: func (stream
, Sbit
? "sh" : "h"); break;
3752 func (stream
, "??");
3755 func (stream
, "??");
3767 for (reg
= 0; reg
< 16; reg
++)
3768 if ((given
& (1 << reg
)) != 0)
3771 func (stream
, ", ");
3773 func (stream
, "%s", arm_regnames
[reg
]);
3781 unsigned int msb
= (given
& 0x0000001f);
3782 unsigned int lsb
= 0;
3784 lsb
|= (given
& 0x000000c0u
) >> 6;
3785 lsb
|= (given
& 0x00007000u
) >> 10;
3786 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
3792 unsigned int width
= (given
& 0x0000001f) + 1;
3793 unsigned int lsb
= 0;
3795 lsb
|= (given
& 0x000000c0u
) >> 6;
3796 lsb
|= (given
& 0x00007000u
) >> 10;
3797 func (stream
, "#%u, #%u", lsb
, width
);
3803 unsigned int S
= (given
& 0x04000000u
) >> 26;
3804 unsigned int J1
= (given
& 0x00002000u
) >> 13;
3805 unsigned int J2
= (given
& 0x00000800u
) >> 11;
3811 offset
|= (given
& 0x003f0000) >> 4;
3812 offset
|= (given
& 0x000007ff) << 1;
3813 offset
-= (1 << 20);
3815 info
->print_address_func (pc
+ 4 + offset
, info
);
3821 unsigned int S
= (given
& 0x04000000u
) >> 26;
3822 unsigned int I1
= (given
& 0x00002000u
) >> 13;
3823 unsigned int I2
= (given
& 0x00000800u
) >> 11;
3827 offset
|= !(I1
^ S
) << 23;
3828 offset
|= !(I2
^ S
) << 22;
3829 offset
|= (given
& 0x03ff0000u
) >> 4;
3830 offset
|= (given
& 0x000007ffu
) << 1;
3831 offset
-= (1 << 24);
3834 /* BLX target addresses are always word aligned. */
3835 if ((given
& 0x00001000u
) == 0)
3838 info
->print_address_func (offset
, info
);
3844 unsigned int shift
= 0;
3846 shift
|= (given
& 0x000000c0u
) >> 6;
3847 shift
|= (given
& 0x00007000u
) >> 10;
3848 if (given
& 0x00200000u
)
3849 func (stream
, ", asr #%u", shift
);
3851 func (stream
, ", lsl #%u", shift
);
3852 /* else print nothing - lsl #0 */
3858 unsigned int rot
= (given
& 0x00000030) >> 4;
3861 func (stream
, ", ror #%u", rot
* 8);
3866 switch (given
& 0xf)
3868 case 0xf: func (stream
, "sy"); break;
3869 case 0x7: func (stream
, "un"); break;
3870 case 0xe: func (stream
, "st"); break;
3871 case 0x6: func (stream
, "unst"); break;
3873 func (stream
, "#%d", (int) given
& 0xf);
3879 if ((given
& 0xff) == 0)
3881 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
3893 func (stream
, psr_name (given
& 0xff));
3898 if ((given
& 0xff) == 0)
3899 func (stream
, "%cPSR", (given
& 0x100000) ? 'S' : 'C');
3901 func (stream
, psr_name (given
& 0xff));
3904 case '0': case '1': case '2': case '3': case '4':
3905 case '5': case '6': case '7': case '8': case '9':
3910 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
3915 func (stream
, "%lu", val
);
3916 value_in_comment
= val
;
3919 func (stream
, "%lu", val
* 4);
3920 value_in_comment
= val
* 4;
3922 case 'r': func (stream
, "%s", arm_regnames
[val
]); break;
3925 func (stream
, "%s", arm_conditional
[val
]);
3930 if (val
== ((1ul << width
) - 1))
3931 func (stream
, "%c", *c
);
3937 func (stream
, "%c", *c
);
3941 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
3956 if (value_in_comment
> 32 || value_in_comment
< -16)
3957 func (stream
, "\t; 0x%lx", value_in_comment
);
3965 /* Print data bytes on INFO->STREAM. */
3968 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
3969 struct disassemble_info
*info
,
3972 switch (info
->bytes_per_chunk
)
3975 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
3978 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
3981 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
3988 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3989 being displayed in symbol relative addresses. */
3992 arm_symbol_is_valid (asymbol
* sym
,
3993 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4000 name
= bfd_asymbol_name (sym
);
4002 return (name
&& *name
!= '$');
4005 /* Parse an individual disassembler option. */
4008 parse_arm_disassembler_option (char *option
)
4013 if (CONST_STRNEQ (option
, "reg-names-"))
4019 for (i
= NUM_ARM_REGNAMES
; i
--;)
4020 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4022 regname_selected
= i
;
4027 /* XXX - should break 'option' at following delimiter. */
4028 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4030 else if (CONST_STRNEQ (option
, "force-thumb"))
4032 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4035 /* XXX - should break 'option' at following delimiter. */
4036 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4041 /* Parse the string of disassembler options, spliting it at whitespaces
4042 or commas. (Whitespace separators supported for backwards compatibility). */
4045 parse_disassembler_options (char *options
)
4047 if (options
== NULL
)
4052 parse_arm_disassembler_option (options
);
4054 /* Skip forward to next seperator. */
4055 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4057 /* Skip forward past seperators. */
4058 while (ISSPACE (*options
) || (*options
== ','))
4063 /* Search back through the insn stream to determine if this instruction is
4064 conditionally executed. */
4067 find_ifthen_state (bfd_vma pc
,
4068 struct disassemble_info
*info
,
4074 /* COUNT is twice the number of instructions seen. It will be odd if we
4075 just crossed an instruction boundary. */
4078 unsigned int seen_it
;
4081 ifthen_address
= pc
;
4088 /* Scan backwards looking for IT instructions, keeping track of where
4089 instruction boundaries are. We don't know if something is actually an
4090 IT instruction until we find a definite instruction boundary. */
4093 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4095 /* A symbol must be on an instruction boundary, and will not
4096 be within an IT block. */
4097 if (seen_it
&& (count
& 1))
4103 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4108 insn
= (b
[0]) | (b
[1] << 8);
4110 insn
= (b
[1]) | (b
[0] << 8);
4113 if ((insn
& 0xf800) < 0xe800)
4115 /* Addr + 2 is an instruction boundary. See if this matches
4116 the expected boundary based on the position of the last
4123 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4125 /* This could be an IT instruction. */
4127 it_count
= count
>> 1;
4129 if ((insn
& 0xf800) >= 0xe800)
4132 count
= (count
+ 2) | 1;
4133 /* IT blocks contain at most 4 instructions. */
4134 if (count
>= 8 && !seen_it
)
4137 /* We found an IT instruction. */
4138 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4139 if ((ifthen_state
& 0xf) == 0)
4143 /* Try to infer the code type (Arm or Thumb) from a symbol.
4144 Returns nonzero if *MAP_TYPE was set. */
4147 get_sym_code_type (struct disassemble_info
*info
,
4149 enum map_type
*map_type
)
4151 elf_symbol_type
*es
;
4155 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4156 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4158 /* If the symbol has function type then use that. */
4159 if (type
== STT_FUNC
|| type
== STT_ARM_TFUNC
)
4161 *map_type
= (type
== STT_ARM_TFUNC
) ? MAP_THUMB
: MAP_ARM
;
4165 /* Check for mapping symbols. */
4166 name
= bfd_asymbol_name (info
->symtab
[n
]);
4167 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4168 && (name
[2] == 0 || name
[2] == '.'))
4170 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4171 : (name
[1] == 't') ? MAP_THUMB
4179 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4180 of the supplied arm_feature_set structure with bitmasks indicating
4181 the support base architectures and coprocessor extensions.
4183 FIXME: This could more efficiently implemented as a constant array,
4184 although it would also be less robust. */
4187 select_arm_features (unsigned long mach
,
4188 arm_feature_set
* features
)
4191 #define ARM_FEATURE(ARCH,CEXT) \
4192 features->core = (ARCH); \
4193 features->coproc = (CEXT) | FPU_FPA; \
4198 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4199 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4200 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4201 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4202 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4203 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4204 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4205 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4206 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4207 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4208 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4209 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4210 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4211 /* If the machine type is unknown allow all
4212 architecture types and all extensions. */
4213 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4220 /* NOTE: There are no checks in these routines that
4221 the relevant number of data bytes exist. */
4224 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4229 int is_thumb
= FALSE
;
4230 int is_data
= FALSE
;
4232 unsigned int size
= 4;
4233 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4234 bfd_boolean found
= FALSE
;
4236 if (info
->disassembler_options
)
4238 parse_disassembler_options (info
->disassembler_options
);
4240 /* To avoid repeated parsing of these options, we remove them here. */
4241 info
->disassembler_options
= NULL
;
4244 /* PR 10288: Control which instructions will be disassembled. */
4245 if (info
->private_data
== NULL
)
4247 static arm_feature_set features
;
4249 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4250 /* If the user did not use the -m command line switch then default to
4251 disassembling all types of ARM instruction.
4253 The info->mach value has to be ignored as this will be based on
4254 the default archictecture for the target and/or hints in the notes
4255 section, but it will never be greater than the current largest arm
4256 machine value (iWMMXt2), which is only equivalent to the V5TE
4257 architecture. ARM architectures have advanced beyond the machine
4258 value encoding, and these newer architectures would be ignored if
4259 the machine value was used.
4261 Ie the -m switch is used to restrict which instructions will be
4262 disassembled. If it is necessary to use the -m switch to tell
4263 objdump that an ARM binary is being disassembled, eg because the
4264 input is a raw binary file, but it is also desired to disassemble
4265 all ARM instructions then use "-marm". This will select the
4266 "unknown" arm architecture which is compatible with any ARM
4268 info
->mach
= bfd_mach_arm_unknown
;
4270 /* Compute the architecture bitmask from the machine number.
4271 Note: This assumes that the machine number will not change
4272 during disassembly.... */
4273 select_arm_features (info
->mach
, & features
);
4275 info
->private_data
= & features
;
4278 /* Decide if our code is going to be little-endian, despite what the
4279 function argument might say. */
4280 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4282 /* First check the full symtab for a mapping symbol, even if there
4283 are no usable non-mapping symbols for this address. */
4284 if (info
->symtab_size
!= 0
4285 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4290 enum map_type type
= MAP_ARM
;
4292 if (pc
<= last_mapping_addr
)
4293 last_mapping_sym
= -1;
4294 is_thumb
= (last_type
== MAP_THUMB
);
4296 /* Start scanning at the start of the function, or wherever
4297 we finished last time. */
4298 n
= info
->symtab_pos
+ 1;
4299 if (n
< last_mapping_sym
)
4300 n
= last_mapping_sym
;
4302 /* Scan up to the location being disassembled. */
4303 for (; n
< info
->symtab_size
; n
++)
4305 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4308 if ((info
->section
== NULL
4309 || info
->section
== info
->symtab
[n
]->section
)
4310 && get_sym_code_type (info
, n
, &type
))
4319 n
= info
->symtab_pos
;
4320 if (n
< last_mapping_sym
- 1)
4321 n
= last_mapping_sym
- 1;
4323 /* No mapping symbol found at this address. Look backwards
4324 for a preceeding one. */
4327 if ((info
->section
== NULL
4328 || info
->section
== info
->symtab
[n
]->section
)
4329 && get_sym_code_type (info
, n
, &type
))
4338 last_mapping_sym
= last_sym
;
4340 is_thumb
= (last_type
== MAP_THUMB
);
4341 is_data
= (last_type
== MAP_DATA
);
4343 /* Look a little bit ahead to see if we should print out
4344 two or four bytes of data. If there's a symbol,
4345 mapping or otherwise, after two bytes then don't
4349 size
= 4 - (pc
& 3);
4350 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4352 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4355 if (addr
- pc
< size
)
4360 /* If the next symbol is after three bytes, we need to
4361 print only part of the data, so that we can use either
4364 size
= (pc
& 1) ? 1 : 2;
4368 if (info
->symbols
!= NULL
)
4370 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4372 coff_symbol_type
* cs
;
4374 cs
= coffsymbol (*info
->symbols
);
4375 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4376 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4377 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4378 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4379 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4381 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4384 /* If no mapping symbol has been found then fall back to the type
4385 of the function symbol. */
4386 elf_symbol_type
* es
;
4389 es
= *(elf_symbol_type
**)(info
->symbols
);
4390 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4392 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
4400 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4402 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4404 info
->bytes_per_line
= 4;
4406 /* PR 10263: Disassemble data if requested to do so by the user. */
4407 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4411 /* Size was already set above. */
4412 info
->bytes_per_chunk
= size
;
4413 printer
= print_insn_data
;
4415 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4418 for (i
= size
- 1; i
>= 0; i
--)
4419 given
= b
[i
] | (given
<< 8);
4421 for (i
= 0; i
< (int) size
; i
++)
4422 given
= b
[i
] | (given
<< 8);
4426 /* In ARM mode endianness is a straightforward issue: the instruction
4427 is four bytes long and is either ordered 0123 or 3210. */
4428 printer
= print_insn_arm
;
4429 info
->bytes_per_chunk
= 4;
4432 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4434 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4436 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4440 /* In Thumb mode we have the additional wrinkle of two
4441 instruction lengths. Fortunately, the bits that determine
4442 the length of the current instruction are always to be found
4443 in the first two bytes. */
4444 printer
= print_insn_thumb16
;
4445 info
->bytes_per_chunk
= 2;
4448 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4450 given
= (b
[0]) | (b
[1] << 8);
4452 given
= (b
[1]) | (b
[0] << 8);
4456 /* These bit patterns signal a four-byte Thumb
4458 if ((given
& 0xF800) == 0xF800
4459 || (given
& 0xF800) == 0xF000
4460 || (given
& 0xF800) == 0xE800)
4462 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4464 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4466 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4468 printer
= print_insn_thumb32
;
4473 if (ifthen_address
!= pc
)
4474 find_ifthen_state (pc
, info
, little_code
);
4478 if ((ifthen_state
& 0xf) == 0x8)
4479 ifthen_next_state
= 0;
4481 ifthen_next_state
= (ifthen_state
& 0xe0)
4482 | ((ifthen_state
& 0xf) << 1);
4488 info
->memory_error_func (status
, pc
, info
);
4491 if (info
->flags
& INSN_HAS_RELOC
)
4492 /* If the instruction has a reloc associated with it, then
4493 the offset field in the instruction will actually be the
4494 addend for the reloc. (We are using REL type relocs).
4495 In such cases, we can ignore the pc when computing
4496 addresses, since the addend is not currently pc-relative. */
4499 printer (pc
, info
, given
);
4503 ifthen_state
= ifthen_next_state
;
4504 ifthen_address
+= size
;
4510 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4512 /* Detect BE8-ness and record it in the disassembler info. */
4513 if (info
->flavour
== bfd_target_elf_flavour
4514 && info
->section
!= NULL
4515 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4516 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4518 return print_insn (pc
, info
, FALSE
);
4522 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4524 return print_insn (pc
, info
, TRUE
);
4528 print_arm_disassembler_options (FILE *stream
)
4532 fprintf (stream
, _("\n\
4533 The following ARM specific disassembler options are supported for use with\n\
4534 the -M switch:\n"));
4536 for (i
= NUM_ARM_REGNAMES
; i
--;)
4537 fprintf (stream
, " reg-names-%s %*c%s\n",
4539 (int)(14 - strlen (regnames
[i
].name
)), ' ',
4540 regnames
[i
].description
);
4542 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
4543 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");