Statistics
| Branch: | Revision:

root / arm-dis.c @ 8c5e95d8

History | View | Annotate | Download (157.8 kB)

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

7
   This file is part of libopcodes.
8

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

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

19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22

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

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

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

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

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

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

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

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

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

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

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

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

106
   %%                        %
107

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

510
   %%                        %
511

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

787
   %%                        %
788

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1225
   print_insn_thumb32 recognizes the following format control codes:
1226

1227
       %%                %
1228

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1535
static bfd_boolean force_thumb = FALSE;
1536

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

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

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

    
1557
 
1558
/* Functions.  */
1559
int
1560
get_arm_regname_num_options (void)
1561
{
1562
  return NUM_ARM_REGNAMES;
1563
}
1564

    
1565
int
1566
set_arm_regname_option (int option)
1567
{
1568
  int old = regname_selected;
1569
  regname_selected = option;
1570
  return old;
1571
}
1572

    
1573
int
1574
get_arm_regnames (int option, const char **setname, const char **setdescription,
1575
                  const char *const **register_names)
1576
{
1577
  *setname = regnames[option].name;
1578
  *setdescription = regnames[option].description;
1579
  *register_names = regnames[option].reg_names;
1580
  return 16;
1581
}
1582

    
1583
/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1584
   Returns pointer to following character of the format string and
1585
   fills in *VALUEP and *WIDTHP with the extracted value and number of
1586
   bits extracted.  WIDTHP can be NULL. */
1587

    
1588
static const char *
1589
arm_decode_bitfield (const char *ptr, unsigned long insn,
1590
                     unsigned long *valuep, int *widthp)
1591
{
1592
  unsigned long value = 0;
1593
  int width = 0;
1594

    
1595
  do
1596
    {
1597
      int start, end;
1598
      int bits;
1599

    
1600
      for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1601
        start = start * 10 + *ptr - '0';
1602
      if (*ptr == '-')
1603
        for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1604
          end = end * 10 + *ptr - '0';
1605
      else
1606
        end = start;
1607
      bits = end - start;
1608
      if (bits < 0)
1609
        abort ();
1610
      value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1611
      width += bits + 1;
1612
    }
1613
  while (*ptr++ == ',');
1614
  *valuep = value;
1615
  if (widthp)
1616
    *widthp = width;
1617
  return ptr - 1;
1618
}
1619

    
1620
static void
1621
arm_decode_shift (long given, fprintf_ftype func, void *stream,
1622
                  int print_shift)
1623
{
1624
  func (stream, "%s", arm_regnames[given & 0xf]);
1625

    
1626
  if ((given & 0xff0) != 0)
1627
    {
1628
      if ((given & 0x10) == 0)
1629
        {
1630
          int amount = (given & 0xf80) >> 7;
1631
          int shift = (given & 0x60) >> 5;
1632

    
1633
          if (amount == 0)
1634
            {
1635
              if (shift == 3)
1636
                {
1637
                  func (stream, ", rrx");
1638
                  return;
1639
                }
1640

    
1641
              amount = 32;
1642
            }
1643

    
1644
          if (print_shift)
1645
            func (stream, ", %s #%d", arm_shift[shift], amount);
1646
          else
1647
            func (stream, ", #%d", amount);
1648
        }
1649
      else if (print_shift)
1650
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1651
              arm_regnames[(given & 0xf00) >> 8]);
1652
      else
1653
        func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1654
    }
1655
}
1656

    
1657
/* Print one coprocessor instruction on INFO->STREAM.
1658
   Return TRUE if the instuction matched, FALSE if this is not a
1659
   recognised coprocessor instruction.  */
1660

    
1661
static bfd_boolean
1662
print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1663
                        bfd_boolean thumb)
1664
{
1665
  const struct opcode32 *insn;
1666
  void *stream = info->stream;
1667
  fprintf_ftype func = info->fprintf_func;
1668
  unsigned long mask;
1669
  unsigned long value;
1670
  int cond;
1671

    
1672
  for (insn = coprocessor_opcodes; insn->assembler; insn++)
1673
    {
1674
      if (insn->value == FIRST_IWMMXT_INSN
1675
          && info->mach != bfd_mach_arm_XScale
1676
          && info->mach != bfd_mach_arm_iWMMXt
1677
          && info->mach != bfd_mach_arm_iWMMXt2)
1678
        insn = insn + IWMMXT_INSN_COUNT;
1679

    
1680
      mask = insn->mask;
1681
      value = insn->value;
1682
      if (thumb)
1683
        {
1684
          /* The high 4 bits are 0xe for Arm conditional instructions, and
1685
             0xe for arm unconditional instructions.  The rest of the
1686
             encoding is the same.  */
1687
          mask |= 0xf0000000;
1688
          value |= 0xe0000000;
1689
          if (ifthen_state)
1690
            cond = IFTHEN_COND;
1691
          else
1692
            cond = 16;
1693
        }
1694
      else
1695
        {
1696
          /* Only match unconditional instuctions against unconditional
1697
             patterns.  */
1698
          if ((given & 0xf0000000) == 0xf0000000)
1699
            {
1700
              mask |= 0xf0000000;
1701
              cond = 16;
1702
            }
1703
          else
1704
            {
1705
              cond = (given >> 28) & 0xf;
1706
              if (cond == 0xe)
1707
                cond = 16;
1708
            }
1709
        }
1710
      if ((given & mask) == value)
1711
        {
1712
          const char *c;
1713

    
1714
          for (c = insn->assembler; *c; c++)
1715
            {
1716
              if (*c == '%')
1717
                {
1718
                  switch (*++c)
1719
                    {
1720
                    case '%':
1721
                      func (stream, "%%");
1722
                      break;
1723

    
1724
                    case 'A':
1725
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1726

    
1727
                      if ((given & (1 << 24)) != 0)
1728
                        {
1729
                          int offset = given & 0xff;
1730

    
1731
                          if (offset)
1732
                            func (stream, ", #%s%d]%s",
1733
                                  ((given & 0x00800000) == 0 ? "-" : ""),
1734
                                  offset * 4,
1735
                                  ((given & 0x00200000) != 0 ? "!" : ""));
1736
                          else
1737
                            func (stream, "]");
1738
                        }
1739
                      else
1740
                        {
1741
                          int offset = given & 0xff;
1742

    
1743
                          func (stream, "]");
1744

    
1745
                          if (given & (1 << 21))
1746
                            {
1747
                              if (offset)
1748
                                func (stream, ", #%s%d",
1749
                                      ((given & 0x00800000) == 0 ? "-" : ""),
1750
                                      offset * 4);
1751
                            }
1752
                          else
1753
                            func (stream, ", {%d}", offset);
1754
                        }
1755
                      break;
1756

    
1757
                    case 'B':
1758
                      {
1759
                        int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1760
                        int offset = (given >> 1) & 0x3f;
1761

    
1762
                        if (offset == 1)
1763
                          func (stream, "{d%d}", regno);
1764
                        else if (regno + offset > 32)
1765
                          func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1766
                        else
1767
                          func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1768
                      }
1769
                      break;
1770

    
1771
                    case 'C':
1772
                      {
1773
                        int rn = (given >> 16) & 0xf;
1774
                        int offset = (given & 0xff) * 4;
1775
                        int add = (given >> 23) & 1;
1776

    
1777
                        func (stream, "[%s", arm_regnames[rn]);
1778

    
1779
                        if (offset)
1780
                          {
1781
                            if (!add)
1782
                              offset = -offset;
1783
                            func (stream, ", #%d", offset);
1784
                          }
1785
                        func (stream, "]");
1786
                        if (rn == 15)
1787
                          {
1788
                            func (stream, "\t; ");
1789
                            /* FIXME: Unsure if info->bytes_per_chunk is the
1790
                               right thing to use here.  */
1791
                            info->print_address_func (offset + pc
1792
                              + info->bytes_per_chunk * 2, info);
1793
                          }
1794
                      }
1795
                      break;
1796

    
1797
                    case 'c':
1798
                      func (stream, "%s", arm_conditional[cond]);
1799
                      break;
1800

    
1801
                    case 'I':
1802
                      /* Print a Cirrus/DSP shift immediate.  */
1803
                      /* Immediates are 7bit signed ints with bits 0..3 in
1804
                         bits 0..3 of opcode and bits 4..6 in bits 5..7
1805
                         of opcode.  */
1806
                      {
1807
                        int imm;
1808

    
1809
                        imm = (given & 0xf) | ((given & 0xe0) >> 1);
1810

    
1811
                        /* Is ``imm'' a negative number?  */
1812
                        if (imm & 0x40)
1813
                          imm |= (-1 << 7);
1814

    
1815
                        func (stream, "%d", imm);
1816
                      }
1817

    
1818
                      break;
1819

    
1820
                    case 'F':
1821
                      switch (given & 0x00408000)
1822
                        {
1823
                        case 0:
1824
                          func (stream, "4");
1825
                          break;
1826
                        case 0x8000:
1827
                          func (stream, "1");
1828
                          break;
1829
                        case 0x00400000:
1830
                          func (stream, "2");
1831
                          break;
1832
                        default:
1833
                          func (stream, "3");
1834
                        }
1835
                      break;
1836

    
1837
                    case 'P':
1838
                      switch (given & 0x00080080)
1839
                        {
1840
                        case 0:
1841
                          func (stream, "s");
1842
                          break;
1843
                        case 0x80:
1844
                          func (stream, "d");
1845
                          break;
1846
                        case 0x00080000:
1847
                          func (stream, "e");
1848
                          break;
1849
                        default:
1850
                          func (stream, _("<illegal precision>"));
1851
                          break;
1852
                        }
1853
                      break;
1854
                    case 'Q':
1855
                      switch (given & 0x00408000)
1856
                        {
1857
                        case 0:
1858
                          func (stream, "s");
1859
                          break;
1860
                        case 0x8000:
1861
                          func (stream, "d");
1862
                          break;
1863
                        case 0x00400000:
1864
                          func (stream, "e");
1865
                          break;
1866
                        default:
1867
                          func (stream, "p");
1868
                          break;
1869
                        }
1870
                      break;
1871
                    case 'R':
1872
                      switch (given & 0x60)
1873
                        {
1874
                        case 0:
1875
                          break;
1876
                        case 0x20:
1877
                          func (stream, "p");
1878
                          break;
1879
                        case 0x40:
1880
                          func (stream, "m");
1881
                          break;
1882
                        default:
1883
                          func (stream, "z");
1884
                          break;
1885
                        }
1886
                      break;
1887

    
1888
                    case '0': case '1': case '2': case '3': case '4':
1889
                    case '5': case '6': case '7': case '8': case '9':
1890
                      {
1891
                        int width;
1892
                        unsigned long value;
1893

    
1894
                        c = arm_decode_bitfield (c, given, &value, &width);
1895

    
1896
                        switch (*c)
1897
                          {
1898
                          case 'r':
1899
                            func (stream, "%s", arm_regnames[value]);
1900
                            break;
1901
                          case 'D':
1902
                            func (stream, "d%ld", value);
1903
                            break;
1904
                          case 'Q':
1905
                            if (value & 1)
1906
                              func (stream, "<illegal reg q%ld.5>", value >> 1);
1907
                            else
1908
                              func (stream, "q%ld", value >> 1);
1909
                            break;
1910
                          case 'd':
1911
                            func (stream, "%ld", value);
1912
                            break;
1913
                          case 'k':
1914
                            {
1915
                              int from = (given & (1 << 7)) ? 32 : 16;
1916
                              func (stream, "%ld", from - value);
1917
                            }
1918
                            break;
1919

    
1920
                          case 'f':
1921
                            if (value > 7)
1922
                              func (stream, "#%s", arm_fp_const[value & 7]);
1923
                            else
1924
                              func (stream, "f%ld", value);
1925
                            break;
1926

    
1927
                          case 'w':
1928
                            if (width == 2)
1929
                              func (stream, "%s", iwmmxt_wwnames[value]);
1930
                            else
1931
                              func (stream, "%s", iwmmxt_wwssnames[value]);
1932
                            break;
1933

    
1934
                          case 'g':
1935
                            func (stream, "%s", iwmmxt_regnames[value]);
1936
                            break;
1937
                          case 'G':
1938
                            func (stream, "%s", iwmmxt_cregnames[value]);
1939
                            break;
1940

    
1941
                          case 'x':
1942
                            func (stream, "0x%lx", value);
1943
                            break;
1944

    
1945
                          case '`':
1946
                            c++;
1947
                            if (value == 0)
1948
                              func (stream, "%c", *c);
1949
                            break;
1950
                          case '\'':
1951
                            c++;
1952
                            if (value == ((1ul << width) - 1))
1953
                              func (stream, "%c", *c);
1954
                            break;
1955
                          case '?':
1956
                            func (stream, "%c", c[(1 << width) - (int)value]);
1957
                            c += 1 << width;
1958
                            break;
1959
                          default:
1960
                            abort ();
1961
                          }
1962
                        break;
1963

    
1964
                      case 'y':
1965
                      case 'z':
1966
                        {
1967
                          int single = *c++ == 'y';
1968
                          int regno;
1969

    
1970
                          switch (*c)
1971
                            {
1972
                            case '4': /* Sm pair */
1973
                              func (stream, "{");
1974
                              /* Fall through.  */
1975
                            case '0': /* Sm, Dm */
1976
                              regno = given & 0x0000000f;
1977
                              if (single)
1978
                                {
1979
                                  regno <<= 1;
1980
                                  regno += (given >> 5) & 1;
1981
                                }
1982
                              else
1983
                                regno += ((given >> 5) & 1) << 4;
1984
                              break;
1985

    
1986
                            case '1': /* Sd, Dd */
1987
                              regno = (given >> 12) & 0x0000000f;
1988
                              if (single)
1989
                                {
1990
                                  regno <<= 1;
1991
                                  regno += (given >> 22) & 1;
1992
                                }
1993
                              else
1994
                                regno += ((given >> 22) & 1) << 4;
1995
                              break;
1996

    
1997
                            case '2': /* Sn, Dn */
1998
                              regno = (given >> 16) & 0x0000000f;
1999
                              if (single)
2000
                                {
2001
                                  regno <<= 1;
2002
                                  regno += (given >> 7) & 1;
2003
                                }
2004
                              else
2005
                                regno += ((given >> 7) & 1) << 4;
2006
                              break;
2007

    
2008
                            case '3': /* List */
2009
                              func (stream, "{");
2010
                              regno = (given >> 12) & 0x0000000f;
2011
                              if (single)
2012
                                {
2013
                                  regno <<= 1;
2014
                                  regno += (given >> 22) & 1;
2015
                                }
2016
                              else
2017
                                regno += ((given >> 22) & 1) << 4;
2018
                              break;
2019

    
2020
                            default:
2021
                              abort ();
2022
                            }
2023

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

    
2026
                          if (*c == '3')
2027
                            {
2028
                              int count = given & 0xff;
2029

    
2030
                              if (single == 0)
2031
                                count >>= 1;
2032

    
2033
                              if (--count)
2034
                                {
2035
                                  func (stream, "-%c%d",
2036
                                        single ? 's' : 'd',
2037
                                        regno + count);
2038
                                }
2039

    
2040
                              func (stream, "}");
2041
                            }
2042
                          else if (*c == '4')
2043
                            func (stream, ", %c%d}", single ? 's' : 'd',
2044
                                  regno + 1);
2045
                        }
2046
                        break;
2047

    
2048
                      case 'L':
2049
                        switch (given & 0x00400100)
2050
                          {
2051
                          case 0x00000000: func (stream, "b"); break;
2052
                          case 0x00400000: func (stream, "h"); break;
2053
                          case 0x00000100: func (stream, "w"); break;
2054
                          case 0x00400100: func (stream, "d"); break;
2055
                          default:
2056
                            break;
2057
                          }
2058
                        break;
2059

    
2060
                      case 'Z':
2061
                        {
2062
                          int value;
2063
                          /* given (20, 23) | given (0, 3) */
2064
                          value = ((given >> 16) & 0xf0) | (given & 0xf);
2065
                          func (stream, "%d", value);
2066
                        }
2067
                        break;
2068

    
2069
                      case 'l':
2070
                        /* This is like the 'A' operator, except that if
2071
                           the width field "M" is zero, then the offset is
2072
                           *not* multiplied by four.  */
2073
                        {
2074
                          int offset = given & 0xff;
2075
                          int multiplier = (given & 0x00000100) ? 4 : 1;
2076

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

    
2079
                          if (offset)
2080
                            {
2081
                              if ((given & 0x01000000) != 0)
2082
                                func (stream, ", #%s%d]%s",
2083
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2084
                                      offset * multiplier,
2085
                                      ((given & 0x00200000) != 0 ? "!" : ""));
2086
                              else
2087
                                func (stream, "], #%s%d",
2088
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2089
                                      offset * multiplier);
2090
                            }
2091
                          else
2092
                            func (stream, "]");
2093
                        }
2094
                        break;
2095

    
2096
                      case 'r':
2097
                        {
2098
                          int imm4 = (given >> 4) & 0xf;
2099
                          int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2100
                          int ubit = (given >> 23) & 1;
2101
                          const char *rm = arm_regnames [given & 0xf];
2102
                          const char *rn = arm_regnames [(given >> 16) & 0xf];
2103

    
2104
                          switch (puw_bits)
2105
                            {
2106
                            case 1:
2107
                              /* fall through */
2108
                            case 3:
2109
                              func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2110
                              if (imm4)
2111
                                func (stream, ", lsl #%d", imm4);
2112
                              break;
2113

    
2114
                            case 4:
2115
                              /* fall through */
2116
                            case 5:
2117
                              /* fall through */
2118
                            case 6:
2119
                              /* fall through */
2120
                            case 7:
2121
                              func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2122
                              if (imm4 > 0)
2123
                                func (stream, ", lsl #%d", imm4);
2124
                              func (stream, "]");
2125
                              if (puw_bits == 5 || puw_bits == 7)
2126
                                func (stream, "!");
2127
                              break;
2128

    
2129
                            default:
2130
                              func (stream, "INVALID");
2131
                            }
2132
                        }
2133
                        break;
2134

    
2135
                      case 'i':
2136
                        {
2137
                          long imm5;
2138
                          imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2139
                          func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2140
                        }
2141
                        break;
2142

    
2143
                      default:
2144
                        abort ();
2145
                      }
2146
                    }
2147
                }
2148
              else
2149
                func (stream, "%c", *c);
2150
            }
2151
          return TRUE;
2152
        }
2153
    }
2154
  return FALSE;
2155
}
2156

    
2157
static void
2158
print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2159
{
2160
  void *stream = info->stream;
2161
  fprintf_ftype func = info->fprintf_func;
2162

    
2163
  if (((given & 0x000f0000) == 0x000f0000)
2164
      && ((given & 0x02000000) == 0))
2165
    {
2166
      int offset = given & 0xfff;
2167

    
2168
      func (stream, "[pc");
2169

    
2170
      if (given & 0x01000000)
2171
        {
2172
          if ((given & 0x00800000) == 0)
2173
            offset = - offset;
2174

    
2175
          /* Pre-indexed.  */
2176
          func (stream, ", #%d]", offset);
2177

    
2178
          offset += pc + 8;
2179

    
2180
          /* Cope with the possibility of write-back
2181
             being used.  Probably a very dangerous thing
2182
             for the programmer to do, but who are we to
2183
             argue ?  */
2184
          if (given & 0x00200000)
2185
            func (stream, "!");
2186
        }
2187
      else
2188
        {
2189
          /* Post indexed.  */
2190
          func (stream, "], #%d", offset);
2191

    
2192
          /* ie ignore the offset.  */
2193
          offset = pc + 8;
2194
        }
2195

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

    
2221
          func (stream, "]%s",
2222
                ((given & 0x00200000) != 0) ? "!" : "");
2223
        }
2224
      else
2225
        {
2226
          if ((given & 0x02000000) == 0)
2227
            {
2228
              int offset = given & 0xfff;
2229
              if (offset)
2230
                func (stream, "], #%s%d",
2231
                      (((given & 0x00800000) == 0)
2232
                       ? "-" : ""), offset);
2233
              else
2234
                func (stream, "]");
2235
            }
2236
          else
2237
            {
2238
              func (stream, "], %s",
2239
                    (((given & 0x00800000) == 0)
2240
                     ? "-" : ""));
2241
              arm_decode_shift (given, func, stream, 1);
2242
            }
2243
        }
2244
    }
2245
}
2246

    
2247
/* Print one neon instruction on INFO->STREAM.
2248
   Return TRUE if the instuction matched, FALSE if this is not a
2249
   recognised neon instruction.  */
2250

    
2251
static bfd_boolean
2252
print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2253
{
2254
  const struct opcode32 *insn;
2255
  void *stream = info->stream;
2256
  fprintf_ftype func = info->fprintf_func;
2257

    
2258
  if (thumb)
2259
    {
2260
      if ((given & 0xef000000) == 0xef000000)
2261
        {
2262
          /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
2263
          unsigned long bit28 = given & (1 << 28);
2264

    
2265
          given &= 0x00ffffff;
2266
          if (bit28)
2267
            given |= 0xf3000000;
2268
          else
2269
            given |= 0xf2000000;
2270
        }
2271
      else if ((given & 0xff000000) == 0xf9000000)
2272
        given ^= 0xf9000000 ^ 0xf4000000;
2273
      else
2274
        return FALSE;
2275
    }
2276

    
2277
  for (insn = neon_opcodes; insn->assembler; insn++)
2278
    {
2279
      if ((given & insn->mask) == insn->value)
2280
        {
2281
          const char *c;
2282

    
2283
          for (c = insn->assembler; *c; c++)
2284
            {
2285
              if (*c == '%')
2286
                {
2287
                  switch (*++c)
2288
                    {
2289
                    case '%':
2290
                      func (stream, "%%");
2291
                      break;
2292

    
2293
                    case 'c':
2294
                      if (thumb && ifthen_state)
2295
                        func (stream, "%s", arm_conditional[IFTHEN_COND]);
2296
                      break;
2297

    
2298
                    case 'A':
2299
                      {
2300
                        static const unsigned char enc[16] =
2301
                        {
2302
                          0x4, 0x14, /* st4 0,1 */
2303
                          0x4, /* st1 2 */
2304
                          0x4, /* st2 3 */
2305
                          0x3, /* st3 4 */
2306
                          0x13, /* st3 5 */
2307
                          0x3, /* st1 6 */
2308
                          0x1, /* st1 7 */
2309
                          0x2, /* st2 8 */
2310
                          0x12, /* st2 9 */
2311
                          0x2, /* st1 10 */
2312
                          0, 0, 0, 0, 0
2313
                        };
2314
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2315
                        int rn = ((given >> 16) & 0xf);
2316
                        int rm = ((given >> 0) & 0xf);
2317
                        int align = ((given >> 4) & 0x3);
2318
                        int type = ((given >> 8) & 0xf);
2319
                        int n = enc[type] & 0xf;
2320
                        int stride = (enc[type] >> 4) + 1;
2321
                        int ix;
2322

    
2323
                        func (stream, "{");
2324
                        if (stride > 1)
2325
                          for (ix = 0; ix != n; ix++)
2326
                            func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2327
                        else if (n == 1)
2328
                          func (stream, "d%d", rd);
2329
                        else
2330
                          func (stream, "d%d-d%d", rd, rd + n - 1);
2331
                        func (stream, "}, [%s", arm_regnames[rn]);
2332
                        if (align)
2333
                          func (stream, ", :%d", 32 << align);
2334
                        func (stream, "]");
2335
                        if (rm == 0xd)
2336
                          func (stream, "!");
2337
                        else if (rm != 0xf)
2338
                          func (stream, ", %s", arm_regnames[rm]);
2339
                      }
2340
                      break;
2341

    
2342
                    case 'B':
2343
                      {
2344
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2345
                        int rn = ((given >> 16) & 0xf);
2346
                        int rm = ((given >> 0) & 0xf);
2347
                        int idx_align = ((given >> 4) & 0xf);
2348
                        int align = 0;
2349
                        int size = ((given >> 10) & 0x3);
2350
                        int idx = idx_align >> (size + 1);
2351
                        int length = ((given >> 8) & 3) + 1;
2352
                        int stride = 1;
2353
                        int i;
2354

    
2355
                        if (length > 1 && size > 0)
2356
                          stride = (idx_align & (1 << size)) ? 2 : 1;
2357

    
2358
                        switch (length)
2359
                          {
2360
                          case 1:
2361
                            {
2362
                              int amask = (1 << size) - 1;
2363
                              if ((idx_align & (1 << size)) != 0)
2364
                                return FALSE;
2365
                              if (size > 0)
2366
                                {
2367
                                  if ((idx_align & amask) == amask)
2368
                                    align = 8 << size;
2369
                                  else if ((idx_align & amask) != 0)
2370
                                    return FALSE;
2371
                                }
2372
                              }
2373
                            break;
2374

    
2375
                          case 2:
2376
                            if (size == 2 && (idx_align & 2) != 0)
2377
                              return FALSE;
2378
                            align = (idx_align & 1) ? 16 << size : 0;
2379
                            break;
2380

    
2381
                          case 3:
2382
                            if ((size == 2 && (idx_align & 3) != 0)
2383
                                || (idx_align & 1) != 0)
2384
                              return FALSE;
2385
                            break;
2386

    
2387
                          case 4:
2388
                            if (size == 2)
2389
                              {
2390
                                if ((idx_align & 3) == 3)
2391
                                  return FALSE;
2392
                                align = (idx_align & 3) * 64;
2393
                              }
2394
                            else
2395
                              align = (idx_align & 1) ? 32 << size : 0;
2396
                            break;
2397

    
2398
                          default:
2399
                            abort ();
2400
                          }
2401

    
2402
                        func (stream, "{");
2403
                        for (i = 0; i < length; i++)
2404
                          func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2405
                            rd + i * stride, idx);
2406
                        func (stream, "}, [%s", arm_regnames[rn]);
2407
                        if (align)
2408
                          func (stream, ", :%d", align);
2409
                        func (stream, "]");
2410
                        if (rm == 0xd)
2411
                          func (stream, "!");
2412
                        else if (rm != 0xf)
2413
                          func (stream, ", %s", arm_regnames[rm]);
2414
                      }
2415
                      break;
2416

    
2417
                    case 'C':
2418
                      {
2419
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2420
                        int rn = ((given >> 16) & 0xf);
2421
                        int rm = ((given >> 0) & 0xf);
2422
                        int align = ((given >> 4) & 0x1);
2423
                        int size = ((given >> 6) & 0x3);
2424
                        int type = ((given >> 8) & 0x3);
2425
                        int n = type + 1;
2426
                        int stride = ((given >> 5) & 0x1);
2427
                        int ix;
2428

    
2429
                        if (stride && (n == 1))
2430
                          n++;
2431
                        else
2432
                          stride++;
2433

    
2434
                        func (stream, "{");
2435
                        if (stride > 1)
2436
                          for (ix = 0; ix != n; ix++)
2437
                            func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2438
                        else if (n == 1)
2439
                          func (stream, "d%d[]", rd);
2440
                        else
2441
                          func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2442
                        func (stream, "}, [%s", arm_regnames[rn]);
2443
                        if (align)
2444
                          {
2445
                            int align = (8 * (type + 1)) << size;
2446
                            if (type == 3)
2447
                              align = (size > 1) ? align >> 1 : align;
2448
                            if (type == 2 || (type == 0 && !size))
2449
                              func (stream, ", :<bad align %d>", align);
2450
                            else
2451
                              func (stream, ", :%d", align);
2452
                          }
2453
                        func (stream, "]");
2454
                        if (rm == 0xd)
2455
                          func (stream, "!");
2456
                        else if (rm != 0xf)
2457
                          func (stream, ", %s", arm_regnames[rm]);
2458
                      }
2459
                      break;
2460

    
2461
                    case 'D':
2462
                      {
2463
                        int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2464
                        int size = (given >> 20) & 3;
2465
                        int reg = raw_reg & ((4 << size) - 1);
2466
                        int ix = raw_reg >> size >> 2;
2467

    
2468
                        func (stream, "d%d[%d]", reg, ix);
2469
                      }
2470
                      break;
2471

    
2472
                    case 'E':
2473
                      /* Neon encoded constant for mov, mvn, vorr, vbic */
2474
                      {
2475
                        int bits = 0;
2476
                        int cmode = (given >> 8) & 0xf;
2477
                        int op = (given >> 5) & 0x1;
2478
                        unsigned long value = 0, hival = 0;
2479
                        unsigned shift;
2480
                        int size = 0;
2481
                        int isfloat = 0;
2482

    
2483
                        bits |= ((given >> 24) & 1) << 7;
2484
                        bits |= ((given >> 16) & 7) << 4;
2485
                        bits |= ((given >> 0) & 15) << 0;
2486

    
2487
                        if (cmode < 8)
2488
                          {
2489
                            shift = (cmode >> 1) & 3;
2490
                            value = (unsigned long)bits << (8 * shift);
2491
                            size = 32;
2492
                          }
2493
                        else if (cmode < 12)
2494
                          {
2495
                            shift = (cmode >> 1) & 1;
2496
                            value = (unsigned long)bits << (8 * shift);
2497
                            size = 16;
2498
                          }
2499
                        else if (cmode < 14)
2500
                          {
2501
                            shift = (cmode & 1) + 1;
2502
                            value = (unsigned long)bits << (8 * shift);
2503
                            value |= (1ul << (8 * shift)) - 1;
2504
                            size = 32;
2505
                          }
2506
                        else if (cmode == 14)
2507
                          {
2508
                            if (op)
2509
                              {
2510
                                /* bit replication into bytes */
2511
                                int ix;
2512
                                unsigned long mask;
2513

    
2514
                                value = 0;
2515
                                hival = 0;
2516
                                for (ix = 7; ix >= 0; ix--)
2517
                                  {
2518
                                    mask = ((bits >> ix) & 1) ? 0xff : 0;
2519
                                    if (ix <= 3)
2520
                                      value = (value << 8) | mask;
2521
                                    else
2522
                                      hival = (hival << 8) | mask;
2523
                                  }
2524
                                size = 64;
2525
                              }
2526
                            else
2527
                              {
2528
                                /* byte replication */
2529
                                value = (unsigned long)bits;
2530
                                size = 8;
2531
                              }
2532
                          }
2533
                        else if (!op)
2534
                          {
2535
                            /* floating point encoding */
2536
                            int tmp;
2537

    
2538
                            value = (unsigned long)(bits & 0x7f) << 19;
2539
                            value |= (unsigned long)(bits & 0x80) << 24;
2540
                            tmp = bits & 0x40 ? 0x3c : 0x40;
2541
                            value |= (unsigned long)tmp << 24;
2542
                            size = 32;
2543
                            isfloat = 1;
2544
                          }
2545
                        else
2546
                          {
2547
                            func (stream, "<illegal constant %.8x:%x:%x>",
2548
                                  bits, cmode, op);
2549
                            size = 32;
2550
                            break;
2551
                          }
2552
                        switch (size)
2553
                          {
2554
                          case 8:
2555
                            func (stream, "#%ld\t; 0x%.2lx", value, value);
2556
                            break;
2557

    
2558
                          case 16:
2559
                            func (stream, "#%ld\t; 0x%.4lx", value, value);
2560
                            break;
2561

    
2562
                          case 32:
2563
                            if (isfloat)
2564
                              {
2565
                                unsigned char valbytes[4];
2566
                                double fvalue;
2567

    
2568
                                /* Do this a byte at a time so we don't have to
2569
                                   worry about the host's endianness.  */
2570
                                valbytes[0] = value & 0xff;
2571
                                valbytes[1] = (value >> 8) & 0xff;
2572
                                valbytes[2] = (value >> 16) & 0xff;
2573
                                valbytes[3] = (value >> 24) & 0xff;
2574

    
2575
                                floatformat_to_double
2576
                                  (&floatformat_ieee_single_little, valbytes,
2577
                                  &fvalue);
2578

    
2579
                                func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2580
                                      value);
2581
                              }
2582
                            else
2583
                              func (stream, "#%ld\t; 0x%.8lx",
2584
                                (long) ((value & 0x80000000)
2585
                                        ? value | ~0xffffffffl : value), value);
2586
                            break;
2587

    
2588
                          case 64:
2589
                            func (stream, "#0x%.8lx%.8lx", hival, value);
2590
                            break;
2591

    
2592
                          default:
2593
                            abort ();
2594
                          }
2595
                      }
2596
                      break;
2597

    
2598
                    case 'F':
2599
                      {
2600
                        int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2601
                        int num = (given >> 8) & 0x3;
2602

    
2603
                        if (!num)
2604
                          func (stream, "{d%d}", regno);
2605
                        else if (num + regno >= 32)
2606
                          func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2607
                        else
2608
                          func (stream, "{d%d-d%d}", regno, regno + num);
2609
                      }
2610
                      break;
2611

    
2612

    
2613
                    case '0': case '1': case '2': case '3': case '4':
2614
                    case '5': case '6': case '7': case '8': case '9':
2615
                      {
2616
                        int width;
2617
                        unsigned long value;
2618

    
2619
                        c = arm_decode_bitfield (c, given, &value, &width);
2620

    
2621
                        switch (*c)
2622
                          {
2623
                          case 'r':
2624
                            func (stream, "%s", arm_regnames[value]);
2625
                            break;
2626
                          case 'd':
2627
                            func (stream, "%ld", value);
2628
                            break;
2629
                          case 'e':
2630
                            func (stream, "%ld", (1ul << width) - value);
2631
                            break;
2632

    
2633
                          case 'S':
2634
                          case 'T':
2635
                          case 'U':
2636
                            /* various width encodings */
2637
                            {
2638
                              int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2639
                              int limit;
2640
                              unsigned low, high;
2641

    
2642
                              c++;
2643
                              if (*c >= '0' && *c <= '9')
2644
                                limit = *c - '0';
2645
                              else if (*c >= 'a' && *c <= 'f')
2646
                                limit = *c - 'a' + 10;
2647
                              else
2648
                                abort ();
2649
                              low = limit >> 2;
2650
                              high = limit & 3;
2651

    
2652
                              if (value < low || value > high)
2653
                                func (stream, "<illegal width %d>", base << value);
2654
                              else
2655
                                func (stream, "%d", base << value);
2656
                            }
2657
                            break;
2658
                          case 'R':
2659
                            if (given & (1 << 6))
2660
                              goto Q;
2661
                            /* FALLTHROUGH */
2662
                          case 'D':
2663
                            func (stream, "d%ld", value);
2664
                            break;
2665
                          case 'Q':
2666
                          Q:
2667
                            if (value & 1)
2668
                              func (stream, "<illegal reg q%ld.5>", value >> 1);
2669
                            else
2670
                              func (stream, "q%ld", value >> 1);
2671
                            break;
2672

    
2673
                          case '`':
2674
                            c++;
2675
                            if (value == 0)
2676
                              func (stream, "%c", *c);
2677
                            break;
2678
                          case '\'':
2679
                            c++;
2680
                            if (value == ((1ul << width) - 1))
2681
                              func (stream, "%c", *c);
2682
                            break;
2683
                          case '?':
2684
                            func (stream, "%c", c[(1 << width) - (int)value]);
2685
                            c += 1 << width;
2686
                            break;
2687
                          default:
2688
                            abort ();
2689
                          }
2690
                        break;
2691

    
2692
                      default:
2693
                        abort ();
2694
                      }
2695
                    }
2696
                }
2697
              else
2698
                func (stream, "%c", *c);
2699
            }
2700
          return TRUE;
2701
        }
2702
    }
2703
  return FALSE;
2704
}
2705

    
2706
/* Print one ARM instruction from PC on INFO->STREAM.  */
2707

    
2708
static void
2709
print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
2710
{
2711
  const struct opcode32 *insn;
2712
  void *stream = info->stream;
2713
  fprintf_ftype func = info->fprintf_func;
2714

    
2715
  if (print_insn_coprocessor (pc, info, given, FALSE))
2716
    return;
2717

    
2718
  if (print_insn_neon (info, given, FALSE))
2719
    return;
2720

    
2721
  for (insn = arm_opcodes; insn->assembler; insn++)
2722
    {
2723
      if (insn->value == FIRST_IWMMXT_INSN
2724
          && info->mach != bfd_mach_arm_XScale
2725
          && info->mach != bfd_mach_arm_iWMMXt)
2726
        insn = insn + IWMMXT_INSN_COUNT;
2727

    
2728
      if ((given & insn->mask) == insn->value
2729
          /* Special case: an instruction with all bits set in the condition field
2730
             (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2731
             or by the catchall at the end of the table.  */
2732
          && ((given & 0xF0000000) != 0xF0000000
2733
              || (insn->mask & 0xF0000000) == 0xF0000000
2734
              || (insn->mask == 0 && insn->value == 0)))
2735
        {
2736
          const char *c;
2737

    
2738
          for (c = insn->assembler; *c; c++)
2739
            {
2740
              if (*c == '%')
2741
                {
2742
                  switch (*++c)
2743
                    {
2744
                    case '%':
2745
                      func (stream, "%%");
2746
                      break;
2747

    
2748
                    case 'a':
2749
                      print_arm_address (pc, info, given);
2750
                      break;
2751

    
2752
                    case 'P':
2753
                      /* Set P address bit and use normal address
2754
                         printing routine.  */
2755
                      print_arm_address (pc, info, given | (1 << 24));
2756
                      break;
2757

    
2758
                    case 's':
2759
                      if ((given & 0x004f0000) == 0x004f0000)
2760
                        {
2761
                          /* PC relative with immediate offset.  */
2762
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2763

    
2764
                          if ((given & 0x00800000) == 0)
2765
                            offset = -offset;
2766

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

    
2795
                              func (stream, "]%s",
2796
                                    ((given & 0x00200000) != 0) ? "!" : "");
2797
                            }
2798
                          else
2799
                            {
2800
                              /* Post-indexed.  */
2801
                              if ((given & 0x00400000) == 0x00400000)
2802
                                {
2803
                                  /* Immediate.  */
2804
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2805
                                  if (offset)
2806
                                    func (stream, "], #%s%d",
2807
                                          (((given & 0x00800000) == 0)
2808
                                           ? "-" : ""), offset);
2809
                                  else
2810
                                    func (stream, "]");
2811
                                }
2812
                              else
2813
                                {
2814
                                  /* Register.  */
2815
                                  func (stream, "], %s%s",
2816
                                        (((given & 0x00800000) == 0)
2817
                                         ? "-" : ""),
2818
                                        arm_regnames[given & 0xf]);
2819
                                }
2820
                            }
2821
                        }
2822
                      break;
2823

    
2824
                    case 'b':
2825
                      {
2826
                        int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2827
                        info->print_address_func (disp*4 + pc + 8, info);
2828
                      }
2829
                      break;
2830

    
2831
                    case 'c':
2832
                      if (((given >> 28) & 0xf) != 0xe)
2833
                        func (stream, "%s",
2834
                              arm_conditional [(given >> 28) & 0xf]);
2835
                      break;
2836

    
2837
                    case 'm':
2838
                      {
2839
                        int started = 0;
2840
                        int reg;
2841

    
2842
                        func (stream, "{");
2843
                        for (reg = 0; reg < 16; reg++)
2844
                          if ((given & (1 << reg)) != 0)
2845
                            {
2846
                              if (started)
2847
                                func (stream, ", ");
2848
                              started = 1;
2849
                              func (stream, "%s", arm_regnames[reg]);
2850
                            }
2851
                        func (stream, "}");
2852
                      }
2853
                      break;
2854

    
2855
                    case 'q':
2856
                      arm_decode_shift (given, func, stream, 0);
2857
                      break;
2858

    
2859
                    case 'o':
2860
                      if ((given & 0x02000000) != 0)
2861
                        {
2862
                          int rotate = (given & 0xf00) >> 7;
2863
                          int immed = (given & 0xff);
2864
                          immed = (((immed << (32 - rotate))
2865
                                    | (immed >> rotate)) & 0xffffffff);
2866
                          func (stream, "#%d\t; 0x%x", immed, immed);
2867
                        }
2868
                      else
2869
                        arm_decode_shift (given, func, stream, 1);
2870
                      break;
2871

    
2872
                    case 'p':
2873
                      if ((given & 0x0000f000) == 0x0000f000)
2874
                        func (stream, "p");
2875
                      break;
2876

    
2877
                    case 't':
2878
                      if ((given & 0x01200000) == 0x00200000)
2879
                        func (stream, "t");
2880
                      break;
2881

    
2882
                    case 'A':
2883
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2884

    
2885
                      if ((given & (1 << 24)) != 0)
2886
                        {
2887
                          int offset = given & 0xff;
2888

    
2889
                          if (offset)
2890
                            func (stream, ", #%s%d]%s",
2891
                                  ((given & 0x00800000) == 0 ? "-" : ""),
2892
                                  offset * 4,
2893
                                  ((given & 0x00200000) != 0 ? "!" : ""));
2894
                          else
2895
                            func (stream, "]");
2896
                        }
2897
                      else
2898
                        {
2899
                          int offset = given & 0xff;
2900

    
2901
                          func (stream, "]");
2902

    
2903
                          if (given & (1 << 21))
2904
                            {
2905
                              if (offset)
2906
                                func (stream, ", #%s%d",
2907
                                      ((given & 0x00800000) == 0 ? "-" : ""),
2908
                                      offset * 4);
2909
                            }
2910
                          else
2911
                            func (stream, ", {%d}", offset);
2912
                        }
2913
                      break;
2914

    
2915
                    case 'B':
2916
                      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2917
                      {
2918
                        bfd_vma address;
2919
                        bfd_vma offset = 0;
2920

    
2921
                        if (given & 0x00800000)
2922
                          /* Is signed, hi bits should be ones.  */
2923
                          offset = (-1) ^ 0x00ffffff;
2924

    
2925
                        /* Offset is (SignExtend(offset field)<<2).  */
2926
                        offset += given & 0x00ffffff;
2927
                        offset <<= 2;
2928
                        address = offset + pc + 8;
2929

    
2930
                        if (given & 0x01000000)
2931
                          /* H bit allows addressing to 2-byte boundaries.  */
2932
                          address += 2;
2933

    
2934
                        info->print_address_func (address, info);
2935
                      }
2936
                      break;
2937

    
2938
                    case 'C':
2939
                      func (stream, "_");
2940
                      if (given & 0x80000)
2941
                        func (stream, "f");
2942
                      if (given & 0x40000)
2943
                        func (stream, "s");
2944
                      if (given & 0x20000)
2945
                        func (stream, "x");
2946
                      if (given & 0x10000)
2947
                        func (stream, "c");
2948
                      break;
2949

    
2950
                    case 'U':
2951
                      switch (given & 0xf)
2952
                        {
2953
                        case 0xf: func(stream, "sy"); break;
2954
                        case 0x7: func(stream, "un"); break;
2955
                        case 0xe: func(stream, "st"); break;
2956
                        case 0x6: func(stream, "unst"); break;
2957
                        default:
2958
                          func(stream, "#%d", (int)given & 0xf);
2959
                          break;
2960
                        }
2961
                      break;
2962

    
2963
                    case '0': case '1': case '2': case '3': case '4':
2964
                    case '5': case '6': case '7': case '8': case '9':
2965
                      {
2966
                        int width;
2967
                        unsigned long value;
2968

    
2969
                        c = arm_decode_bitfield (c, given, &value, &width);
2970

    
2971
                        switch (*c)
2972
                          {
2973
                          case 'r':
2974
                            func (stream, "%s", arm_regnames[value]);
2975
                            break;
2976
                          case 'd':
2977
                            func (stream, "%ld", value);
2978
                            break;
2979
                          case 'b':
2980
                            func (stream, "%ld", value * 8);
2981
                            break;
2982
                          case 'W':
2983
                            func (stream, "%ld", value + 1);
2984
                            break;
2985
                          case 'x':
2986
                            func (stream, "0x%08lx", value);
2987

    
2988
                            /* Some SWI instructions have special
2989
                               meanings.  */
2990
                            if ((given & 0x0fffffff) == 0x0FF00000)
2991
                              func (stream, "\t; IMB");
2992
                            else if ((given & 0x0fffffff) == 0x0FF00001)
2993
                              func (stream, "\t; IMBRange");
2994
                            break;
2995
                          case 'X':
2996
                            func (stream, "%01lx", value & 0xf);
2997
                            break;
2998
                          case '`':
2999
                            c++;
3000
                            if (value == 0)
3001
                              func (stream, "%c", *c);
3002
                            break;
3003
                          case '\'':
3004
                            c++;
3005
                            if (value == ((1ul << width) - 1))
3006
                              func (stream, "%c", *c);
3007
                            break;
3008
                          case '?':
3009
                            func (stream, "%c", c[(1 << width) - (int)value]);
3010
                            c += 1 << width;
3011
                            break;
3012
                          default:
3013
                            abort ();
3014
                          }
3015
                        break;
3016

    
3017
                      case 'e':
3018
                        {
3019
                          int imm;
3020

    
3021
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3022
                          func (stream, "%d", imm);
3023
                        }
3024
                        break;
3025

    
3026
                      case 'E':
3027
                        /* LSB and WIDTH fields of BFI or BFC.  The machine-
3028
                           language instruction encodes LSB and MSB.  */
3029
                        {
3030
                          long msb = (given & 0x001f0000) >> 16;
3031
                          long lsb = (given & 0x00000f80) >> 7;
3032

    
3033
                          long width = msb - lsb + 1;
3034
                          if (width > 0)
3035
                            func (stream, "#%lu, #%lu", lsb, width);
3036
                          else
3037
                            func (stream, "(invalid: %lu:%lu)", lsb, msb);
3038
                        }
3039
                        break;
3040

    
3041
                      case 'V':
3042
                        /* 16-bit unsigned immediate from a MOVT or MOVW
3043
                           instruction, encoded in bits 0:11 and 15:19.  */
3044
                        {
3045
                          long hi = (given & 0x000f0000) >> 4;
3046
                          long lo = (given & 0x00000fff);
3047
                          long imm16 = hi | lo;
3048
                          func (stream, "#%lu\t; 0x%lx", imm16, imm16);
3049
                        }
3050
                        break;
3051

    
3052
                      default:
3053
                        abort ();
3054
                      }
3055
                    }
3056
                }
3057
              else
3058
                func (stream, "%c", *c);
3059
            }
3060
          return;
3061
        }
3062
    }
3063
  abort ();
3064
}
3065

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

    
3068
static void
3069
print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3070
{
3071
  const struct opcode16 *insn;
3072
  void *stream = info->stream;
3073
  fprintf_ftype func = info->fprintf_func;
3074

    
3075
  for (insn = thumb_opcodes; insn->assembler; insn++)
3076
    if ((given & insn->mask) == insn->value)
3077
      {
3078
        const char *c = insn->assembler;
3079
        for (; *c; c++)
3080
          {
3081
            int domaskpc = 0;
3082
            int domasklr = 0;
3083

    
3084
            if (*c != '%')
3085
              {
3086
                func (stream, "%c", *c);
3087
                continue;
3088
              }
3089

    
3090
            switch (*++c)
3091
              {
3092
              case '%':
3093
                func (stream, "%%");
3094
                break;
3095

    
3096
              case 'c':
3097
                if (ifthen_state)
3098
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3099
                break;
3100

    
3101
              case 'C':
3102
                if (ifthen_state)
3103
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3104
                else
3105
                  func (stream, "s");
3106
                break;
3107

    
3108
              case 'I':
3109
                {
3110
                  unsigned int tmp;
3111

    
3112
                  ifthen_next_state = given & 0xff;
3113
                  for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3114
                    func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3115
                  func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3116
                }
3117
                break;
3118

    
3119
              case 'x':
3120
                if (ifthen_next_state)
3121
                  func (stream, "\t; unpredictable branch in IT block\n");
3122
                break;
3123

    
3124
              case 'X':
3125
                if (ifthen_state)
3126
                  func (stream, "\t; unpredictable <IT:%s>",
3127
                        arm_conditional[IFTHEN_COND]);
3128
                break;
3129

    
3130
              case 'S':
3131
                {
3132
                  long reg;
3133

    
3134
                  reg = (given >> 3) & 0x7;
3135
                  if (given & (1 << 6))
3136
                    reg += 8;
3137

    
3138
                  func (stream, "%s", arm_regnames[reg]);
3139
                }
3140
                break;
3141

    
3142
              case 'D':
3143
                {
3144
                  long reg;
3145

    
3146
                  reg = given & 0x7;
3147
                  if (given & (1 << 7))
3148
                    reg += 8;
3149

    
3150
                  func (stream, "%s", arm_regnames[reg]);
3151
                }
3152
                break;
3153

    
3154
              case 'N':
3155
                if (given & (1 << 8))
3156
                  domasklr = 1;
3157
                /* Fall through.  */
3158
              case 'O':
3159
                if (*c == 'O' && (given & (1 << 8)))
3160
                  domaskpc = 1;
3161
                /* Fall through.  */
3162
              case 'M':
3163
                {
3164
                  int started = 0;
3165
                  int reg;
3166

    
3167
                  func (stream, "{");
3168

    
3169
                  /* It would be nice if we could spot
3170
                     ranges, and generate the rS-rE format: */
3171
                  for (reg = 0; (reg < 8); reg++)
3172
                    if ((given & (1 << reg)) != 0)
3173
                      {
3174
                        if (started)
3175
                          func (stream, ", ");
3176
                        started = 1;
3177
                        func (stream, "%s", arm_regnames[reg]);
3178
                      }
3179

    
3180
                  if (domasklr)
3181
                    {
3182
                      if (started)
3183
                        func (stream, ", ");
3184
                      started = 1;
3185
                      func (stream, arm_regnames[14] /* "lr" */);
3186
                    }
3187

    
3188
                  if (domaskpc)
3189
                    {
3190
                      if (started)
3191
                        func (stream, ", ");
3192
                      func (stream, arm_regnames[15] /* "pc" */);
3193
                    }
3194

    
3195
                  func (stream, "}");
3196
                }
3197
                break;
3198

    
3199
              case 'b':
3200
                /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3201
                {
3202
                  bfd_vma address = (pc + 4
3203
                                     + ((given & 0x00f8) >> 2)
3204
                                     + ((given & 0x0200) >> 3));
3205
                  info->print_address_func (address, info);
3206
                }
3207
                break;
3208

    
3209
              case 's':
3210
                /* Right shift immediate -- bits 6..10; 1-31 print
3211
                   as themselves, 0 prints as 32.  */
3212
                {
3213
                  long imm = (given & 0x07c0) >> 6;
3214
                  if (imm == 0)
3215
                    imm = 32;
3216
                  func (stream, "#%ld", imm);
3217
                }
3218
                break;
3219

    
3220
              case '0': case '1': case '2': case '3': case '4':
3221
              case '5': case '6': case '7': case '8': case '9':
3222
                {
3223
                  int bitstart = *c++ - '0';
3224
                  int bitend = 0;
3225

    
3226
                  while (*c >= '0' && *c <= '9')
3227
                    bitstart = (bitstart * 10) + *c++ - '0';
3228

    
3229
                  switch (*c)
3230
                    {
3231
                    case '-':
3232
                      {
3233
                        long reg;
3234

    
3235
                        c++;
3236
                        while (*c >= '0' && *c <= '9')
3237
                          bitend = (bitend * 10) + *c++ - '0';
3238
                        if (!bitend)
3239
                          abort ();
3240
                        reg = given >> bitstart;
3241
                        reg &= (2 << (bitend - bitstart)) - 1;
3242
                        switch (*c)
3243
                          {
3244
                          case 'r':
3245
                            func (stream, "%s", arm_regnames[reg]);
3246
                            break;
3247

    
3248
                          case 'd':
3249
                            func (stream, "%ld", reg);
3250
                            break;
3251

    
3252
                          case 'H':
3253
                            func (stream, "%ld", reg << 1);
3254
                            break;
3255

    
3256
                          case 'W':
3257
                            func (stream, "%ld", reg << 2);
3258
                            break;
3259

    
3260
                          case 'a':
3261
                            /* PC-relative address -- the bottom two
3262
                               bits of the address are dropped
3263
                               before the calculation.  */
3264
                            info->print_address_func
3265
                              (((pc + 4) & ~3) + (reg << 2), info);
3266
                            break;
3267

    
3268
                          case 'x':
3269
                            func (stream, "0x%04lx", reg);
3270
                            break;
3271

    
3272
                          case 'B':
3273
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3274
                            info->print_address_func (reg * 2 + pc + 4, info);
3275
                            break;
3276

    
3277
                          case 'c':
3278
                            func (stream, "%s", arm_conditional [reg]);
3279
                            break;
3280

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

    
3287
                    case '\'':
3288
                      c++;
3289
                      if ((given & (1 << bitstart)) != 0)
3290
                        func (stream, "%c", *c);
3291
                      break;
3292

    
3293
                    case '?':
3294
                      ++c;
3295
                      if ((given & (1 << bitstart)) != 0)
3296
                        func (stream, "%c", *c++);
3297
                      else
3298
                        func (stream, "%c", *++c);
3299
                      break;
3300

    
3301
                    default:
3302
                      abort ();
3303
                    }
3304
                }
3305
                break;
3306

    
3307
              default:
3308
                abort ();
3309
              }
3310
          }
3311
        return;
3312
      }
3313

    
3314
  /* No match.  */
3315
  abort ();
3316
}
3317

    
3318
/* Return the name of an V7M special register.  */
3319
static const char *
3320
psr_name (int regno)
3321
{
3322
  switch (regno)
3323
    {
3324
    case 0: return "APSR";
3325
    case 1: return "IAPSR";
3326
    case 2: return "EAPSR";
3327
    case 3: return "PSR";
3328
    case 5: return "IPSR";
3329
    case 6: return "EPSR";
3330
    case 7: return "IEPSR";
3331
    case 8: return "MSP";
3332
    case 9: return "PSP";
3333
    case 16: return "PRIMASK";
3334
    case 17: return "BASEPRI";
3335
    case 18: return "BASEPRI_MASK";
3336
    case 19: return "FAULTMASK";
3337
    case 20: return "CONTROL";
3338
    default: return "<unknown>";
3339
    }
3340
}
3341

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

    
3344
static void
3345
print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3346
{
3347
  const struct opcode32 *insn;
3348
  void *stream = info->stream;
3349
  fprintf_ftype func = info->fprintf_func;
3350

    
3351
  if (print_insn_coprocessor (pc, info, given, TRUE))
3352
    return;
3353

    
3354
  if (print_insn_neon (info, given, TRUE))
3355
    return;
3356

    
3357
  for (insn = thumb32_opcodes; insn->assembler; insn++)
3358
    if ((given & insn->mask) == insn->value)
3359
      {
3360
        const char *c = insn->assembler;
3361
        for (; *c; c++)
3362
          {
3363
            if (*c != '%')
3364
              {
3365
                func (stream, "%c", *c);
3366
                continue;
3367
              }
3368

    
3369
            switch (*++c)
3370
              {
3371
              case '%':
3372
                func (stream, "%%");
3373
                break;
3374

    
3375
              case 'c':
3376
                if (ifthen_state)
3377
                  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3378
                break;
3379

    
3380
              case 'x':
3381
                if (ifthen_next_state)
3382
                  func (stream, "\t; unpredictable branch in IT block\n");
3383
                break;
3384

    
3385
              case 'X':
3386
                if (ifthen_state)
3387
                  func (stream, "\t; unpredictable <IT:%s>",
3388
                        arm_conditional[IFTHEN_COND]);
3389
                break;
3390

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

    
3401
              case 'M':
3402
                {
3403
                  unsigned int bits = 0, imm, imm8, mod;
3404
                  bits |= (given & 0x000000ffu);
3405
                  bits |= (given & 0x00007000u) >> 4;
3406
                  bits |= (given & 0x04000000u) >> 15;
3407
                  imm8 = (bits & 0x0ff);
3408
                  mod = (bits & 0xf00) >> 8;
3409
                  switch (mod)
3410
                    {
3411
                    case 0: imm = imm8; break;
3412
                    case 1: imm = ((imm8<<16) | imm8); break;
3413
                    case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3414
                    case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3415
                    default:
3416
                      mod  = (bits & 0xf80) >> 7;
3417
                      imm8 = (bits & 0x07f) | 0x80;
3418
                      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3419
                    }
3420
                  func (stream, "#%u\t; 0x%x", imm, imm);
3421
                }
3422
                break;
3423

    
3424
              case 'J':
3425
                {
3426
                  unsigned int imm = 0;
3427
                  imm |= (given & 0x000000ffu);
3428
                  imm |= (given & 0x00007000u) >> 4;
3429
                  imm |= (given & 0x04000000u) >> 15;
3430
                  imm |= (given & 0x000f0000u) >> 4;
3431
                  func (stream, "#%u\t; 0x%x", imm, imm);
3432
                }
3433
                break;
3434

    
3435
              case 'K':
3436
                {
3437
                  unsigned int imm = 0;
3438
                  imm |= (given & 0x000f0000u) >> 16;
3439
                  imm |= (given & 0x00000ff0u) >> 0;
3440
                  imm |= (given & 0x0000000fu) << 12;
3441
                  func (stream, "#%u\t; 0x%x", imm, imm);
3442
                }
3443
                break;
3444

    
3445
              case 'S':
3446
                {
3447
                  unsigned int reg = (given & 0x0000000fu);
3448
                  unsigned int stp = (given & 0x00000030u) >> 4;
3449
                  unsigned int imm = 0;
3450
                  imm |= (given & 0x000000c0u) >> 6;
3451
                  imm |= (given & 0x00007000u) >> 10;
3452

    
3453
                  func (stream, "%s", arm_regnames[reg]);
3454
                  switch (stp)
3455
                    {
3456
                    case 0:
3457
                      if (imm > 0)
3458
                        func (stream, ", lsl #%u", imm);
3459
                      break;
3460

    
3461
                    case 1:
3462
                      if (imm == 0)
3463
                        imm = 32;
3464
                      func (stream, ", lsr #%u", imm);
3465
                      break;
3466

    
3467
                    case 2:
3468
                      if (imm == 0)
3469
                        imm = 32;
3470
                      func (stream, ", asr #%u", imm);
3471
                      break;
3472

    
3473
                    case 3:
3474
                      if (imm == 0)
3475
                        func (stream, ", rrx");
3476
                      else
3477
                        func (stream, ", ror #%u", imm);
3478
                    }
3479
                }
3480
                break;
3481

    
3482
              case 'a':
3483
                {
3484
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
3485
                  unsigned int U   = (given & 0x00800000) >> 23;
3486
                  unsigned int op  = (given & 0x00000f00) >> 8;
3487
                  unsigned int i12 = (given & 0x00000fff);
3488
                  unsigned int i8  = (given & 0x000000ff);
3489
                  bfd_boolean writeback = FALSE, postind = FALSE;
3490
                  int offset = 0;
3491

    
3492
                  func (stream, "[%s", arm_regnames[Rn]);
3493
                  if (U) /* 12-bit positive immediate offset */
3494
                    offset = i12;
3495
                  else if (Rn == 15) /* 12-bit negative immediate offset */
3496
                    offset = -(int)i12;
3497
                  else if (op == 0x0) /* shifted register offset */
3498
                    {
3499
                      unsigned int Rm = (i8 & 0x0f);
3500
                      unsigned int sh = (i8 & 0x30) >> 4;
3501
                      func (stream, ", %s", arm_regnames[Rm]);
3502
                      if (sh)
3503
                        func (stream, ", lsl #%u", sh);
3504
                      func (stream, "]");
3505
                      break;
3506
                    }
3507
                  else switch (op)
3508
                    {
3509
                    case 0xE:  /* 8-bit positive immediate offset */
3510
                      offset = i8;
3511
                      break;
3512

    
3513
                    case 0xC:  /* 8-bit negative immediate offset */
3514
                      offset = -i8;
3515
                      break;
3516

    
3517
                    case 0xF:  /* 8-bit + preindex with wb */
3518
                      offset = i8;
3519
                      writeback = TRUE;
3520
                      break;
3521

    
3522
                    case 0xD:  /* 8-bit - preindex with wb */
3523
                      offset = -i8;
3524
                      writeback = TRUE;
3525
                      break;
3526

    
3527
                    case 0xB:  /* 8-bit + postindex */
3528
                      offset = i8;
3529
                      postind = TRUE;
3530
                      break;
3531

    
3532
                    case 0x9:  /* 8-bit - postindex */
3533
                      offset = -i8;
3534
                      postind = TRUE;
3535
                      break;
3536

    
3537
                    default:
3538
                      func (stream, ", <undefined>]");
3539
                      goto skip;
3540
                    }
3541

    
3542
                  if (postind)
3543
                    func (stream, "], #%d", offset);
3544
                  else
3545
                    {
3546
                      if (offset)
3547
                        func (stream, ", #%d", offset);
3548
                      func (stream, writeback ? "]!" : "]");
3549
                    }
3550

    
3551
                  if (Rn == 15)
3552
                    {
3553
                      func (stream, "\t; ");
3554
                      info->print_address_func (((pc + 4) & ~3) + offset, info);
3555
                    }
3556
                }
3557
              skip:
3558
                break;
3559

    
3560
              case 'A':
3561
                {
3562
                  unsigned int P   = (given & 0x01000000) >> 24;
3563
                  unsigned int U   = (given & 0x00800000) >> 23;
3564
                  unsigned int W   = (given & 0x00400000) >> 21;
3565
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
3566
                  unsigned int off = (given & 0x000000ff);
3567

    
3568
                  func (stream, "[%s", arm_regnames[Rn]);
3569
                  if (P)
3570
                    {
3571
                      if (off || !U)
3572
                        func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3573
                      func (stream, "]");
3574
                      if (W)
3575
                        func (stream, "!");
3576
                    }
3577
                  else
3578
                    {
3579
                      func (stream, "], ");
3580
                      if (W)
3581
                        func (stream, "#%c%u", U ? '+' : '-', off * 4);
3582
                      else
3583
                        func (stream, "{%u}", off);
3584
                    }
3585
                }
3586
                break;
3587

    
3588
              case 'w':
3589
                {
3590
                  unsigned int Sbit = (given & 0x01000000) >> 24;
3591
                  unsigned int type = (given & 0x00600000) >> 21;
3592
                  switch (type)
3593
                    {
3594
                    case 0: func (stream, Sbit ? "sb" : "b"); break;
3595
                    case 1: func (stream, Sbit ? "sh" : "h"); break;
3596
                    case 2:
3597
                      if (Sbit)
3598
                        func (stream, "??");
3599
                      break;
3600
                    case 3:
3601
                      func (stream, "??");
3602
                      break;
3603
                    }
3604
                }
3605
                break;
3606

    
3607
              case 'm':
3608
                {
3609
                  int started = 0;
3610
                  int reg;
3611

    
3612
                  func (stream, "{");
3613
                  for (reg = 0; reg < 16; reg++)
3614
                    if ((given & (1 << reg)) != 0)
3615
                      {
3616
                        if (started)
3617
                          func (stream, ", ");
3618
                        started = 1;
3619
                        func (stream, "%s", arm_regnames[reg]);
3620
                      }
3621
                  func (stream, "}");
3622
                }
3623
                break;
3624

    
3625
              case 'E':
3626
                {
3627
                  unsigned int msb = (given & 0x0000001f);
3628
                  unsigned int lsb = 0;
3629
                  lsb |= (given & 0x000000c0u) >> 6;
3630
                  lsb |= (given & 0x00007000u) >> 10;
3631
                  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3632
                }
3633
                break;
3634

    
3635
              case 'F':
3636
                {
3637
                  unsigned int width = (given & 0x0000001f) + 1;
3638
                  unsigned int lsb = 0;
3639
                  lsb |= (given & 0x000000c0u) >> 6;
3640
                  lsb |= (given & 0x00007000u) >> 10;
3641
                  func (stream, "#%u, #%u", lsb, width);
3642
                }
3643
                break;
3644

    
3645
              case 'b':
3646
                {
3647
                  unsigned int S = (given & 0x04000000u) >> 26;
3648
                  unsigned int J1 = (given & 0x00002000u) >> 13;
3649
                  unsigned int J2 = (given & 0x00000800u) >> 11;
3650
                  int offset = 0;
3651

    
3652
                  offset |= !S << 20;
3653
                  offset |= J2 << 19;
3654
                  offset |= J1 << 18;
3655
                  offset |= (given & 0x003f0000) >> 4;
3656
                  offset |= (given & 0x000007ff) << 1;
3657
                  offset -= (1 << 20);
3658

    
3659
                  info->print_address_func (pc + 4 + offset, info);
3660
                }
3661
                break;
3662

    
3663
              case 'B':
3664
                {
3665
                  unsigned int S = (given & 0x04000000u) >> 26;
3666
                  unsigned int I1 = (given & 0x00002000u) >> 13;
3667
                  unsigned int I2 = (given & 0x00000800u) >> 11;
3668
                  int offset = 0;
3669

    
3670
                  offset |= !S << 24;
3671
                  offset |= !(I1 ^ S) << 23;
3672
                  offset |= !(I2 ^ S) << 22;
3673
                  offset |= (given & 0x03ff0000u) >> 4;
3674
                  offset |= (given & 0x000007ffu) << 1;
3675
                  offset -= (1 << 24);
3676
                  offset += pc + 4;
3677

    
3678
                  /* BLX target addresses are always word aligned.  */
3679
                  if ((given & 0x00001000u) == 0)
3680
                      offset &= ~2u;
3681

    
3682
                  info->print_address_func (offset, info);
3683
                }
3684
                break;
3685

    
3686
              case 's':
3687
                {
3688
                  unsigned int shift = 0;
3689
                  shift |= (given & 0x000000c0u) >> 6;
3690
                  shift |= (given & 0x00007000u) >> 10;
3691
                  if (given & 0x00200000u)
3692
                    func (stream, ", asr #%u", shift);
3693
                  else if (shift)
3694
                    func (stream, ", lsl #%u", shift);
3695
                  /* else print nothing - lsl #0 */
3696
                }
3697
                break;
3698

    
3699
              case 'R':
3700
                {
3701
                  unsigned int rot = (given & 0x00000030) >> 4;
3702
                  if (rot)
3703
                    func (stream, ", ror #%u", rot * 8);
3704
                }
3705
                break;
3706

    
3707
              case 'U':
3708
                switch (given & 0xf)
3709
                  {
3710
                  case 0xf: func(stream, "sy"); break;
3711
                  case 0x7: func(stream, "un"); break;
3712
                  case 0xe: func(stream, "st"); break;
3713
                  case 0x6: func(stream, "unst"); break;
3714
                  default:
3715
                    func(stream, "#%d", (int)given & 0xf);
3716
                    break;
3717
                  }
3718
                break;
3719

    
3720
              case 'C':
3721
                if ((given & 0xff) == 0)
3722
                  {
3723
                    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3724
                    if (given & 0x800)
3725
                      func (stream, "f");
3726
                    if (given & 0x400)
3727
                      func (stream, "s");
3728
                    if (given & 0x200)
3729
                      func (stream, "x");
3730
                    if (given & 0x100)
3731
                      func (stream, "c");
3732
                  }
3733
                else
3734
                  {
3735
                    func (stream, psr_name (given & 0xff));
3736
                  }
3737
                break;
3738

    
3739
              case 'D':
3740
                if ((given & 0xff) == 0)
3741
                  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3742
                else
3743
                  func (stream, psr_name (given & 0xff));
3744
                break;
3745

    
3746
              case '0': case '1': case '2': case '3': case '4':
3747
              case '5': case '6': case '7': case '8': case '9':
3748
                {
3749
                  int width;
3750
                  unsigned long val;
3751

    
3752
                  c = arm_decode_bitfield (c, given, &val, &width);
3753

    
3754
                  switch (*c)
3755
                    {
3756
                    case 'd': func (stream, "%lu", val); break;
3757
                    case 'W': func (stream, "%lu", val * 4); break;
3758
                    case 'r': func (stream, "%s", arm_regnames[val]); break;
3759

    
3760
                    case 'c':
3761
                      func (stream, "%s", arm_conditional[val]);
3762
                      break;
3763

    
3764
                    case '\'':
3765
                      c++;
3766
                      if (val == ((1ul << width) - 1))
3767
                        func (stream, "%c", *c);
3768
                      break;
3769

    
3770
                    case '`':
3771
                      c++;
3772
                      if (val == 0)
3773
                        func (stream, "%c", *c);
3774
                      break;
3775

    
3776
                    case '?':
3777
                      func (stream, "%c", c[(1 << width) - (int)val]);
3778
                      c += 1 << width;
3779
                      break;
3780

    
3781
                    default:
3782
                      abort ();
3783
                    }
3784
                }
3785
                break;
3786

    
3787
              default:
3788
                abort ();
3789
              }
3790
          }
3791
        return;
3792
      }
3793

    
3794
  /* No match.  */
3795
  abort ();
3796
}
3797

    
3798
/* Print data bytes on INFO->STREAM.  */
3799

    
3800
static void
3801
print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3802
                 long given)
3803
{
3804
  switch (info->bytes_per_chunk)
3805
    {
3806
    case 1:
3807
      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3808
      break;
3809
    case 2:
3810
      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3811
      break;
3812
    case 4:
3813
      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3814
      break;
3815
    default:
3816
      abort ();
3817
    }
3818
}
3819

    
3820
/* Search back through the insn stream to determine if this instruction is
3821
   conditionally executed.  */
3822
static void
3823
find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3824
                   bfd_boolean little)
3825
{
3826
  unsigned char b[2];
3827
  unsigned int insn;
3828
  int status;
3829
  /* COUNT is twice the number of instructions seen.  It will be odd if we
3830
     just crossed an instruction boundary.  */
3831
  int count;
3832
  int it_count;
3833
  unsigned int seen_it;
3834
  bfd_vma addr;
3835

    
3836
  ifthen_address = pc;
3837
  ifthen_state = 0;
3838

    
3839
  addr = pc;
3840
  count = 1;
3841
  it_count = 0;
3842
  seen_it = 0;
3843
  /* Scan backwards looking for IT instructions, keeping track of where
3844
     instruction boundaries are.  We don't know if something is actually an
3845
     IT instruction until we find a definite instruction boundary.  */
3846
  for (;;)
3847
    {
3848
      if (addr == 0 || info->symbol_at_address_func(addr, info))
3849
        {
3850
          /* A symbol must be on an instruction boundary, and will not
3851
             be within an IT block.  */
3852
          if (seen_it && (count & 1))
3853
            break;
3854

    
3855
          return;
3856
        }
3857
      addr -= 2;
3858
      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3859
      if (status)
3860
        return;
3861

    
3862
      if (little)
3863
        insn = (b[0]) | (b[1] << 8);
3864
      else
3865
        insn = (b[1]) | (b[0] << 8);
3866
      if (seen_it)
3867
        {
3868
          if ((insn & 0xf800) < 0xe800)
3869
            {
3870
              /* Addr + 2 is an instruction boundary.  See if this matches
3871
                 the expected boundary based on the position of the last
3872
                 IT candidate.  */
3873
              if (count & 1)
3874
                break;
3875
              seen_it = 0;
3876
            }
3877
        }
3878
      if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3879
        {
3880
          /* This could be an IT instruction.  */
3881
          seen_it = insn;
3882
          it_count = count >> 1;
3883
        }
3884
      if ((insn & 0xf800) >= 0xe800)
3885
        count++;
3886
      else
3887
        count = (count + 2) | 1;
3888
      /* IT blocks contain at most 4 instructions.  */
3889
      if (count >= 8 && !seen_it)
3890
        return;
3891
    }
3892
  /* We found an IT instruction.  */
3893
  ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3894
  if ((ifthen_state & 0xf) == 0)
3895
    ifthen_state = 0;
3896
}
3897

    
3898
/* NOTE: There are no checks in these routines that
3899
   the relevant number of data bytes exist.  */
3900

    
3901
int
3902
print_insn_arm (bfd_vma pc, struct disassemble_info *info)
3903
{
3904
  unsigned char b[4];
3905
  long                given;
3906
  int           status;
3907
  int           is_thumb = FALSE;
3908
  int           is_data = FALSE;
3909
  unsigned int        size = 4;
3910
  void                 (*printer) (bfd_vma, struct disassemble_info *, long);
3911
#if 0
3912
  bfd_boolean   found = FALSE;
3913

3914
  if (info->disassembler_options)
3915
    {
3916
      parse_disassembler_options (info->disassembler_options);
3917

3918
      /* To avoid repeated parsing of these options, we remove them here.  */
3919
      info->disassembler_options = NULL;
3920
    }
3921

3922
  /* First check the full symtab for a mapping symbol, even if there
3923
     are no usable non-mapping symbols for this address.  */
3924
  if (info->symtab != NULL
3925
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3926
    {
3927
      bfd_vma addr;
3928
      int n;
3929
      int last_sym = -1;
3930
      enum map_type type = MAP_ARM;
3931

3932
      if (pc <= last_mapping_addr)
3933
        last_mapping_sym = -1;
3934
      is_thumb = (last_type == MAP_THUMB);
3935
      found = FALSE;
3936
      /* Start scanning at the start of the function, or wherever
3937
         we finished last time.  */
3938
      n = info->symtab_pos + 1;
3939
      if (n < last_mapping_sym)
3940
        n = last_mapping_sym;
3941

3942
      /* Scan up to the location being disassembled.  */
3943
      for (; n < info->symtab_size; n++)
3944
        {
3945
          addr = bfd_asymbol_value (info->symtab[n]);
3946
          if (addr > pc)
3947
            break;
3948
          if ((info->section == NULL
3949
               || info->section == info->symtab[n]->section)
3950
              && get_sym_code_type (info, n, &type))
3951
            {
3952
              last_sym = n;
3953
              found = TRUE;
3954
            }
3955
        }
3956

3957
      if (!found)
3958
        {
3959
          n = info->symtab_pos;
3960
          if (n < last_mapping_sym - 1)
3961
            n = last_mapping_sym - 1;
3962

3963
          /* No mapping symbol found at this address.  Look backwards
3964
             for a preceeding one.  */
3965
          for (; n >= 0; n--)
3966
            {
3967
              if (get_sym_code_type (info, n, &type))
3968
                {
3969
                  last_sym = n;
3970
                  found = TRUE;
3971
                  break;
3972
                }
3973
            }
3974
        }
3975

3976
      last_mapping_sym = last_sym;
3977
      last_type = type;
3978
      is_thumb = (last_type == MAP_THUMB);
3979
      is_data = (last_type == MAP_DATA);
3980

3981
      /* Look a little bit ahead to see if we should print out
3982
         two or four bytes of data.  If there's a symbol,
3983
         mapping or otherwise, after two bytes then don't
3984
         print more.  */
3985
      if (is_data)
3986
        {
3987
          size = 4 - (pc & 3);
3988
          for (n = last_sym + 1; n < info->symtab_size; n++)
3989
            {
3990
              addr = bfd_asymbol_value (info->symtab[n]);
3991
              if (addr > pc)
3992
                {
3993
                  if (addr - pc < size)
3994
                    size = addr - pc;
3995
                  break;
3996
                }
3997
            }
3998
          /* If the next symbol is after three bytes, we need to
3999
             print only part of the data, so that we can use either
4000
             .byte or .short.  */
4001
          if (size == 3)
4002
            size = (pc & 1) ? 1 : 2;
4003
        }
4004
    }
4005

4006
  if (info->symbols != NULL)
4007
    {
4008
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4009
        {
4010
          coff_symbol_type * cs;
4011

4012
          cs = coffsymbol (*info->symbols);
4013
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
4014
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
4015
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
4016
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4017
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4018
        }
4019
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4020
               && !found)
4021
        {
4022
          /* If no mapping symbol has been found then fall back to the type
4023
             of the function symbol.  */
4024
          elf_symbol_type *  es;
4025
          unsigned int       type;
4026

4027
          es = *(elf_symbol_type **)(info->symbols);
4028
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4029

4030
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4031
        }
4032
    }
4033
#else
4034
  int little;
4035

    
4036
  little = (info->endian == BFD_ENDIAN_LITTLE);
4037
  is_thumb |= (pc & 1);
4038
  pc &= ~(bfd_vma)1;
4039
#endif
4040

    
4041
  if (force_thumb)
4042
    is_thumb = TRUE;
4043

    
4044
  info->bytes_per_line = 4;
4045

    
4046
  if (is_data)
4047
    {
4048
      int i;
4049

    
4050
      /* size was already set above.  */
4051
      info->bytes_per_chunk = size;
4052
      printer = print_insn_data;
4053

    
4054
      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4055
      given = 0;
4056
      if (little)
4057
        for (i = size - 1; i >= 0; i--)
4058
          given = b[i] | (given << 8);
4059
      else
4060
        for (i = 0; i < (int) size; i++)
4061
          given = b[i] | (given << 8);
4062
    }
4063
  else if (!is_thumb)
4064
    {
4065
      /* In ARM mode endianness is a straightforward issue: the instruction
4066
         is four bytes long and is either ordered 0123 or 3210.  */
4067
      printer = print_insn_arm_internal;
4068
      info->bytes_per_chunk = 4;
4069
      size = 4;
4070

    
4071
      status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4072
      if (little)
4073
        given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4074
      else
4075
        given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4076
    }
4077
  else
4078
    {
4079
      /* In Thumb mode we have the additional wrinkle of two
4080
         instruction lengths.  Fortunately, the bits that determine
4081
         the length of the current instruction are always to be found
4082
         in the first two bytes.  */
4083
      printer = print_insn_thumb16;
4084
      info->bytes_per_chunk = 2;
4085
      size = 2;
4086

    
4087
      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4088
      if (little)
4089
        given = (b[0]) | (b[1] << 8);
4090
      else
4091
        given = (b[1]) | (b[0] << 8);
4092

    
4093
      if (!status)
4094
        {
4095
          /* These bit patterns signal a four-byte Thumb
4096
             instruction.  */
4097
          if ((given & 0xF800) == 0xF800
4098
              || (given & 0xF800) == 0xF000
4099
              || (given & 0xF800) == 0xE800)
4100
            {
4101
              status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4102
              if (little)
4103
                given = (b[0]) | (b[1] << 8) | (given << 16);
4104
              else
4105
                given = (b[1]) | (b[0] << 8) | (given << 16);
4106

    
4107
              printer = print_insn_thumb32;
4108
              size = 4;
4109
            }
4110
        }
4111

    
4112
      if (ifthen_address != pc)
4113
        find_ifthen_state(pc, info, little);
4114

    
4115
      if (ifthen_state)
4116
        {
4117
          if ((ifthen_state & 0xf) == 0x8)
4118
            ifthen_next_state = 0;
4119
          else
4120
            ifthen_next_state = (ifthen_state & 0xe0)
4121
                                | ((ifthen_state & 0xf) << 1);
4122
        }
4123
    }
4124

    
4125
  if (status)
4126
    {
4127
      info->memory_error_func (status, pc, info);
4128
      return -1;
4129
    }
4130
  if (info->flags & INSN_HAS_RELOC)
4131
    /* If the instruction has a reloc associated with it, then
4132
       the offset field in the instruction will actually be the
4133
       addend for the reloc.  (We are using REL type relocs).
4134
       In such cases, we can ignore the pc when computing
4135
       addresses, since the addend is not currently pc-relative.  */
4136
    pc = 0;
4137

    
4138
  printer (pc, info, given);
4139

    
4140
  if (is_thumb)
4141
    {
4142
      ifthen_state = ifthen_next_state;
4143
      ifthen_address += size;
4144
    }
4145
  return size;
4146
}
4147

    
4148
void
4149
print_arm_disassembler_options (FILE *stream)
4150
{
4151
  int i;
4152

    
4153
  fprintf (stream, _("\n\
4154
The following ARM specific disassembler options are supported for use with\n\
4155
the -M switch:\n"));
4156

    
4157
  for (i = NUM_ARM_REGNAMES; i--;)
4158
    fprintf (stream, "  reg-names-%s %*c%s\n",
4159
             regnames[i].name,
4160
             (int)(14 - strlen (regnames[i].name)), ' ',
4161
             regnames[i].description);
4162

    
4163
  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
4164
  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
4165
}