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

Subversion Repositories openrisc

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

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

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

powered by: WebSVN 2.1.0

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