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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [opcodes/] [arm-dis.c] - Blame information for rev 855

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

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

powered by: WebSVN 2.1.0

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