OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [opcodes/] [arm-dis.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.