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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [arm-dis.c] - Blame information for rev 127

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

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

powered by: WebSVN 2.1.0

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