Statistics
| Branch: | Revision:

root / arm-dis.c @ d9346e81

History | View | Annotate | Download (156.4 kB)

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

7
   This file is part of libopcodes.
8

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

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

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

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

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

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

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

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

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

    
74
/* End of qemu specific additions.  */
75

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

    
81
#ifndef NUM_ELEM
82
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
83
#endif
84

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

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

    
99
/* print_insn_coprocessor recognizes the following format control codes:
100

101
   %%                        %
102

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

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

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

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

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

    
146
/* Common coprocessor opcodes shared between Arm and Thumb-2.  */
147

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

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

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

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

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

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

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

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

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

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

    
496
  {0, 0, 0, 0}
497
};
498

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

    
503
/* print_insn_neon recognizes the following format control codes:
504

505
   %%                        %
506

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

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

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

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

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

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

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

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

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

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

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

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

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

    
773
  {0,0 ,0, 0}
774
};
775

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

    
780
/* print_insn_arm recognizes the following format control codes:
781

782
   %%                        %
783

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1070
/* print_insn_thumb16 recognizes the following format control codes:
1071

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

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

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

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

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

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

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

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

1220
   print_insn_thumb32 recognizes the following format control codes:
1221

1222
       %%                %
1223

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1527
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1528
#define arm_regnames      regnames[regname_selected].reg_names
1529

    
1530
static bfd_boolean force_thumb = false;
1531

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

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

    
1548
enum map_type last_type;
1549
int last_mapping_sym = -1;
1550
bfd_vma last_mapping_addr = 0;
1551

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

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

    
1564
  do
1565
    {
1566
      int start, end;
1567
      int bits;
1568

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

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

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

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

    
1610
              amount = 32;
1611
            }
1612

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

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

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

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

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

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

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

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

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

    
1712
                          func (stream, "]");
1713

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

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

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

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

    
1746
                        func (stream, "[%s", arm_regnames[rn]);
1747

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

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

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

    
1778
                        imm = (given & 0xf) | ((given & 0xe0) >> 1);
1779

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

    
1784
                        func (stream, "%d", imm);
1785
                      }
1786

    
1787
                      break;
1788

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

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

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

    
1863
                        c = arm_decode_bitfield (c, given, &value, &width);
1864

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

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

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

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

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

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

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

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

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

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

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

    
1989
                            default:
1990
                              abort ();
1991
                            }
1992

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

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

    
1999
                              if (single == 0)
2000
                                count >>= 1;
2001

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2137
      func (stream, "[pc");
2138

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

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

    
2147
          offset += pc + 8;
2148

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

    
2161
          /* ie ignore the offset.  */
2162
          offset = pc + 8;
2163
        }
2164

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2367
                          default:
2368
                            abort ();
2369
                          }
2370

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

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

    
2398
                        if (stride && (n == 1))
2399
                          n++;
2400
                        else
2401
                          stride++;
2402

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

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

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

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

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

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

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

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

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

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

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

    
2544
                                floatformat_to_double (valbytes, &fvalue);
2545

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

    
2555
                          case 64:
2556
                            func (stream, "#0x%.8lx%.8lx", hival, value);
2557
                            break;
2558

    
2559
                          default:
2560
                            abort ();
2561
                          }
2562
                      }
2563
                      break;
2564

    
2565
                    case 'F':
2566
                      {
2567
                        int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2568
                        int num = (given >> 8) & 0x3;
2569

    
2570
                        if (!num)
2571
                          func (stream, "{d%d}", regno);
2572
                        else if (num + regno >= 32)
2573
                          func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2574
                        else
2575
                          func (stream, "{d%d-d%d}", regno, regno + num);
2576
                      }
2577
                      break;
2578

    
2579

    
2580
                    case '0': case '1': case '2': case '3': case '4':
2581
                    case '5': case '6': case '7': case '8': case '9':
2582
                      {
2583
                        int width;
2584
                        unsigned long value;
2585

    
2586
                        c = arm_decode_bitfield (c, given, &value, &width);
2587

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

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

    
2609
                              c++;
2610
                              if (*c >= '0' && *c <= '9')
2611
                                limit = *c - '0';
2612
                              else if (*c >= 'a' && *c <= 'f')
2613
                                limit = *c - 'a' + 10;
2614
                              else
2615
                                abort ();
2616
                              low = limit >> 2;
2617
                              high = limit & 3;
2618

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

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

    
2659
                      default:
2660
                        abort ();
2661
                      }
2662
                    }
2663
                }
2664
              else
2665
                func (stream, "%c", *c);
2666
            }
2667
          return true;
2668
        }
2669
    }
2670
  return false;
2671
}
2672

    
2673
/* Print one ARM instruction from PC on INFO->STREAM.  */
2674

    
2675
static void
2676
print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
2677
{
2678
  const struct opcode32 *insn;
2679
  void *stream = info->stream;
2680
  fprintf_ftype func = info->fprintf_func;
2681

    
2682
  if (print_insn_coprocessor (pc, info, given, false))
2683
    return;
2684

    
2685
  if (print_insn_neon (info, given, false))
2686
    return;
2687

    
2688
  for (insn = arm_opcodes; insn->assembler; insn++)
2689
    {
2690
      if (insn->value == FIRST_IWMMXT_INSN
2691
          && info->mach != bfd_mach_arm_XScale
2692
          && info->mach != bfd_mach_arm_iWMMXt)
2693
        insn = insn + IWMMXT_INSN_COUNT;
2694

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

    
2705
          for (c = insn->assembler; *c; c++)
2706
            {
2707
              if (*c == '%')
2708
                {
2709
                  switch (*++c)
2710
                    {
2711
                    case '%':
2712
                      func (stream, "%%");
2713
                      break;
2714

    
2715
                    case 'a':
2716
                      print_arm_address (pc, info, given);
2717
                      break;
2718

    
2719
                    case 'P':
2720
                      /* Set P address bit and use normal address
2721
                         printing routine.  */
2722
                      print_arm_address (pc, info, given | (1 << 24));
2723
                      break;
2724

    
2725
                    case 's':
2726
                      if ((given & 0x004f0000) == 0x004f0000)
2727
                        {
2728
                          /* PC relative with immediate offset.  */
2729
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2730

    
2731
                          if ((given & 0x00800000) == 0)
2732
                            offset = -offset;
2733

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

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

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

    
2798
                    case 'c':
2799
                      if (((given >> 28) & 0xf) != 0xe)
2800
                        func (stream, "%s",
2801
                              arm_conditional [(given >> 28) & 0xf]);
2802
                      break;
2803

    
2804
                    case 'm':
2805
                      {
2806
                        int started = 0;
2807
                        int reg;
2808

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

    
2822
                    case 'q':
2823
                      arm_decode_shift (given, func, stream, 0);
2824
                      break;
2825

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

    
2839
                    case 'p':
2840
                      if ((given & 0x0000f000) == 0x0000f000)
2841
                        func (stream, "p");
2842
                      break;
2843

    
2844
                    case 't':
2845
                      if ((given & 0x01200000) == 0x00200000)
2846
                        func (stream, "t");
2847
                      break;
2848

    
2849
                    case 'A':
2850
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2851

    
2852
                      if ((given & (1 << 24)) != 0)
2853
                        {
2854
                          int offset = given & 0xff;
2855

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

    
2868
                          func (stream, "]");
2869

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

    
2882
                    case 'B':
2883
                      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2884
                      {
2885
                        bfd_vma address;
2886
                        bfd_vma offset = 0;
2887

    
2888
                        if (given & 0x00800000)
2889
                          /* Is signed, hi bits should be ones.  */
2890
                          offset = (-1) ^ 0x00ffffff;
2891

    
2892
                        /* Offset is (SignExtend(offset field)<<2).  */
2893
                        offset += given & 0x00ffffff;
2894
                        offset <<= 2;
2895
                        address = offset + pc + 8;
2896

    
2897
                        if (given & 0x01000000)
2898
                          /* H bit allows addressing to 2-byte boundaries.  */
2899
                          address += 2;
2900

    
2901
                        info->print_address_func (address, info);
2902
                      }
2903
                      break;
2904

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

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

    
2930
                    case '0': case '1': case '2': case '3': case '4':
2931
                    case '5': case '6': case '7': case '8': case '9':
2932
                      {
2933
                        int width;
2934
                        unsigned long value;
2935

    
2936
                        c = arm_decode_bitfield (c, given, &value, &width);
2937

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

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

    
2984
                      case 'e':
2985
                        {
2986
                          int imm;
2987

    
2988
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2989
                          func (stream, "%d", imm);
2990
                        }
2991
                        break;
2992

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

    
3000
                          long width = msb - lsb + 1;
3001
                          if (width > 0)
3002
                            func (stream, "#%lu, #%lu", lsb, width);
3003
                          else
3004
                            func (stream, "(invalid: %lu:%lu)", lsb, msb);
3005
                        }
3006
                        break;
3007

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

    
3019
                      default:
3020
                        abort ();
3021
                      }
3022
                    }
3023
                }
3024
              else
3025
                func (stream, "%c", *c);
3026
            }
3027
          return;
3028
        }
3029
    }
3030
  abort ();
3031
}
3032

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

    
3035
static void
3036
print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3037
{
3038
  const struct opcode16 *insn;
3039
  void *stream = info->stream;
3040
  fprintf_ftype func = info->fprintf_func;
3041

    
3042
  for (insn = thumb_opcodes; insn->assembler; insn++)
3043
    if ((given & insn->mask) == insn->value)
3044
      {
3045
        const char *c = insn->assembler;
3046
        for (; *c; c++)
3047
          {
3048
            int domaskpc = 0;
3049
            int domasklr = 0;
3050

    
3051
            if (*c != '%')
3052
              {
3053
                func (stream, "%c", *c);
3054
                continue;
3055
              }
3056

    
3057
            switch (*++c)
3058
              {
3059
              case '%':
3060
                func (stream, "%%");
3061
                break;
3062

    
3063
              case 'c':
3064
                if (ifthen_state)
3065
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3066
                break;
3067

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

    
3075
              case 'I':
3076
                {
3077
                  unsigned int tmp;
3078

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

    
3086
              case 'x':
3087
                if (ifthen_next_state)
3088
                  func (stream, "\t; unpredictable branch in IT block\n");
3089
                break;
3090

    
3091
              case 'X':
3092
                if (ifthen_state)
3093
                  func (stream, "\t; unpredictable <IT:%s>",
3094
                        arm_conditional[IFTHEN_COND]);
3095
                break;
3096

    
3097
              case 'S':
3098
                {
3099
                  long reg;
3100

    
3101
                  reg = (given >> 3) & 0x7;
3102
                  if (given & (1 << 6))
3103
                    reg += 8;
3104

    
3105
                  func (stream, "%s", arm_regnames[reg]);
3106
                }
3107
                break;
3108

    
3109
              case 'D':
3110
                {
3111
                  long reg;
3112

    
3113
                  reg = given & 0x7;
3114
                  if (given & (1 << 7))
3115
                    reg += 8;
3116

    
3117
                  func (stream, "%s", arm_regnames[reg]);
3118
                }
3119
                break;
3120

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

    
3134
                  func (stream, "{");
3135

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

    
3147
                  if (domasklr)
3148
                    {
3149
                      if (started)
3150
                        func (stream, ", ");
3151
                      started = 1;
3152
                      func (stream, arm_regnames[14] /* "lr" */);
3153
                    }
3154

    
3155
                  if (domaskpc)
3156
                    {
3157
                      if (started)
3158
                        func (stream, ", ");
3159
                      func (stream, arm_regnames[15] /* "pc" */);
3160
                    }
3161

    
3162
                  func (stream, "}");
3163
                }
3164
                break;
3165

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

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

    
3187
              case '0': case '1': case '2': case '3': case '4':
3188
              case '5': case '6': case '7': case '8': case '9':
3189
                {
3190
                  int bitstart = *c++ - '0';
3191
                  int bitend = 0;
3192

    
3193
                  while (*c >= '0' && *c <= '9')
3194
                    bitstart = (bitstart * 10) + *c++ - '0';
3195

    
3196
                  switch (*c)
3197
                    {
3198
                    case '-':
3199
                      {
3200
                        long reg;
3201

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

    
3215
                          case 'd':
3216
                            func (stream, "%ld", reg);
3217
                            break;
3218

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

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

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

    
3235
                          case 'x':
3236
                            func (stream, "0x%04lx", reg);
3237
                            break;
3238

    
3239
                          case 'B':
3240
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3241
                            info->print_address_func (reg * 2 + pc + 4, info);
3242
                            break;
3243

    
3244
                          case 'c':
3245
                            func (stream, "%s", arm_conditional [reg]);
3246
                            break;
3247

    
3248
                          default:
3249
                            abort ();
3250
                          }
3251
                      }
3252
                      break;
3253

    
3254
                    case '\'':
3255
                      c++;
3256
                      if ((given & (1 << bitstart)) != 0)
3257
                        func (stream, "%c", *c);
3258
                      break;
3259

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

    
3268
                    default:
3269
                      abort ();
3270
                    }
3271
                }
3272
                break;
3273

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

    
3281
  /* No match.  */
3282
  abort ();
3283
}
3284

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

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

    
3311
static void
3312
print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3313
{
3314
  const struct opcode32 *insn;
3315
  void *stream = info->stream;
3316
  fprintf_ftype func = info->fprintf_func;
3317

    
3318
  if (print_insn_coprocessor (pc, info, given, true))
3319
    return;
3320

    
3321
  if (print_insn_neon (info, given, true))
3322
    return;
3323

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

    
3336
            switch (*++c)
3337
              {
3338
              case '%':
3339
                func (stream, "%%");
3340
                break;
3341

    
3342
              case 'c':
3343
                if (ifthen_state)
3344
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3345
                break;
3346

    
3347
              case 'x':
3348
                if (ifthen_next_state)
3349
                  func (stream, "\t; unpredictable branch in IT block\n");
3350
                break;
3351

    
3352
              case 'X':
3353
                if (ifthen_state)
3354
                  func (stream, "\t; unpredictable <IT:%s>",
3355
                        arm_conditional[IFTHEN_COND]);
3356
                break;
3357

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

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

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

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

    
3412
              case 'S':
3413
                {
3414
                  unsigned int reg = (given & 0x0000000fu);
3415
                  unsigned int stp = (given & 0x00000030u) >> 4;
3416
                  unsigned int imm = 0;
3417
                  imm |= (given & 0x000000c0u) >> 6;
3418
                  imm |= (given & 0x00007000u) >> 10;
3419

    
3420
                  func (stream, "%s", arm_regnames[reg]);
3421
                  switch (stp)
3422
                    {
3423
                    case 0:
3424
                      if (imm > 0)
3425
                        func (stream, ", lsl #%u", imm);
3426
                      break;
3427

    
3428
                    case 1:
3429
                      if (imm == 0)
3430
                        imm = 32;
3431
                      func (stream, ", lsr #%u", imm);
3432
                      break;
3433

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

    
3440
                    case 3:
3441
                      if (imm == 0)
3442
                        func (stream, ", rrx");
3443
                      else
3444
                        func (stream, ", ror #%u", imm);
3445
                    }
3446
                }
3447
                break;
3448

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

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

    
3480
                    case 0xC:  /* 8-bit negative immediate offset */
3481
                      offset = -i8;
3482
                      break;
3483

    
3484
                    case 0xF:  /* 8-bit + preindex with wb */
3485
                      offset = i8;
3486
                      writeback = true;
3487
                      break;
3488

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

    
3494
                    case 0xB:  /* 8-bit + postindex */
3495
                      offset = i8;
3496
                      postind = true;
3497
                      break;
3498

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

    
3504
                    default:
3505
                      func (stream, ", <undefined>]");
3506
                      goto skip;
3507
                    }
3508

    
3509
                  if (postind)
3510
                    func (stream, "], #%d", offset);
3511
                  else
3512
                    {
3513
                      if (offset)
3514
                        func (stream, ", #%d", offset);
3515
                      func (stream, writeback ? "]!" : "]");
3516
                    }
3517

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

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

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

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

    
3574
              case 'm':
3575
                {
3576
                  int started = 0;
3577
                  int reg;
3578

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

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

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

    
3612
              case 'b':
3613
                {
3614
                  unsigned int S = (given & 0x04000000u) >> 26;
3615
                  unsigned int J1 = (given & 0x00002000u) >> 13;
3616
                  unsigned int J2 = (given & 0x00000800u) >> 11;
3617
                  int offset = 0;
3618

    
3619
                  offset |= !S << 20;
3620
                  offset |= J2 << 19;
3621
                  offset |= J1 << 18;
3622
                  offset |= (given & 0x003f0000) >> 4;
3623
                  offset |= (given & 0x000007ff) << 1;
3624
                  offset -= (1 << 20);
3625

    
3626
                  info->print_address_func (pc + 4 + offset, info);
3627
                }
3628
                break;
3629

    
3630
              case 'B':
3631
                {
3632
                  unsigned int S = (given & 0x04000000u) >> 26;
3633
                  unsigned int I1 = (given & 0x00002000u) >> 13;
3634
                  unsigned int I2 = (given & 0x00000800u) >> 11;
3635
                  int offset = 0;
3636

    
3637
                  offset |= !S << 24;
3638
                  offset |= !(I1 ^ S) << 23;
3639
                  offset |= !(I2 ^ S) << 22;
3640
                  offset |= (given & 0x03ff0000u) >> 4;
3641
                  offset |= (given & 0x000007ffu) << 1;
3642
                  offset -= (1 << 24);
3643
                  offset += pc + 4;
3644

    
3645
                  /* BLX target addresses are always word aligned.  */
3646
                  if ((given & 0x00001000u) == 0)
3647
                      offset &= ~2u;
3648

    
3649
                  info->print_address_func (offset, info);
3650
                }
3651
                break;
3652

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

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

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

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

    
3706
              case 'D':
3707
                if ((given & 0xff) == 0)
3708
                  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3709
                else
3710
                  func (stream, psr_name (given & 0xff));
3711
                break;
3712

    
3713
              case '0': case '1': case '2': case '3': case '4':
3714
              case '5': case '6': case '7': case '8': case '9':
3715
                {
3716
                  int width;
3717
                  unsigned long val;
3718

    
3719
                  c = arm_decode_bitfield (c, given, &val, &width);
3720

    
3721
                  switch (*c)
3722
                    {
3723
                    case 'd': func (stream, "%lu", val); break;
3724
                    case 'W': func (stream, "%lu", val * 4); break;
3725
                    case 'r': func (stream, "%s", arm_regnames[val]); break;
3726

    
3727
                    case 'c':
3728
                      func (stream, "%s", arm_conditional[val]);
3729
                      break;
3730

    
3731
                    case '\'':
3732
                      c++;
3733
                      if (val == ((1ul << width) - 1))
3734
                        func (stream, "%c", *c);
3735
                      break;
3736

    
3737
                    case '`':
3738
                      c++;
3739
                      if (val == 0)
3740
                        func (stream, "%c", *c);
3741
                      break;
3742

    
3743
                    case '?':
3744
                      func (stream, "%c", c[(1 << width) - (int)val]);
3745
                      c += 1 << width;
3746
                      break;
3747

    
3748
                    default:
3749
                      abort ();
3750
                    }
3751
                }
3752
                break;
3753

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

    
3761
  /* No match.  */
3762
  abort ();
3763
}
3764

    
3765
/* Print data bytes on INFO->STREAM.  */
3766

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

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

    
3803
  ifthen_address = pc;
3804
  ifthen_state = 0;
3805

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

    
3822
          return;
3823
        }
3824
      addr -= 2;
3825
      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3826
      if (status)
3827
        return;
3828

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

    
3865
/* NOTE: There are no checks in these routines that
3866
   the relevant number of data bytes exist.  */
3867

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

3881
  if (info->disassembler_options)
3882
    {
3883
      parse_disassembler_options (info->disassembler_options);
3884

3885
      /* To avoid repeated parsing of these options, we remove them here.  */
3886
      info->disassembler_options = NULL;
3887
    }
3888

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

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

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

3924
      if (!found)
3925
        {
3926
          n = info->symtab_pos;
3927
          if (n < last_mapping_sym - 1)
3928
            n = last_mapping_sym - 1;
3929

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

3943
      last_mapping_sym = last_sym;
3944
      last_type = type;
3945
      is_thumb = (last_type == MAP_THUMB);
3946
      is_data = (last_type == MAP_DATA);
3947

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

3973
  if (info->symbols != NULL)
3974
    {
3975
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3976
        {
3977
          coff_symbol_type * cs;
3978

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

3994
          es = *(elf_symbol_type **)(info->symbols);
3995
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3996

3997
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
3998
        }
3999
    }
4000
#else
4001
  int little;
4002

    
4003
  little = (info->endian == BFD_ENDIAN_LITTLE);
4004
  is_thumb |= (pc & 1);
4005
  pc &= ~(bfd_vma)1;
4006
#endif
4007

    
4008
  if (force_thumb)
4009
    is_thumb = true;
4010

    
4011
  info->bytes_per_line = 4;
4012

    
4013
  if (is_data)
4014
    {
4015
      int i;
4016

    
4017
      /* size was already set above.  */
4018
      info->bytes_per_chunk = size;
4019
      printer = print_insn_data;
4020

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

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

    
4054
      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4055
      if (little)
4056
        given = (b[0]) | (b[1] << 8);
4057
      else
4058
        given = (b[1]) | (b[0] << 8);
4059

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

    
4074
              printer = print_insn_thumb32;
4075
              size = 4;
4076
            }
4077
        }
4078

    
4079
      if (ifthen_address != pc)
4080
        find_ifthen_state(pc, info, little);
4081

    
4082
      if (ifthen_state)
4083
        {
4084
          if ((ifthen_state & 0xf) == 0x8)
4085
            ifthen_next_state = 0;
4086
          else
4087
            ifthen_next_state = (ifthen_state & 0xe0)
4088
                                | ((ifthen_state & 0xf) << 1);
4089
        }
4090
    }
4091

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

    
4105
  printer (pc, info, given);
4106

    
4107
  if (is_thumb)
4108
    {
4109
      ifthen_state = ifthen_next_state;
4110
      ifthen_address += size;
4111
    }
4112
  return size;
4113
}