Statistics
| Branch: | Revision:

root / arm-dis.c @ 5a2e3c2e

History | View | Annotate | Download (156.6 kB)

1
/* Instruction printing code for the ARM
2
   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3
   2007, Free Software Foundation, Inc.
4
   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5
   Modification by James G. Smith (jsmith@cygnus.co.uk)
6

7
   This file is part of libopcodes.
8

9
   This program is free software; you can redistribute it and/or modify it under
10
   the terms of the GNU General Public License as published by the Free
11
   Software Foundation; either version 2 of the License, or (at your option)
12
   any later version.
13

14
   This program is distributed in the hope that it will be useful, but WITHOUT
15
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17
   more details.
18

19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
21

    
22
/* Start of qemu specific additions.  Mostly this is stub definitions
23
   for things we don't care about.  */
24

    
25
#include "dis-asm.h"
26
#define ATTRIBUTE_UNUSED __attribute__((unused))
27
#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
28

    
29
#define ARM_EXT_V1         0
30
#define ARM_EXT_V2         0
31
#define ARM_EXT_V2S         0
32
#define ARM_EXT_V3         0
33
#define ARM_EXT_V3M         0
34
#define ARM_EXT_V4         0
35
#define ARM_EXT_V4T         0
36
#define ARM_EXT_V5         0
37
#define ARM_EXT_V5T         0
38
#define ARM_EXT_V5ExP         0
39
#define ARM_EXT_V5E         0
40
#define ARM_EXT_V5J         0
41
#define ARM_EXT_V6       0
42
#define ARM_EXT_V6K      0
43
#define ARM_EXT_V6Z      0
44
#define ARM_EXT_V6T2         0
45
#define ARM_EXT_V7         0
46
#define ARM_EXT_DIV         0
47

    
48
/* Co-processor space extensions.  */
49
#define ARM_CEXT_XSCALE   0
50
#define ARM_CEXT_MAVERICK 0
51
#define ARM_CEXT_IWMMXT   0
52

    
53
#define FPU_FPA_EXT_V1         0
54
#define FPU_FPA_EXT_V2         0
55
#define FPU_VFP_EXT_NONE 0
56
#define FPU_VFP_EXT_V1xD 0
57
#define FPU_VFP_EXT_V1         0
58
#define FPU_VFP_EXT_V2         0
59
#define FPU_MAVERICK         0
60
#define FPU_VFP_EXT_V3         0
61
#define FPU_NEON_EXT_V1         0
62

    
63
int floatformat_ieee_single_little;
64
/* Assume host uses ieee float.  */
65
static void floatformat_to_double (int *ignored, unsigned char *data,
66
                                   double *dest)
67
{
68
    union {
69
        uint32_t i;
70
        float f;
71
    } u;
72
    u.i = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
73
    *dest = u.f;
74
}
75

    
76
/* End of qemu specific additions.  */
77

    
78
/* FIXME: Belongs in global header.  */
79
#ifndef strneq
80
#define strneq(a,b,n)        (strncmp ((a), (b), (n)) == 0)
81
#endif
82

    
83
#ifndef NUM_ELEM
84
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
85
#endif
86

    
87
struct opcode32
88
{
89
  unsigned long arch;                /* Architecture defining this insn.  */
90
  unsigned long value, mask;        /* Recognise insn if (op&mask)==value.  */
91
  const char *assembler;        /* How to disassemble this insn.  */
92
};
93

    
94
struct opcode16
95
{
96
  unsigned long arch;                /* Architecture defining this insn.  */
97
  unsigned short value, mask;        /* Recognise insn if (op&mask)==value.  */
98
  const char *assembler;        /* How to disassemble this insn.  */
99
};
100

    
101
/* print_insn_coprocessor recognizes the following format control codes:
102

103
   %%                        %
104

105
   %c                        print condition code (always bits 28-31 in ARM mode)
106
   %q                        print shifter argument
107
   %u                        print condition code (unconditional in ARM mode)
108
   %A                        print address for ldc/stc/ldf/stf instruction
109
   %B                        print vstm/vldm register list
110
   %C                        print vstr/vldr address operand
111
   %I                   print cirrus signed shift immediate: bits 0..3|4..6
112
   %F                        print the COUNT field of a LFM/SFM instruction.
113
   %P                        print floating point precision in arithmetic insn
114
   %Q                        print floating point precision in ldf/stf insn
115
   %R                        print floating point rounding mode
116

117
   %<bitfield>r                print as an ARM register
118
   %<bitfield>d                print the bitfield in decimal
119
   %<bitfield>k                print immediate for VFPv3 conversion instruction
120
   %<bitfield>x                print the bitfield in hex
121
   %<bitfield>X                print the bitfield as 1 hex digit without leading "0x"
122
   %<bitfield>f                print a floating point constant if >7 else a
123
                        floating point register
124
   %<bitfield>w         print as an iWMMXt width field - [bhwd]ss/us
125
   %<bitfield>g         print as an iWMMXt 64-bit register
126
   %<bitfield>G         print as an iWMMXt general purpose or control register
127
   %<bitfield>D                print as a NEON D register
128
   %<bitfield>Q                print as a NEON Q register
129

130
   %y<code>                print a single precision VFP reg.
131
                          Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
132
   %z<code>                print a double precision VFP reg
133
                          Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
134

135
   %<bitfield>'c        print specified char iff bitfield is all ones
136
   %<bitfield>`c        print specified char iff bitfield is all zeroes
137
   %<bitfield>?ab...    select from array of values in big endian order
138

139
   %L                        print as an iWMMXt N/M width field.
140
   %Z                        print the Immediate of a WSHUFH instruction.
141
   %l                        like 'A' except use byte offsets for 'B' & 'H'
142
                        versions.
143
   %i                        print 5-bit immediate in bits 8,3..0
144
                        (print "32" when 0)
145
   %r                        print register offset address for wldt/wstr instruction
146
*/
147

    
148
/* Common coprocessor opcodes shared between Arm and Thumb-2.  */
149

    
150
static const struct opcode32 coprocessor_opcodes[] =
151
{
152
  /* XScale instructions.  */
153
  {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
154
  {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
155
  {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
156
  {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
157
  {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
158

    
159
  /* Intel Wireless MMX technology instructions.  */
160
#define FIRST_IWMMXT_INSN 0x0e130130
161
#define IWMMXT_INSN_COUNT 73
162
  {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
163
  {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
164
  {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
165
  {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
166
  {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
167
  {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
168
  {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
169
  {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
170
  {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
171
  {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
172
  {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
173
  {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
174
  {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
175
  {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
176
  {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
177
  {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
178
  {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
179
  {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
180
  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
181
  {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
182
  {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
183
  {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
184
  {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
185
  {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
186
  {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
187
  {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
188
  {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
189
  {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
190
  {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
191
  {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
192
  {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
193
  {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
194
  {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
195
  {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
196
  {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
197
  {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
198
  {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
199
  {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
200
  {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
201
  {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
202
  {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
203
  {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
204
  {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
205
  {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
206
  {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
207
  {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
208
  {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
209
  {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
210
  {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
211
  {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
212
  {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
213
  {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
214
  {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
215
  {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
216
  {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
217
  {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
218
  {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
219
  {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
220
  {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
221
  {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
222
  {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
223
  {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
224
  {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
225
  {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
226
  {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
227
  {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
228
  {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
229
  {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
230
  {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
231
  {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
232
  {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
233
  {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
234
  {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
235
  {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
236
  {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
237

    
238
  /* Floating point coprocessor (FPA) instructions */
239
  {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240
  {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241
  {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242
  {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
243
  {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
244
  {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245
  {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
246
  {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
247
  {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
248
  {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
249
  {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
250
  {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
251
  {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
252
  {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
253
  {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
254
  {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
255
  {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
256
  {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
257
  {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
258
  {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
259
  {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
260
  {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
261
  {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
262
  {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
263
  {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
264
  {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
265
  {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
266
  {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
267
  {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
268
  {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
269
  {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
270
  {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
271
  {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
272
  {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
273
  {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
274
  {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
275
  {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
276
  {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
277
  {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
278
  {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
279
  {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
280
  {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
281
  {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
282

    
283
  /* Register load/store */
284
  {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
285
  {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
286
  {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
287
  {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
288
  {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
289
  {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
290

    
291
  /* Data transfer between ARM and NEON registers */
292
  {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
293
  {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
294
  {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
295
  {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
296
  {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
297
  {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
298
  {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
299
  {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
300
  {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
301
  {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
302
  {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
303
  {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
304
  {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
305
  {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
306

    
307
  /* Floating point coprocessor (VFP) instructions */
308
  {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
309
  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
310
  {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
311
  {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"},
312
  {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"},
313
  {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
314
  {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
315
  {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
316
  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
317
  {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
318
  {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"},
319
  {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"},
320
  {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
321
  {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
322
  {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
323
  {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
324
  {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
325
  {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
326
  {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
327
  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"},
328
  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"},
329
  {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
330
  {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
331
  {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
332
  {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
333
  {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
334
  {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
335
  {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
336
  {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
337
  {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
338
  {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
339
  {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
340
  {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
341
  {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
342
  {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
343
  {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
344
  {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
345
  {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
346
  {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
347
  {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
348
  {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
349
  {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
350
  {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
351
  {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
352
  {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
353
  {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
354
  {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
355
  {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
356
  {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
357
  {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
358
  {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
359
  {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
360
  {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
361
  {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
362
  {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
363
  {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
364
  {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
365
  {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
366
  {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
367
  {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
368
  {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
369
  {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
370
  {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
371
  {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
372
  {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
373
  {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
374
  {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
375
  {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
376
  {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
377
  {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
378
  {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
379
  {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
380
  {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
381
  {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
382
  {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
383
  {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
384
  {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
385
  {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
386
  {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
387
  {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
388
  {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
389
  {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
390
  {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
391

    
392
  /* Cirrus coprocessor instructions.  */
393
  {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
394
  {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
395
  {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
396
  {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
397
  {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
398
  {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
399
  {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
400
  {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
401
  {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
402
  {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
403
  {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
404
  {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
405
  {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
406
  {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
407
  {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
408
  {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
409
  {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
410
  {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
411
  {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
412
  {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
413
  {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
414
  {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
415
  {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
416
  {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
417
  {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
418
  {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
419
  {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
420
  {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
421
  {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
422
  {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
423
  {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
424
  {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
425
  {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
426
  {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
427
  {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
428
  {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
429
  {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
430
  {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
431
  {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
432
  {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
433
  {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
434
  {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
435
  {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
436
  {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
437
  {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
438
  {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
439
  {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
440
  {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
441
  {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
442
  {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
443
  {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
444
  {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
445
  {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
446
  {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
447
  {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
448
  {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
449
  {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
450
  {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
451
  {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
452
  {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
453
  {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
454
  {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
455
  {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
456
  {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
457
  {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
458
  {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
459
  {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
460
  {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
461
  {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
462
  {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
463
  {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
464
  {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
465
  {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
466
  {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
467
  {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
468
  {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
469
  {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
470
  {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
471
  {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472
  {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
473
  {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474
  {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
475
  {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
476
  {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
477

    
478
  /* Generic coprocessor instructions */
479
  {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
480
  {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
481
  {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
482
  {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
483
  {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
484
  {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
485
  {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
486

    
487
  /* V6 coprocessor instructions */
488
  {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
489
  {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
490

    
491
  /* V5 coprocessor instructions */
492
  {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
493
  {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
494
  {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
495
  {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
496
  {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
497

    
498
  {0, 0, 0, 0}
499
};
500

    
501
/* Neon opcode table:  This does not encode the top byte -- that is
502
   checked by the print_insn_neon routine, as it depends on whether we are
503
   doing thumb32 or arm32 disassembly.  */
504

    
505
/* print_insn_neon recognizes the following format control codes:
506

507
   %%                        %
508

509
   %c                        print condition code
510
   %A                        print v{st,ld}[1234] operands
511
   %B                        print v{st,ld}[1234] any one operands
512
   %C                        print v{st,ld}[1234] single->all operands
513
   %D                        print scalar
514
   %E                        print vmov, vmvn, vorr, vbic encoded constant
515
   %F                        print vtbl,vtbx register list
516

517
   %<bitfield>r                print as an ARM register
518
   %<bitfield>d                print the bitfield in decimal
519
   %<bitfield>e         print the 2^N - bitfield in decimal
520
   %<bitfield>D                print as a NEON D register
521
   %<bitfield>Q                print as a NEON Q register
522
   %<bitfield>R                print as a NEON D or Q register
523
   %<bitfield>Sn        print byte scaled width limited by n
524
   %<bitfield>Tn        print short scaled width limited by n
525
   %<bitfield>Un        print long scaled width limited by n
526

527
   %<bitfield>'c        print specified char iff bitfield is all ones
528
   %<bitfield>`c        print specified char iff bitfield is all zeroes
529
   %<bitfield>?ab...    select from array of values in big endian order  */
530

    
531
static const struct opcode32 neon_opcodes[] =
532
{
533
  /* Extract */
534
  {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
535
  {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
536

    
537
  /* Move data element to all lanes */
538
  {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
539
  {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
540
  {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
541

    
542
  /* Table lookup */
543
  {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
544
  {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
545

    
546
  /* Two registers, miscellaneous */
547
  {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
548
  {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
549
  {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
550
  {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
551
  {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
552
  {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
553
  {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
554
  {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
555
  {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
556
  {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
557
  {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
558
  {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
559
  {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
560
  {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
561
  {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
562
  {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
563
  {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
564
  {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
565
  {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
566
  {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
567
  {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
568
  {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
569
  {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
570
  {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
571
  {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
572
  {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
573
  {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
574
  {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
575
  {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
576
  {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
577
  {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
578
  {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
579
  {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"},
580

    
581
  /* Three registers of the same length */
582
  {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
583
  {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
584
  {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
585
  {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
586
  {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
587
  {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
588
  {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
589
  {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
590
  {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
591
  {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
592
  {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
593
  {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
594
  {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
595
  {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
596
  {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
597
  {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
598
  {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
599
  {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
600
  {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
601
  {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
602
  {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
603
  {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
604
  {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
605
  {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
606
  {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
607
  {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
608
  {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
609
  {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
610
  {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
611
  {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
612
  {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
613
  {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
614
  {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
615
  {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
616
  {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
617
  {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
618
  {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
619
  {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
620
  {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
621
  {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
622
  {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
623
  {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
624
  {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
625
  {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
626
  {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
627
  {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
628
  {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
629
  {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
630
  {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
631
  {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
632
  {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
633
  {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634
  {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635

    
636
  /* One register and an immediate value */
637
  {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
638
  {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
639
  {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
640
  {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
641
  {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
642
  {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
643
  {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
644
  {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
645
  {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
646
  {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
647
  {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
648
  {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
649
  {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
650

    
651
  /* Two registers and a shift amount */
652
  {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
653
  {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
654
  {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
655
  {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
656
  {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
657
  {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
658
  {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
659
  {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
660
  {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
661
  {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
662
  {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
663
  {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
664
  {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
665
  {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
666
  {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
667
  {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
668
  {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
669
  {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
670
  {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
671
  {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
672
  {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
673
  {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
674
  {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
675
  {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
676
  {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
677
  {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
678
  {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
679
  {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
680
  {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
681
  {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
682
  {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
683
  {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
684
  {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
685
  {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
686
  {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
687
  {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
688
  {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
689
  {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
690
  {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
691
  {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
692
  {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
693
  {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
694
  {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
695
  {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
696
  {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
697
  {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
698
  {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
699
  {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
700
  {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
701
  {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
702
  {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
703
  {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
704
  {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
705
  {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
706
  {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
707
  {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
708
  {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
709
  {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
710

    
711
  /* Three registers of different lengths */
712
  {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
713
  {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
714
  {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
715
  {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
716
  {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
717
  {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
718
  {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
719
  {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
720
  {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
721
  {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
722
  {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
723
  {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
724
  {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
725
  {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
726
  {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
727
  {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
728
  {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
729

    
730
  /* Two registers and a scalar */
731
  {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
732
  {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
733
  {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
734
  {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
735
  {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
736
  {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
737
  {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
738
  {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
739
  {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
740
  {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
741
  {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
742
  {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
743
  {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
744
  {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
745
  {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
746
  {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
747
  {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
748
  {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
749
  {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
750
  {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
751
  {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
752
  {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
753

    
754
  /* Element and structure load/store */
755
  {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
756
  {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
757
  {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
758
  {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
759
  {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
760
  {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
761
  {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
762
  {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
763
  {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
764
  {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
765
  {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
766
  {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
767
  {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
768
  {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
769
  {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
770
  {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
771
  {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
772
  {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
773
  {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
774

    
775
  {0,0 ,0, 0}
776
};
777

    
778
/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
779
   ordered: they must be searched linearly from the top to obtain a correct
780
   match.  */
781

    
782
/* print_insn_arm recognizes the following format control codes:
783

784
   %%                        %
785

786
   %a                        print address for ldr/str instruction
787
   %s                   print address for ldr/str halfword/signextend instruction
788
   %b                        print branch destination
789
   %c                        print condition code (always bits 28-31)
790
   %m                        print register mask for ldm/stm instruction
791
   %o                        print operand2 (immediate or register + shift)
792
   %p                        print 'p' iff bits 12-15 are 15
793
   %t                        print 't' iff bit 21 set and bit 24 clear
794
   %B                        print arm BLX(1) destination
795
   %C                        print the PSR sub type.
796
   %U                        print barrier type.
797
   %P                        print address for pli instruction.
798

799
   %<bitfield>r                print as an ARM register
800
   %<bitfield>d                print the bitfield in decimal
801
   %<bitfield>W         print the bitfield plus one in decimal
802
   %<bitfield>x                print the bitfield in hex
803
   %<bitfield>X                print the bitfield as 1 hex digit without leading "0x"
804

805
   %<bitfield>'c        print specified char iff bitfield is all ones
806
   %<bitfield>`c        print specified char iff bitfield is all zeroes
807
   %<bitfield>?ab...    select from array of values in big endian order
808

809
   %e                   print arm SMI operand (bits 0..7,8..19).
810
   %E                        print the LSB and WIDTH fields of a BFI or BFC instruction.
811
   %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
812

    
813
static const struct opcode32 arm_opcodes[] =
814
{
815
  /* ARM instructions.  */
816
  {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
817
  {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
818
  {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
819
  {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
820
  {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
821
  {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
822
  {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
823

    
824
  /* V7 instructions.  */
825
  {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
826
  {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
827
  {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
828
  {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
829
  {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
830

    
831
  /* ARM V6T2 instructions.  */
832
  {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
833
  {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
834
  {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
835
  {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
836
  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
837
  {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
838
  {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
839
  {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
840
  {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
841

    
842
  /* ARM V6Z instructions.  */
843
  {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
844

    
845
  /* ARM V6K instructions.  */
846
  {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
847
  {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
848
  {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
849
  {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
850
  {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
851
  {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
852
  {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
853

    
854
  /* ARM V6K NOP hints.  */
855
  {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
856
  {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
857
  {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
858
  {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
859
  {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
860

    
861
  /* ARM V6 instructions. */
862
  {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
863
  {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
864
  {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
865
  {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
866
  {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
867
  {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
868
  {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
869
  {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
870
  {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
871
  {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
872
  {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
873
  {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
874
  {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
875
  {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
876
  {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
877
  {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
878
  {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
879
  {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
880
  {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
881
  {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
882
  {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
883
  {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
884
  {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
885
  {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
886
  {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
887
  {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
888
  {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
889
  {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
890
  {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
891
  {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
892
  {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
893
  {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
894
  {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
895
  {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
896
  {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
897
  {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
898
  {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
899
  {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
900
  {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
901
  {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
902
  {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
903
  {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
904
  {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
905
  {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
906
  {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
907
  {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
908
  {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
909
  {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
910
  {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
911
  {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
912
  {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
913
  {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
914
  {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
915
  {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
916
  {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
917
  {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
918
  {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
919
  {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
920
  {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
921
  {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
922
  {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
923
  {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
924
  {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
925
  {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
926
  {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
927
  {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
928
  {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
929
  {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
930
  {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
931
  {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
932
  {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
933
  {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
934
  {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
935
  {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
936
  {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
937
  {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
938
  {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
939
  {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
940
  {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
941
  {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
942
  {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
943
  {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
944
  {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
945
  {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
946
  {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
947
  {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
948
  {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
949
  {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
950
  {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
951
  {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
952
  {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
953
  {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
954
  {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
955
  {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
956
  {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
957
  {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
958
  {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
959
  {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
960
  {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
961
  {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
962
  {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
963
  {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
964
  {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
965
  {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
966
  {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
967
  {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
968
  {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
969
  {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
970
  {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
971
  {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
972
  {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
973
  {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
974
  {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
975
  {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
976
  {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
977
  {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
978
  {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
979
  {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
980
  {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
981
  {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
982
  {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
983
  {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
984

    
985
  /* V5J instruction.  */
986
  {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
987

    
988
  /* V5 Instructions.  */
989
  {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
990
  {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
991
  {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
992
  {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
993

    
994
  /* V5E "El Segundo" Instructions.  */
995
  {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
996
  {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
997
  {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
998
  {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
999
  {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1000
  {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1001
  {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1002

    
1003
  {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1004
  {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1005

    
1006
  {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1007
  {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1008
  {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1009
  {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1010

    
1011
  {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1012
  {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1013
  {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1014
  {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1015

    
1016
  {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1017
  {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1018

    
1019
  {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
1020
  {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1021
  {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
1022
  {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1023

    
1024
  /* ARM Instructions.  */
1025
  {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"},
1026
  {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1027
  {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1028
  {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1029
  {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1030
  {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1031
  {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1032
  {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1033
  {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1034
  {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1035
  {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1036
  {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1037
  {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
1038
  {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
1039
  {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
1040
  {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
1041
  {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1042
  {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1043
  {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1044
  {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1045
  {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1046
  {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1047
  {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1048
  {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1049
  {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1050
  {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
1051
  {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1052
  {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1053
  {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1054
  {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1055
  {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
1056
  {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1057
  {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1058
  {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1059
  {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1060
  {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1061
  {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1062
  {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1063
  {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1064
  {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1065
  {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1066

    
1067
  /* The rest.  */
1068
  {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
1069
  {0, 0x00000000, 0x00000000, 0}
1070
};
1071

    
1072
/* print_insn_thumb16 recognizes the following format control codes:
1073

1074
   %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
1075
   %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
1076
   %<bitfield>I         print bitfield as a signed decimal
1077
                                   (top bit of range being the sign bit)
1078
   %N                   print Thumb register mask (with LR)
1079
   %O                   print Thumb register mask (with PC)
1080
   %M                   print Thumb register mask
1081
   %b                        print CZB's 6-bit unsigned branch destination
1082
   %s                        print Thumb right-shift immediate (6..10; 0 == 32).
1083
   %c                        print the condition code
1084
   %C                        print the condition code, or "s" if not conditional
1085
   %x                        print warning if conditional an not at end of IT block"
1086
   %X                        print "\t; unpredictable <IT:code>" if conditional
1087
   %I                        print IT instruction suffix and operands
1088
   %<bitfield>r                print bitfield as an ARM register
1089
   %<bitfield>d                print bitfield as a decimal
1090
   %<bitfield>H         print (bitfield * 2) as a decimal
1091
   %<bitfield>W         print (bitfield * 4) as a decimal
1092
   %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
1093
   %<bitfield>B         print Thumb branch destination (signed displacement)
1094
   %<bitfield>c         print bitfield as a condition code
1095
   %<bitnum>'c                print specified char iff bit is one
1096
   %<bitnum>?ab                print a if bit is one else print b.  */
1097

    
1098
static const struct opcode16 thumb_opcodes[] =
1099
{
1100
  /* Thumb instructions.  */
1101

    
1102
  /* ARM V6K no-argument instructions.  */
1103
  {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1104
  {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1105
  {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1106
  {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1107
  {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1108
  {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1109

    
1110
  /* ARM V6T2 instructions.  */
1111
  {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1112
  {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1113
  {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1114

    
1115
  /* ARM V6.  */
1116
  {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1117
  {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1118
  {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1119
  {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1120
  {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1121
  {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1122
  {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1123
  {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1124
  {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1125
  {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1126
  {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1127

    
1128
  /* ARM V5 ISA extends Thumb.  */
1129
  {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional.  */
1130
  /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
1131
  {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"},        /* note: 4 bit register number.  */
1132
  /* ARM V4T ISA (Thumb v1).  */
1133
  {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
1134
  /* Format 4.  */
1135
  {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1136
  {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1137
  {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1138
  {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1139
  {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1140
  {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1141
  {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1142
  {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1143
  {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1144
  {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1145
  {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1146
  {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1147
  {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1148
  {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1149
  {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1150
  {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1151
  /* format 13 */
1152
  {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1153
  {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1154
  /* format 5 */
1155
  {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1156
  {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1157
  {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1158
  {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1159
  /* format 14 */
1160
  {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1161
  {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1162
  /* format 2 */
1163
  {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1164
  {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1165
  {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1166
  {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1167
  /* format 8 */
1168
  {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1169
  {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1170
  {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1171
  /* format 7 */
1172
  {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1173
  {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1174
  /* format 1 */
1175
  {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1176
  {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1177
  {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1178
  /* format 3 */
1179
  {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1180
  {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1181
  {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1182
  {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1183
  /* format 6 */
1184
  {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1185
  /* format 9 */
1186
  {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1187
  {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1188
  {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1189
  {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1190
  /* format 10 */
1191
  {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1192
  {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1193
  /* format 11 */
1194
  {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1195
  {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1196
  /* format 12 */
1197
  {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
1198
  {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1199
  /* format 15 */
1200
  {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1201
  {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1202
  /* format 17 */
1203
  {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1204
  /* format 16 */
1205
  {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"},
1206
  {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1207
  /* format 18 */
1208
  {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1209

    
1210
  /* The E800 .. FFFF range is unconditionally redirected to the
1211
     32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1212
     are processed via that table.  Thus, we can never encounter a
1213
     bare "second half of BL/BLX(1)" instruction here.  */
1214
  {ARM_EXT_V1,  0x0000, 0x0000, "undefined"},
1215
  {0, 0, 0, 0}
1216
};
1217

    
1218
/* Thumb32 opcodes use the same table structure as the ARM opcodes.
1219
   We adopt the convention that hw1 is the high 16 bits of .value and
1220
   .mask, hw2 the low 16 bits.
1221

1222
   print_insn_thumb32 recognizes the following format control codes:
1223

1224
       %%                %
1225

1226
       %I                print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1227
       %M                print a modified 12-bit immediate (same location)
1228
       %J                print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1229
       %K                print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1230
       %S                print a possibly-shifted Rm
1231

1232
       %a                print the address of a plain load/store
1233
       %w                print the width and signedness of a core load/store
1234
       %m                print register mask for ldm/stm
1235

1236
       %E                print the lsb and width fields of a bfc/bfi instruction
1237
       %F                print the lsb and width fields of a sbfx/ubfx instruction
1238
       %b                print a conditional branch offset
1239
       %B                print an unconditional branch offset
1240
       %s                print the shift field of an SSAT instruction
1241
       %R                print the rotation field of an SXT instruction
1242
       %U                print barrier type.
1243
       %P                print address for pli instruction.
1244
       %c                print the condition code
1245
       %x                print warning if conditional an not at end of IT block"
1246
       %X                print "\t; unpredictable <IT:code>" if conditional
1247

1248
       %<bitfield>d        print bitfield in decimal
1249
       %<bitfield>W        print bitfield*4 in decimal
1250
       %<bitfield>r        print bitfield as an ARM register
1251
       %<bitfield>c        print bitfield as a condition code
1252

1253
       %<bitfield>'c        print specified char iff bitfield is all ones
1254
       %<bitfield>`c        print specified char iff bitfield is all zeroes
1255
       %<bitfield>?ab... select from array of values in big endian order
1256

1257
   With one exception at the bottom (done because BL and BLX(1) need
1258
   to come dead last), this table was machine-sorted first in
1259
   decreasing order of number of bits set in the mask, then in
1260
   increasing numeric order of mask, then in increasing numeric order
1261
   of opcode.  This order is not the clearest for a human reader, but
1262
   is guaranteed never to catch a special-case bit pattern with a more
1263
   general mask, which is important, because this instruction encoding
1264
   makes heavy use of special-case bit patterns.  */
1265
static const struct opcode32 thumb32_opcodes[] =
1266
{
1267
  /* V7 instructions.  */
1268
  {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1269
  {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1270
  {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1271
  {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1272
  {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1273
  {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1274
  {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1275

    
1276
  /* Instructions defined in the basic V6T2 set.  */
1277
  {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1278
  {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1279
  {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1280
  {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1281
  {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
1282
  {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1283

    
1284
  {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1285
  {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1286
  {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1287
  {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1288
  {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1289
  {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1290
  {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1291
  {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1292
  {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1293
  {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1294
  {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1295
  {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1296
  {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1297
  {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1298
  {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1299
  {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1300
  {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1301
  {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1302
  {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1303
  {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1304
  {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1305
  {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1306
  {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1307
  {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1308
  {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1309
  {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1310
  {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1311
  {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1312
  {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1313
  {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1314
  {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1315
  {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1316
  {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1317
  {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1318
  {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1319
  {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1320
  {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1321
  {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1322
  {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1323
  {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1324
  {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1325
  {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1326
  {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1327
  {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1328
  {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1329
  {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1330
  {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1331
  {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1332
  {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1333
  {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1334
  {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1335
  {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1336
  {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1337
  {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1338
  {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1339
  {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1340
  {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1341
  {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1342
  {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1343
  {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1344
  {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1345
  {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1346
  {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1347
  {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1348
  {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1349
  {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1350
  {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1351
  {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1352
  {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1353
  {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1354
  {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1355
  {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1356
  {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1357
  {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1358
  {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1359
  {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1360
  {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1361
  {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1362
  {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1363
  {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1364
  {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1365
  {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1366
  {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1367
  {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1368
  {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1369
  {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1370
  {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1371
  {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1372
  {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1373
  {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1374
  {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1375
  {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1376
  {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1377
  {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1378
  {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1379
  {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1380
  {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1381
  {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1382
  {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1383
  {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1384
  {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1385
  {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1386
  {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1387
  {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1388
  {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1389
  {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1390
  {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1391
  {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1392
  {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1393
  {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1394
  {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1395
  {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1396
  {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1397
  {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1398
  {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1399
  {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1400
  {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1401
  {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1402
  {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1403
  {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1404
  {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1405
  {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1406
  {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1407
  {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1408
  {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1409
  {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1410
  {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1411
  {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1412
  {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1413
  {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1414
  {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1415
  {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1416
  {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1417
  {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1418
  {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1419
  {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1420
  {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1421
  {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1422
  {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1423
  {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1424
  {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1425
  {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1426
  {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1427
  {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1428
  {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1429
  {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1430
  {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1431
  {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1432
  {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1433
  {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1434
  {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1435
  {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1436
  {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1437
  {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1438
  {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1439
  {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1440
  {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1441
  {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1442
  {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1443
  {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1444
  {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1445
  {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1446
  {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1447
  {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1448
  {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1449
  {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1450
  {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1451
  {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1452
  {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1453
  {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1454
  {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1455
  {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1456

    
1457
  /* Filter out Bcc with cond=E or F, which are used for other instructions.  */
1458
  {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1459
  {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1460
  {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1461
  {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1462

    
1463
  /* These have been 32-bit since the invention of Thumb.  */
1464
  {ARM_EXT_V4T,  0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1465
  {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1466

    
1467
  /* Fallback.  */
1468
  {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
1469
  {0, 0, 0, 0}
1470
};
1471

    
1472
static const char *const arm_conditional[] =
1473
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1474
 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1475

    
1476
static const char *const arm_fp_const[] =
1477
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1478

    
1479
static const char *const arm_shift[] =
1480
{"lsl", "lsr", "asr", "ror"};
1481

    
1482
typedef struct
1483
{
1484
  const char *name;
1485
  const char *description;
1486
  const char *reg_names[16];
1487
}
1488
arm_regname;
1489

    
1490
static const arm_regname regnames[] =
1491
{
1492
  { "raw" , "Select raw register names",
1493
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1494
  { "gcc",  "Select register names used by GCC",
1495
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1496
  { "std",  "Select register names used in ARM's ISA documentation",
1497
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
1498
  { "apcs", "Select register names used in the APCS",
1499
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1500
  { "atpcs", "Select register names used in the ATPCS",
1501
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
1502
  { "special-atpcs", "Select special register names used in the ATPCS",
1503
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
1504
};
1505

    
1506
static const char *const iwmmxt_wwnames[] =
1507
{"b", "h", "w", "d"};
1508

    
1509
static const char *const iwmmxt_wwssnames[] =
1510
{"b", "bus", "bc", "bss",
1511
 "h", "hus", "hc", "hss",
1512
 "w", "wus", "wc", "wss",
1513
 "d", "dus", "dc", "dss"
1514
};
1515

    
1516
static const char *const iwmmxt_regnames[] =
1517
{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1518
  "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1519
};
1520

    
1521
static const char *const iwmmxt_cregnames[] =
1522
{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1523
  "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1524
};
1525

    
1526
/* Default to GCC register name set.  */
1527
static unsigned int regname_selected = 1;
1528

    
1529
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1530
#define arm_regnames      regnames[regname_selected].reg_names
1531

    
1532
static bfd_boolean force_thumb = false;
1533

    
1534
/* Current IT instruction state.  This contains the same state as the IT
1535
   bits in the CPSR.  */
1536
static unsigned int ifthen_state;
1537
/* IT state for the next instruction.  */
1538
static unsigned int ifthen_next_state;
1539
/* The address of the insn for which the IT state is valid.  */
1540
static bfd_vma ifthen_address;
1541
#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1542

    
1543
/* Cached mapping symbol state.  */
1544
enum map_type {
1545
  MAP_ARM,
1546
  MAP_THUMB,
1547
  MAP_DATA
1548
};
1549

    
1550
enum map_type last_type;
1551
int last_mapping_sym = -1;
1552
bfd_vma last_mapping_addr = 0;
1553

    
1554
/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1555
   Returns pointer to following character of the format string and
1556
   fills in *VALUEP and *WIDTHP with the extracted value and number of
1557
   bits extracted.  WIDTHP can be NULL. */
1558

    
1559
static const char *
1560
arm_decode_bitfield (const char *ptr, unsigned long insn,
1561
                     unsigned long *valuep, int *widthp)
1562
{
1563
  unsigned long value = 0;
1564
  int width = 0;
1565

    
1566
  do
1567
    {
1568
      int start, end;
1569
      int bits;
1570

    
1571
      for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1572
        start = start * 10 + *ptr - '0';
1573
      if (*ptr == '-')
1574
        for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1575
          end = end * 10 + *ptr - '0';
1576
      else
1577
        end = start;
1578
      bits = end - start;
1579
      if (bits < 0)
1580
        abort ();
1581
      value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1582
      width += bits + 1;
1583
    }
1584
  while (*ptr++ == ',');
1585
  *valuep = value;
1586
  if (widthp)
1587
    *widthp = width;
1588
  return ptr - 1;
1589
}
1590

    
1591
static void
1592
arm_decode_shift (long given, fprintf_ftype func, void *stream,
1593
                  int print_shift)
1594
{
1595
  func (stream, "%s", arm_regnames[given & 0xf]);
1596

    
1597
  if ((given & 0xff0) != 0)
1598
    {
1599
      if ((given & 0x10) == 0)
1600
        {
1601
          int amount = (given & 0xf80) >> 7;
1602
          int shift = (given & 0x60) >> 5;
1603

    
1604
          if (amount == 0)
1605
            {
1606
              if (shift == 3)
1607
                {
1608
                  func (stream, ", rrx");
1609
                  return;
1610
                }
1611

    
1612
              amount = 32;
1613
            }
1614

    
1615
          if (print_shift)
1616
            func (stream, ", %s #%d", arm_shift[shift], amount);
1617
          else
1618
            func (stream, ", #%d", amount);
1619
        }
1620
      else if (print_shift)
1621
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1622
              arm_regnames[(given & 0xf00) >> 8]);
1623
      else
1624
        func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1625
    }
1626
}
1627

    
1628
/* Print one coprocessor instruction on INFO->STREAM.
1629
   Return true if the instuction matched, false if this is not a
1630
   recognised coprocessor instruction.  */
1631

    
1632
static bfd_boolean
1633
print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1634
                        bfd_boolean thumb)
1635
{
1636
  const struct opcode32 *insn;
1637
  void *stream = info->stream;
1638
  fprintf_ftype func = info->fprintf_func;
1639
  unsigned long mask;
1640
  unsigned long value;
1641
  int cond;
1642

    
1643
  for (insn = coprocessor_opcodes; insn->assembler; insn++)
1644
    {
1645
      if (insn->value == FIRST_IWMMXT_INSN
1646
          && info->mach != bfd_mach_arm_XScale
1647
          && info->mach != bfd_mach_arm_iWMMXt
1648
          && info->mach != bfd_mach_arm_iWMMXt2)
1649
        insn = insn + IWMMXT_INSN_COUNT;
1650

    
1651
      mask = insn->mask;
1652
      value = insn->value;
1653
      if (thumb)
1654
        {
1655
          /* The high 4 bits are 0xe for Arm conditional instructions, and
1656
             0xe for arm unconditional instructions.  The rest of the
1657
             encoding is the same.  */
1658
          mask |= 0xf0000000;
1659
          value |= 0xe0000000;
1660
          if (ifthen_state)
1661
            cond = IFTHEN_COND;
1662
          else
1663
            cond = 16;
1664
        }
1665
      else
1666
        {
1667
          /* Only match unconditional instuctions against unconditional
1668
             patterns.  */
1669
          if ((given & 0xf0000000) == 0xf0000000)
1670
            {
1671
              mask |= 0xf0000000;
1672
              cond = 16;
1673
            }
1674
          else
1675
            {
1676
              cond = (given >> 28) & 0xf;
1677
              if (cond == 0xe)
1678
                cond = 16;
1679
            }
1680
        }
1681
      if ((given & mask) == value)
1682
        {
1683
          const char *c;
1684

    
1685
          for (c = insn->assembler; *c; c++)
1686
            {
1687
              if (*c == '%')
1688
                {
1689
                  switch (*++c)
1690
                    {
1691
                    case '%':
1692
                      func (stream, "%%");
1693
                      break;
1694

    
1695
                    case 'A':
1696
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1697

    
1698
                      if ((given & (1 << 24)) != 0)
1699
                        {
1700
                          int offset = given & 0xff;
1701

    
1702
                          if (offset)
1703
                            func (stream, ", #%s%d]%s",
1704
                                  ((given & 0x00800000) == 0 ? "-" : ""),
1705
                                  offset * 4,
1706
                                  ((given & 0x00200000) != 0 ? "!" : ""));
1707
                          else
1708
                            func (stream, "]");
1709
                        }
1710
                      else
1711
                        {
1712
                          int offset = given & 0xff;
1713

    
1714
                          func (stream, "]");
1715

    
1716
                          if (given & (1 << 21))
1717
                            {
1718
                              if (offset)
1719
                                func (stream, ", #%s%d",
1720
                                      ((given & 0x00800000) == 0 ? "-" : ""),
1721
                                      offset * 4);
1722
                            }
1723
                          else
1724
                            func (stream, ", {%d}", offset);
1725
                        }
1726
                      break;
1727

    
1728
                    case 'B':
1729
                      {
1730
                        int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1731
                        int offset = (given >> 1) & 0x3f;
1732

    
1733
                        if (offset == 1)
1734
                          func (stream, "{d%d}", regno);
1735
                        else if (regno + offset > 32)
1736
                          func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1737
                        else
1738
                          func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1739
                      }
1740
                      break;
1741

    
1742
                    case 'C':
1743
                      {
1744
                        int rn = (given >> 16) & 0xf;
1745
                        int offset = (given & 0xff) * 4;
1746
                        int add = (given >> 23) & 1;
1747

    
1748
                        func (stream, "[%s", arm_regnames[rn]);
1749

    
1750
                        if (offset)
1751
                          {
1752
                            if (!add)
1753
                              offset = -offset;
1754
                            func (stream, ", #%d", offset);
1755
                          }
1756
                        func (stream, "]");
1757
                        if (rn == 15)
1758
                          {
1759
                            func (stream, "\t; ");
1760
                            /* FIXME: Unsure if info->bytes_per_chunk is the
1761
                               right thing to use here.  */
1762
                            info->print_address_func (offset + pc
1763
                              + info->bytes_per_chunk * 2, info);
1764
                          }
1765
                      }
1766
                      break;
1767

    
1768
                    case 'c':
1769
                      func (stream, "%s", arm_conditional[cond]);
1770
                      break;
1771

    
1772
                    case 'I':
1773
                      /* Print a Cirrus/DSP shift immediate.  */
1774
                      /* Immediates are 7bit signed ints with bits 0..3 in
1775
                         bits 0..3 of opcode and bits 4..6 in bits 5..7
1776
                         of opcode.  */
1777
                      {
1778
                        int imm;
1779

    
1780
                        imm = (given & 0xf) | ((given & 0xe0) >> 1);
1781

    
1782
                        /* Is ``imm'' a negative number?  */
1783
                        if (imm & 0x40)
1784
                          imm |= (-1 << 7);
1785

    
1786
                        func (stream, "%d", imm);
1787
                      }
1788

    
1789
                      break;
1790

    
1791
                    case 'F':
1792
                      switch (given & 0x00408000)
1793
                        {
1794
                        case 0:
1795
                          func (stream, "4");
1796
                          break;
1797
                        case 0x8000:
1798
                          func (stream, "1");
1799
                          break;
1800
                        case 0x00400000:
1801
                          func (stream, "2");
1802
                          break;
1803
                        default:
1804
                          func (stream, "3");
1805
                        }
1806
                      break;
1807

    
1808
                    case 'P':
1809
                      switch (given & 0x00080080)
1810
                        {
1811
                        case 0:
1812
                          func (stream, "s");
1813
                          break;
1814
                        case 0x80:
1815
                          func (stream, "d");
1816
                          break;
1817
                        case 0x00080000:
1818
                          func (stream, "e");
1819
                          break;
1820
                        default:
1821
                          func (stream, _("<illegal precision>"));
1822
                          break;
1823
                        }
1824
                      break;
1825
                    case 'Q':
1826
                      switch (given & 0x00408000)
1827
                        {
1828
                        case 0:
1829
                          func (stream, "s");
1830
                          break;
1831
                        case 0x8000:
1832
                          func (stream, "d");
1833
                          break;
1834
                        case 0x00400000:
1835
                          func (stream, "e");
1836
                          break;
1837
                        default:
1838
                          func (stream, "p");
1839
                          break;
1840
                        }
1841
                      break;
1842
                    case 'R':
1843
                      switch (given & 0x60)
1844
                        {
1845
                        case 0:
1846
                          break;
1847
                        case 0x20:
1848
                          func (stream, "p");
1849
                          break;
1850
                        case 0x40:
1851
                          func (stream, "m");
1852
                          break;
1853
                        default:
1854
                          func (stream, "z");
1855
                          break;
1856
                        }
1857
                      break;
1858

    
1859
                    case '0': case '1': case '2': case '3': case '4':
1860
                    case '5': case '6': case '7': case '8': case '9':
1861
                      {
1862
                        int width;
1863
                        unsigned long value;
1864

    
1865
                        c = arm_decode_bitfield (c, given, &value, &width);
1866

    
1867
                        switch (*c)
1868
                          {
1869
                          case 'r':
1870
                            func (stream, "%s", arm_regnames[value]);
1871
                            break;
1872
                          case 'D':
1873
                            func (stream, "d%ld", value);
1874
                            break;
1875
                          case 'Q':
1876
                            if (value & 1)
1877
                              func (stream, "<illegal reg q%ld.5>", value >> 1);
1878
                            else
1879
                              func (stream, "q%ld", value >> 1);
1880
                            break;
1881
                          case 'd':
1882
                            func (stream, "%ld", value);
1883
                            break;
1884
                          case 'k':
1885
                            {
1886
                              int from = (given & (1 << 7)) ? 32 : 16;
1887
                              func (stream, "%ld", from - value);
1888
                            }
1889
                            break;
1890

    
1891
                          case 'f':
1892
                            if (value > 7)
1893
                              func (stream, "#%s", arm_fp_const[value & 7]);
1894
                            else
1895
                              func (stream, "f%ld", value);
1896
                            break;
1897

    
1898
                          case 'w':
1899
                            if (width == 2)
1900
                              func (stream, "%s", iwmmxt_wwnames[value]);
1901
                            else
1902
                              func (stream, "%s", iwmmxt_wwssnames[value]);
1903
                            break;
1904

    
1905
                          case 'g':
1906
                            func (stream, "%s", iwmmxt_regnames[value]);
1907
                            break;
1908
                          case 'G':
1909
                            func (stream, "%s", iwmmxt_cregnames[value]);
1910
                            break;
1911

    
1912
                          case 'x':
1913
                            func (stream, "0x%lx", value);
1914
                            break;
1915

    
1916
                          case '`':
1917
                            c++;
1918
                            if (value == 0)
1919
                              func (stream, "%c", *c);
1920
                            break;
1921
                          case '\'':
1922
                            c++;
1923
                            if (value == ((1ul << width) - 1))
1924
                              func (stream, "%c", *c);
1925
                            break;
1926
                          case '?':
1927
                            func (stream, "%c", c[(1 << width) - (int)value]);
1928
                            c += 1 << width;
1929
                            break;
1930
                          default:
1931
                            abort ();
1932
                          }
1933
                        break;
1934

    
1935
                      case 'y':
1936
                      case 'z':
1937
                        {
1938
                          int single = *c++ == 'y';
1939
                          int regno;
1940

    
1941
                          switch (*c)
1942
                            {
1943
                            case '4': /* Sm pair */
1944
                              func (stream, "{");
1945
                              /* Fall through.  */
1946
                            case '0': /* Sm, Dm */
1947
                              regno = given & 0x0000000f;
1948
                              if (single)
1949
                                {
1950
                                  regno <<= 1;
1951
                                  regno += (given >> 5) & 1;
1952
                                }
1953
                              else
1954
                                regno += ((given >> 5) & 1) << 4;
1955
                              break;
1956

    
1957
                            case '1': /* Sd, Dd */
1958
                              regno = (given >> 12) & 0x0000000f;
1959
                              if (single)
1960
                                {
1961
                                  regno <<= 1;
1962
                                  regno += (given >> 22) & 1;
1963
                                }
1964
                              else
1965
                                regno += ((given >> 22) & 1) << 4;
1966
                              break;
1967

    
1968
                            case '2': /* Sn, Dn */
1969
                              regno = (given >> 16) & 0x0000000f;
1970
                              if (single)
1971
                                {
1972
                                  regno <<= 1;
1973
                                  regno += (given >> 7) & 1;
1974
                                }
1975
                              else
1976
                                regno += ((given >> 7) & 1) << 4;
1977
                              break;
1978

    
1979
                            case '3': /* List */
1980
                              func (stream, "{");
1981
                              regno = (given >> 12) & 0x0000000f;
1982
                              if (single)
1983
                                {
1984
                                  regno <<= 1;
1985
                                  regno += (given >> 22) & 1;
1986
                                }
1987
                              else
1988
                                regno += ((given >> 22) & 1) << 4;
1989
                              break;
1990

    
1991
                            default:
1992
                              abort ();
1993
                            }
1994

    
1995
                          func (stream, "%c%d", single ? 's' : 'd', regno);
1996

    
1997
                          if (*c == '3')
1998
                            {
1999
                              int count = given & 0xff;
2000

    
2001
                              if (single == 0)
2002
                                count >>= 1;
2003

    
2004
                              if (--count)
2005
                                {
2006
                                  func (stream, "-%c%d",
2007
                                        single ? 's' : 'd',
2008
                                        regno + count);
2009
                                }
2010

    
2011
                              func (stream, "}");
2012
                            }
2013
                          else if (*c == '4')
2014
                            func (stream, ", %c%d}", single ? 's' : 'd',
2015
                                  regno + 1);
2016
                        }
2017
                        break;
2018

    
2019
                      case 'L':
2020
                        switch (given & 0x00400100)
2021
                          {
2022
                          case 0x00000000: func (stream, "b"); break;
2023
                          case 0x00400000: func (stream, "h"); break;
2024
                          case 0x00000100: func (stream, "w"); break;
2025
                          case 0x00400100: func (stream, "d"); break;
2026
                          default:
2027
                            break;
2028
                          }
2029
                        break;
2030

    
2031
                      case 'Z':
2032
                        {
2033
                          int value;
2034
                          /* given (20, 23) | given (0, 3) */
2035
                          value = ((given >> 16) & 0xf0) | (given & 0xf);
2036
                          func (stream, "%d", value);
2037
                        }
2038
                        break;
2039

    
2040
                      case 'l':
2041
                        /* This is like the 'A' operator, except that if
2042
                           the width field "M" is zero, then the offset is
2043
                           *not* multiplied by four.  */
2044
                        {
2045
                          int offset = given & 0xff;
2046
                          int multiplier = (given & 0x00000100) ? 4 : 1;
2047

    
2048
                          func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2049

    
2050
                          if (offset)
2051
                            {
2052
                              if ((given & 0x01000000) != 0)
2053
                                func (stream, ", #%s%d]%s",
2054
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2055
                                      offset * multiplier,
2056
                                      ((given & 0x00200000) != 0 ? "!" : ""));
2057
                              else
2058
                                func (stream, "], #%s%d",
2059
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2060
                                      offset * multiplier);
2061
                            }
2062
                          else
2063
                            func (stream, "]");
2064
                        }
2065
                        break;
2066

    
2067
                      case 'r':
2068
                        {
2069
                          int imm4 = (given >> 4) & 0xf;
2070
                          int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2071
                          int ubit = (given >> 23) & 1;
2072
                          const char *rm = arm_regnames [given & 0xf];
2073
                          const char *rn = arm_regnames [(given >> 16) & 0xf];
2074

    
2075
                          switch (puw_bits)
2076
                            {
2077
                            case 1:
2078
                              /* fall through */
2079
                            case 3:
2080
                              func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2081
                              if (imm4)
2082
                                func (stream, ", lsl #%d", imm4);
2083
                              break;
2084

    
2085
                            case 4:
2086
                              /* fall through */
2087
                            case 5:
2088
                              /* fall through */
2089
                            case 6:
2090
                              /* fall through */
2091
                            case 7:
2092
                              func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2093
                              if (imm4 > 0)
2094
                                func (stream, ", lsl #%d", imm4);
2095
                              func (stream, "]");
2096
                              if (puw_bits == 5 || puw_bits == 7)
2097
                                func (stream, "!");
2098
                              break;
2099

    
2100
                            default:
2101
                              func (stream, "INVALID");
2102
                            }
2103
                        }
2104
                        break;
2105

    
2106
                      case 'i':
2107
                        {
2108
                          long imm5;
2109
                          imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2110
                          func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2111
                        }
2112
                        break;
2113

    
2114
                      default:
2115
                        abort ();
2116
                      }
2117
                    }
2118
                }
2119
              else
2120
                func (stream, "%c", *c);
2121
            }
2122
          return true;
2123
        }
2124
    }
2125
  return false;
2126
}
2127

    
2128
static void
2129
print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2130
{
2131
  void *stream = info->stream;
2132
  fprintf_ftype func = info->fprintf_func;
2133

    
2134
  if (((given & 0x000f0000) == 0x000f0000)
2135
      && ((given & 0x02000000) == 0))
2136
    {
2137
      int offset = given & 0xfff;
2138

    
2139
      func (stream, "[pc");
2140

    
2141
      if (given & 0x01000000)
2142
        {
2143
          if ((given & 0x00800000) == 0)
2144
            offset = - offset;
2145

    
2146
          /* Pre-indexed.  */
2147
          func (stream, ", #%d]", offset);
2148

    
2149
          offset += pc + 8;
2150

    
2151
          /* Cope with the possibility of write-back
2152
             being used.  Probably a very dangerous thing
2153
             for the programmer to do, but who are we to
2154
             argue ?  */
2155
          if (given & 0x00200000)
2156
            func (stream, "!");
2157
        }
2158
      else
2159
        {
2160
          /* Post indexed.  */
2161
          func (stream, "], #%d", offset);
2162

    
2163
          /* ie ignore the offset.  */
2164
          offset = pc + 8;
2165
        }
2166

    
2167
      func (stream, "\t; ");
2168
      info->print_address_func (offset, info);
2169
    }
2170
  else
2171
    {
2172
      func (stream, "[%s",
2173
            arm_regnames[(given >> 16) & 0xf]);
2174
      if ((given & 0x01000000) != 0)
2175
        {
2176
          if ((given & 0x02000000) == 0)
2177
            {
2178
              int offset = given & 0xfff;
2179
              if (offset)
2180
                func (stream, ", #%s%d",
2181
                      (((given & 0x00800000) == 0)
2182
                       ? "-" : ""), offset);
2183
            }
2184
          else
2185
            {
2186
              func (stream, ", %s",
2187
                    (((given & 0x00800000) == 0)
2188
                     ? "-" : ""));
2189
              arm_decode_shift (given, func, stream, 1);
2190
            }
2191

    
2192
          func (stream, "]%s",
2193
                ((given & 0x00200000) != 0) ? "!" : "");
2194
        }
2195
      else
2196
        {
2197
          if ((given & 0x02000000) == 0)
2198
            {
2199
              int offset = given & 0xfff;
2200
              if (offset)
2201
                func (stream, "], #%s%d",
2202
                      (((given & 0x00800000) == 0)
2203
                       ? "-" : ""), offset);
2204
              else
2205
                func (stream, "]");
2206
            }
2207
          else
2208
            {
2209
              func (stream, "], %s",
2210
                    (((given & 0x00800000) == 0)
2211
                     ? "-" : ""));
2212
              arm_decode_shift (given, func, stream, 1);
2213
            }
2214
        }
2215
    }
2216
}
2217

    
2218
/* Print one neon instruction on INFO->STREAM.
2219
   Return true if the instuction matched, false if this is not a
2220
   recognised neon instruction.  */
2221

    
2222
static bfd_boolean
2223
print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2224
{
2225
  const struct opcode32 *insn;
2226
  void *stream = info->stream;
2227
  fprintf_ftype func = info->fprintf_func;
2228

    
2229
  if (thumb)
2230
    {
2231
      if ((given & 0xef000000) == 0xef000000)
2232
        {
2233
          /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
2234
          unsigned long bit28 = given & (1 << 28);
2235

    
2236
          given &= 0x00ffffff;
2237
          if (bit28)
2238
            given |= 0xf3000000;
2239
          else
2240
            given |= 0xf2000000;
2241
        }
2242
      else if ((given & 0xff000000) == 0xf9000000)
2243
        given ^= 0xf9000000 ^ 0xf4000000;
2244
      else
2245
        return false;
2246
    }
2247

    
2248
  for (insn = neon_opcodes; insn->assembler; insn++)
2249
    {
2250
      if ((given & insn->mask) == insn->value)
2251
        {
2252
          const char *c;
2253

    
2254
          for (c = insn->assembler; *c; c++)
2255
            {
2256
              if (*c == '%')
2257
                {
2258
                  switch (*++c)
2259
                    {
2260
                    case '%':
2261
                      func (stream, "%%");
2262
                      break;
2263

    
2264
                    case 'c':
2265
                      if (thumb && ifthen_state)
2266
                        func (stream, "%s", arm_conditional[IFTHEN_COND]);
2267
                      break;
2268

    
2269
                    case 'A':
2270
                      {
2271
                        static const unsigned char enc[16] =
2272
                        {
2273
                          0x4, 0x14, /* st4 0,1 */
2274
                          0x4, /* st1 2 */
2275
                          0x4, /* st2 3 */
2276
                          0x3, /* st3 4 */
2277
                          0x13, /* st3 5 */
2278
                          0x3, /* st1 6 */
2279
                          0x1, /* st1 7 */
2280
                          0x2, /* st2 8 */
2281
                          0x12, /* st2 9 */
2282
                          0x2, /* st1 10 */
2283
                          0, 0, 0, 0, 0
2284
                        };
2285
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2286
                        int rn = ((given >> 16) & 0xf);
2287
                        int rm = ((given >> 0) & 0xf);
2288
                        int align = ((given >> 4) & 0x3);
2289
                        int type = ((given >> 8) & 0xf);
2290
                        int n = enc[type] & 0xf;
2291
                        int stride = (enc[type] >> 4) + 1;
2292
                        int ix;
2293

    
2294
                        func (stream, "{");
2295
                        if (stride > 1)
2296
                          for (ix = 0; ix != n; ix++)
2297
                            func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2298
                        else if (n == 1)
2299
                          func (stream, "d%d", rd);
2300
                        else
2301
                          func (stream, "d%d-d%d", rd, rd + n - 1);
2302
                        func (stream, "}, [%s", arm_regnames[rn]);
2303
                        if (align)
2304
                          func (stream, ", :%d", 32 << align);
2305
                        func (stream, "]");
2306
                        if (rm == 0xd)
2307
                          func (stream, "!");
2308
                        else if (rm != 0xf)
2309
                          func (stream, ", %s", arm_regnames[rm]);
2310
                      }
2311
                      break;
2312

    
2313
                    case 'B':
2314
                      {
2315
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2316
                        int rn = ((given >> 16) & 0xf);
2317
                        int rm = ((given >> 0) & 0xf);
2318
                        int idx_align = ((given >> 4) & 0xf);
2319
                        int align = 0;
2320
                        int size = ((given >> 10) & 0x3);
2321
                        int idx = idx_align >> (size + 1);
2322
                        int length = ((given >> 8) & 3) + 1;
2323
                        int stride = 1;
2324
                        int i;
2325

    
2326
                        if (length > 1 && size > 0)
2327
                          stride = (idx_align & (1 << size)) ? 2 : 1;
2328

    
2329
                        switch (length)
2330
                          {
2331
                          case 1:
2332
                            {
2333
                              int amask = (1 << size) - 1;
2334
                              if ((idx_align & (1 << size)) != 0)
2335
                                return false;
2336
                              if (size > 0)
2337
                                {
2338
                                  if ((idx_align & amask) == amask)
2339
                                    align = 8 << size;
2340
                                  else if ((idx_align & amask) != 0)
2341
                                    return false;
2342
                                }
2343
                              }
2344
                            break;
2345

    
2346
                          case 2:
2347
                            if (size == 2 && (idx_align & 2) != 0)
2348
                              return false;
2349
                            align = (idx_align & 1) ? 16 << size : 0;
2350
                            break;
2351

    
2352
                          case 3:
2353
                            if ((size == 2 && (idx_align & 3) != 0)
2354
                                || (idx_align & 1) != 0)
2355
                              return false;
2356
                            break;
2357

    
2358
                          case 4:
2359
                            if (size == 2)
2360
                              {
2361
                                if ((idx_align & 3) == 3)
2362
                                  return false;
2363
                                align = (idx_align & 3) * 64;
2364
                              }
2365
                            else
2366
                              align = (idx_align & 1) ? 32 << size : 0;
2367
                            break;
2368

    
2369
                          default:
2370
                            abort ();
2371
                          }
2372

    
2373
                        func (stream, "{");
2374
                        for (i = 0; i < length; i++)
2375
                          func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2376
                            rd + i * stride, idx);
2377
                        func (stream, "}, [%s", arm_regnames[rn]);
2378
                        if (align)
2379
                          func (stream, ", :%d", align);
2380
                        func (stream, "]");
2381
                        if (rm == 0xd)
2382
                          func (stream, "!");
2383
                        else if (rm != 0xf)
2384
                          func (stream, ", %s", arm_regnames[rm]);
2385
                      }
2386
                      break;
2387

    
2388
                    case 'C':
2389
                      {
2390
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2391
                        int rn = ((given >> 16) & 0xf);
2392
                        int rm = ((given >> 0) & 0xf);
2393
                        int align = ((given >> 4) & 0x1);
2394
                        int size = ((given >> 6) & 0x3);
2395
                        int type = ((given >> 8) & 0x3);
2396
                        int n = type + 1;
2397
                        int stride = ((given >> 5) & 0x1);
2398
                        int ix;
2399

    
2400
                        if (stride && (n == 1))
2401
                          n++;
2402
                        else
2403
                          stride++;
2404

    
2405
                        func (stream, "{");
2406
                        if (stride > 1)
2407
                          for (ix = 0; ix != n; ix++)
2408
                            func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2409
                        else if (n == 1)
2410
                          func (stream, "d%d[]", rd);
2411
                        else
2412
                          func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2413
                        func (stream, "}, [%s", arm_regnames[rn]);
2414
                        if (align)
2415
                          {
2416
                            int align = (8 * (type + 1)) << size;
2417
                            if (type == 3)
2418
                              align = (size > 1) ? align >> 1 : align;
2419
                            if (type == 2 || (type == 0 && !size))
2420
                              func (stream, ", :<bad align %d>", align);
2421
                            else
2422
                              func (stream, ", :%d", align);
2423
                          }
2424
                        func (stream, "]");
2425
                        if (rm == 0xd)
2426
                          func (stream, "!");
2427
                        else if (rm != 0xf)
2428
                          func (stream, ", %s", arm_regnames[rm]);
2429
                      }
2430
                      break;
2431

    
2432
                    case 'D':
2433
                      {
2434
                        int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2435
                        int size = (given >> 20) & 3;
2436
                        int reg = raw_reg & ((4 << size) - 1);
2437
                        int ix = raw_reg >> size >> 2;
2438

    
2439
                        func (stream, "d%d[%d]", reg, ix);
2440
                      }
2441
                      break;
2442

    
2443
                    case 'E':
2444
                      /* Neon encoded constant for mov, mvn, vorr, vbic */
2445
                      {
2446
                        int bits = 0;
2447
                        int cmode = (given >> 8) & 0xf;
2448
                        int op = (given >> 5) & 0x1;
2449
                        unsigned long value = 0, hival = 0;
2450
                        unsigned shift;
2451
                        int size = 0;
2452
                        int isfloat = 0;
2453

    
2454
                        bits |= ((given >> 24) & 1) << 7;
2455
                        bits |= ((given >> 16) & 7) << 4;
2456
                        bits |= ((given >> 0) & 15) << 0;
2457

    
2458
                        if (cmode < 8)
2459
                          {
2460
                            shift = (cmode >> 1) & 3;
2461
                            value = (unsigned long)bits << (8 * shift);
2462
                            size = 32;
2463
                          }
2464
                        else if (cmode < 12)
2465
                          {
2466
                            shift = (cmode >> 1) & 1;
2467
                            value = (unsigned long)bits << (8 * shift);
2468
                            size = 16;
2469
                          }
2470
                        else if (cmode < 14)
2471
                          {
2472
                            shift = (cmode & 1) + 1;
2473
                            value = (unsigned long)bits << (8 * shift);
2474
                            value |= (1ul << (8 * shift)) - 1;
2475
                            size = 32;
2476
                          }
2477
                        else if (cmode == 14)
2478
                          {
2479
                            if (op)
2480
                              {
2481
                                /* bit replication into bytes */
2482
                                int ix;
2483
                                unsigned long mask;
2484

    
2485
                                value = 0;
2486
                                hival = 0;
2487
                                for (ix = 7; ix >= 0; ix--)
2488
                                  {
2489
                                    mask = ((bits >> ix) & 1) ? 0xff : 0;
2490
                                    if (ix <= 3)
2491
                                      value = (value << 8) | mask;
2492
                                    else
2493
                                      hival = (hival << 8) | mask;
2494
                                  }
2495
                                size = 64;
2496
                              }
2497
                            else
2498
                              {
2499
                                /* byte replication */
2500
                                value = (unsigned long)bits;
2501
                                size = 8;
2502
                              }
2503
                          }
2504
                        else if (!op)
2505
                          {
2506
                            /* floating point encoding */
2507
                            int tmp;
2508

    
2509
                            value = (unsigned long)(bits & 0x7f) << 19;
2510
                            value |= (unsigned long)(bits & 0x80) << 24;
2511
                            tmp = bits & 0x40 ? 0x3c : 0x40;
2512
                            value |= (unsigned long)tmp << 24;
2513
                            size = 32;
2514
                            isfloat = 1;
2515
                          }
2516
                        else
2517
                          {
2518
                            func (stream, "<illegal constant %.8x:%x:%x>",
2519
                                  bits, cmode, op);
2520
                            size = 32;
2521
                            break;
2522
                          }
2523
                        switch (size)
2524
                          {
2525
                          case 8:
2526
                            func (stream, "#%ld\t; 0x%.2lx", value, value);
2527
                            break;
2528

    
2529
                          case 16:
2530
                            func (stream, "#%ld\t; 0x%.4lx", value, value);
2531
                            break;
2532

    
2533
                          case 32:
2534
                            if (isfloat)
2535
                              {
2536
                                unsigned char valbytes[4];
2537
                                double fvalue;
2538

    
2539
                                /* Do this a byte at a time so we don't have to
2540
                                   worry about the host's endianness.  */
2541
                                valbytes[0] = value & 0xff;
2542
                                valbytes[1] = (value >> 8) & 0xff;
2543
                                valbytes[2] = (value >> 16) & 0xff;
2544
                                valbytes[3] = (value >> 24) & 0xff;
2545

    
2546
                                floatformat_to_double
2547
                                  (&floatformat_ieee_single_little, valbytes,
2548
                                  &fvalue);
2549

    
2550
                                func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2551
                                      value);
2552
                              }
2553
                            else
2554
                              func (stream, "#%ld\t; 0x%.8lx",
2555
                                (long) ((value & 0x80000000)
2556
                                        ? value | ~0xffffffffl : value), value);
2557
                            break;
2558

    
2559
                          case 64:
2560
                            func (stream, "#0x%.8lx%.8lx", hival, value);
2561
                            break;
2562

    
2563
                          default:
2564
                            abort ();
2565
                          }
2566
                      }
2567
                      break;
2568

    
2569
                    case 'F':
2570
                      {
2571
                        int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2572
                        int num = (given >> 8) & 0x3;
2573

    
2574
                        if (!num)
2575
                          func (stream, "{d%d}", regno);
2576
                        else if (num + regno >= 32)
2577
                          func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2578
                        else
2579
                          func (stream, "{d%d-d%d}", regno, regno + num);
2580
                      }
2581
                      break;
2582

    
2583

    
2584
                    case '0': case '1': case '2': case '3': case '4':
2585
                    case '5': case '6': case '7': case '8': case '9':
2586
                      {
2587
                        int width;
2588
                        unsigned long value;
2589

    
2590
                        c = arm_decode_bitfield (c, given, &value, &width);
2591

    
2592
                        switch (*c)
2593
                          {
2594
                          case 'r':
2595
                            func (stream, "%s", arm_regnames[value]);
2596
                            break;
2597
                          case 'd':
2598
                            func (stream, "%ld", value);
2599
                            break;
2600
                          case 'e':
2601
                            func (stream, "%ld", (1ul << width) - value);
2602
                            break;
2603

    
2604
                          case 'S':
2605
                          case 'T':
2606
                          case 'U':
2607
                            /* various width encodings */
2608
                            {
2609
                              int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2610
                              int limit;
2611
                              unsigned low, high;
2612

    
2613
                              c++;
2614
                              if (*c >= '0' && *c <= '9')
2615
                                limit = *c - '0';
2616
                              else if (*c >= 'a' && *c <= 'f')
2617
                                limit = *c - 'a' + 10;
2618
                              else
2619
                                abort ();
2620
                              low = limit >> 2;
2621
                              high = limit & 3;
2622

    
2623
                              if (value < low || value > high)
2624
                                func (stream, "<illegal width %d>", base << value);
2625
                              else
2626
                                func (stream, "%d", base << value);
2627
                            }
2628
                            break;
2629
                          case 'R':
2630
                            if (given & (1 << 6))
2631
                              goto Q;
2632
                            /* FALLTHROUGH */
2633
                          case 'D':
2634
                            func (stream, "d%ld", value);
2635
                            break;
2636
                          case 'Q':
2637
                          Q:
2638
                            if (value & 1)
2639
                              func (stream, "<illegal reg q%ld.5>", value >> 1);
2640
                            else
2641
                              func (stream, "q%ld", value >> 1);
2642
                            break;
2643

    
2644
                          case '`':
2645
                            c++;
2646
                            if (value == 0)
2647
                              func (stream, "%c", *c);
2648
                            break;
2649
                          case '\'':
2650
                            c++;
2651
                            if (value == ((1ul << width) - 1))
2652
                              func (stream, "%c", *c);
2653
                            break;
2654
                          case '?':
2655
                            func (stream, "%c", c[(1 << width) - (int)value]);
2656
                            c += 1 << width;
2657
                            break;
2658
                          default:
2659
                            abort ();
2660
                          }
2661
                        break;
2662

    
2663
                      default:
2664
                        abort ();
2665
                      }
2666
                    }
2667
                }
2668
              else
2669
                func (stream, "%c", *c);
2670
            }
2671
          return true;
2672
        }
2673
    }
2674
  return false;
2675
}
2676

    
2677
/* Print one ARM instruction from PC on INFO->STREAM.  */
2678

    
2679
static void
2680
print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
2681
{
2682
  const struct opcode32 *insn;
2683
  void *stream = info->stream;
2684
  fprintf_ftype func = info->fprintf_func;
2685

    
2686
  if (print_insn_coprocessor (pc, info, given, false))
2687
    return;
2688

    
2689
  if (print_insn_neon (info, given, false))
2690
    return;
2691

    
2692
  for (insn = arm_opcodes; insn->assembler; insn++)
2693
    {
2694
      if (insn->value == FIRST_IWMMXT_INSN
2695
          && info->mach != bfd_mach_arm_XScale
2696
          && info->mach != bfd_mach_arm_iWMMXt)
2697
        insn = insn + IWMMXT_INSN_COUNT;
2698

    
2699
      if ((given & insn->mask) == insn->value
2700
          /* Special case: an instruction with all bits set in the condition field
2701
             (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2702
             or by the catchall at the end of the table.  */
2703
          && ((given & 0xF0000000) != 0xF0000000
2704
              || (insn->mask & 0xF0000000) == 0xF0000000
2705
              || (insn->mask == 0 && insn->value == 0)))
2706
        {
2707
          const char *c;
2708

    
2709
          for (c = insn->assembler; *c; c++)
2710
            {
2711
              if (*c == '%')
2712
                {
2713
                  switch (*++c)
2714
                    {
2715
                    case '%':
2716
                      func (stream, "%%");
2717
                      break;
2718

    
2719
                    case 'a':
2720
                      print_arm_address (pc, info, given);
2721
                      break;
2722

    
2723
                    case 'P':
2724
                      /* Set P address bit and use normal address
2725
                         printing routine.  */
2726
                      print_arm_address (pc, info, given | (1 << 24));
2727
                      break;
2728

    
2729
                    case 's':
2730
                      if ((given & 0x004f0000) == 0x004f0000)
2731
                        {
2732
                          /* PC relative with immediate offset.  */
2733
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2734

    
2735
                          if ((given & 0x00800000) == 0)
2736
                            offset = -offset;
2737

    
2738
                          func (stream, "[pc, #%d]\t; ", offset);
2739
                          info->print_address_func (offset + pc + 8, info);
2740
                        }
2741
                      else
2742
                        {
2743
                          func (stream, "[%s",
2744
                                arm_regnames[(given >> 16) & 0xf]);
2745
                          if ((given & 0x01000000) != 0)
2746
                            {
2747
                              /* Pre-indexed.  */
2748
                              if ((given & 0x00400000) == 0x00400000)
2749
                                {
2750
                                  /* Immediate.  */
2751
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2752
                                  if (offset)
2753
                                    func (stream, ", #%s%d",
2754
                                          (((given & 0x00800000) == 0)
2755
                                           ? "-" : ""), offset);
2756
                                }
2757
                              else
2758
                                {
2759
                                  /* Register.  */
2760
                                  func (stream, ", %s%s",
2761
                                        (((given & 0x00800000) == 0)
2762
                                         ? "-" : ""),
2763
                                        arm_regnames[given & 0xf]);
2764
                                }
2765

    
2766
                              func (stream, "]%s",
2767
                                    ((given & 0x00200000) != 0) ? "!" : "");
2768
                            }
2769
                          else
2770
                            {
2771
                              /* Post-indexed.  */
2772
                              if ((given & 0x00400000) == 0x00400000)
2773
                                {
2774
                                  /* Immediate.  */
2775
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2776
                                  if (offset)
2777
                                    func (stream, "], #%s%d",
2778
                                          (((given & 0x00800000) == 0)
2779
                                           ? "-" : ""), offset);
2780
                                  else
2781
                                    func (stream, "]");
2782
                                }
2783
                              else
2784
                                {
2785
                                  /* Register.  */
2786
                                  func (stream, "], %s%s",
2787
                                        (((given & 0x00800000) == 0)
2788
                                         ? "-" : ""),
2789
                                        arm_regnames[given & 0xf]);
2790
                                }
2791
                            }
2792
                        }
2793
                      break;
2794

    
2795
                    case 'b':
2796
                      {
2797
                        int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2798
                        info->print_address_func (disp*4 + pc + 8, info);
2799
                      }
2800
                      break;
2801

    
2802
                    case 'c':
2803
                      if (((given >> 28) & 0xf) != 0xe)
2804
                        func (stream, "%s",
2805
                              arm_conditional [(given >> 28) & 0xf]);
2806
                      break;
2807

    
2808
                    case 'm':
2809
                      {
2810
                        int started = 0;
2811
                        int reg;
2812

    
2813
                        func (stream, "{");
2814
                        for (reg = 0; reg < 16; reg++)
2815
                          if ((given & (1 << reg)) != 0)
2816
                            {
2817
                              if (started)
2818
                                func (stream, ", ");
2819
                              started = 1;
2820
                              func (stream, "%s", arm_regnames[reg]);
2821
                            }
2822
                        func (stream, "}");
2823
                      }
2824
                      break;
2825

    
2826
                    case 'q':
2827
                      arm_decode_shift (given, func, stream, 0);
2828
                      break;
2829

    
2830
                    case 'o':
2831
                      if ((given & 0x02000000) != 0)
2832
                        {
2833
                          int rotate = (given & 0xf00) >> 7;
2834
                          int immed = (given & 0xff);
2835
                          immed = (((immed << (32 - rotate))
2836
                                    | (immed >> rotate)) & 0xffffffff);
2837
                          func (stream, "#%d\t; 0x%x", immed, immed);
2838
                        }
2839
                      else
2840
                        arm_decode_shift (given, func, stream, 1);
2841
                      break;
2842

    
2843
                    case 'p':
2844
                      if ((given & 0x0000f000) == 0x0000f000)
2845
                        func (stream, "p");
2846
                      break;
2847

    
2848
                    case 't':
2849
                      if ((given & 0x01200000) == 0x00200000)
2850
                        func (stream, "t");
2851
                      break;
2852

    
2853
                    case 'A':
2854
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2855

    
2856
                      if ((given & (1 << 24)) != 0)
2857
                        {
2858
                          int offset = given & 0xff;
2859

    
2860
                          if (offset)
2861
                            func (stream, ", #%s%d]%s",
2862
                                  ((given & 0x00800000) == 0 ? "-" : ""),
2863
                                  offset * 4,
2864
                                  ((given & 0x00200000) != 0 ? "!" : ""));
2865
                          else
2866
                            func (stream, "]");
2867
                        }
2868
                      else
2869
                        {
2870
                          int offset = given & 0xff;
2871

    
2872
                          func (stream, "]");
2873

    
2874
                          if (given & (1 << 21))
2875
                            {
2876
                              if (offset)
2877
                                func (stream, ", #%s%d",
2878
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2879
                                      offset * 4);
2880
                            }
2881
                          else
2882
                            func (stream, ", {%d}", offset);
2883
                        }
2884
                      break;
2885

    
2886
                    case 'B':
2887
                      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2888
                      {
2889
                        bfd_vma address;
2890
                        bfd_vma offset = 0;
2891

    
2892
                        if (given & 0x00800000)
2893
                          /* Is signed, hi bits should be ones.  */
2894
                          offset = (-1) ^ 0x00ffffff;
2895

    
2896
                        /* Offset is (SignExtend(offset field)<<2).  */
2897
                        offset += given & 0x00ffffff;
2898
                        offset <<= 2;
2899
                        address = offset + pc + 8;
2900

    
2901
                        if (given & 0x01000000)
2902
                          /* H bit allows addressing to 2-byte boundaries.  */
2903
                          address += 2;
2904

    
2905
                        info->print_address_func (address, info);
2906
                      }
2907
                      break;
2908

    
2909
                    case 'C':
2910
                      func (stream, "_");
2911
                      if (given & 0x80000)
2912
                        func (stream, "f");
2913
                      if (given & 0x40000)
2914
                        func (stream, "s");
2915
                      if (given & 0x20000)
2916
                        func (stream, "x");
2917
                      if (given & 0x10000)
2918
                        func (stream, "c");
2919
                      break;
2920

    
2921
                    case 'U':
2922
                      switch (given & 0xf)
2923
                        {
2924
                        case 0xf: func(stream, "sy"); break;
2925
                        case 0x7: func(stream, "un"); break;
2926
                        case 0xe: func(stream, "st"); break;
2927
                        case 0x6: func(stream, "unst"); break;
2928
                        default:
2929
                          func(stream, "#%d", (int)given & 0xf);
2930
                          break;
2931
                        }
2932
                      break;
2933

    
2934
                    case '0': case '1': case '2': case '3': case '4':
2935
                    case '5': case '6': case '7': case '8': case '9':
2936
                      {
2937
                        int width;
2938
                        unsigned long value;
2939

    
2940
                        c = arm_decode_bitfield (c, given, &value, &width);
2941

    
2942
                        switch (*c)
2943
                          {
2944
                          case 'r':
2945
                            func (stream, "%s", arm_regnames[value]);
2946
                            break;
2947
                          case 'd':
2948
                            func (stream, "%ld", value);
2949
                            break;
2950
                          case 'b':
2951
                            func (stream, "%ld", value * 8);
2952
                            break;
2953
                          case 'W':
2954
                            func (stream, "%ld", value + 1);
2955
                            break;
2956
                          case 'x':
2957
                            func (stream, "0x%08lx", value);
2958

    
2959
                            /* Some SWI instructions have special
2960
                               meanings.  */
2961
                            if ((given & 0x0fffffff) == 0x0FF00000)
2962
                              func (stream, "\t; IMB");
2963
                            else if ((given & 0x0fffffff) == 0x0FF00001)
2964
                              func (stream, "\t; IMBRange");
2965
                            break;
2966
                          case 'X':
2967
                            func (stream, "%01lx", value & 0xf);
2968
                            break;
2969
                          case '`':
2970
                            c++;
2971
                            if (value == 0)
2972
                              func (stream, "%c", *c);
2973
                            break;
2974
                          case '\'':
2975
                            c++;
2976
                            if (value == ((1ul << width) - 1))
2977
                              func (stream, "%c", *c);
2978
                            break;
2979
                          case '?':
2980
                            func (stream, "%c", c[(1 << width) - (int)value]);
2981
                            c += 1 << width;
2982
                            break;
2983
                          default:
2984
                            abort ();
2985
                          }
2986
                        break;
2987

    
2988
                      case 'e':
2989
                        {
2990
                          int imm;
2991

    
2992
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2993
                          func (stream, "%d", imm);
2994
                        }
2995
                        break;
2996

    
2997
                      case 'E':
2998
                        /* LSB and WIDTH fields of BFI or BFC.  The machine-
2999
                           language instruction encodes LSB and MSB.  */
3000
                        {
3001
                          long msb = (given & 0x001f0000) >> 16;
3002
                          long lsb = (given & 0x00000f80) >> 7;
3003

    
3004
                          long width = msb - lsb + 1;
3005
                          if (width > 0)
3006
                            func (stream, "#%lu, #%lu", lsb, width);
3007
                          else
3008
                            func (stream, "(invalid: %lu:%lu)", lsb, msb);
3009
                        }
3010
                        break;
3011

    
3012
                      case 'V':
3013
                        /* 16-bit unsigned immediate from a MOVT or MOVW
3014
                           instruction, encoded in bits 0:11 and 15:19.  */
3015
                        {
3016
                          long hi = (given & 0x000f0000) >> 4;
3017
                          long lo = (given & 0x00000fff);
3018
                          long imm16 = hi | lo;
3019
                          func (stream, "#%lu\t; 0x%lx", imm16, imm16);
3020
                        }
3021
                        break;
3022

    
3023
                      default:
3024
                        abort ();
3025
                      }
3026
                    }
3027
                }
3028
              else
3029
                func (stream, "%c", *c);
3030
            }
3031
          return;
3032
        }
3033
    }
3034
  abort ();
3035
}
3036

    
3037
/* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
3038

    
3039
static void
3040
print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3041
{
3042
  const struct opcode16 *insn;
3043
  void *stream = info->stream;
3044
  fprintf_ftype func = info->fprintf_func;
3045

    
3046
  for (insn = thumb_opcodes; insn->assembler; insn++)
3047
    if ((given & insn->mask) == insn->value)
3048
      {
3049
        const char *c = insn->assembler;
3050
        for (; *c; c++)
3051
          {
3052
            int domaskpc = 0;
3053
            int domasklr = 0;
3054

    
3055
            if (*c != '%')
3056
              {
3057
                func (stream, "%c", *c);
3058
                continue;
3059
              }
3060

    
3061
            switch (*++c)
3062
              {
3063
              case '%':
3064
                func (stream, "%%");
3065
                break;
3066

    
3067
              case 'c':
3068
                if (ifthen_state)
3069
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3070
                break;
3071

    
3072
              case 'C':
3073
                if (ifthen_state)
3074
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3075
                else
3076
                  func (stream, "s");
3077
                break;
3078

    
3079
              case 'I':
3080
                {
3081
                  unsigned int tmp;
3082

    
3083
                  ifthen_next_state = given & 0xff;
3084
                  for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3085
                    func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3086
                  func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3087
                }
3088
                break;
3089

    
3090
              case 'x':
3091
                if (ifthen_next_state)
3092
                  func (stream, "\t; unpredictable branch in IT block\n");
3093
                break;
3094

    
3095
              case 'X':
3096
                if (ifthen_state)
3097
                  func (stream, "\t; unpredictable <IT:%s>",
3098
                        arm_conditional[IFTHEN_COND]);
3099
                break;
3100

    
3101
              case 'S':
3102
                {
3103
                  long reg;
3104

    
3105
                  reg = (given >> 3) & 0x7;
3106
                  if (given & (1 << 6))
3107
                    reg += 8;
3108

    
3109
                  func (stream, "%s", arm_regnames[reg]);
3110
                }
3111
                break;
3112

    
3113
              case 'D':
3114
                {
3115
                  long reg;
3116

    
3117
                  reg = given & 0x7;
3118
                  if (given & (1 << 7))
3119
                    reg += 8;
3120

    
3121
                  func (stream, "%s", arm_regnames[reg]);
3122
                }
3123
                break;
3124

    
3125
              case 'N':
3126
                if (given & (1 << 8))
3127
                  domasklr = 1;
3128
                /* Fall through.  */
3129
              case 'O':
3130
                if (*c == 'O' && (given & (1 << 8)))
3131
                  domaskpc = 1;
3132
                /* Fall through.  */
3133
              case 'M':
3134
                {
3135
                  int started = 0;
3136
                  int reg;
3137

    
3138
                  func (stream, "{");
3139

    
3140
                  /* It would be nice if we could spot
3141
                     ranges, and generate the rS-rE format: */
3142
                  for (reg = 0; (reg < 8); reg++)
3143
                    if ((given & (1 << reg)) != 0)
3144
                      {
3145
                        if (started)
3146
                          func (stream, ", ");
3147
                        started = 1;
3148
                        func (stream, "%s", arm_regnames[reg]);
3149
                      }
3150

    
3151
                  if (domasklr)
3152
                    {
3153
                      if (started)
3154
                        func (stream, ", ");
3155
                      started = 1;
3156
                      func (stream, arm_regnames[14] /* "lr" */);
3157
                    }
3158

    
3159
                  if (domaskpc)
3160
                    {
3161
                      if (started)
3162
                        func (stream, ", ");
3163
                      func (stream, arm_regnames[15] /* "pc" */);
3164
                    }
3165

    
3166
                  func (stream, "}");
3167
                }
3168
                break;
3169

    
3170
              case 'b':
3171
                /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3172
                {
3173
                  bfd_vma address = (pc + 4
3174
                                     + ((given & 0x00f8) >> 2)
3175
                                     + ((given & 0x0200) >> 3));
3176
                  info->print_address_func (address, info);
3177
                }
3178
                break;
3179

    
3180
              case 's':
3181
                /* Right shift immediate -- bits 6..10; 1-31 print
3182
                   as themselves, 0 prints as 32.  */
3183
                {
3184
                  long imm = (given & 0x07c0) >> 6;
3185
                  if (imm == 0)
3186
                    imm = 32;
3187
                  func (stream, "#%ld", imm);
3188
                }
3189
                break;
3190

    
3191
              case '0': case '1': case '2': case '3': case '4':
3192
              case '5': case '6': case '7': case '8': case '9':
3193
                {
3194
                  int bitstart = *c++ - '0';
3195
                  int bitend = 0;
3196

    
3197
                  while (*c >= '0' && *c <= '9')
3198
                    bitstart = (bitstart * 10) + *c++ - '0';
3199

    
3200
                  switch (*c)
3201
                    {
3202
                    case '-':
3203
                      {
3204
                        long reg;
3205

    
3206
                        c++;
3207
                        while (*c >= '0' && *c <= '9')
3208
                          bitend = (bitend * 10) + *c++ - '0';
3209
                        if (!bitend)
3210
                          abort ();
3211
                        reg = given >> bitstart;
3212
                        reg &= (2 << (bitend - bitstart)) - 1;
3213
                        switch (*c)
3214
                          {
3215
                          case 'r':
3216
                            func (stream, "%s", arm_regnames[reg]);
3217
                            break;
3218

    
3219
                          case 'd':
3220
                            func (stream, "%ld", reg);
3221
                            break;
3222

    
3223
                          case 'H':
3224
                            func (stream, "%ld", reg << 1);
3225
                            break;
3226

    
3227
                          case 'W':
3228
                            func (stream, "%ld", reg << 2);
3229
                            break;
3230

    
3231
                          case 'a':
3232
                            /* PC-relative address -- the bottom two
3233
                               bits of the address are dropped
3234
                               before the calculation.  */
3235
                            info->print_address_func
3236
                              (((pc + 4) & ~3) + (reg << 2), info);
3237
                            break;
3238

    
3239
                          case 'x':
3240
                            func (stream, "0x%04lx", reg);
3241
                            break;
3242

    
3243
                          case 'B':
3244
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3245
                            info->print_address_func (reg * 2 + pc + 4, info);
3246
                            break;
3247

    
3248
                          case 'c':
3249
                            func (stream, "%s", arm_conditional [reg]);
3250
                            break;
3251

    
3252
                          default:
3253
                            abort ();
3254
                          }
3255
                      }
3256
                      break;
3257

    
3258
                    case '\'':
3259
                      c++;
3260
                      if ((given & (1 << bitstart)) != 0)
3261
                        func (stream, "%c", *c);
3262
                      break;
3263

    
3264
                    case '?':
3265
                      ++c;
3266
                      if ((given & (1 << bitstart)) != 0)
3267
                        func (stream, "%c", *c++);
3268
                      else
3269
                        func (stream, "%c", *++c);
3270
                      break;
3271

    
3272
                    default:
3273
                      abort ();
3274
                    }
3275
                }
3276
                break;
3277

    
3278
              default:
3279
                abort ();
3280
              }
3281
          }
3282
        return;
3283
      }
3284

    
3285
  /* No match.  */
3286
  abort ();
3287
}
3288

    
3289
/* Return the name of an V7M special register.  */
3290
static const char *
3291
psr_name (int regno)
3292
{
3293
  switch (regno)
3294
    {
3295
    case 0: return "APSR";
3296
    case 1: return "IAPSR";
3297
    case 2: return "EAPSR";
3298
    case 3: return "PSR";
3299
    case 5: return "IPSR";
3300
    case 6: return "EPSR";
3301
    case 7: return "IEPSR";
3302
    case 8: return "MSP";
3303
    case 9: return "PSP";
3304
    case 16: return "PRIMASK";
3305
    case 17: return "BASEPRI";
3306
    case 18: return "BASEPRI_MASK";
3307
    case 19: return "FAULTMASK";
3308
    case 20: return "CONTROL";
3309
    default: return "<unknown>";
3310
    }
3311
}
3312

    
3313
/* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
3314

    
3315
static void
3316
print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3317
{
3318
  const struct opcode32 *insn;
3319
  void *stream = info->stream;
3320
  fprintf_ftype func = info->fprintf_func;
3321

    
3322
  if (print_insn_coprocessor (pc, info, given, true))
3323
    return;
3324

    
3325
  if (print_insn_neon (info, given, true))
3326
    return;
3327

    
3328
  for (insn = thumb32_opcodes; insn->assembler; insn++)
3329
    if ((given & insn->mask) == insn->value)
3330
      {
3331
        const char *c = insn->assembler;
3332
        for (; *c; c++)
3333
          {
3334
            if (*c != '%')
3335
              {
3336
                func (stream, "%c", *c);
3337
                continue;
3338
              }
3339

    
3340
            switch (*++c)
3341
              {
3342
              case '%':
3343
                func (stream, "%%");
3344
                break;
3345

    
3346
              case 'c':
3347
                if (ifthen_state)
3348
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3349
                break;
3350

    
3351
              case 'x':
3352
                if (ifthen_next_state)
3353
                  func (stream, "\t; unpredictable branch in IT block\n");
3354
                break;
3355

    
3356
              case 'X':
3357
                if (ifthen_state)
3358
                  func (stream, "\t; unpredictable <IT:%s>",
3359
                        arm_conditional[IFTHEN_COND]);
3360
                break;
3361

    
3362
              case 'I':
3363
                {
3364
                  unsigned int imm12 = 0;
3365
                  imm12 |= (given & 0x000000ffu);
3366
                  imm12 |= (given & 0x00007000u) >> 4;
3367
                  imm12 |= (given & 0x04000000u) >> 15;
3368
                  func (stream, "#%u\t; 0x%x", imm12, imm12);
3369
                }
3370
                break;
3371

    
3372
              case 'M':
3373
                {
3374
                  unsigned int bits = 0, imm, imm8, mod;
3375
                  bits |= (given & 0x000000ffu);
3376
                  bits |= (given & 0x00007000u) >> 4;
3377
                  bits |= (given & 0x04000000u) >> 15;
3378
                  imm8 = (bits & 0x0ff);
3379
                  mod = (bits & 0xf00) >> 8;
3380
                  switch (mod)
3381
                    {
3382
                    case 0: imm = imm8; break;
3383
                    case 1: imm = ((imm8<<16) | imm8); break;
3384
                    case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3385
                    case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3386
                    default:
3387
                      mod  = (bits & 0xf80) >> 7;
3388
                      imm8 = (bits & 0x07f) | 0x80;
3389
                      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3390
                    }
3391
                  func (stream, "#%u\t; 0x%x", imm, imm);
3392
                }
3393
                break;
3394

    
3395
              case 'J':
3396
                {
3397
                  unsigned int imm = 0;
3398
                  imm |= (given & 0x000000ffu);
3399
                  imm |= (given & 0x00007000u) >> 4;
3400
                  imm |= (given & 0x04000000u) >> 15;
3401
                  imm |= (given & 0x000f0000u) >> 4;
3402
                  func (stream, "#%u\t; 0x%x", imm, imm);
3403
                }
3404
                break;
3405

    
3406
              case 'K':
3407
                {
3408
                  unsigned int imm = 0;
3409
                  imm |= (given & 0x000f0000u) >> 16;
3410
                  imm |= (given & 0x00000ff0u) >> 0;
3411
                  imm |= (given & 0x0000000fu) << 12;
3412
                  func (stream, "#%u\t; 0x%x", imm, imm);
3413
                }
3414
                break;
3415

    
3416
              case 'S':
3417
                {
3418
                  unsigned int reg = (given & 0x0000000fu);
3419
                  unsigned int stp = (given & 0x00000030u) >> 4;
3420
                  unsigned int imm = 0;
3421
                  imm |= (given & 0x000000c0u) >> 6;
3422
                  imm |= (given & 0x00007000u) >> 10;
3423

    
3424
                  func (stream, "%s", arm_regnames[reg]);
3425
                  switch (stp)
3426
                    {
3427
                    case 0:
3428
                      if (imm > 0)
3429
                        func (stream, ", lsl #%u", imm);
3430
                      break;
3431

    
3432
                    case 1:
3433
                      if (imm == 0)
3434
                        imm = 32;
3435
                      func (stream, ", lsr #%u", imm);
3436
                      break;
3437

    
3438
                    case 2:
3439
                      if (imm == 0)
3440
                        imm = 32;
3441
                      func (stream, ", asr #%u", imm);
3442
                      break;
3443

    
3444
                    case 3:
3445
                      if (imm == 0)
3446
                        func (stream, ", rrx");
3447
                      else
3448
                        func (stream, ", ror #%u", imm);
3449
                    }
3450
                }
3451
                break;
3452

    
3453
              case 'a':
3454
                {
3455
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
3456
                  unsigned int U   = (given & 0x00800000) >> 23;
3457
                  unsigned int op  = (given & 0x00000f00) >> 8;
3458
                  unsigned int i12 = (given & 0x00000fff);
3459
                  unsigned int i8  = (given & 0x000000ff);
3460
                  bfd_boolean writeback = false, postind = false;
3461
                  int offset = 0;
3462

    
3463
                  func (stream, "[%s", arm_regnames[Rn]);
3464
                  if (U) /* 12-bit positive immediate offset */
3465
                    offset = i12;
3466
                  else if (Rn == 15) /* 12-bit negative immediate offset */
3467
                    offset = -(int)i12;
3468
                  else if (op == 0x0) /* shifted register offset */
3469
                    {
3470
                      unsigned int Rm = (i8 & 0x0f);
3471
                      unsigned int sh = (i8 & 0x30) >> 4;
3472
                      func (stream, ", %s", arm_regnames[Rm]);
3473
                      if (sh)
3474
                        func (stream, ", lsl #%u", sh);
3475
                      func (stream, "]");
3476
                      break;
3477
                    }
3478
                  else switch (op)
3479
                    {
3480
                    case 0xE:  /* 8-bit positive immediate offset */
3481
                      offset = i8;
3482
                      break;
3483

    
3484
                    case 0xC:  /* 8-bit negative immediate offset */
3485
                      offset = -i8;
3486
                      break;
3487

    
3488
                    case 0xF:  /* 8-bit + preindex with wb */
3489
                      offset = i8;
3490
                      writeback = true;
3491
                      break;
3492

    
3493
                    case 0xD:  /* 8-bit - preindex with wb */
3494
                      offset = -i8;
3495
                      writeback = true;
3496
                      break;
3497

    
3498
                    case 0xB:  /* 8-bit + postindex */
3499
                      offset = i8;
3500
                      postind = true;
3501
                      break;
3502

    
3503
                    case 0x9:  /* 8-bit - postindex */
3504
                      offset = -i8;
3505
                      postind = true;
3506
                      break;
3507

    
3508
                    default:
3509
                      func (stream, ", <undefined>]");
3510
                      goto skip;
3511
                    }
3512

    
3513
                  if (postind)
3514
                    func (stream, "], #%d", offset);
3515
                  else
3516
                    {
3517
                      if (offset)
3518
                        func (stream, ", #%d", offset);
3519
                      func (stream, writeback ? "]!" : "]");
3520
                    }
3521

    
3522
                  if (Rn == 15)
3523
                    {
3524
                      func (stream, "\t; ");
3525
                      info->print_address_func (((pc + 4) & ~3) + offset, info);
3526
                    }
3527
                }
3528
              skip:
3529
                break;
3530

    
3531
              case 'A':
3532
                {
3533
                  unsigned int P   = (given & 0x01000000) >> 24;
3534
                  unsigned int U   = (given & 0x00800000) >> 23;
3535
                  unsigned int W   = (given & 0x00400000) >> 21;
3536
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
3537
                  unsigned int off = (given & 0x000000ff);
3538

    
3539
                  func (stream, "[%s", arm_regnames[Rn]);
3540
                  if (P)
3541
                    {
3542
                      if (off || !U)
3543
                        func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3544
                      func (stream, "]");
3545
                      if (W)
3546
                        func (stream, "!");
3547
                    }
3548
                  else
3549
                    {
3550
                      func (stream, "], ");
3551
                      if (W)
3552
                        func (stream, "#%c%u", U ? '+' : '-', off * 4);
3553
                      else
3554
                        func (stream, "{%u}", off);
3555
                    }
3556
                }
3557
                break;
3558

    
3559
              case 'w':
3560
                {
3561
                  unsigned int Sbit = (given & 0x01000000) >> 24;
3562
                  unsigned int type = (given & 0x00600000) >> 21;
3563
                  switch (type)
3564
                    {
3565
                    case 0: func (stream, Sbit ? "sb" : "b"); break;
3566
                    case 1: func (stream, Sbit ? "sh" : "h"); break;
3567
                    case 2:
3568
                      if (Sbit)
3569
                        func (stream, "??");
3570
                      break;
3571
                    case 3:
3572
                      func (stream, "??");
3573
                      break;
3574
                    }
3575
                }
3576
                break;
3577

    
3578
              case 'm':
3579
                {
3580
                  int started = 0;
3581
                  int reg;
3582

    
3583
                  func (stream, "{");
3584
                  for (reg = 0; reg < 16; reg++)
3585
                    if ((given & (1 << reg)) != 0)
3586
                      {
3587
                        if (started)
3588
                          func (stream, ", ");
3589
                        started = 1;
3590
                        func (stream, "%s", arm_regnames[reg]);
3591
                      }
3592
                  func (stream, "}");
3593
                }
3594
                break;
3595

    
3596
              case 'E':
3597
                {
3598
                  unsigned int msb = (given & 0x0000001f);
3599
                  unsigned int lsb = 0;
3600
                  lsb |= (given & 0x000000c0u) >> 6;
3601
                  lsb |= (given & 0x00007000u) >> 10;
3602
                  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3603
                }
3604
                break;
3605

    
3606
              case 'F':
3607
                {
3608
                  unsigned int width = (given & 0x0000001f) + 1;
3609
                  unsigned int lsb = 0;
3610
                  lsb |= (given & 0x000000c0u) >> 6;
3611
                  lsb |= (given & 0x00007000u) >> 10;
3612
                  func (stream, "#%u, #%u", lsb, width);
3613
                }
3614
                break;
3615

    
3616
              case 'b':
3617
                {
3618
                  unsigned int S = (given & 0x04000000u) >> 26;
3619
                  unsigned int J1 = (given & 0x00002000u) >> 13;
3620
                  unsigned int J2 = (given & 0x00000800u) >> 11;
3621
                  int offset = 0;
3622

    
3623
                  offset |= !S << 20;
3624
                  offset |= J2 << 19;
3625
                  offset |= J1 << 18;
3626
                  offset |= (given & 0x003f0000) >> 4;
3627
                  offset |= (given & 0x000007ff) << 1;
3628
                  offset -= (1 << 20);
3629

    
3630
                  info->print_address_func (pc + 4 + offset, info);
3631
                }
3632
                break;
3633

    
3634
              case 'B':
3635
                {
3636
                  unsigned int S = (given & 0x04000000u) >> 26;
3637
                  unsigned int I1 = (given & 0x00002000u) >> 13;
3638
                  unsigned int I2 = (given & 0x00000800u) >> 11;
3639
                  int offset = 0;
3640

    
3641
                  offset |= !S << 24;
3642
                  offset |= !(I1 ^ S) << 23;
3643
                  offset |= !(I2 ^ S) << 22;
3644
                  offset |= (given & 0x03ff0000u) >> 4;
3645
                  offset |= (given & 0x000007ffu) << 1;
3646
                  offset -= (1 << 24);
3647
                  offset += pc + 4;
3648

    
3649
                  /* BLX target addresses are always word aligned.  */
3650
                  if ((given & 0x00001000u) == 0)
3651
                      offset &= ~2u;
3652

    
3653
                  info->print_address_func (offset, info);
3654
                }
3655
                break;
3656

    
3657
              case 's':
3658
                {
3659
                  unsigned int shift = 0;
3660
                  shift |= (given & 0x000000c0u) >> 6;
3661
                  shift |= (given & 0x00007000u) >> 10;
3662
                  if (given & 0x00200000u)
3663
                    func (stream, ", asr #%u", shift);
3664
                  else if (shift)
3665
                    func (stream, ", lsl #%u", shift);
3666
                  /* else print nothing - lsl #0 */
3667
                }
3668
                break;
3669

    
3670
              case 'R':
3671
                {
3672
                  unsigned int rot = (given & 0x00000030) >> 4;
3673
                  if (rot)
3674
                    func (stream, ", ror #%u", rot * 8);
3675
                }
3676
                break;
3677

    
3678
              case 'U':
3679
                switch (given & 0xf)
3680
                  {
3681
                  case 0xf: func(stream, "sy"); break;
3682
                  case 0x7: func(stream, "un"); break;
3683
                  case 0xe: func(stream, "st"); break;
3684
                  case 0x6: func(stream, "unst"); break;
3685
                  default:
3686
                    func(stream, "#%d", (int)given & 0xf);
3687
                    break;
3688
                  }
3689
                break;
3690

    
3691
              case 'C':
3692
                if ((given & 0xff) == 0)
3693
                  {
3694
                    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3695
                    if (given & 0x800)
3696
                      func (stream, "f");
3697
                    if (given & 0x400)
3698
                      func (stream, "s");
3699
                    if (given & 0x200)
3700
                      func (stream, "x");
3701
                    if (given & 0x100)
3702
                      func (stream, "c");
3703
                  }
3704
                else
3705
                  {
3706
                    func (stream, psr_name (given & 0xff));
3707
                  }
3708
                break;
3709

    
3710
              case 'D':
3711
                if ((given & 0xff) == 0)
3712
                  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3713
                else
3714
                  func (stream, psr_name (given & 0xff));
3715
                break;
3716

    
3717
              case '0': case '1': case '2': case '3': case '4':
3718
              case '5': case '6': case '7': case '8': case '9':
3719
                {
3720
                  int width;
3721
                  unsigned long val;
3722

    
3723
                  c = arm_decode_bitfield (c, given, &val, &width);
3724

    
3725
                  switch (*c)
3726
                    {
3727
                    case 'd': func (stream, "%lu", val); break;
3728
                    case 'W': func (stream, "%lu", val * 4); break;
3729
                    case 'r': func (stream, "%s", arm_regnames[val]); break;
3730

    
3731
                    case 'c':
3732
                      func (stream, "%s", arm_conditional[val]);
3733
                      break;
3734

    
3735
                    case '\'':
3736
                      c++;
3737
                      if (val == ((1ul << width) - 1))
3738
                        func (stream, "%c", *c);
3739
                      break;
3740

    
3741
                    case '`':
3742
                      c++;
3743
                      if (val == 0)
3744
                        func (stream, "%c", *c);
3745
                      break;
3746

    
3747
                    case '?':
3748
                      func (stream, "%c", c[(1 << width) - (int)val]);
3749
                      c += 1 << width;
3750
                      break;
3751

    
3752
                    default:
3753
                      abort ();
3754
                    }
3755
                }
3756
                break;
3757

    
3758
              default:
3759
                abort ();
3760
              }
3761
          }
3762
        return;
3763
      }
3764

    
3765
  /* No match.  */
3766
  abort ();
3767
}
3768

    
3769
/* Print data bytes on INFO->STREAM.  */
3770

    
3771
static void
3772
print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3773
                 long given)
3774
{
3775
  switch (info->bytes_per_chunk)
3776
    {
3777
    case 1:
3778
      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3779
      break;
3780
    case 2:
3781
      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3782
      break;
3783
    case 4:
3784
      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3785
      break;
3786
    default:
3787
      abort ();
3788
    }
3789
}
3790

    
3791
/* Search back through the insn stream to determine if this instruction is
3792
   conditionally executed.  */
3793
static void
3794
find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3795
                   bfd_boolean little)
3796
{
3797
  unsigned char b[2];
3798
  unsigned int insn;
3799
  int status;
3800
  /* COUNT is twice the number of instructions seen.  It will be odd if we
3801
     just crossed an instruction boundary.  */
3802
  int count;
3803
  int it_count;
3804
  unsigned int seen_it;
3805
  bfd_vma addr;
3806

    
3807
  ifthen_address = pc;
3808
  ifthen_state = 0;
3809

    
3810
  addr = pc;
3811
  count = 1;
3812
  it_count = 0;
3813
  seen_it = 0;
3814
  /* Scan backwards looking for IT instructions, keeping track of where
3815
     instruction boundaries are.  We don't know if something is actually an
3816
     IT instruction until we find a definite instruction boundary.  */
3817
  for (;;)
3818
    {
3819
      if (addr == 0 || info->symbol_at_address_func(addr, info))
3820
        {
3821
          /* A symbol must be on an instruction boundary, and will not
3822
             be within an IT block.  */
3823
          if (seen_it && (count & 1))
3824
            break;
3825

    
3826
          return;
3827
        }
3828
      addr -= 2;
3829
      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3830
      if (status)
3831
        return;
3832

    
3833
      if (little)
3834
        insn = (b[0]) | (b[1] << 8);
3835
      else
3836
        insn = (b[1]) | (b[0] << 8);
3837
      if (seen_it)
3838
        {
3839
          if ((insn & 0xf800) < 0xe800)
3840
            {
3841
              /* Addr + 2 is an instruction boundary.  See if this matches
3842
                 the expected boundary based on the position of the last
3843
                 IT candidate.  */
3844
              if (count & 1)
3845
                break;
3846
              seen_it = 0;
3847
            }
3848
        }
3849
      if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3850
        {
3851
          /* This could be an IT instruction.  */
3852
          seen_it = insn;
3853
          it_count = count >> 1;
3854
        }
3855
      if ((insn & 0xf800) >= 0xe800)
3856
        count++;
3857
      else
3858
        count = (count + 2) | 1;
3859
      /* IT blocks contain at most 4 instructions.  */
3860
      if (count >= 8 && !seen_it)
3861
        return;
3862
    }
3863
  /* We found an IT instruction.  */
3864
  ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3865
  if ((ifthen_state & 0xf) == 0)
3866
    ifthen_state = 0;
3867
}
3868

    
3869
/* NOTE: There are no checks in these routines that
3870
   the relevant number of data bytes exist.  */
3871

    
3872
int
3873
print_insn_arm (bfd_vma pc, struct disassemble_info *info)
3874
{
3875
  unsigned char b[4];
3876
  long                given;
3877
  int           status;
3878
  int           is_thumb = false;
3879
  int           is_data = false;
3880
  unsigned int        size = 4;
3881
  void                 (*printer) (bfd_vma, struct disassemble_info *, long);
3882
#if 0
3883
  bfd_boolean   found = false;
3884

3885
  if (info->disassembler_options)
3886
    {
3887
      parse_disassembler_options (info->disassembler_options);
3888

3889
      /* To avoid repeated parsing of these options, we remove them here.  */
3890
      info->disassembler_options = NULL;
3891
    }
3892

3893
  /* First check the full symtab for a mapping symbol, even if there
3894
     are no usable non-mapping symbols for this address.  */
3895
  if (info->symtab != NULL
3896
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3897
    {
3898
      bfd_vma addr;
3899
      int n;
3900
      int last_sym = -1;
3901
      enum map_type type = MAP_ARM;
3902

3903
      if (pc <= last_mapping_addr)
3904
        last_mapping_sym = -1;
3905
      is_thumb = (last_type == MAP_THUMB);
3906
      found = false;
3907
      /* Start scanning at the start of the function, or wherever
3908
         we finished last time.  */
3909
      n = info->symtab_pos + 1;
3910
      if (n < last_mapping_sym)
3911
        n = last_mapping_sym;
3912

3913
      /* Scan up to the location being disassembled.  */
3914
      for (; n < info->symtab_size; n++)
3915
        {
3916
          addr = bfd_asymbol_value (info->symtab[n]);
3917
          if (addr > pc)
3918
            break;
3919
          if ((info->section == NULL
3920
               || info->section == info->symtab[n]->section)
3921
              && get_sym_code_type (info, n, &type))
3922
            {
3923
              last_sym = n;
3924
              found = true;
3925
            }
3926
        }
3927

3928
      if (!found)
3929
        {
3930
          n = info->symtab_pos;
3931
          if (n < last_mapping_sym - 1)
3932
            n = last_mapping_sym - 1;
3933

3934
          /* No mapping symbol found at this address.  Look backwards
3935
             for a preceeding one.  */
3936
          for (; n >= 0; n--)
3937
            {
3938
              if (get_sym_code_type (info, n, &type))
3939
                {
3940
                  last_sym = n;
3941
                  found = true;
3942
                  break;
3943
                }
3944
            }
3945
        }
3946

3947
      last_mapping_sym = last_sym;
3948
      last_type = type;
3949
      is_thumb = (last_type == MAP_THUMB);
3950
      is_data = (last_type == MAP_DATA);
3951

3952
      /* Look a little bit ahead to see if we should print out
3953
         two or four bytes of data.  If there's a symbol,
3954
         mapping or otherwise, after two bytes then don't
3955
         print more.  */
3956
      if (is_data)
3957
        {
3958
          size = 4 - (pc & 3);
3959
          for (n = last_sym + 1; n < info->symtab_size; n++)
3960
            {
3961
              addr = bfd_asymbol_value (info->symtab[n]);
3962
              if (addr > pc)
3963
                {
3964
                  if (addr - pc < size)
3965
                    size = addr - pc;
3966
                  break;
3967
                }
3968
            }
3969
          /* If the next symbol is after three bytes, we need to
3970
             print only part of the data, so that we can use either
3971
             .byte or .short.  */
3972
          if (size == 3)
3973
            size = (pc & 1) ? 1 : 2;
3974
        }
3975
    }
3976

3977
  if (info->symbols != NULL)
3978
    {
3979
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3980
        {
3981
          coff_symbol_type * cs;
3982

3983
          cs = coffsymbol (*info->symbols);
3984
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
3985
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
3986
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
3987
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3988
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3989
        }
3990
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
3991
               && !found)
3992
        {
3993
          /* If no mapping symbol has been found then fall back to the type
3994
             of the function symbol.  */
3995
          elf_symbol_type *  es;
3996
          unsigned int       type;
3997

3998
          es = *(elf_symbol_type **)(info->symbols);
3999
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4000

4001
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4002
        }
4003
    }
4004
#else
4005
  int little;
4006

    
4007
  little = (info->endian == BFD_ENDIAN_LITTLE);
4008
  is_thumb |= (pc & 1);
4009
  pc &= ~(bfd_vma)1;
4010
#endif
4011

    
4012
  if (force_thumb)
4013
    is_thumb = true;
4014

    
4015
  info->bytes_per_line = 4;
4016

    
4017
  if (is_data)
4018
    {
4019
      int i;
4020

    
4021
      /* size was already set above.  */
4022
      info->bytes_per_chunk = size;
4023
      printer = print_insn_data;
4024

    
4025
      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4026
      given = 0;
4027
      if (little)
4028
        for (i = size - 1; i >= 0; i--)
4029
          given = b[i] | (given << 8);
4030
      else
4031
        for (i = 0; i < (int) size; i++)
4032
          given = b[i] | (given << 8);
4033
    }
4034
  else if (!is_thumb)
4035
    {
4036
      /* In ARM mode endianness is a straightforward issue: the instruction
4037
         is four bytes long and is either ordered 0123 or 3210.  */
4038
      printer = print_insn_arm_internal;
4039
      info->bytes_per_chunk = 4;
4040
      size = 4;
4041

    
4042
      status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4043
      if (little)
4044
        given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4045
      else
4046
        given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4047
    }
4048
  else
4049
    {
4050
      /* In Thumb mode we have the additional wrinkle of two
4051
         instruction lengths.  Fortunately, the bits that determine
4052
         the length of the current instruction are always to be found
4053
         in the first two bytes.  */
4054
      printer = print_insn_thumb16;
4055
      info->bytes_per_chunk = 2;
4056
      size = 2;
4057

    
4058
      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4059
      if (little)
4060
        given = (b[0]) | (b[1] << 8);
4061
      else
4062
        given = (b[1]) | (b[0] << 8);
4063

    
4064
      if (!status)
4065
        {
4066
          /* These bit patterns signal a four-byte Thumb
4067
             instruction.  */
4068
          if ((given & 0xF800) == 0xF800
4069
              || (given & 0xF800) == 0xF000
4070
              || (given & 0xF800) == 0xE800)
4071
            {
4072
              status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4073
              if (little)
4074
                given = (b[0]) | (b[1] << 8) | (given << 16);
4075
              else
4076
                given = (b[1]) | (b[0] << 8) | (given << 16);
4077

    
4078
              printer = print_insn_thumb32;
4079
              size = 4;
4080
            }
4081
        }
4082

    
4083
      if (ifthen_address != pc)
4084
        find_ifthen_state(pc, info, little);
4085

    
4086
      if (ifthen_state)
4087
        {
4088
          if ((ifthen_state & 0xf) == 0x8)
4089
            ifthen_next_state = 0;
4090
          else
4091
            ifthen_next_state = (ifthen_state & 0xe0)
4092
                                | ((ifthen_state & 0xf) << 1);
4093
        }
4094
    }
4095

    
4096
  if (status)
4097
    {
4098
      info->memory_error_func (status, pc, info);
4099
      return -1;
4100
    }
4101
  if (info->flags & INSN_HAS_RELOC)
4102
    /* If the instruction has a reloc associated with it, then
4103
       the offset field in the instruction will actually be the
4104
       addend for the reloc.  (We are using REL type relocs).
4105
       In such cases, we can ignore the pc when computing
4106
       addresses, since the addend is not currently pc-relative.  */
4107
    pc = 0;
4108

    
4109
  printer (pc, info, given);
4110

    
4111
  if (is_thumb)
4112
    {
4113
      ifthen_state = ifthen_next_state;
4114
      ifthen_address += size;
4115
    }
4116
  return size;
4117
}