Statistics
| Branch: | Revision:

root / arm-dis.c @ 0087375e

History | View | Annotate | Download (156.7 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, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22

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

    
26
#include "dis-asm.h"
27
#define FALSE 0
28
#define TRUE (!FALSE)
29
#define ATTRIBUTE_UNUSED __attribute__((unused))
30
#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
31

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

    
51
/* Co-processor space extensions.  */
52
#define ARM_CEXT_XSCALE   0
53
#define ARM_CEXT_MAVERICK 0
54
#define ARM_CEXT_IWMMXT   0
55

    
56
#define FPU_FPA_EXT_V1         0
57
#define FPU_FPA_EXT_V2         0
58
#define FPU_VFP_EXT_NONE 0
59
#define FPU_VFP_EXT_V1xD 0
60
#define FPU_VFP_EXT_V1         0
61
#define FPU_VFP_EXT_V2         0
62
#define FPU_MAVERICK         0
63
#define FPU_VFP_EXT_V3         0
64
#define FPU_NEON_EXT_V1         0
65

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

    
79
/* End of qemu specific additions.  */
80

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

    
86
#ifndef NUM_ELEM
87
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
88
#endif
89

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

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

    
104
/* print_insn_coprocessor recognizes the following format control codes:
105

106
   %%                        %
107

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

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

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

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

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

    
151
/* Common coprocessor opcodes shared between Arm and Thumb-2.  */
152

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

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

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

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

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

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

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

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

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

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

    
501
  {0, 0, 0, 0}
502
};
503

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

    
508
/* print_insn_neon recognizes the following format control codes:
509

510
   %%                        %
511

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

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

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

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

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

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

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

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

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

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

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

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

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

    
778
  {0,0 ,0, 0}
779
};
780

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

    
785
/* print_insn_arm recognizes the following format control codes:
786

787
   %%                        %
788

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

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

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

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

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

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

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

    
845
  /* ARM V6Z instructions.  */
846
  {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
847

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

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

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

    
988
  /* V5J instruction.  */
989
  {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
990

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

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

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

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

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

    
1019
  {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1020
  {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1021

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

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

    
1070
  /* The rest.  */
1071
  {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
1072
  {0, 0x00000000, 0x00000000, 0}
1073
};
1074

    
1075
/* print_insn_thumb16 recognizes the following format control codes:
1076

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

    
1101
static const struct opcode16 thumb_opcodes[] =
1102
{
1103
  /* Thumb instructions.  */
1104

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

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

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

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

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

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

1225
   print_insn_thumb32 recognizes the following format control codes:
1226

1227
       %%                %
1228

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

1235
       %a                print the address of a plain load/store
1236
       %w                print the width and signedness of a core load/store
1237
       %m                print register mask for ldm/stm
1238

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

1251
       %<bitfield>d        print bitfield in decimal
1252
       %<bitfield>W        print bitfield*4 in decimal
1253
       %<bitfield>r        print bitfield as an ARM register
1254
       %<bitfield>c        print bitfield as a condition code
1255

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

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

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

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

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

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

    
1470
  /* Fallback.  */
1471
  {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
1472
  {0, 0, 0, 0}
1473
};
1474

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

    
1479
static const char *const arm_fp_const[] =
1480
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1481

    
1482
static const char *const arm_shift[] =
1483
{"lsl", "lsr", "asr", "ror"};
1484

    
1485
typedef struct
1486
{
1487
  const char *name;
1488
  const char *description;
1489
  const char *reg_names[16];
1490
}
1491
arm_regname;
1492

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

    
1509
static const char *const iwmmxt_wwnames[] =
1510
{"b", "h", "w", "d"};
1511

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

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

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

    
1529
/* Default to GCC register name set.  */
1530
static unsigned int regname_selected = 1;
1531

    
1532
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1533
#define arm_regnames      regnames[regname_selected].reg_names
1534

    
1535
static bfd_boolean force_thumb = FALSE;
1536

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

    
1546
/* Cached mapping symbol state.  */
1547
enum map_type {
1548
  MAP_ARM,
1549
  MAP_THUMB,
1550
  MAP_DATA
1551
};
1552

    
1553
enum map_type last_type;
1554
int last_mapping_sym = -1;
1555
bfd_vma last_mapping_addr = 0;
1556

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

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

    
1569
  do
1570
    {
1571
      int start, end;
1572
      int bits;
1573

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

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

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

    
1607
          if (amount == 0)
1608
            {
1609
              if (shift == 3)
1610
                {
1611
                  func (stream, ", rrx");
1612
                  return;
1613
                }
1614

    
1615
              amount = 32;
1616
            }
1617

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

    
1631
/* Print one coprocessor instruction on INFO->STREAM.
1632
   Return TRUE if the instuction matched, FALSE if this is not a
1633
   recognised coprocessor instruction.  */
1634

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

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

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

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

    
1698
                    case 'A':
1699
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1700

    
1701
                      if ((given & (1 << 24)) != 0)
1702
                        {
1703
                          int offset = given & 0xff;
1704

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

    
1717
                          func (stream, "]");
1718

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

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

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

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

    
1751
                        func (stream, "[%s", arm_regnames[rn]);
1752

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

    
1771
                    case 'c':
1772
                      func (stream, "%s", arm_conditional[cond]);
1773
                      break;
1774

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

    
1783
                        imm = (given & 0xf) | ((given & 0xe0) >> 1);
1784

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

    
1789
                        func (stream, "%d", imm);
1790
                      }
1791

    
1792
                      break;
1793

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

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

    
1862
                    case '0': case '1': case '2': case '3': case '4':
1863
                    case '5': case '6': case '7': case '8': case '9':
1864
                      {
1865
                        int width;
1866
                        unsigned long value;
1867

    
1868
                        c = arm_decode_bitfield (c, given, &value, &width);
1869

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

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

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

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

    
1915
                          case 'x':
1916
                            func (stream, "0x%lx", value);
1917
                            break;
1918

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

    
1938
                      case 'y':
1939
                      case 'z':
1940
                        {
1941
                          int single = *c++ == 'y';
1942
                          int regno;
1943

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

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

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

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

    
1994
                            default:
1995
                              abort ();
1996
                            }
1997

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

    
2000
                          if (*c == '3')
2001
                            {
2002
                              int count = given & 0xff;
2003

    
2004
                              if (single == 0)
2005
                                count >>= 1;
2006

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

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

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

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

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

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

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

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

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

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

    
2103
                            default:
2104
                              func (stream, "INVALID");
2105
                            }
2106
                        }
2107
                        break;
2108

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

    
2117
                      default:
2118
                        abort ();
2119
                      }
2120
                    }
2121
                }
2122
              else
2123
                func (stream, "%c", *c);
2124
            }
2125
          return TRUE;
2126
        }
2127
    }
2128
  return FALSE;
2129
}
2130

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

    
2137
  if (((given & 0x000f0000) == 0x000f0000)
2138
      && ((given & 0x02000000) == 0))
2139
    {
2140
      int offset = given & 0xfff;
2141

    
2142
      func (stream, "[pc");
2143

    
2144
      if (given & 0x01000000)
2145
        {
2146
          if ((given & 0x00800000) == 0)
2147
            offset = - offset;
2148

    
2149
          /* Pre-indexed.  */
2150
          func (stream, ", #%d]", offset);
2151

    
2152
          offset += pc + 8;
2153

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

    
2166
          /* ie ignore the offset.  */
2167
          offset = pc + 8;
2168
        }
2169

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

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

    
2221
/* Print one neon instruction on INFO->STREAM.
2222
   Return TRUE if the instuction matched, FALSE if this is not a
2223
   recognised neon instruction.  */
2224

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

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

    
2239
          given &= 0x00ffffff;
2240
          if (bit28)
2241
            given |= 0xf3000000;
2242
          else
2243
            given |= 0xf2000000;
2244
        }
2245
      else if ((given & 0xff000000) == 0xf9000000)
2246
        given ^= 0xf9000000 ^ 0xf4000000;
2247
      else
2248
        return FALSE;
2249
    }
2250

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

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

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

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

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

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

    
2329
                        if (length > 1 && size > 0)
2330
                          stride = (idx_align & (1 << size)) ? 2 : 1;
2331

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

    
2349
                          case 2:
2350
                            if (size == 2 && (idx_align & 2) != 0)
2351
                              return FALSE;
2352
                            align = (idx_align & 1) ? 16 << size : 0;
2353
                            break;
2354

    
2355
                          case 3:
2356
                            if ((size == 2 && (idx_align & 3) != 0)
2357
                                || (idx_align & 1) != 0)
2358
                              return FALSE;
2359
                            break;
2360

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

    
2372
                          default:
2373
                            abort ();
2374
                          }
2375

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

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

    
2403
                        if (stride && (n == 1))
2404
                          n++;
2405
                        else
2406
                          stride++;
2407

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

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

    
2442
                        func (stream, "d%d[%d]", reg, ix);
2443
                      }
2444
                      break;
2445

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

    
2457
                        bits |= ((given >> 24) & 1) << 7;
2458
                        bits |= ((given >> 16) & 7) << 4;
2459
                        bits |= ((given >> 0) & 15) << 0;
2460

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

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

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

    
2532
                          case 16:
2533
                            func (stream, "#%ld\t; 0x%.4lx", value, value);
2534
                            break;
2535

    
2536
                          case 32:
2537
                            if (isfloat)
2538
                              {
2539
                                unsigned char valbytes[4];
2540
                                double fvalue;
2541

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

    
2549
                                floatformat_to_double
2550
                                  (&floatformat_ieee_single_little, valbytes,
2551
                                  &fvalue);
2552

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

    
2562
                          case 64:
2563
                            func (stream, "#0x%.8lx%.8lx", hival, value);
2564
                            break;
2565

    
2566
                          default:
2567
                            abort ();
2568
                          }
2569
                      }
2570
                      break;
2571

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

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

    
2586

    
2587
                    case '0': case '1': case '2': case '3': case '4':
2588
                    case '5': case '6': case '7': case '8': case '9':
2589
                      {
2590
                        int width;
2591
                        unsigned long value;
2592

    
2593
                        c = arm_decode_bitfield (c, given, &value, &width);
2594

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

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

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

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

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

    
2666
                      default:
2667
                        abort ();
2668
                      }
2669
                    }
2670
                }
2671
              else
2672
                func (stream, "%c", *c);
2673
            }
2674
          return TRUE;
2675
        }
2676
    }
2677
  return FALSE;
2678
}
2679

    
2680
/* Print one ARM instruction from PC on INFO->STREAM.  */
2681

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

    
2689
  if (print_insn_coprocessor (pc, info, given, FALSE))
2690
    return;
2691

    
2692
  if (print_insn_neon (info, given, FALSE))
2693
    return;
2694

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

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

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

    
2722
                    case 'a':
2723
                      print_arm_address (pc, info, given);
2724
                      break;
2725

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

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

    
2738
                          if ((given & 0x00800000) == 0)
2739
                            offset = -offset;
2740

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

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

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

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

    
2811
                    case 'm':
2812
                      {
2813
                        int started = 0;
2814
                        int reg;
2815

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

    
2829
                    case 'q':
2830
                      arm_decode_shift (given, func, stream, 0);
2831
                      break;
2832

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

    
2846
                    case 'p':
2847
                      if ((given & 0x0000f000) == 0x0000f000)
2848
                        func (stream, "p");
2849
                      break;
2850

    
2851
                    case 't':
2852
                      if ((given & 0x01200000) == 0x00200000)
2853
                        func (stream, "t");
2854
                      break;
2855

    
2856
                    case 'A':
2857
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2858

    
2859
                      if ((given & (1 << 24)) != 0)
2860
                        {
2861
                          int offset = given & 0xff;
2862

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

    
2875
                          func (stream, "]");
2876

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

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

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

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

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

    
2908
                        info->print_address_func (address, info);
2909
                      }
2910
                      break;
2911

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

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

    
2937
                    case '0': case '1': case '2': case '3': case '4':
2938
                    case '5': case '6': case '7': case '8': case '9':
2939
                      {
2940
                        int width;
2941
                        unsigned long value;
2942

    
2943
                        c = arm_decode_bitfield (c, given, &value, &width);
2944

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

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

    
2991
                      case 'e':
2992
                        {
2993
                          int imm;
2994

    
2995
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2996
                          func (stream, "%d", imm);
2997
                        }
2998
                        break;
2999

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

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

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

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

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

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

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

    
3058
            if (*c != '%')
3059
              {
3060
                func (stream, "%c", *c);
3061
                continue;
3062
              }
3063

    
3064
            switch (*++c)
3065
              {
3066
              case '%':
3067
                func (stream, "%%");
3068
                break;
3069

    
3070
              case 'c':
3071
                if (ifthen_state)
3072
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3073
                break;
3074

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

    
3082
              case 'I':
3083
                {
3084
                  unsigned int tmp;
3085

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

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

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

    
3104
              case 'S':
3105
                {
3106
                  long reg;
3107

    
3108
                  reg = (given >> 3) & 0x7;
3109
                  if (given & (1 << 6))
3110
                    reg += 8;
3111

    
3112
                  func (stream, "%s", arm_regnames[reg]);
3113
                }
3114
                break;
3115

    
3116
              case 'D':
3117
                {
3118
                  long reg;
3119

    
3120
                  reg = given & 0x7;
3121
                  if (given & (1 << 7))
3122
                    reg += 8;
3123

    
3124
                  func (stream, "%s", arm_regnames[reg]);
3125
                }
3126
                break;
3127

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

    
3141
                  func (stream, "{");
3142

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

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

    
3162
                  if (domaskpc)
3163
                    {
3164
                      if (started)
3165
                        func (stream, ", ");
3166
                      func (stream, arm_regnames[15] /* "pc" */);
3167
                    }
3168

    
3169
                  func (stream, "}");
3170
                }
3171
                break;
3172

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

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

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

    
3200
                  while (*c >= '0' && *c <= '9')
3201
                    bitstart = (bitstart * 10) + *c++ - '0';
3202

    
3203
                  switch (*c)
3204
                    {
3205
                    case '-':
3206
                      {
3207
                        long reg;
3208

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

    
3222
                          case 'd':
3223
                            func (stream, "%ld", reg);
3224
                            break;
3225

    
3226
                          case 'H':
3227
                            func (stream, "%ld", reg << 1);
3228
                            break;
3229

    
3230
                          case 'W':
3231
                            func (stream, "%ld", reg << 2);
3232
                            break;
3233

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

    
3242
                          case 'x':
3243
                            func (stream, "0x%04lx", reg);
3244
                            break;
3245

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

    
3251
                          case 'c':
3252
                            func (stream, "%s", arm_conditional [reg]);
3253
                            break;
3254

    
3255
                          default:
3256
                            abort ();
3257
                          }
3258
                      }
3259
                      break;
3260

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

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

    
3275
                    default:
3276
                      abort ();
3277
                    }
3278
                }
3279
                break;
3280

    
3281
              default:
3282
                abort ();
3283
              }
3284
          }
3285
        return;
3286
      }
3287

    
3288
  /* No match.  */
3289
  abort ();
3290
}
3291

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

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

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

    
3325
  if (print_insn_coprocessor (pc, info, given, TRUE))
3326
    return;
3327

    
3328
  if (print_insn_neon (info, given, TRUE))
3329
    return;
3330

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

    
3343
            switch (*++c)
3344
              {
3345
              case '%':
3346
                func (stream, "%%");
3347
                break;
3348

    
3349
              case 'c':
3350
                if (ifthen_state)
3351
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3352
                break;
3353

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

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

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

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

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

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

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

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

    
3435
                    case 1:
3436
                      if (imm == 0)
3437
                        imm = 32;
3438
                      func (stream, ", lsr #%u", imm);
3439
                      break;
3440

    
3441
                    case 2:
3442
                      if (imm == 0)
3443
                        imm = 32;
3444
                      func (stream, ", asr #%u", imm);
3445
                      break;
3446

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

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

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

    
3487
                    case 0xC:  /* 8-bit negative immediate offset */
3488
                      offset = -i8;
3489
                      break;
3490

    
3491
                    case 0xF:  /* 8-bit + preindex with wb */
3492
                      offset = i8;
3493
                      writeback = TRUE;
3494
                      break;
3495

    
3496
                    case 0xD:  /* 8-bit - preindex with wb */
3497
                      offset = -i8;
3498
                      writeback = TRUE;
3499
                      break;
3500

    
3501
                    case 0xB:  /* 8-bit + postindex */
3502
                      offset = i8;
3503
                      postind = TRUE;
3504
                      break;
3505

    
3506
                    case 0x9:  /* 8-bit - postindex */
3507
                      offset = -i8;
3508
                      postind = TRUE;
3509
                      break;
3510

    
3511
                    default:
3512
                      func (stream, ", <undefined>]");
3513
                      goto skip;
3514
                    }
3515

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

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

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

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

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

    
3581
              case 'm':
3582
                {
3583
                  int started = 0;
3584
                  int reg;
3585

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

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

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

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

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

    
3633
                  info->print_address_func (pc + 4 + offset, info);
3634
                }
3635
                break;
3636

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

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

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

    
3656
                  info->print_address_func (offset, info);
3657
                }
3658
                break;
3659

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

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

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

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

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

    
3720
              case '0': case '1': case '2': case '3': case '4':
3721
              case '5': case '6': case '7': case '8': case '9':
3722
                {
3723
                  int width;
3724
                  unsigned long val;
3725

    
3726
                  c = arm_decode_bitfield (c, given, &val, &width);
3727

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

    
3734
                    case 'c':
3735
                      func (stream, "%s", arm_conditional[val]);
3736
                      break;
3737

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

    
3744
                    case '`':
3745
                      c++;
3746
                      if (val == 0)
3747
                        func (stream, "%c", *c);
3748
                      break;
3749

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

    
3755
                    default:
3756
                      abort ();
3757
                    }
3758
                }
3759
                break;
3760

    
3761
              default:
3762
                abort ();
3763
              }
3764
          }
3765
        return;
3766
      }
3767

    
3768
  /* No match.  */
3769
  abort ();
3770
}
3771

    
3772
/* Print data bytes on INFO->STREAM.  */
3773

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

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

    
3810
  ifthen_address = pc;
3811
  ifthen_state = 0;
3812

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

    
3829
          return;
3830
        }
3831
      addr -= 2;
3832
      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3833
      if (status)
3834
        return;
3835

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

    
3872
/* NOTE: There are no checks in these routines that
3873
   the relevant number of data bytes exist.  */
3874

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

3888
  if (info->disassembler_options)
3889
    {
3890
      parse_disassembler_options (info->disassembler_options);
3891

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

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

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

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

3931
      if (!found)
3932
        {
3933
          n = info->symtab_pos;
3934
          if (n < last_mapping_sym - 1)
3935
            n = last_mapping_sym - 1;
3936

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

3950
      last_mapping_sym = last_sym;
3951
      last_type = type;
3952
      is_thumb = (last_type == MAP_THUMB);
3953
      is_data = (last_type == MAP_DATA);
3954

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

3980
  if (info->symbols != NULL)
3981
    {
3982
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3983
        {
3984
          coff_symbol_type * cs;
3985

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

4001
          es = *(elf_symbol_type **)(info->symbols);
4002
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4003

4004
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4005
        }
4006
    }
4007
#else
4008
  int little;
4009

    
4010
  little = (info->endian == BFD_ENDIAN_LITTLE);
4011
  is_thumb |= (pc & 1);
4012
  pc &= ~(bfd_vma)1;
4013
#endif
4014

    
4015
  if (force_thumb)
4016
    is_thumb = TRUE;
4017

    
4018
  info->bytes_per_line = 4;
4019

    
4020
  if (is_data)
4021
    {
4022
      int i;
4023

    
4024
      /* size was already set above.  */
4025
      info->bytes_per_chunk = size;
4026
      printer = print_insn_data;
4027

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

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

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

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

    
4081
              printer = print_insn_thumb32;
4082
              size = 4;
4083
            }
4084
        }
4085

    
4086
      if (ifthen_address != pc)
4087
        find_ifthen_state(pc, info, little);
4088

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

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

    
4112
  printer (pc, info, given);
4113

    
4114
  if (is_thumb)
4115
    {
4116
      ifthen_state = ifthen_next_state;
4117
      ifthen_address += size;
4118
    }
4119
  return size;
4120
}