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 222

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 163 khays
                          unsigned int rotate = (given & 0xf00) >> 7;
3144
                          unsigned int immed = (given & 0xff);
3145
                          unsigned int a, i;
3146 18 khays
 
3147 163 khays
                          a = (((immed << (32 - rotate))
3148
                                | (immed >> rotate)) & 0xffffffff);
3149
                          /* If there is another encoding with smaller rotate,
3150
                             the rotate should be specified directly.  */
3151
                          for (i = 0; i < 32; i += 2)
3152
                            if ((a << i | a >> (32 - i)) <= 0xff)
3153
                              break;
3154
 
3155
                          if (i != rotate)
3156
                            func (stream, "#%d, %d", immed, rotate);
3157
                          else
3158
                            func (stream, "#%d", a);
3159
                          value_in_comment = a;
3160 18 khays
                        }
3161
                      else
3162
                        arm_decode_shift (given, func, stream, TRUE);
3163
                      break;
3164
 
3165
                    case 'p':
3166
                      if ((given & 0x0000f000) == 0x0000f000)
3167
                        {
3168
                          /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3169
                             mechanism for setting PSR flag bits.  They are
3170
                             obsolete in V6 onwards.  */
3171
                          if ((private_data->features.core & ARM_EXT_V6) == 0)
3172
                            func (stream, "p");
3173
                        }
3174
                      break;
3175
 
3176
                    case 't':
3177
                      if ((given & 0x01200000) == 0x00200000)
3178
                        func (stream, "t");
3179
                      break;
3180
 
3181
                    case 'A':
3182
                      {
3183
                        int offset = given & 0xff;
3184
 
3185
                        value_in_comment = offset * 4;
3186
                        if (NEGATIVE_BIT_SET)
3187
                          value_in_comment = - value_in_comment;
3188
 
3189
                        func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3190
 
3191
                        if (PRE_BIT_SET)
3192
                          {
3193
                            if (offset)
3194
                              func (stream, ", #%d]%s",
3195
                                    value_in_comment,
3196
                                    WRITEBACK_BIT_SET ? "!" : "");
3197
                            else
3198
                              func (stream, "]");
3199
                          }
3200
                        else
3201
                          {
3202
                            func (stream, "]");
3203
 
3204
                            if (WRITEBACK_BIT_SET)
3205
                              {
3206
                                if (offset)
3207
                                  func (stream, ", #%d", value_in_comment);
3208
                              }
3209
                            else
3210
                              {
3211
                                func (stream, ", {%d}", offset);
3212
                                value_in_comment = offset;
3213
                              }
3214
                          }
3215
                      }
3216
                      break;
3217
 
3218
                    case 'B':
3219
                      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
3220
                      {
3221
                        bfd_vma address;
3222
                        bfd_vma offset = 0;
3223
 
3224
                        if (! NEGATIVE_BIT_SET)
3225
                          /* Is signed, hi bits should be ones.  */
3226
                          offset = (-1) ^ 0x00ffffff;
3227
 
3228
                        /* Offset is (SignExtend(offset field)<<2).  */
3229
                        offset += given & 0x00ffffff;
3230
                        offset <<= 2;
3231
                        address = offset + pc + 8;
3232
 
3233
                        if (given & 0x01000000)
3234
                          /* H bit allows addressing to 2-byte boundaries.  */
3235
                          address += 2;
3236
 
3237
                        info->print_address_func (address, info);
3238
                      }
3239
                      break;
3240
 
3241
                    case 'C':
3242
                      if ((given & 0x02000200) == 0x200)
3243
                        {
3244
                          const char * name;
3245
                          unsigned sysm = (given & 0x004f0000) >> 16;
3246
 
3247
                          sysm |= (given & 0x300) >> 4;
3248
                          name = banked_regname (sysm);
3249
 
3250
                          if (name != NULL)
3251
                            func (stream, "%s", name);
3252
                          else
3253
                            func (stream, "(UNDEF: %lu)", sysm);
3254
                        }
3255
                      else
3256
                        {
3257
                          func (stream, "%cPSR_",
3258
                                (given & 0x00400000) ? 'S' : 'C');
3259
                          if (given & 0x80000)
3260
                            func (stream, "f");
3261
                          if (given & 0x40000)
3262
                            func (stream, "s");
3263
                          if (given & 0x20000)
3264
                            func (stream, "x");
3265
                          if (given & 0x10000)
3266
                            func (stream, "c");
3267
                        }
3268
                      break;
3269
 
3270
                    case 'U':
3271
                      if ((given & 0xf0) == 0x60)
3272
                        {
3273
                          switch (given & 0xf)
3274
                            {
3275
                            case 0xf: func (stream, "sy"); break;
3276
                            default:
3277
                              func (stream, "#%d", (int) given & 0xf);
3278
                              break;
3279
                            }
3280
                        }
3281
                      else
3282
                        {
3283
                          switch (given & 0xf)
3284
                            {
3285
                            case 0xf: func (stream, "sy"); break;
3286
                            case 0x7: func (stream, "un"); break;
3287
                            case 0xe: func (stream, "st"); break;
3288
                            case 0x6: func (stream, "unst"); break;
3289
                            case 0xb: func (stream, "ish"); break;
3290
                            case 0xa: func (stream, "ishst"); break;
3291
                            case 0x3: func (stream, "osh"); break;
3292
                            case 0x2: func (stream, "oshst"); break;
3293
                            default:
3294
                              func (stream, "#%d", (int) given & 0xf);
3295
                              break;
3296
                            }
3297
                        }
3298
                      break;
3299
 
3300
                    case '0': case '1': case '2': case '3': case '4':
3301
                    case '5': case '6': case '7': case '8': case '9':
3302
                      {
3303
                        int width;
3304
                        unsigned long value;
3305
 
3306
                        c = arm_decode_bitfield (c, given, &value, &width);
3307
 
3308
                        switch (*c)
3309
                          {
3310
                          case 'R':
3311
                            if (value == 15)
3312
                              is_unpredictable = TRUE;
3313
                            /* Fall through.  */
3314
                          case 'r':
3315
                            if (c[1] == 'u')
3316
                              {
3317
                                /* Eat the 'u' character.  */
3318
                                ++ c;
3319
 
3320
                                if (u_reg == value)
3321
                                  is_unpredictable = TRUE;
3322
                                u_reg = value;
3323
                              }
3324
                            if (c[1] == 'U')
3325
                              {
3326
                                /* Eat the 'U' character.  */
3327
                                ++ c;
3328
 
3329
                                if (U_reg == value)
3330
                                  is_unpredictable = TRUE;
3331
                                U_reg = value;
3332
                              }
3333
                            func (stream, "%s", arm_regnames[value]);
3334
                            break;
3335
                          case 'd':
3336
                            func (stream, "%ld", value);
3337
                            value_in_comment = value;
3338
                            break;
3339
                          case 'b':
3340
                            func (stream, "%ld", value * 8);
3341
                            value_in_comment = value * 8;
3342
                            break;
3343
                          case 'W':
3344
                            func (stream, "%ld", value + 1);
3345
                            value_in_comment = value + 1;
3346
                            break;
3347
                          case 'x':
3348
                            func (stream, "0x%08lx", value);
3349
 
3350
                            /* Some SWI instructions have special
3351
                               meanings.  */
3352
                            if ((given & 0x0fffffff) == 0x0FF00000)
3353
                              func (stream, "\t; IMB");
3354
                            else if ((given & 0x0fffffff) == 0x0FF00001)
3355
                              func (stream, "\t; IMBRange");
3356
                            break;
3357
                          case 'X':
3358
                            func (stream, "%01lx", value & 0xf);
3359
                            value_in_comment = value;
3360
                            break;
3361
                          case '`':
3362
                            c++;
3363
                            if (value == 0)
3364
                              func (stream, "%c", *c);
3365
                            break;
3366
                          case '\'':
3367
                            c++;
3368
                            if (value == ((1ul << width) - 1))
3369
                              func (stream, "%c", *c);
3370
                            break;
3371
                          case '?':
3372
                            func (stream, "%c", c[(1 << width) - (int) value]);
3373
                            c += 1 << width;
3374
                            break;
3375
                          default:
3376
                            abort ();
3377
                          }
3378
                        break;
3379
 
3380
                      case 'e':
3381
                        {
3382
                          int imm;
3383
 
3384
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3385
                          func (stream, "%d", imm);
3386
                          value_in_comment = imm;
3387
                        }
3388
                        break;
3389
 
3390
                      case 'E':
3391
                        /* LSB and WIDTH fields of BFI or BFC.  The machine-
3392
                           language instruction encodes LSB and MSB.  */
3393
                        {
3394
                          long msb = (given & 0x001f0000) >> 16;
3395
                          long lsb = (given & 0x00000f80) >> 7;
3396
                          long w = msb - lsb + 1;
3397
 
3398
                          if (w > 0)
3399
                            func (stream, "#%lu, #%lu", lsb, w);
3400
                          else
3401
                            func (stream, "(invalid: %lu:%lu)", lsb, msb);
3402
                        }
3403
                        break;
3404
 
3405
                      case 'R':
3406
                        /* Get the PSR/banked register name.  */
3407
                        {
3408
                          const char * name;
3409
                          unsigned sysm = (given & 0x004f0000) >> 16;
3410
 
3411
                          sysm |= (given & 0x300) >> 4;
3412
                          name = banked_regname (sysm);
3413
 
3414
                          if (name != NULL)
3415
                            func (stream, "%s", name);
3416
                          else
3417
                            func (stream, "(UNDEF: %lu)", sysm);
3418
                        }
3419
                        break;
3420
 
3421
                      case 'V':
3422
                        /* 16-bit unsigned immediate from a MOVT or MOVW
3423
                           instruction, encoded in bits 0:11 and 15:19.  */
3424
                        {
3425
                          long hi = (given & 0x000f0000) >> 4;
3426
                          long lo = (given & 0x00000fff);
3427
                          long imm16 = hi | lo;
3428
 
3429
                          func (stream, "#%lu", imm16);
3430
                          value_in_comment = imm16;
3431
                        }
3432
                        break;
3433
 
3434
                      default:
3435
                        abort ();
3436
                      }
3437
                    }
3438
                }
3439
              else
3440
                func (stream, "%c", *c);
3441
            }
3442
 
3443
          if (value_in_comment > 32 || value_in_comment < -16)
3444
            func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3445
 
3446
          if (is_unpredictable)
3447
            func (stream, UNPREDICTABLE_INSTRUCTION);
3448
 
3449
          return;
3450
        }
3451
    }
3452
  abort ();
3453
}
3454
 
3455
/* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
3456
 
3457
static void
3458
print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3459
{
3460
  const struct opcode16 *insn;
3461
  void *stream = info->stream;
3462
  fprintf_ftype func = info->fprintf_func;
3463
 
3464
  for (insn = thumb_opcodes; insn->assembler; insn++)
3465
    if ((given & insn->mask) == insn->value)
3466
      {
3467
        signed long value_in_comment = 0;
3468
        const char *c = insn->assembler;
3469
 
3470
        for (; *c; c++)
3471
          {
3472
            int domaskpc = 0;
3473
            int domasklr = 0;
3474
 
3475
            if (*c != '%')
3476
              {
3477
                func (stream, "%c", *c);
3478
                continue;
3479
              }
3480
 
3481
            switch (*++c)
3482
              {
3483
              case '%':
3484
                func (stream, "%%");
3485
                break;
3486
 
3487
              case 'c':
3488
                if (ifthen_state)
3489
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3490
                break;
3491
 
3492
              case 'C':
3493
                if (ifthen_state)
3494
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3495
                else
3496
                  func (stream, "s");
3497
                break;
3498
 
3499
              case 'I':
3500
                {
3501
                  unsigned int tmp;
3502
 
3503
                  ifthen_next_state = given & 0xff;
3504
                  for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3505
                    func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3506
                  func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3507
                }
3508
                break;
3509
 
3510
              case 'x':
3511
                if (ifthen_next_state)
3512
                  func (stream, "\t; unpredictable branch in IT block\n");
3513
                break;
3514
 
3515
              case 'X':
3516
                if (ifthen_state)
3517
                  func (stream, "\t; unpredictable <IT:%s>",
3518
                        arm_conditional[IFTHEN_COND]);
3519
                break;
3520
 
3521
              case 'S':
3522
                {
3523
                  long reg;
3524
 
3525
                  reg = (given >> 3) & 0x7;
3526
                  if (given & (1 << 6))
3527
                    reg += 8;
3528
 
3529
                  func (stream, "%s", arm_regnames[reg]);
3530
                }
3531
                break;
3532
 
3533
              case 'D':
3534
                {
3535
                  long reg;
3536
 
3537
                  reg = given & 0x7;
3538
                  if (given & (1 << 7))
3539
                    reg += 8;
3540
 
3541
                  func (stream, "%s", arm_regnames[reg]);
3542
                }
3543
                break;
3544
 
3545
              case 'N':
3546
                if (given & (1 << 8))
3547
                  domasklr = 1;
3548
                /* Fall through.  */
3549
              case 'O':
3550
                if (*c == 'O' && (given & (1 << 8)))
3551
                  domaskpc = 1;
3552
                /* Fall through.  */
3553
              case 'M':
3554
                {
3555
                  int started = 0;
3556
                  int reg;
3557
 
3558
                  func (stream, "{");
3559
 
3560
                  /* It would be nice if we could spot
3561
                     ranges, and generate the rS-rE format: */
3562
                  for (reg = 0; (reg < 8); reg++)
3563
                    if ((given & (1 << reg)) != 0)
3564
                      {
3565
                        if (started)
3566
                          func (stream, ", ");
3567
                        started = 1;
3568
                        func (stream, "%s", arm_regnames[reg]);
3569
                      }
3570
 
3571
                  if (domasklr)
3572
                    {
3573
                      if (started)
3574
                        func (stream, ", ");
3575
                      started = 1;
3576
                      func (stream, arm_regnames[14] /* "lr" */);
3577
                    }
3578
 
3579
                  if (domaskpc)
3580
                    {
3581
                      if (started)
3582
                        func (stream, ", ");
3583
                      func (stream, arm_regnames[15] /* "pc" */);
3584
                    }
3585
 
3586
                  func (stream, "}");
3587
                }
3588
                break;
3589
 
3590
              case 'W':
3591
                /* Print writeback indicator for a LDMIA.  We are doing a
3592
                   writeback if the base register is not in the register
3593
                   mask.  */
3594
                if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3595
                  func (stream, "!");
3596
                break;
3597
 
3598
              case 'b':
3599
                /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3600
                {
3601
                  bfd_vma address = (pc + 4
3602
                                     + ((given & 0x00f8) >> 2)
3603
                                     + ((given & 0x0200) >> 3));
3604
                  info->print_address_func (address, info);
3605
                }
3606
                break;
3607
 
3608
              case 's':
3609
                /* Right shift immediate -- bits 6..10; 1-31 print
3610
                   as themselves, 0 prints as 32.  */
3611
                {
3612
                  long imm = (given & 0x07c0) >> 6;
3613
                  if (imm == 0)
3614
                    imm = 32;
3615
                  func (stream, "#%ld", imm);
3616
                }
3617
                break;
3618
 
3619
              case '0': case '1': case '2': case '3': case '4':
3620
              case '5': case '6': case '7': case '8': case '9':
3621
                {
3622
                  int bitstart = *c++ - '0';
3623
                  int bitend = 0;
3624
 
3625
                  while (*c >= '0' && *c <= '9')
3626
                    bitstart = (bitstart * 10) + *c++ - '0';
3627
 
3628
                  switch (*c)
3629
                    {
3630
                    case '-':
3631
                      {
3632
                        bfd_vma reg;
3633
 
3634
                        c++;
3635
                        while (*c >= '0' && *c <= '9')
3636
                          bitend = (bitend * 10) + *c++ - '0';
3637
                        if (!bitend)
3638
                          abort ();
3639
                        reg = given >> bitstart;
3640
                        reg &= (2 << (bitend - bitstart)) - 1;
3641
 
3642
                        switch (*c)
3643
                          {
3644
                          case 'r':
3645
                            func (stream, "%s", arm_regnames[reg]);
3646
                            break;
3647
 
3648
                          case 'd':
3649
                            func (stream, "%ld", reg);
3650
                            value_in_comment = reg;
3651
                            break;
3652
 
3653
                          case 'H':
3654
                            func (stream, "%ld", reg << 1);
3655
                            value_in_comment = reg << 1;
3656
                            break;
3657
 
3658
                          case 'W':
3659
                            func (stream, "%ld", reg << 2);
3660
                            value_in_comment = reg << 2;
3661
                            break;
3662
 
3663
                          case 'a':
3664
                            /* PC-relative address -- the bottom two
3665
                               bits of the address are dropped
3666
                               before the calculation.  */
3667
                            info->print_address_func
3668
                              (((pc + 4) & ~3) + (reg << 2), info);
3669
                            value_in_comment = 0;
3670
                            break;
3671
 
3672
                          case 'x':
3673
                            func (stream, "0x%04lx", reg);
3674
                            break;
3675
 
3676
                          case 'B':
3677
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3678
                            info->print_address_func (reg * 2 + pc + 4, info);
3679
                            value_in_comment = 0;
3680
                            break;
3681
 
3682
                          case 'c':
3683
                            func (stream, "%s", arm_conditional [reg]);
3684
                            break;
3685
 
3686
                          default:
3687
                            abort ();
3688
                          }
3689
                      }
3690
                      break;
3691
 
3692
                    case '\'':
3693
                      c++;
3694
                      if ((given & (1 << bitstart)) != 0)
3695
                        func (stream, "%c", *c);
3696
                      break;
3697
 
3698
                    case '?':
3699
                      ++c;
3700
                      if ((given & (1 << bitstart)) != 0)
3701
                        func (stream, "%c", *c++);
3702
                      else
3703
                        func (stream, "%c", *++c);
3704
                      break;
3705
 
3706
                    default:
3707
                      abort ();
3708
                    }
3709
                }
3710
                break;
3711
 
3712
              default:
3713
                abort ();
3714
              }
3715
          }
3716
 
3717
        if (value_in_comment > 32 || value_in_comment < -16)
3718
          func (stream, "\t; 0x%lx", value_in_comment);
3719
        return;
3720
      }
3721
 
3722
  /* No match.  */
3723
  abort ();
3724
}
3725
 
3726
/* Return the name of an V7M special register.  */
3727
 
3728
static const char *
3729
psr_name (int regno)
3730
{
3731
  switch (regno)
3732
    {
3733
    case 0: return "APSR";
3734
    case 1: return "IAPSR";
3735
    case 2: return "EAPSR";
3736
    case 3: return "PSR";
3737
    case 5: return "IPSR";
3738
    case 6: return "EPSR";
3739
    case 7: return "IEPSR";
3740
    case 8: return "MSP";
3741
    case 9: return "PSP";
3742
    case 16: return "PRIMASK";
3743
    case 17: return "BASEPRI";
3744
    case 18: return "BASEPRI_MAX";
3745
    case 19: return "FAULTMASK";
3746
    case 20: return "CONTROL";
3747
    default: return "<unknown>";
3748
    }
3749
}
3750
 
3751
/* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
3752
 
3753
static void
3754
print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3755
{
3756
  const struct opcode32 *insn;
3757
  void *stream = info->stream;
3758
  fprintf_ftype func = info->fprintf_func;
3759
 
3760
  if (print_insn_coprocessor (pc, info, given, TRUE))
3761
    return;
3762
 
3763
  if (print_insn_neon (info, given, TRUE))
3764
    return;
3765
 
3766
  for (insn = thumb32_opcodes; insn->assembler; insn++)
3767
    if ((given & insn->mask) == insn->value)
3768
      {
3769
        bfd_boolean is_unpredictable = FALSE;
3770
        signed long value_in_comment = 0;
3771
        const char *c = insn->assembler;
3772
 
3773
        for (; *c; c++)
3774
          {
3775
            if (*c != '%')
3776
              {
3777
                func (stream, "%c", *c);
3778
                continue;
3779
              }
3780
 
3781
            switch (*++c)
3782
              {
3783
              case '%':
3784
                func (stream, "%%");
3785
                break;
3786
 
3787
              case 'c':
3788
                if (ifthen_state)
3789
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3790
                break;
3791
 
3792
              case 'x':
3793
                if (ifthen_next_state)
3794
                  func (stream, "\t; unpredictable branch in IT block\n");
3795
                break;
3796
 
3797
              case 'X':
3798
                if (ifthen_state)
3799
                  func (stream, "\t; unpredictable <IT:%s>",
3800
                        arm_conditional[IFTHEN_COND]);
3801
                break;
3802
 
3803
              case 'I':
3804
                {
3805
                  unsigned int imm12 = 0;
3806
 
3807
                  imm12 |= (given & 0x000000ffu);
3808
                  imm12 |= (given & 0x00007000u) >> 4;
3809
                  imm12 |= (given & 0x04000000u) >> 15;
3810
                  func (stream, "#%u", imm12);
3811
                  value_in_comment = imm12;
3812
                }
3813
                break;
3814
 
3815
              case 'M':
3816
                {
3817
                  unsigned int bits = 0, imm, imm8, mod;
3818
 
3819
                  bits |= (given & 0x000000ffu);
3820
                  bits |= (given & 0x00007000u) >> 4;
3821
                  bits |= (given & 0x04000000u) >> 15;
3822
                  imm8 = (bits & 0x0ff);
3823
                  mod = (bits & 0xf00) >> 8;
3824
                  switch (mod)
3825
                    {
3826
                    case 0: imm = imm8; break;
3827
                    case 1: imm = ((imm8 << 16) | imm8); break;
3828
                    case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3829
                    case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3830
                    default:
3831
                      mod  = (bits & 0xf80) >> 7;
3832
                      imm8 = (bits & 0x07f) | 0x80;
3833
                      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3834
                    }
3835
                  func (stream, "#%u", imm);
3836
                  value_in_comment = imm;
3837
                }
3838
                break;
3839
 
3840
              case 'J':
3841
                {
3842
                  unsigned int imm = 0;
3843
 
3844
                  imm |= (given & 0x000000ffu);
3845
                  imm |= (given & 0x00007000u) >> 4;
3846
                  imm |= (given & 0x04000000u) >> 15;
3847
                  imm |= (given & 0x000f0000u) >> 4;
3848
                  func (stream, "#%u", imm);
3849
                  value_in_comment = imm;
3850
                }
3851
                break;
3852
 
3853
              case 'K':
3854
                {
3855
                  unsigned int imm = 0;
3856
 
3857
                  imm |= (given & 0x000f0000u) >> 16;
3858
                  imm |= (given & 0x00000ff0u) >> 0;
3859
                  imm |= (given & 0x0000000fu) << 12;
3860
                  func (stream, "#%u", imm);
3861
                  value_in_comment = imm;
3862
                }
3863
                break;
3864
 
3865
              case 'V':
3866
                {
3867
                  unsigned int imm = 0;
3868
 
3869
                  imm |= (given & 0x00000fffu);
3870
                  imm |= (given & 0x000f0000u) >> 4;
3871
                  func (stream, "#%u", imm);
3872
                  value_in_comment = imm;
3873
                }
3874
                break;
3875
 
3876
              case 'S':
3877
                {
3878
                  unsigned int reg = (given & 0x0000000fu);
3879
                  unsigned int stp = (given & 0x00000030u) >> 4;
3880
                  unsigned int imm = 0;
3881
                  imm |= (given & 0x000000c0u) >> 6;
3882
                  imm |= (given & 0x00007000u) >> 10;
3883
 
3884
                  func (stream, "%s", arm_regnames[reg]);
3885
                  switch (stp)
3886
                    {
3887
                    case 0:
3888
                      if (imm > 0)
3889
                        func (stream, ", lsl #%u", imm);
3890
                      break;
3891
 
3892
                    case 1:
3893
                      if (imm == 0)
3894
                        imm = 32;
3895
                      func (stream, ", lsr #%u", imm);
3896
                      break;
3897
 
3898
                    case 2:
3899
                      if (imm == 0)
3900
                        imm = 32;
3901
                      func (stream, ", asr #%u", imm);
3902
                      break;
3903
 
3904
                    case 3:
3905
                      if (imm == 0)
3906
                        func (stream, ", rrx");
3907
                      else
3908
                        func (stream, ", ror #%u", imm);
3909
                    }
3910
                }
3911
                break;
3912
 
3913
              case 'a':
3914
                {
3915
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
3916
                  unsigned int U   = ! NEGATIVE_BIT_SET;
3917
                  unsigned int op  = (given & 0x00000f00) >> 8;
3918
                  unsigned int i12 = (given & 0x00000fff);
3919
                  unsigned int i8  = (given & 0x000000ff);
3920
                  bfd_boolean writeback = FALSE, postind = FALSE;
3921
                  bfd_vma offset = 0;
3922
 
3923
                  func (stream, "[%s", arm_regnames[Rn]);
3924
                  if (U) /* 12-bit positive immediate offset.  */
3925
                    {
3926
                      offset = i12;
3927
                      if (Rn != 15)
3928
                        value_in_comment = offset;
3929
                    }
3930
                  else if (Rn == 15) /* 12-bit negative immediate offset.  */
3931
                    offset = - (int) i12;
3932
                  else if (op == 0x0) /* Shifted register offset.  */
3933
                    {
3934
                      unsigned int Rm = (i8 & 0x0f);
3935
                      unsigned int sh = (i8 & 0x30) >> 4;
3936
 
3937
                      func (stream, ", %s", arm_regnames[Rm]);
3938
                      if (sh)
3939
                        func (stream, ", lsl #%u", sh);
3940
                      func (stream, "]");
3941
                      break;
3942
                    }
3943
                  else switch (op)
3944
                    {
3945
                    case 0xE:  /* 8-bit positive immediate offset.  */
3946
                      offset = i8;
3947
                      break;
3948
 
3949
                    case 0xC:  /* 8-bit negative immediate offset.  */
3950
                      offset = -i8;
3951
                      break;
3952
 
3953
                    case 0xF:  /* 8-bit + preindex with wb.  */
3954
                      offset = i8;
3955
                      writeback = TRUE;
3956
                      break;
3957
 
3958
                    case 0xD:  /* 8-bit - preindex with wb.  */
3959
                      offset = -i8;
3960
                      writeback = TRUE;
3961
                      break;
3962
 
3963
                    case 0xB:  /* 8-bit + postindex.  */
3964
                      offset = i8;
3965
                      postind = TRUE;
3966
                      break;
3967
 
3968
                    case 0x9:  /* 8-bit - postindex.  */
3969
                      offset = -i8;
3970
                      postind = TRUE;
3971
                      break;
3972
 
3973
                    default:
3974
                      func (stream, ", <undefined>]");
3975
                      goto skip;
3976
                    }
3977
 
3978
                  if (postind)
3979
                    func (stream, "], #%d", offset);
3980
                  else
3981
                    {
3982
                      if (offset)
3983
                        func (stream, ", #%d", offset);
3984
                      func (stream, writeback ? "]!" : "]");
3985
                    }
3986
 
3987
                  if (Rn == 15)
3988
                    {
3989
                      func (stream, "\t; ");
3990
                      info->print_address_func (((pc + 4) & ~3) + offset, info);
3991
                    }
3992
                }
3993
              skip:
3994
                break;
3995
 
3996
              case 'A':
3997
                {
3998
                  unsigned int U   = ! NEGATIVE_BIT_SET;
3999
                  unsigned int W   = WRITEBACK_BIT_SET;
4000
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
4001
                  unsigned int off = (given & 0x000000ff);
4002
 
4003
                  func (stream, "[%s", arm_regnames[Rn]);
4004
 
4005
                  if (PRE_BIT_SET)
4006
                    {
4007
                      if (off || !U)
4008
                        {
4009
                          func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4010
                          value_in_comment = off * 4 * U ? 1 : -1;
4011
                        }
4012
                      func (stream, "]");
4013
                      if (W)
4014
                        func (stream, "!");
4015
                    }
4016
                  else
4017
                    {
4018
                      func (stream, "], ");
4019
                      if (W)
4020
                        {
4021
                          func (stream, "#%c%u", U ? '+' : '-', off * 4);
4022
                          value_in_comment = off * 4 * U ? 1 : -1;
4023
                        }
4024
                      else
4025
                        {
4026
                          func (stream, "{%u}", off);
4027
                          value_in_comment = off;
4028
                        }
4029
                    }
4030
                }
4031
                break;
4032
 
4033
              case 'w':
4034
                {
4035
                  unsigned int Sbit = (given & 0x01000000) >> 24;
4036
                  unsigned int type = (given & 0x00600000) >> 21;
4037
 
4038
                  switch (type)
4039
                    {
4040
                    case 0: func (stream, Sbit ? "sb" : "b"); break;
4041
                    case 1: func (stream, Sbit ? "sh" : "h"); break;
4042
                    case 2:
4043
                      if (Sbit)
4044
                        func (stream, "??");
4045
                      break;
4046
                    case 3:
4047
                      func (stream, "??");
4048
                      break;
4049
                    }
4050
                }
4051
                break;
4052
 
4053
              case 'm':
4054
                {
4055
                  int started = 0;
4056
                  int reg;
4057
 
4058
                  func (stream, "{");
4059
                  for (reg = 0; reg < 16; reg++)
4060
                    if ((given & (1 << reg)) != 0)
4061
                      {
4062
                        if (started)
4063
                          func (stream, ", ");
4064
                        started = 1;
4065
                        func (stream, "%s", arm_regnames[reg]);
4066
                      }
4067
                  func (stream, "}");
4068
                }
4069
                break;
4070
 
4071
              case 'E':
4072
                {
4073
                  unsigned int msb = (given & 0x0000001f);
4074
                  unsigned int lsb = 0;
4075
 
4076
                  lsb |= (given & 0x000000c0u) >> 6;
4077
                  lsb |= (given & 0x00007000u) >> 10;
4078
                  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4079
                }
4080
                break;
4081
 
4082
              case 'F':
4083
                {
4084
                  unsigned int width = (given & 0x0000001f) + 1;
4085
                  unsigned int lsb = 0;
4086
 
4087
                  lsb |= (given & 0x000000c0u) >> 6;
4088
                  lsb |= (given & 0x00007000u) >> 10;
4089
                  func (stream, "#%u, #%u", lsb, width);
4090
                }
4091
                break;
4092
 
4093
              case 'b':
4094
                {
4095
                  unsigned int S = (given & 0x04000000u) >> 26;
4096
                  unsigned int J1 = (given & 0x00002000u) >> 13;
4097
                  unsigned int J2 = (given & 0x00000800u) >> 11;
4098
                  bfd_vma offset = 0;
4099
 
4100
                  offset |= !S << 20;
4101
                  offset |= J2 << 19;
4102
                  offset |= J1 << 18;
4103
                  offset |= (given & 0x003f0000) >> 4;
4104
                  offset |= (given & 0x000007ff) << 1;
4105
                  offset -= (1 << 20);
4106
 
4107
                  info->print_address_func (pc + 4 + offset, info);
4108
                }
4109
                break;
4110
 
4111
              case 'B':
4112
                {
4113
                  unsigned int S = (given & 0x04000000u) >> 26;
4114
                  unsigned int I1 = (given & 0x00002000u) >> 13;
4115
                  unsigned int I2 = (given & 0x00000800u) >> 11;
4116
                  bfd_vma offset = 0;
4117
 
4118
                  offset |= !S << 24;
4119
                  offset |= !(I1 ^ S) << 23;
4120
                  offset |= !(I2 ^ S) << 22;
4121
                  offset |= (given & 0x03ff0000u) >> 4;
4122
                  offset |= (given & 0x000007ffu) << 1;
4123
                  offset -= (1 << 24);
4124
                  offset += pc + 4;
4125
 
4126
                  /* BLX target addresses are always word aligned.  */
4127
                  if ((given & 0x00001000u) == 0)
4128
                      offset &= ~2u;
4129
 
4130
                  info->print_address_func (offset, info);
4131
                }
4132
                break;
4133
 
4134
              case 's':
4135
                {
4136
                  unsigned int shift = 0;
4137
 
4138
                  shift |= (given & 0x000000c0u) >> 6;
4139
                  shift |= (given & 0x00007000u) >> 10;
4140
                  if (WRITEBACK_BIT_SET)
4141
                    func (stream, ", asr #%u", shift);
4142
                  else if (shift)
4143
                    func (stream, ", lsl #%u", shift);
4144
                  /* else print nothing - lsl #0 */
4145
                }
4146
                break;
4147
 
4148
              case 'R':
4149
                {
4150
                  unsigned int rot = (given & 0x00000030) >> 4;
4151
 
4152
                  if (rot)
4153
                    func (stream, ", ror #%u", rot * 8);
4154
                }
4155
                break;
4156
 
4157
              case 'U':
4158
                if ((given & 0xf0) == 0x60)
4159
                  {
4160
                    switch (given & 0xf)
4161
                      {
4162
                        case 0xf: func (stream, "sy"); break;
4163
                        default:
4164
                          func (stream, "#%d", (int) given & 0xf);
4165
                              break;
4166
                      }
4167
                  }
4168
                else
4169
                  {
4170
                    switch (given & 0xf)
4171
                      {
4172
                        case 0xf: func (stream, "sy"); break;
4173
                        case 0x7: func (stream, "un"); break;
4174
                        case 0xe: func (stream, "st"); break;
4175
                        case 0x6: func (stream, "unst"); break;
4176
                        case 0xb: func (stream, "ish"); break;
4177
                        case 0xa: func (stream, "ishst"); break;
4178
                        case 0x3: func (stream, "osh"); break;
4179
                        case 0x2: func (stream, "oshst"); break;
4180
                        default:
4181
                          func (stream, "#%d", (int) given & 0xf);
4182
                          break;
4183
                      }
4184
                   }
4185
                break;
4186
 
4187
              case 'C':
4188
                if ((given & 0xff) == 0)
4189
                  {
4190
                    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4191
                    if (given & 0x800)
4192
                      func (stream, "f");
4193
                    if (given & 0x400)
4194
                      func (stream, "s");
4195
                    if (given & 0x200)
4196
                      func (stream, "x");
4197
                    if (given & 0x100)
4198
                      func (stream, "c");
4199
                  }
4200
                else if ((given & 0x20) == 0x20)
4201
                  {
4202
                    char const* name;
4203
                    unsigned sysm = (given & 0xf00) >> 8;
4204
 
4205
                    sysm |= (given & 0x30);
4206
                    sysm |= (given & 0x00100000) >> 14;
4207
                    name = banked_regname (sysm);
4208
 
4209
                    if (name != NULL)
4210
                      func (stream, "%s", name);
4211
                    else
4212
                      func (stream, "(UNDEF: %lu)", sysm);
4213
                  }
4214
                else
4215
                  {
4216
                    func (stream, psr_name (given & 0xff));
4217
                  }
4218
                break;
4219
 
4220
              case 'D':
4221
                if (((given & 0xff) == 0)
4222
                    || ((given & 0x20) == 0x20))
4223
                  {
4224
                    char const* name;
4225
                    unsigned sm = (given & 0xf0000) >> 16;
4226
 
4227
                    sm |= (given & 0x30);
4228
                    sm |= (given & 0x00100000) >> 14;
4229
                    name = banked_regname (sm);
4230
 
4231
                    if (name != NULL)
4232
                      func (stream, "%s", name);
4233
                    else
4234
                      func (stream, "(UNDEF: %lu)", sm);
4235
                  }
4236
                else
4237
                  func (stream, psr_name (given & 0xff));
4238
                break;
4239
 
4240
              case '0': case '1': case '2': case '3': case '4':
4241
              case '5': case '6': case '7': case '8': case '9':
4242
                {
4243
                  int width;
4244
                  unsigned long val;
4245
 
4246
                  c = arm_decode_bitfield (c, given, &val, &width);
4247
 
4248
                  switch (*c)
4249
                    {
4250
                    case 'd':
4251
                      func (stream, "%lu", val);
4252
                      value_in_comment = val;
4253
                      break;
4254
 
4255
                    case 'W':
4256
                      func (stream, "%lu", val * 4);
4257
                      value_in_comment = val * 4;
4258
                      break;
4259
 
4260
                    case 'R':
4261
                      if (val == 15)
4262
                        is_unpredictable = TRUE;
4263
                      /* Fall through.  */
4264
                    case 'r':
4265
                      func (stream, "%s", arm_regnames[val]);
4266
                      break;
4267
 
4268
                    case 'c':
4269
                      func (stream, "%s", arm_conditional[val]);
4270
                      break;
4271
 
4272
                    case '\'':
4273
                      c++;
4274
                      if (val == ((1ul << width) - 1))
4275
                        func (stream, "%c", *c);
4276
                      break;
4277
 
4278
                    case '`':
4279
                      c++;
4280
                      if (val == 0)
4281
                        func (stream, "%c", *c);
4282
                      break;
4283
 
4284
                    case '?':
4285
                      func (stream, "%c", c[(1 << width) - (int) val]);
4286
                      c += 1 << width;
4287
                      break;
4288
 
4289
                    case 'x':
4290
                      func (stream, "0x%lx", val & 0xffffffffUL);
4291
                      break;
4292
 
4293
                    default:
4294
                      abort ();
4295
                    }
4296
                }
4297
                break;
4298
 
4299
              case 'L':
4300
                /* PR binutils/12534
4301
                   If we have a PC relative offset in an LDRD or STRD
4302
                   instructions then display the decoded address.  */
4303
                if (((given >> 16) & 0xf) == 0xf)
4304
                  {
4305
                    bfd_vma offset = (given & 0xff) * 4;
4306
 
4307
                    if ((given & (1 << 23)) == 0)
4308
                      offset = - offset;
4309
                    func (stream, "\t; ");
4310
                    info->print_address_func ((pc & ~3) + 4 + offset, info);
4311
                  }
4312
                break;
4313
 
4314
              default:
4315
                abort ();
4316
              }
4317
          }
4318
 
4319
        if (value_in_comment > 32 || value_in_comment < -16)
4320
          func (stream, "\t; 0x%lx", value_in_comment);
4321
 
4322
        if (is_unpredictable)
4323
          func (stream, UNPREDICTABLE_INSTRUCTION);
4324
 
4325
        return;
4326
      }
4327
 
4328
  /* No match.  */
4329
  abort ();
4330
}
4331
 
4332
/* Print data bytes on INFO->STREAM.  */
4333
 
4334
static void
4335
print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4336
                 struct disassemble_info *info,
4337
                 long given)
4338
{
4339
  switch (info->bytes_per_chunk)
4340
    {
4341
    case 1:
4342
      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4343
      break;
4344
    case 2:
4345
      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4346
      break;
4347
    case 4:
4348
      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4349
      break;
4350
    default:
4351
      abort ();
4352
    }
4353
}
4354
 
4355
/* Disallow mapping symbols ($a, $b, $d, $t etc) from
4356
   being displayed in symbol relative addresses.  */
4357
 
4358
bfd_boolean
4359
arm_symbol_is_valid (asymbol * sym,
4360
                     struct disassemble_info * info ATTRIBUTE_UNUSED)
4361
{
4362
  const char * name;
4363
 
4364
  if (sym == NULL)
4365
    return FALSE;
4366
 
4367
  name = bfd_asymbol_name (sym);
4368
 
4369
  return (name && *name != '$');
4370
}
4371
 
4372
/* Parse an individual disassembler option.  */
4373
 
4374
void
4375
parse_arm_disassembler_option (char *option)
4376
{
4377
  if (option == NULL)
4378
    return;
4379
 
4380
  if (CONST_STRNEQ (option, "reg-names-"))
4381
    {
4382
      int i;
4383
 
4384
      option += 10;
4385
 
4386
      for (i = NUM_ARM_REGNAMES; i--;)
4387
        if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4388
          {
4389
            regname_selected = i;
4390
            break;
4391
          }
4392
 
4393
      if (i < 0)
4394
        /* XXX - should break 'option' at following delimiter.  */
4395
        fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4396
    }
4397
  else if (CONST_STRNEQ (option, "force-thumb"))
4398
    force_thumb = 1;
4399
  else if (CONST_STRNEQ (option, "no-force-thumb"))
4400
    force_thumb = 0;
4401
  else
4402
    /* XXX - should break 'option' at following delimiter.  */
4403
    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4404
 
4405
  return;
4406
}
4407
 
4408
/* Parse the string of disassembler options, spliting it at whitespaces
4409
   or commas.  (Whitespace separators supported for backwards compatibility).  */
4410
 
4411
static void
4412
parse_disassembler_options (char *options)
4413
{
4414
  if (options == NULL)
4415
    return;
4416
 
4417
  while (*options)
4418
    {
4419
      parse_arm_disassembler_option (options);
4420
 
4421
      /* Skip forward to next seperator.  */
4422
      while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4423
        ++ options;
4424
      /* Skip forward past seperators.  */
4425
      while (ISSPACE (*options) || (*options == ','))
4426
        ++ options;
4427
    }
4428
}
4429
 
4430
/* Search back through the insn stream to determine if this instruction is
4431
   conditionally executed.  */
4432
 
4433
static void
4434
find_ifthen_state (bfd_vma pc,
4435
                   struct disassemble_info *info,
4436
                   bfd_boolean little)
4437
{
4438
  unsigned char b[2];
4439
  unsigned int insn;
4440
  int status;
4441
  /* COUNT is twice the number of instructions seen.  It will be odd if we
4442
     just crossed an instruction boundary.  */
4443
  int count;
4444
  int it_count;
4445
  unsigned int seen_it;
4446
  bfd_vma addr;
4447
 
4448
  ifthen_address = pc;
4449
  ifthen_state = 0;
4450
 
4451
  addr = pc;
4452
  count = 1;
4453
  it_count = 0;
4454
  seen_it = 0;
4455
  /* Scan backwards looking for IT instructions, keeping track of where
4456
     instruction boundaries are.  We don't know if something is actually an
4457
     IT instruction until we find a definite instruction boundary.  */
4458
  for (;;)
4459
    {
4460
      if (addr == 0 || info->symbol_at_address_func (addr, info))
4461
        {
4462
          /* A symbol must be on an instruction boundary, and will not
4463
             be within an IT block.  */
4464
          if (seen_it && (count & 1))
4465
            break;
4466
 
4467
          return;
4468
        }
4469
      addr -= 2;
4470
      status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4471
      if (status)
4472
        return;
4473
 
4474
      if (little)
4475
        insn = (b[0]) | (b[1] << 8);
4476
      else
4477
        insn = (b[1]) | (b[0] << 8);
4478
      if (seen_it)
4479
        {
4480
          if ((insn & 0xf800) < 0xe800)
4481
            {
4482
              /* Addr + 2 is an instruction boundary.  See if this matches
4483
                 the expected boundary based on the position of the last
4484
                 IT candidate.  */
4485
              if (count & 1)
4486
                break;
4487
              seen_it = 0;
4488
            }
4489
        }
4490
      if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4491
        {
4492
          /* This could be an IT instruction.  */
4493
          seen_it = insn;
4494
          it_count = count >> 1;
4495
        }
4496
      if ((insn & 0xf800) >= 0xe800)
4497
        count++;
4498
      else
4499
        count = (count + 2) | 1;
4500
      /* IT blocks contain at most 4 instructions.  */
4501
      if (count >= 8 && !seen_it)
4502
        return;
4503
    }
4504
  /* We found an IT instruction.  */
4505
  ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4506
  if ((ifthen_state & 0xf) == 0)
4507
    ifthen_state = 0;
4508
}
4509
 
4510
/* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4511
   mapping symbol.  */
4512
 
4513
static int
4514
is_mapping_symbol (struct disassemble_info *info, int n,
4515
                   enum map_type *map_type)
4516
{
4517
  const char *name;
4518
 
4519
  name = bfd_asymbol_name (info->symtab[n]);
4520
  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4521
      && (name[2] == 0 || name[2] == '.'))
4522
    {
4523
      *map_type = ((name[1] == 'a') ? MAP_ARM
4524
                   : (name[1] == 't') ? MAP_THUMB
4525
                   : MAP_DATA);
4526
      return TRUE;
4527
    }
4528
 
4529
  return FALSE;
4530
}
4531
 
4532
/* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4533
   Returns nonzero if *MAP_TYPE was set.  */
4534
 
4535
static int
4536
get_map_sym_type (struct disassemble_info *info,
4537
                  int n,
4538
                  enum map_type *map_type)
4539
{
4540
  /* If the symbol is in a different section, ignore it.  */
4541
  if (info->section != NULL && info->section != info->symtab[n]->section)
4542
    return FALSE;
4543
 
4544
  return is_mapping_symbol (info, n, map_type);
4545
}
4546
 
4547
/* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4548
   Returns nonzero if *MAP_TYPE was set.  */
4549
 
4550
static int
4551
get_sym_code_type (struct disassemble_info *info,
4552
                   int n,
4553
                   enum map_type *map_type)
4554
{
4555
  elf_symbol_type *es;
4556
  unsigned int type;
4557
 
4558
  /* If the symbol is in a different section, ignore it.  */
4559
  if (info->section != NULL && info->section != info->symtab[n]->section)
4560
    return FALSE;
4561
 
4562
  es = *(elf_symbol_type **)(info->symtab + n);
4563
  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4564
 
4565
  /* If the symbol has function type then use that.  */
4566
  if (type == STT_FUNC || type == STT_GNU_IFUNC)
4567
    {
4568
      if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4569
        *map_type = MAP_THUMB;
4570
      else
4571
        *map_type = MAP_ARM;
4572
      return TRUE;
4573
    }
4574
 
4575
  return FALSE;
4576
}
4577
 
4578
/* Given a bfd_mach_arm_XXX value, this function fills in the fields
4579
   of the supplied arm_feature_set structure with bitmasks indicating
4580
   the support base architectures and coprocessor extensions.
4581
 
4582
   FIXME: This could more efficiently implemented as a constant array,
4583
   although it would also be less robust.  */
4584
 
4585
static void
4586
select_arm_features (unsigned long mach,
4587
                     arm_feature_set * features)
4588
{
4589
#undef  ARM_FEATURE
4590
#define ARM_FEATURE(ARCH,CEXT) \
4591
  features->core = (ARCH); \
4592
  features->coproc = (CEXT) | FPU_FPA; \
4593
  return
4594
 
4595
  switch (mach)
4596
    {
4597
    case bfd_mach_arm_2:       ARM_ARCH_V2;
4598
    case bfd_mach_arm_2a:      ARM_ARCH_V2S;
4599
    case bfd_mach_arm_3:       ARM_ARCH_V3;
4600
    case bfd_mach_arm_3M:      ARM_ARCH_V3M;
4601
    case bfd_mach_arm_4:       ARM_ARCH_V4;
4602
    case bfd_mach_arm_4T:      ARM_ARCH_V4T;
4603
    case bfd_mach_arm_5:       ARM_ARCH_V5;
4604
    case bfd_mach_arm_5T:      ARM_ARCH_V5T;
4605
    case bfd_mach_arm_5TE:     ARM_ARCH_V5TE;
4606
    case bfd_mach_arm_XScale:  ARM_ARCH_XSCALE;
4607
    case bfd_mach_arm_ep9312:  ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4608
    case bfd_mach_arm_iWMMXt:  ARM_ARCH_IWMMXT;
4609
    case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4610
      /* If the machine type is unknown allow all
4611
         architecture types and all extensions.  */
4612
    case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4613
    default:
4614
      abort ();
4615
    }
4616
}
4617
 
4618
 
4619
/* NOTE: There are no checks in these routines that
4620
   the relevant number of data bytes exist.  */
4621
 
4622
static int
4623
print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4624
{
4625
  unsigned char b[4];
4626
  long          given;
4627
  int           status;
4628
  int           is_thumb = FALSE;
4629
  int           is_data = FALSE;
4630
  int           little_code;
4631
  unsigned int  size = 4;
4632
  void          (*printer) (bfd_vma, struct disassemble_info *, long);
4633
  bfd_boolean   found = FALSE;
4634
  struct arm_private_data *private_data;
4635
 
4636
  if (info->disassembler_options)
4637
    {
4638
      parse_disassembler_options (info->disassembler_options);
4639
 
4640
      /* To avoid repeated parsing of these options, we remove them here.  */
4641
      info->disassembler_options = NULL;
4642
    }
4643
 
4644
  /* PR 10288: Control which instructions will be disassembled.  */
4645
  if (info->private_data == NULL)
4646
    {
4647
      static struct arm_private_data private;
4648
 
4649
      if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4650
        /* If the user did not use the -m command line switch then default to
4651
           disassembling all types of ARM instruction.
4652
 
4653
           The info->mach value has to be ignored as this will be based on
4654
           the default archictecture for the target and/or hints in the notes
4655
           section, but it will never be greater than the current largest arm
4656
           machine value (iWMMXt2), which is only equivalent to the V5TE
4657
           architecture.  ARM architectures have advanced beyond the machine
4658
           value encoding, and these newer architectures would be ignored if
4659
           the machine value was used.
4660
 
4661
           Ie the -m switch is used to restrict which instructions will be
4662
           disassembled.  If it is necessary to use the -m switch to tell
4663
           objdump that an ARM binary is being disassembled, eg because the
4664
           input is a raw binary file, but it is also desired to disassemble
4665
           all ARM instructions then use "-marm".  This will select the
4666
           "unknown" arm architecture which is compatible with any ARM
4667
           instruction.  */
4668
          info->mach = bfd_mach_arm_unknown;
4669
 
4670
      /* Compute the architecture bitmask from the machine number.
4671
         Note: This assumes that the machine number will not change
4672
         during disassembly....  */
4673
      select_arm_features (info->mach, & private.features);
4674
 
4675
      private.has_mapping_symbols = -1;
4676
      private.last_mapping_sym = -1;
4677
      private.last_mapping_addr = 0;
4678
 
4679
      info->private_data = & private;
4680
    }
4681
 
4682
  private_data = info->private_data;
4683
 
4684
  /* Decide if our code is going to be little-endian, despite what the
4685
     function argument might say.  */
4686
  little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4687
 
4688
  /* For ELF, consult the symbol table to determine what kind of code
4689
     or data we have.  */
4690
  if (info->symtab_size != 0
4691
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4692
    {
4693
      bfd_vma addr;
4694
      int n, start;
4695
      int last_sym = -1;
4696
      enum map_type type = MAP_ARM;
4697
 
4698
      /* Start scanning at the start of the function, or wherever
4699
         we finished last time.  */
4700
      start = info->symtab_pos + 1;
4701
      if (start < private_data->last_mapping_sym)
4702
        start = private_data->last_mapping_sym;
4703
      found = FALSE;
4704
 
4705
      /* First, look for mapping symbols.  */
4706
      if (private_data->has_mapping_symbols != 0)
4707
        {
4708
          /* Scan up to the location being disassembled.  */
4709
          for (n = start; n < info->symtab_size; n++)
4710
            {
4711
              addr = bfd_asymbol_value (info->symtab[n]);
4712
              if (addr > pc)
4713
                break;
4714
              if (get_map_sym_type (info, n, &type))
4715
                {
4716
                  last_sym = n;
4717
                  found = TRUE;
4718
                }
4719
            }
4720
 
4721
          if (!found)
4722
            {
4723
              /* No mapping symbol found at this address.  Look backwards
4724
                 for a preceding one.  */
4725
              for (n = start - 1; n >= 0; n--)
4726
                {
4727
                  if (get_map_sym_type (info, n, &type))
4728
                    {
4729
                      last_sym = n;
4730
                      found = TRUE;
4731
                      break;
4732
                    }
4733
                }
4734
            }
4735
 
4736
          if (found)
4737
            private_data->has_mapping_symbols = 1;
4738
 
4739
          /* No mapping symbols were found.  A leading $d may be
4740
             omitted for sections which start with data; but for
4741
             compatibility with legacy and stripped binaries, only
4742
             assume the leading $d if there is at least one mapping
4743
             symbol in the file.  */
4744
          if (!found && private_data->has_mapping_symbols == -1)
4745
            {
4746
              /* Look for mapping symbols, in any section.  */
4747
              for (n = 0; n < info->symtab_size; n++)
4748
                if (is_mapping_symbol (info, n, &type))
4749
                  {
4750
                    private_data->has_mapping_symbols = 1;
4751
                    break;
4752
                  }
4753
              if (private_data->has_mapping_symbols == -1)
4754
                private_data->has_mapping_symbols = 0;
4755
            }
4756
 
4757
          if (!found && private_data->has_mapping_symbols == 1)
4758
            {
4759
              type = MAP_DATA;
4760
              found = TRUE;
4761
            }
4762
        }
4763
 
4764
      /* Next search for function symbols to separate ARM from Thumb
4765
         in binaries without mapping symbols.  */
4766
      if (!found)
4767
        {
4768
          /* Scan up to the location being disassembled.  */
4769
          for (n = start; n < info->symtab_size; n++)
4770
            {
4771
              addr = bfd_asymbol_value (info->symtab[n]);
4772
              if (addr > pc)
4773
                break;
4774
              if (get_sym_code_type (info, n, &type))
4775
                {
4776
                  last_sym = n;
4777
                  found = TRUE;
4778
                }
4779
            }
4780
 
4781
          if (!found)
4782
            {
4783
              /* No mapping symbol found at this address.  Look backwards
4784
                 for a preceding one.  */
4785
              for (n = start - 1; n >= 0; n--)
4786
                {
4787
                  if (get_sym_code_type (info, n, &type))
4788
                    {
4789
                      last_sym = n;
4790
                      found = TRUE;
4791
                      break;
4792
                    }
4793
                }
4794
            }
4795
        }
4796
 
4797
      private_data->last_mapping_sym = last_sym;
4798
      private_data->last_type = type;
4799
      is_thumb = (private_data->last_type == MAP_THUMB);
4800
      is_data = (private_data->last_type == MAP_DATA);
4801
 
4802
      /* Look a little bit ahead to see if we should print out
4803
         two or four bytes of data.  If there's a symbol,
4804
         mapping or otherwise, after two bytes then don't
4805
         print more.  */
4806
      if (is_data)
4807
        {
4808
          size = 4 - (pc & 3);
4809
          for (n = last_sym + 1; n < info->symtab_size; n++)
4810
            {
4811
              addr = bfd_asymbol_value (info->symtab[n]);
4812
              if (addr > pc
4813
                  && (info->section == NULL
4814
                      || info->section == info->symtab[n]->section))
4815
                {
4816
                  if (addr - pc < size)
4817
                    size = addr - pc;
4818
                  break;
4819
                }
4820
            }
4821
          /* If the next symbol is after three bytes, we need to
4822
             print only part of the data, so that we can use either
4823
             .byte or .short.  */
4824
          if (size == 3)
4825
            size = (pc & 1) ? 1 : 2;
4826
        }
4827
    }
4828
 
4829
  if (info->symbols != NULL)
4830
    {
4831
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4832
        {
4833
          coff_symbol_type * cs;
4834
 
4835
          cs = coffsymbol (*info->symbols);
4836
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
4837
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
4838
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
4839
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4840
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4841
        }
4842
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4843
               && !found)
4844
        {
4845
          /* If no mapping symbol has been found then fall back to the type
4846
             of the function symbol.  */
4847
          elf_symbol_type *  es;
4848
          unsigned int       type;
4849
 
4850
          es = *(elf_symbol_type **)(info->symbols);
4851
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4852
 
4853
          is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4854
                       == ST_BRANCH_TO_THUMB)
4855
                      || type == STT_ARM_16BIT);
4856
        }
4857
    }
4858
 
4859
  if (force_thumb)
4860
    is_thumb = TRUE;
4861
 
4862
  if (is_data)
4863
    info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4864
  else
4865
    info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4866
 
4867
  info->bytes_per_line = 4;
4868
 
4869
  /* PR 10263: Disassemble data if requested to do so by the user.  */
4870
  if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4871
    {
4872
      int i;
4873
 
4874
      /* Size was already set above.  */
4875
      info->bytes_per_chunk = size;
4876
      printer = print_insn_data;
4877
 
4878
      status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4879
      given = 0;
4880
      if (little)
4881
        for (i = size - 1; i >= 0; i--)
4882
          given = b[i] | (given << 8);
4883
      else
4884
        for (i = 0; i < (int) size; i++)
4885
          given = b[i] | (given << 8);
4886
    }
4887
  else if (!is_thumb)
4888
    {
4889
      /* In ARM mode endianness is a straightforward issue: the instruction
4890
         is four bytes long and is either ordered 0123 or 3210.  */
4891
      printer = print_insn_arm;
4892
      info->bytes_per_chunk = 4;
4893
      size = 4;
4894
 
4895
      status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4896
      if (little_code)
4897
        given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4898
      else
4899
        given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4900
    }
4901
  else
4902
    {
4903
      /* In Thumb mode we have the additional wrinkle of two
4904
         instruction lengths.  Fortunately, the bits that determine
4905
         the length of the current instruction are always to be found
4906
         in the first two bytes.  */
4907
      printer = print_insn_thumb16;
4908
      info->bytes_per_chunk = 2;
4909
      size = 2;
4910
 
4911
      status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4912
      if (little_code)
4913
        given = (b[0]) | (b[1] << 8);
4914
      else
4915
        given = (b[1]) | (b[0] << 8);
4916
 
4917
      if (!status)
4918
        {
4919
          /* These bit patterns signal a four-byte Thumb
4920
             instruction.  */
4921
          if ((given & 0xF800) == 0xF800
4922
              || (given & 0xF800) == 0xF000
4923
              || (given & 0xF800) == 0xE800)
4924
            {
4925
              status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4926
              if (little_code)
4927
                given = (b[0]) | (b[1] << 8) | (given << 16);
4928
              else
4929
                given = (b[1]) | (b[0] << 8) | (given << 16);
4930
 
4931
              printer = print_insn_thumb32;
4932
              size = 4;
4933
            }
4934
        }
4935
 
4936
      if (ifthen_address != pc)
4937
        find_ifthen_state (pc, info, little_code);
4938
 
4939
      if (ifthen_state)
4940
        {
4941
          if ((ifthen_state & 0xf) == 0x8)
4942
            ifthen_next_state = 0;
4943
          else
4944
            ifthen_next_state = (ifthen_state & 0xe0)
4945
                                | ((ifthen_state & 0xf) << 1);
4946
        }
4947
    }
4948
 
4949
  if (status)
4950
    {
4951
      info->memory_error_func (status, pc, info);
4952
      return -1;
4953
    }
4954
  if (info->flags & INSN_HAS_RELOC)
4955
    /* If the instruction has a reloc associated with it, then
4956
       the offset field in the instruction will actually be the
4957
       addend for the reloc.  (We are using REL type relocs).
4958
       In such cases, we can ignore the pc when computing
4959
       addresses, since the addend is not currently pc-relative.  */
4960
    pc = 0;
4961
 
4962
  printer (pc, info, given);
4963
 
4964
  if (is_thumb)
4965
    {
4966
      ifthen_state = ifthen_next_state;
4967
      ifthen_address += size;
4968
    }
4969
  return size;
4970
}
4971
 
4972
int
4973
print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4974
{
4975
  /* Detect BE8-ness and record it in the disassembler info.  */
4976
  if (info->flavour == bfd_target_elf_flavour
4977
      && info->section != NULL
4978
      && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4979
    info->endian_code = BFD_ENDIAN_LITTLE;
4980
 
4981
  return print_insn (pc, info, FALSE);
4982
}
4983
 
4984
int
4985
print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4986
{
4987
  return print_insn (pc, info, TRUE);
4988
}
4989
 
4990
void
4991
print_arm_disassembler_options (FILE *stream)
4992
{
4993
  int i;
4994
 
4995
  fprintf (stream, _("\n\
4996
The following ARM specific disassembler options are supported for use with\n\
4997
the -M switch:\n"));
4998
 
4999
  for (i = NUM_ARM_REGNAMES; i--;)
5000
    fprintf (stream, "  reg-names-%s %*c%s\n",
5001
             regnames[i].name,
5002
             (int)(14 - strlen (regnames[i].name)), ' ',
5003
             regnames[i].description);
5004
 
5005
  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
5006
  fprintf (stream, "  no-force-thumb           Examine preceding label to determine an insn's type\n\n");
5007
}

powered by: WebSVN 2.1.0

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