Statistics
| Branch: | Revision:

root / arm-dis.c @ 09d85fb8

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, see <http://www.gnu.org/licenses/>.  */
21

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

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

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

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

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

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

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

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

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

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

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

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

105
   %%                        %
106

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
500
  {0, 0, 0, 0}
501
};
502

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

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

509
   %%                        %
510

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

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

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

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

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

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

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

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

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

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

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

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

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

    
777
  {0,0 ,0, 0}
778
};
779

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

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

786
   %%                        %
787

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1224
   print_insn_thumb32 recognizes the following format control codes:
1225

1226
       %%                %
1227

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1534
static bfd_boolean force_thumb = FALSE;
1535

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

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

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

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

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

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

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

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

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

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

    
1614
              amount = 32;
1615
            }
1616

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

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

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

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

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

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

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

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

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

    
1716
                          func (stream, "]");
1717

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

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

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

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

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

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

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

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

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

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

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

    
1791
                      break;
1792

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1993
                            default:
1994
                              abort ();
1995
                            }
1996

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2151
          offset += pc + 8;
2152

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2371
                          default:
2372
                            abort ();
2373
                          }
2374

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2585

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2874
                          func (stream, "]");
2875

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3140
                  func (stream, "{");
3141

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3809
  ifthen_address = pc;
3810
  ifthen_state = 0;
3811

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4014
  if (force_thumb)
4015
    is_thumb = TRUE;
4016

    
4017
  info->bytes_per_line = 4;
4018

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

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

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

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

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

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

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

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

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

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

    
4111
  printer (pc, info, given);
4112

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