Statistics
| Branch: | Revision:

root / disas / arm.c @ 76cad711

History | View | Annotate | Download (157.1 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 "disas/bfd.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_function 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 instruction 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_function 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_function 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 instruction 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_function 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
                            break;
2519
                          }
2520
                        switch (size)
2521
                          {
2522
                          case 8:
2523
                            func (stream, "#%ld\t; 0x%.2lx", value, value);
2524
                            break;
2525

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

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

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

    
2543
                                floatformat_to_double (valbytes, &fvalue);
2544

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

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

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

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

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

    
2578

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2867
                          func (stream, "]");
2868

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3133
                  func (stream, "{");
3134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3802
  ifthen_address = pc;
3803
  ifthen_state = 0;
3804

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4007
  if (force_thumb)
4008
    is_thumb = true;
4009

    
4010
  info->bytes_per_line = 4;
4011

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

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

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

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

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

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

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

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

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

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

    
4104
  /* We include the hexdump of the instruction. The format here
4105
     matches that used by objdump and the ARM ARM (in particular,
4106
     32 bit Thumb instructions are displayed as pairs of halfwords,
4107
     not as a single word.)  */
4108
  if (is_thumb)
4109
    {
4110
      if (size == 2)
4111
        {
4112
          info->fprintf_func(info->stream, "%04lx       ",
4113
                             ((unsigned long)given) & 0xffff);
4114
        }
4115
      else
4116
        {
4117
          info->fprintf_func(info->stream, "%04lx %04lx  ",
4118
                             (((unsigned long)given) >> 16) & 0xffff,
4119
                             ((unsigned long)given) & 0xffff);
4120
        }
4121
    }
4122
  else
4123
    {
4124
      info->fprintf_func(info->stream, "%08lx      ",
4125
                         ((unsigned long)given) & 0xffffffff);
4126
    }
4127

    
4128
  printer (pc, info, given);
4129

    
4130
  if (is_thumb)
4131
    {
4132
      ifthen_state = ifthen_next_state;
4133
      ifthen_address += size;
4134
    }
4135
  return size;
4136
}