]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/binutils/gas/config/tc-arm.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / binutils / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5         Modified by David Taylor (dtaylor@armltd.co.uk)
6         Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7         Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8         Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
9
10    This file is part of GAS, the GNU Assembler.
11
12    GAS is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2, or (at your option)
15    any later version.
16
17    GAS is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with GAS; see the file COPYING.  If not, write to the Free
24    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25    02111-1307, USA.  */
26
27 #include <string.h>
28 #define  NO_RELOC 0
29 #include "as.h"
30 #include "safe-ctype.h"
31
32 /* Need TARGET_CPU.  */
33 #include "config.h"
34 #include "subsegs.h"
35 #include "obstack.h"
36 #include "symbols.h"
37 #include "listing.h"
38
39 #ifdef OBJ_ELF
40 #include "elf/arm.h"
41 #include "dwarf2dbg.h"
42 #endif
43
44 /* XXX Set this to 1 after the next binutils release */
45 #define WARN_DEPRECATED 0
46
47 /* The following bitmasks control CPU extensions:  */
48 #define ARM_EXT_V1       0x00000001     /* All processors (core set).  */
49 #define ARM_EXT_V2       0x00000002     /* Multiply instructions.  */
50 #define ARM_EXT_V2S      0x00000004     /* SWP instructions.       */
51 #define ARM_EXT_V3       0x00000008     /* MSR MRS.                */
52 #define ARM_EXT_V3M      0x00000010     /* Allow long multiplies.  */
53 #define ARM_EXT_V4       0x00000020     /* Allow half word loads.  */
54 #define ARM_EXT_V4T      0x00000040     /* Thumb v1.               */
55 #define ARM_EXT_V5       0x00000080     /* Allow CLZ, etc.         */
56 #define ARM_EXT_V5T      0x00000100     /* Thumb v2.               */
57 #define ARM_EXT_V5ExP    0x00000200     /* DSP core set.           */
58 #define ARM_EXT_V5E      0x00000400     /* DSP Double transfers.   */
59 #define ARM_EXT_V5J      0x00000800     /* Jazelle extension.      */
60 #define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
61
62 /* Co-processor space extensions.  */
63 #define ARM_CEXT_XSCALE   0x00800000    /* Allow MIA etc.          */
64 #define ARM_CEXT_MAVERICK 0x00400000    /* Use Cirrus/DSP coprocessor.  */
65 #define ARM_CEXT_IWMMXT   0x00200000    /* Intel Wireless MMX technology coprocessor.   */
66
67 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
68    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
69    ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
70    three more to cover cores prior to ARM6.  Finally, there are cores which
71    implement further extensions in the co-processor space.  */
72 #define ARM_ARCH_V1                       ARM_EXT_V1
73 #define ARM_ARCH_V2     (ARM_ARCH_V1    | ARM_EXT_V2)
74 #define ARM_ARCH_V2S    (ARM_ARCH_V2    | ARM_EXT_V2S)
75 #define ARM_ARCH_V3     (ARM_ARCH_V2S   | ARM_EXT_V3)
76 #define ARM_ARCH_V3M    (ARM_ARCH_V3    | ARM_EXT_V3M)
77 #define ARM_ARCH_V4xM   (ARM_ARCH_V3    | ARM_EXT_V4)
78 #define ARM_ARCH_V4     (ARM_ARCH_V3M   | ARM_EXT_V4)
79 #define ARM_ARCH_V4TxM  (ARM_ARCH_V4xM  | ARM_EXT_V4T)
80 #define ARM_ARCH_V4T    (ARM_ARCH_V4    | ARM_EXT_V4T)
81 #define ARM_ARCH_V5xM   (ARM_ARCH_V4xM  | ARM_EXT_V5)
82 #define ARM_ARCH_V5     (ARM_ARCH_V4    | ARM_EXT_V5)
83 #define ARM_ARCH_V5TxM  (ARM_ARCH_V5xM  | ARM_EXT_V4T | ARM_EXT_V5T)
84 #define ARM_ARCH_V5T    (ARM_ARCH_V5    | ARM_EXT_V4T | ARM_EXT_V5T)
85 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T   | ARM_EXT_V5ExP)
86 #define ARM_ARCH_V5TE   (ARM_ARCH_V5TExP | ARM_EXT_V5E)
87 #define ARM_ARCH_V5TEJ  (ARM_ARCH_V5TE  | ARM_EXT_V5J)
88 #define ARM_ARCH_V6     (ARM_ARCH_V5TEJ | ARM_EXT_V6)
89
90 /* Processors with specific extensions in the co-processor space.  */
91 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE  | ARM_CEXT_XSCALE)
92 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
93
94 /* Some useful combinations:  */
95 #define ARM_ANY         0x0000ffff      /* Any basic core.  */
96 #define ARM_ALL         0x00ffffff      /* Any core + co-processor */
97 #define CPROC_ANY       0x00ff0000      /* Any co-processor */
98 #define FPU_ANY         0xff000000      /* Note this is ~ARM_ALL.  */
99
100
101 #define FPU_FPA_EXT_V1   0x80000000     /* Base FPA instruction set.  */
102 #define FPU_FPA_EXT_V2   0x40000000     /* LFM/SFM.                   */
103 #define FPU_VFP_EXT_NONE 0x20000000     /* Use VFP word-ordering.     */
104 #define FPU_VFP_EXT_V1xD 0x10000000     /* Base VFP instruction set.  */
105 #define FPU_VFP_EXT_V1   0x08000000     /* Double-precision insns.    */
106 #define FPU_VFP_EXT_V2   0x04000000     /* ARM10E VFPr1.              */
107 #define FPU_MAVERICK     0x02000000     /* Cirrus Maverick.           */
108 #define FPU_NONE         0
109
110 #define FPU_ARCH_FPE     FPU_FPA_EXT_V1
111 #define FPU_ARCH_FPA    (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
112
113 #define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
114 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
115 #define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
116 #define FPU_ARCH_VFP_V2   (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
117
118 #define FPU_ARCH_MAVERICK  FPU_MAVERICK
119
120 enum arm_float_abi
121 {
122   ARM_FLOAT_ABI_HARD,
123   ARM_FLOAT_ABI_SOFTFP,
124   ARM_FLOAT_ABI_SOFT
125 };
126
127 /* Types of processor to assemble for.  */
128 #define ARM_1           ARM_ARCH_V1
129 #define ARM_2           ARM_ARCH_V2
130 #define ARM_3           ARM_ARCH_V2S
131 #define ARM_250         ARM_ARCH_V2S
132 #define ARM_6           ARM_ARCH_V3
133 #define ARM_7           ARM_ARCH_V3
134 #define ARM_8           ARM_ARCH_V4
135 #define ARM_9           ARM_ARCH_V4T
136 #define ARM_STRONG      ARM_ARCH_V4
137 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
138
139 #ifndef CPU_DEFAULT
140 #if defined __XSCALE__
141 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
142 #else
143 #if defined __thumb__
144 #define CPU_DEFAULT     (ARM_ARCH_V5T)
145 #else
146 #define CPU_DEFAULT     ARM_ANY
147 #endif
148 #endif
149 #endif
150
151 #ifdef TE_LINUX
152 #define FPU_DEFAULT FPU_ARCH_FPA
153 #endif
154
155 #ifdef TE_NetBSD
156 #ifdef OBJ_ELF
157 #define FPU_DEFAULT FPU_ARCH_VFP        /* Soft-float, but VFP order.  */
158 #else
159 /* Legacy a.out format.  */
160 #define FPU_DEFAULT FPU_ARCH_FPA        /* Soft-float, but FPA order.  */
161 #endif
162 #endif
163
164 /* For backwards compatibility we default to the FPA.  */
165 #ifndef FPU_DEFAULT
166 #define FPU_DEFAULT FPU_ARCH_FPA
167 #endif
168
169 #define streq(a, b)           (strcmp (a, b) == 0)
170 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
171
172 static unsigned long cpu_variant;
173 static int target_oabi = 0;
174
175 /* Flags stored in private area of BFD structure.  */
176 static int uses_apcs_26      = FALSE;
177 static int atpcs             = FALSE;
178 static int support_interwork = FALSE;
179 static int uses_apcs_float   = FALSE;
180 static int pic_code          = FALSE;
181
182 /* Variables that we set while parsing command-line options.  Once all
183    options have been read we re-process these values to set the real
184    assembly flags.  */
185 static int legacy_cpu = -1;
186 static int legacy_fpu = -1;
187
188 static int mcpu_cpu_opt = -1;
189 static int mcpu_fpu_opt = -1;
190 static int march_cpu_opt = -1;
191 static int march_fpu_opt = -1;
192 static int mfpu_opt = -1;
193 static int mfloat_abi_opt = -1;
194
195 /* This array holds the chars that always start a comment.  If the
196    pre-processor is disabled, these aren't very useful.  */
197 const char comment_chars[] = "@";
198
199 /* This array holds the chars that only start a comment at the beginning of
200    a line.  If the line seems to have the form '# 123 filename'
201    .line and .file directives will appear in the pre-processed output.  */
202 /* Note that input_file.c hand checks for '#' at the beginning of the
203    first line of the input file.  This is because the compiler outputs
204    #NO_APP at the beginning of its output.  */
205 /* Also note that comments like this one will always work.  */
206 const char line_comment_chars[] = "#";
207
208 const char line_separator_chars[] = ";";
209
210 /* Chars that can be used to separate mant
211    from exp in floating point numbers.  */
212 const char EXP_CHARS[] = "eE";
213
214 /* Chars that mean this number is a floating point constant.  */
215 /* As in 0f12.456  */
216 /* or    0d1.2345e12  */
217
218 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
219
220 /* Prefix characters that indicate the start of an immediate
221    value.  */
222 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
223
224 #ifdef OBJ_ELF
225 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
226 symbolS * GOT_symbol;
227 #endif
228
229 /* Size of relocation record.  */
230 const int md_reloc_size = 8;
231
232 /* 0: assemble for ARM,
233    1: assemble for Thumb,
234    2: assemble for Thumb even though target CPU does not support thumb
235       instructions.  */
236 static int thumb_mode = 0;
237
238 typedef struct arm_fix
239 {
240   int thumb_mode;
241 } arm_fix_data;
242
243 struct arm_it
244 {
245   const char *  error;
246   unsigned long instruction;
247   int           size;
248   struct
249   {
250     bfd_reloc_code_real_type type;
251     expressionS              exp;
252     int                      pc_rel;
253   } reloc;
254 };
255
256 struct arm_it inst;
257
258 enum asm_shift_index
259 {
260   SHIFT_LSL = 0,
261   SHIFT_LSR,
262   SHIFT_ASR,
263   SHIFT_ROR,
264   SHIFT_RRX
265 };
266
267 struct asm_shift_properties
268 {
269   enum asm_shift_index index;
270   unsigned long        bit_field;
271   unsigned int         allows_0  : 1;
272   unsigned int         allows_32 : 1;
273 };
274
275 static const struct asm_shift_properties shift_properties [] =
276 {
277   { SHIFT_LSL, 0,    1, 0},
278   { SHIFT_LSR, 0x20, 0, 1},
279   { SHIFT_ASR, 0x40, 0, 1},
280   { SHIFT_ROR, 0x60, 0, 0},
281   { SHIFT_RRX, 0x60, 0, 0}
282 };
283
284 struct asm_shift_name
285 {
286   const char *                        name;
287   const struct asm_shift_properties * properties;
288 };
289
290 static const struct asm_shift_name shift_names [] =
291 {
292   { "asl", shift_properties + SHIFT_LSL },
293   { "lsl", shift_properties + SHIFT_LSL },
294   { "lsr", shift_properties + SHIFT_LSR },
295   { "asr", shift_properties + SHIFT_ASR },
296   { "ror", shift_properties + SHIFT_ROR },
297   { "rrx", shift_properties + SHIFT_RRX },
298   { "ASL", shift_properties + SHIFT_LSL },
299   { "LSL", shift_properties + SHIFT_LSL },
300   { "LSR", shift_properties + SHIFT_LSR },
301   { "ASR", shift_properties + SHIFT_ASR },
302   { "ROR", shift_properties + SHIFT_ROR },
303   { "RRX", shift_properties + SHIFT_RRX }
304 };
305
306 /* Any kind of shift is accepted.  */
307 #define NO_SHIFT_RESTRICT 1
308 /* The shift operand must be an immediate value, not a register.  */
309 #define SHIFT_IMMEDIATE   0
310 /* The shift must be LSL or ASR and the operand must be an immediate.  */
311 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
312 /* The shift must be ASR and the operand must be an immediate.  */
313 #define SHIFT_ASR_IMMEDIATE 3
314 /* The shift must be LSL and the operand must be an immediate.  */
315 #define SHIFT_LSL_IMMEDIATE 4
316
317 #define NUM_FLOAT_VALS 8
318
319 const char * fp_const[] =
320 {
321   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
322 };
323
324 /* Number of littlenums required to hold an extended precision number.  */
325 #define MAX_LITTLENUMS 6
326
327 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
328
329 #define FAIL    (-1)
330 #define SUCCESS (0)
331
332 /* Whether a Co-processor load/store operation accepts write-back forms.  */
333 #define CP_WB_OK 1
334 #define CP_NO_WB 0
335
336 #define SUFF_S 1
337 #define SUFF_D 2
338 #define SUFF_E 3
339 #define SUFF_P 4
340
341 #define CP_T_X   0x00008000
342 #define CP_T_Y   0x00400000
343 #define CP_T_Pre 0x01000000
344 #define CP_T_UD  0x00800000
345 #define CP_T_WB  0x00200000
346
347 #define CONDS_BIT        0x00100000
348 #define LOAD_BIT         0x00100000
349
350 #define DOUBLE_LOAD_FLAG 0x00000001
351
352 struct asm_cond
353 {
354   const char *  template;
355   unsigned long value;
356 };
357
358 #define COND_ALWAYS 0xe0000000
359 #define COND_MASK   0xf0000000
360
361 static const struct asm_cond conds[] =
362 {
363   {"eq", 0x00000000},
364   {"ne", 0x10000000},
365   {"cs", 0x20000000}, {"hs", 0x20000000},
366   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
367   {"mi", 0x40000000},
368   {"pl", 0x50000000},
369   {"vs", 0x60000000},
370   {"vc", 0x70000000},
371   {"hi", 0x80000000},
372   {"ls", 0x90000000},
373   {"ge", 0xa0000000},
374   {"lt", 0xb0000000},
375   {"gt", 0xc0000000},
376   {"le", 0xd0000000},
377   {"al", 0xe0000000},
378   {"nv", 0xf0000000}
379 };
380
381 struct asm_psr
382 {
383   const char *template;
384   bfd_boolean cpsr;
385   unsigned long field;
386 };
387
388 /* The bit that distinguishes CPSR and SPSR.  */
389 #define SPSR_BIT   (1 << 22)
390
391 /* How many bits to shift the PSR_xxx bits up by.  */
392 #define PSR_SHIFT  16
393
394 #define PSR_c   (1 << 0)
395 #define PSR_x   (1 << 1)
396 #define PSR_s   (1 << 2)
397 #define PSR_f   (1 << 3)
398
399 static const struct asm_psr psrs[] =
400 {
401   {"CPSR",      TRUE,  PSR_c | PSR_f},
402   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
403   {"SPSR",      FALSE, PSR_c | PSR_f},
404   {"SPSR_all",  FALSE, PSR_c | PSR_f},
405   {"CPSR_flg",  TRUE,  PSR_f},
406   {"CPSR_f",    TRUE,  PSR_f},
407   {"SPSR_flg",  FALSE, PSR_f},
408   {"SPSR_f",    FALSE, PSR_f},
409   {"CPSR_c",    TRUE,  PSR_c},
410   {"CPSR_ctl",  TRUE,  PSR_c},
411   {"SPSR_c",    FALSE, PSR_c},
412   {"SPSR_ctl",  FALSE, PSR_c},
413   {"CPSR_x",    TRUE,  PSR_x},
414   {"CPSR_s",    TRUE,  PSR_s},
415   {"SPSR_x",    FALSE, PSR_x},
416   {"SPSR_s",    FALSE, PSR_s},
417   /* Combinations of flags.  */
418   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
419   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
420   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
421   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
422   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
423   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
424   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
425   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
426   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
427   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
428   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
429   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
430   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
431   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
432   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
433   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
434   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
435   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
436   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
437   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
438   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
439   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
440   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
441   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
442   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
443   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
444   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
445   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
446   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
447   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
448   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
449   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
450   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
451   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
452   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
453   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
454   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
455   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
456   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
457   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
458   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
459   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
460   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
461   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
462   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
463   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
464   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
465   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
466   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
467   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
468   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
469   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
470   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
471   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
472   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
473   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
474   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
475   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
476   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
477   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
478   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
479   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
480   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
481   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
482   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
483   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
484   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
485   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
486   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
487   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
488   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
489   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
490   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
491   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
492   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
493   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
494   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
495   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
496   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
497   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
498   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
499   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
500   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
501   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
502   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
503   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
504   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
505   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
506   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
507   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
508   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
509   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
510   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
511   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
512   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
513   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
514   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
515   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
516   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
517   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
518   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
519   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
520   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
521   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
522   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
523   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
524   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
525   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
526   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
527   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
528   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
529   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
530   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
531   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
532   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
533   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
534   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
535   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
536   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
537   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
538 };
539
540 enum wreg_type
541   {
542     IWMMXT_REG_WR = 0,
543     IWMMXT_REG_WC = 1,
544     IWMMXT_REG_WR_OR_WC = 2,
545     IWMMXT_REG_WCG
546   };
547
548 enum iwmmxt_insn_type
549 {
550   check_rd,
551   check_wr,
552   check_wrwr,
553   check_wrwrwr,
554   check_wrwrwcg,
555   check_tbcst,
556   check_tmovmsk,
557   check_tmia,
558   check_tmcrr,
559   check_tmrrc,
560   check_tmcr,
561   check_tmrc,
562   check_tinsr,
563   check_textrc,
564   check_waligni,
565   check_textrm,
566   check_wshufh
567 };
568
569 enum vfp_dp_reg_pos
570 {
571   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
572 };
573
574 enum vfp_sp_reg_pos
575 {
576   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
577 };
578
579 enum vfp_ldstm_type
580 {
581   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
582 };
583
584 /* VFP system registers.  */
585 struct vfp_reg
586 {
587   const char *name;
588   unsigned long regno;
589 };
590
591 static const struct vfp_reg vfp_regs[] =
592 {
593   {"fpsid", 0x00000000},
594   {"FPSID", 0x00000000},
595   {"fpscr", 0x00010000},
596   {"FPSCR", 0x00010000},
597   {"fpexc", 0x00080000},
598   {"FPEXC", 0x00080000}
599 };
600
601 /* Structure for a hash table entry for a register.  */
602 struct reg_entry
603 {
604   const char * name;
605   int          number;
606   bfd_boolean  builtin;
607 };
608
609 /* Some well known registers that we refer to directly elsewhere.  */
610 #define REG_SP  13
611 #define REG_LR  14
612 #define REG_PC  15
613
614 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
615 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
616 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
617
618 /* These are the standard names.  Users can add aliases with .req.
619    and delete them with .unreq.  */
620
621 /* Integer Register Numbers.  */
622 static const struct reg_entry rn_table[] =
623 {
624   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
625   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
626   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
627   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
628   /* ATPCS Synonyms.  */
629   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
630   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
631   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
632   /* Well-known aliases.  */
633   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
634   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
635   {NULL, 0, TRUE}
636 };
637
638 #define WR_PREFIX 0x200
639 #define WC_PREFIX 0x400
640
641 static const struct reg_entry iwmmxt_table[] =
642 {
643   /* Intel Wireless MMX technology register names.  */
644   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
645   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
646   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
647   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
648   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
649   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
650   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
651   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
652   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
653   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
654   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
655   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
656
657   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
658   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
659   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
660   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
661   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
662   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
663   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
664   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
665   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
666   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
667   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
668   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
669   {NULL, 0, TRUE}
670 };
671
672 /* Co-processor Numbers.  */
673 static const struct reg_entry cp_table[] =
674 {
675   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
676   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
677   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
678   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
679   {NULL, 0, TRUE}
680 };
681
682 /* Co-processor Register Numbers.  */
683 static const struct reg_entry cn_table[] =
684 {
685   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
686   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
687   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
688   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
689   /* Not really valid, but kept for back-wards compatibility.  */
690   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
691   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
692   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
693   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
694   {NULL, 0, TRUE}
695 };
696
697 /* FPA Registers.  */
698 static const struct reg_entry fn_table[] =
699 {
700   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
701   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
702   {NULL, 0, TRUE}
703 };
704
705 /* VFP SP Registers.  */
706 static const struct reg_entry sn_table[] =
707 {
708   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
709   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
710   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
711   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
712   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
713   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
714   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
715   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
716   {NULL, 0, TRUE}
717 };
718
719 /* VFP DP Registers.  */
720 static const struct reg_entry dn_table[] =
721 {
722   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
723   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
724   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
725   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
726   {NULL, 0, TRUE}
727 };
728
729 /* Maverick DSP coprocessor registers.  */
730 static const struct reg_entry mav_mvf_table[] =
731 {
732   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
733   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
734   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
735   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
736   {NULL, 0, TRUE}
737 };
738
739 static const struct reg_entry mav_mvd_table[] =
740 {
741   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
742   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
743   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
744   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
745   {NULL, 0, TRUE}
746 };
747
748 static const struct reg_entry mav_mvfx_table[] =
749 {
750   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
751   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
752   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
753   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
754   {NULL, 0, TRUE}
755 };
756
757 static const struct reg_entry mav_mvdx_table[] =
758 {
759   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
760   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
761   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
762   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
763   {NULL, 0, TRUE}
764 };
765
766 static const struct reg_entry mav_mvax_table[] =
767 {
768   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
769   {NULL, 0, TRUE}
770 };
771
772 static const struct reg_entry mav_dspsc_table[] =
773 {
774   {"dspsc", 0, TRUE},
775   {NULL, 0, TRUE}
776 };
777
778 struct reg_map
779 {
780   const struct reg_entry *names;
781   int max_regno;
782   struct hash_control *htab;
783   const char *expected;
784 };
785
786 struct reg_map all_reg_maps[] =
787 {
788   {rn_table,        15, NULL, N_("ARM register expected")},
789   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
790   {cn_table,        15, NULL, N_("co-processor register expected")},
791   {fn_table,         7, NULL, N_("FPA register expected")},
792   {sn_table,        31, NULL, N_("VFP single precision register expected")},
793   {dn_table,        15, NULL, N_("VFP double precision register expected")},
794   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
795   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
796   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
797   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
798   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
799   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
800   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
801 };
802
803 /* Enumeration matching entries in table above.  */
804 enum arm_reg_type
805 {
806   REG_TYPE_RN = 0,
807 #define REG_TYPE_FIRST REG_TYPE_RN
808   REG_TYPE_CP = 1,
809   REG_TYPE_CN = 2,
810   REG_TYPE_FN = 3,
811   REG_TYPE_SN = 4,
812   REG_TYPE_DN = 5,
813   REG_TYPE_MVF = 6,
814   REG_TYPE_MVD = 7,
815   REG_TYPE_MVFX = 8,
816   REG_TYPE_MVDX = 9,
817   REG_TYPE_MVAX = 10,
818   REG_TYPE_DSPSC = 11,
819   REG_TYPE_IWMMXT = 12,
820
821   REG_TYPE_MAX = 13
822 };
823
824 /* Functions called by parser.  */
825 /* ARM instructions.  */
826 static void do_arit             PARAMS ((char *));
827 static void do_cmp              PARAMS ((char *));
828 static void do_mov              PARAMS ((char *));
829 static void do_ldst             PARAMS ((char *));
830 static void do_ldstt            PARAMS ((char *));
831 static void do_ldmstm           PARAMS ((char *));
832 static void do_branch           PARAMS ((char *));
833 static void do_swi              PARAMS ((char *));
834
835 /* Pseudo Op codes.  */
836 static void do_adr              PARAMS ((char *));
837 static void do_adrl             PARAMS ((char *));
838 static void do_empty            PARAMS ((char *));
839
840 /* ARM v2.  */
841 static void do_mul              PARAMS ((char *));
842 static void do_mla              PARAMS ((char *));
843
844 /* ARM v2S.  */
845 static void do_swap             PARAMS ((char *));
846
847 /* ARM v3.  */
848 static void do_msr              PARAMS ((char *));
849 static void do_mrs              PARAMS ((char *));
850
851 /* ARM v3M.  */
852 static void do_mull             PARAMS ((char *));
853
854 /* ARM v4.  */
855 static void do_ldstv4           PARAMS ((char *));
856
857 /* ARM v4T.  */
858 static void do_bx               PARAMS ((char *));
859
860 /* ARM v5T.  */
861 static void do_blx              PARAMS ((char *));
862 static void do_bkpt             PARAMS ((char *));
863 static void do_clz              PARAMS ((char *));
864 static void do_lstc2            PARAMS ((char *));
865 static void do_cdp2             PARAMS ((char *));
866 static void do_co_reg2          PARAMS ((char *));
867
868 /* ARM v5TExP.  */
869 static void do_smla             PARAMS ((char *));
870 static void do_smlal            PARAMS ((char *));
871 static void do_smul             PARAMS ((char *));
872 static void do_qadd             PARAMS ((char *));
873
874 /* ARM v5TE.  */
875 static void do_pld              PARAMS ((char *));
876 static void do_ldrd             PARAMS ((char *));
877 static void do_co_reg2c         PARAMS ((char *));
878
879 /* ARM v5TEJ.  */
880 static void do_bxj              PARAMS ((char *));
881
882 /* ARM V6. */
883 static void do_cps              PARAMS ((char *));
884 static void do_cpsi             PARAMS ((char *));
885 static void do_ldrex            PARAMS ((char *));
886 static void do_pkhbt            PARAMS ((char *));
887 static void do_pkhtb            PARAMS ((char *));
888 static void do_qadd16           PARAMS ((char *));
889 static void do_rev              PARAMS ((char *));
890 static void do_rfe              PARAMS ((char *));
891 static void do_sxtah            PARAMS ((char *));
892 static void do_sxth             PARAMS ((char *));
893 static void do_setend           PARAMS ((char *));
894 static void do_smlad            PARAMS ((char *));
895 static void do_smlald           PARAMS ((char *));
896 static void do_smmul            PARAMS ((char *));
897 static void do_ssat             PARAMS ((char *));
898 static void do_usat             PARAMS ((char *));
899 static void do_srs              PARAMS ((char *));
900 static void do_ssat16           PARAMS ((char *));
901 static void do_usat16           PARAMS ((char *));
902 static void do_strex            PARAMS ((char *));
903 static void do_umaal            PARAMS ((char *));
904
905 static void do_cps_mode         PARAMS ((char **));
906 static void do_cps_flags        PARAMS ((char **, int));
907 static int do_endian_specifier  PARAMS ((char *));
908 static void do_pkh_core         PARAMS ((char *, int));
909 static void do_sat              PARAMS ((char **, int));
910 static void do_sat16            PARAMS ((char **, int));
911
912 /* Coprocessor Instructions.  */
913 static void do_cdp              PARAMS ((char *));
914 static void do_lstc             PARAMS ((char *));
915 static void do_co_reg           PARAMS ((char *));
916
917 /* FPA instructions.  */
918 static void do_fpa_ctrl         PARAMS ((char *));
919 static void do_fpa_ldst         PARAMS ((char *));
920 static void do_fpa_ldmstm       PARAMS ((char *));
921 static void do_fpa_dyadic       PARAMS ((char *));
922 static void do_fpa_monadic      PARAMS ((char *));
923 static void do_fpa_cmp          PARAMS ((char *));
924 static void do_fpa_from_reg     PARAMS ((char *));
925 static void do_fpa_to_reg       PARAMS ((char *));
926
927 /* VFP instructions.  */
928 static void do_vfp_sp_monadic   PARAMS ((char *));
929 static void do_vfp_dp_monadic   PARAMS ((char *));
930 static void do_vfp_sp_dyadic    PARAMS ((char *));
931 static void do_vfp_dp_dyadic    PARAMS ((char *));
932 static void do_vfp_reg_from_sp  PARAMS ((char *));
933 static void do_vfp_sp_from_reg  PARAMS ((char *));
934 static void do_vfp_reg2_from_sp2 PARAMS ((char *));
935 static void do_vfp_sp2_from_reg2 PARAMS ((char *));
936 static void do_vfp_reg_from_dp  PARAMS ((char *));
937 static void do_vfp_reg2_from_dp PARAMS ((char *));
938 static void do_vfp_dp_from_reg  PARAMS ((char *));
939 static void do_vfp_dp_from_reg2 PARAMS ((char *));
940 static void do_vfp_reg_from_ctrl PARAMS ((char *));
941 static void do_vfp_ctrl_from_reg PARAMS ((char *));
942 static void do_vfp_sp_ldst      PARAMS ((char *));
943 static void do_vfp_dp_ldst      PARAMS ((char *));
944 static void do_vfp_sp_ldstmia   PARAMS ((char *));
945 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
946 static void do_vfp_dp_ldstmia   PARAMS ((char *));
947 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
948 static void do_vfp_xp_ldstmia   PARAMS ((char *));
949 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
950 static void do_vfp_sp_compare_z PARAMS ((char *));
951 static void do_vfp_dp_compare_z PARAMS ((char *));
952 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
953 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
954
955 /* XScale.  */
956 static void do_xsc_mia          PARAMS ((char *));
957 static void do_xsc_mar          PARAMS ((char *));
958 static void do_xsc_mra          PARAMS ((char *));
959
960 /* Maverick.  */
961 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
962                                          enum arm_reg_type));
963 static void do_mav_binops_1a    PARAMS ((char *));
964 static void do_mav_binops_1b    PARAMS ((char *));
965 static void do_mav_binops_1c    PARAMS ((char *));
966 static void do_mav_binops_1d    PARAMS ((char *));
967 static void do_mav_binops_1e    PARAMS ((char *));
968 static void do_mav_binops_1f    PARAMS ((char *));
969 static void do_mav_binops_1g    PARAMS ((char *));
970 static void do_mav_binops_1h    PARAMS ((char *));
971 static void do_mav_binops_1i    PARAMS ((char *));
972 static void do_mav_binops_1j    PARAMS ((char *));
973 static void do_mav_binops_1k    PARAMS ((char *));
974 static void do_mav_binops_1l    PARAMS ((char *));
975 static void do_mav_binops_1m    PARAMS ((char *));
976 static void do_mav_binops_1n    PARAMS ((char *));
977 static void do_mav_binops_1o    PARAMS ((char *));
978 static void do_mav_binops_2a    PARAMS ((char *));
979 static void do_mav_binops_2b    PARAMS ((char *));
980 static void do_mav_binops_2c    PARAMS ((char *));
981 static void do_mav_binops_3a    PARAMS ((char *));
982 static void do_mav_binops_3b    PARAMS ((char *));
983 static void do_mav_binops_3c    PARAMS ((char *));
984 static void do_mav_binops_3d    PARAMS ((char *));
985 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
986                                          enum arm_reg_type,
987                                          enum arm_reg_type));
988 static void do_mav_triple_4a    PARAMS ((char *));
989 static void do_mav_triple_4b    PARAMS ((char *));
990 static void do_mav_triple_5a    PARAMS ((char *));
991 static void do_mav_triple_5b    PARAMS ((char *));
992 static void do_mav_triple_5c    PARAMS ((char *));
993 static void do_mav_triple_5d    PARAMS ((char *));
994 static void do_mav_triple_5e    PARAMS ((char *));
995 static void do_mav_triple_5f    PARAMS ((char *));
996 static void do_mav_triple_5g    PARAMS ((char *));
997 static void do_mav_triple_5h    PARAMS ((char *));
998 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
999                                          enum arm_reg_type,
1000                                          enum arm_reg_type,
1001                                          enum arm_reg_type));
1002 static void do_mav_quad_6a      PARAMS ((char *));
1003 static void do_mav_quad_6b      PARAMS ((char *));
1004 static void do_mav_dspsc_1      PARAMS ((char *));
1005 static void do_mav_dspsc_2      PARAMS ((char *));
1006 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
1007                                          enum arm_reg_type));
1008 static void do_mav_shift_1      PARAMS ((char *));
1009 static void do_mav_shift_2      PARAMS ((char *));
1010 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
1011 static void do_mav_ldst_1       PARAMS ((char *));
1012 static void do_mav_ldst_2       PARAMS ((char *));
1013 static void do_mav_ldst_3       PARAMS ((char *));
1014 static void do_mav_ldst_4       PARAMS ((char *));
1015
1016 static int mav_reg_required_here        PARAMS ((char **, int,
1017                                                  enum arm_reg_type));
1018 static int mav_parse_offset     PARAMS ((char **, int *));
1019
1020 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
1021                                          int, int));
1022 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
1023 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1024 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1025 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
1026                                          fragS *));
1027 static int add_to_lit_pool      PARAMS ((void));
1028 static unsigned validate_immediate PARAMS ((unsigned));
1029 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1030                                                     unsigned int *));
1031 static int validate_offset_imm  PARAMS ((unsigned int, int));
1032 static void opcode_select       PARAMS ((int));
1033 static void end_of_line         PARAMS ((char *));
1034 static int reg_required_here    PARAMS ((char **, int));
1035 static int psr_required_here    PARAMS ((char **));
1036 static int co_proc_number       PARAMS ((char **));
1037 static int cp_opc_expr          PARAMS ((char **, int, int));
1038 static int cp_reg_required_here PARAMS ((char **, int));
1039 static int fp_reg_required_here PARAMS ((char **, int));
1040 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1041 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1042 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1043 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1044 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
1045 static long vfp_dp_reg_list     PARAMS ((char **));
1046 static int vfp_psr_required_here PARAMS ((char **str));
1047 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1048 static int cp_address_offset    PARAMS ((char **));
1049 static int cp_address_required_here     PARAMS ((char **, int));
1050 static int my_get_float_expression      PARAMS ((char **));
1051 static int skip_past_comma      PARAMS ((char **));
1052 static int walk_no_bignums      PARAMS ((symbolS *));
1053 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
1054 static int data_op2             PARAMS ((char **));
1055 static int fp_op2               PARAMS ((char **));
1056 static long reg_list            PARAMS ((char **));
1057 static void thumb_load_store    PARAMS ((char *, int, int));
1058 static int decode_shift         PARAMS ((char **, int));
1059 static int ldst_extend          PARAMS ((char **));
1060 static int ldst_extend_v4               PARAMS ((char **));
1061 static void thumb_add_sub       PARAMS ((char *, int));
1062 static void insert_reg          PARAMS ((const struct reg_entry *,
1063                                          struct hash_control *));
1064 static void thumb_shift         PARAMS ((char *, int));
1065 static void thumb_mov_compare   PARAMS ((char *, int));
1066 static void build_arm_ops_hsh   PARAMS ((void));
1067 static void set_constant_flonums        PARAMS ((void));
1068 static valueT md_chars_to_number        PARAMS ((char *, int));
1069 static void build_reg_hsh       PARAMS ((struct reg_map *));
1070 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
1071 static int create_register_alias        PARAMS ((char *, char *));
1072 static void output_inst         PARAMS ((const char *));
1073 static int accum0_required_here PARAMS ((char **));
1074 static int ld_mode_required_here PARAMS ((char **));
1075 static void do_branch25         PARAMS ((char *));
1076 static symbolS * find_real_start PARAMS ((symbolS *));
1077 #ifdef OBJ_ELF
1078 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1079 #endif
1080
1081 static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1082 static void do_iwmmxt_byte_addr PARAMS ((char *));
1083 static void do_iwmmxt_tandc     PARAMS ((char *));
1084 static void do_iwmmxt_tbcst     PARAMS ((char *));
1085 static void do_iwmmxt_textrc    PARAMS ((char *));
1086 static void do_iwmmxt_textrm    PARAMS ((char *));
1087 static void do_iwmmxt_tinsr     PARAMS ((char *));
1088 static void do_iwmmxt_tmcr      PARAMS ((char *));
1089 static void do_iwmmxt_tmcrr     PARAMS ((char *));
1090 static void do_iwmmxt_tmia      PARAMS ((char *));
1091 static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1092 static void do_iwmmxt_tmrc      PARAMS ((char *));
1093 static void do_iwmmxt_tmrrc     PARAMS ((char *));
1094 static void do_iwmmxt_torc      PARAMS ((char *));
1095 static void do_iwmmxt_waligni   PARAMS ((char *));
1096 static void do_iwmmxt_wmov      PARAMS ((char *));
1097 static void do_iwmmxt_word_addr PARAMS ((char *));
1098 static void do_iwmmxt_wrwr      PARAMS ((char *));
1099 static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1100 static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1101 static void do_iwmmxt_wshufh    PARAMS ((char *));
1102 static void do_iwmmxt_wzero     PARAMS ((char *));
1103 static int cp_byte_address_offset         PARAMS ((char **));
1104 static int cp_byte_address_required_here  PARAMS ((char **));
1105
1106 /* ARM instructions take 4bytes in the object file, Thumb instructions
1107    take 2:  */
1108 #define INSN_SIZE       4
1109
1110 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1111 #define MAV_MODE1       0x100c
1112
1113 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1114 #define MAV_MODE2       0x0c10
1115
1116 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1117 #define MAV_MODE3       0x100c
1118
1119 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1120 #define MAV_MODE4       0x0c0010
1121
1122 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1123 #define MAV_MODE5       0x00100c
1124
1125 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1126 #define MAV_MODE6       0x00100c05
1127
1128 struct asm_opcode
1129 {
1130   /* Basic string to match.  */
1131   const char * template;
1132
1133   /* Basic instruction code.  */
1134   unsigned long value;
1135
1136   /* Offset into the template where the condition code (if any) will be.
1137      If zero, then the instruction is never conditional.  */
1138   unsigned cond_offset;
1139
1140   /* Which architecture variant provides this instruction.  */
1141   unsigned long variant;
1142
1143   /* Function to call to parse args.  */
1144   void (* parms) PARAMS ((char *));
1145 };
1146
1147 static const struct asm_opcode insns[] =
1148 {
1149   /* Core ARM Instructions.  */
1150   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1151   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1152   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1153   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1154   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1155   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1156   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1157   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1158   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1159   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1160   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1161   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1162   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1163   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1164   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1165   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1166   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1167   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1168   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1169   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1170
1171   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1172   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1173   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1174   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1175   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1176   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1177   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1178   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1179   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1180   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1181   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1182   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1183
1184   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1185   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1186   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1187   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1188
1189   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1190   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1191   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1192   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1193   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1194   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1195   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1196   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1197
1198   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1199   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1200   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1201   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1202   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1203   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1204   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1205   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1206
1207   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1208   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1209   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1210   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1211   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1212   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1213   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1214   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1215
1216   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1217 #ifdef TE_WINCE
1218   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1219   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1220   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1221 #else
1222   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1223   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1224 #endif
1225
1226   /* Pseudo ops.  */
1227   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1228   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1229   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1230
1231   /* ARM 2 multiplies.  */
1232   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1233   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1234   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1235   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1236
1237   /* Generic coprocessor instructions.  */
1238   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1239   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1240   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1241   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1242   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1243   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1244   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1245
1246   /* ARM 3 - swp instructions.  */
1247   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1248   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1249
1250   /* ARM 6 Status register instructions.  */
1251   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1252   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1253   /* ScottB: our code uses     0xe128f000 for msr.
1254      NickC:  but this is wrong because the bits 16 through 19 are
1255              handled by the PSR_xxx defines above.  */
1256
1257   /* ARM 7M long multiplies.  */
1258   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1259   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1260   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1261   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1262   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1263   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1264   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1265   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1266
1267   /* ARM Architecture 4.  */
1268   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1269   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1270   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1271   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1272
1273   /* ARM Architecture 4T.  */
1274   /* Note: bx (and blx) are required on V5, even if the processor does
1275      not support Thumb.  */
1276   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1277
1278   /*  ARM Architecture 5T.  */
1279   /* Note: blx has 2 variants, so the .value is set dynamically.
1280      Only one of the variants has conditional execution.  */
1281   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1282   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1283   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1284   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1285   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1286   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1287   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1288   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1289   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1290   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1291
1292   /*  ARM Architecture 5TExP.  */
1293   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1294   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1295   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1296   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1297
1298   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1299   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1300
1301   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1302   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1303   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1304   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1305
1306   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1307   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1308   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1309   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1310
1311   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1312   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1313
1314   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1315   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1316   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1317   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1318
1319   /*  ARM Architecture 5TE.  */
1320   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1321   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1322   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1323
1324   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1325   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1326
1327   /*  ARM Architecture 5TEJ.  */
1328   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1329
1330   /*  ARM V6.  */
1331   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1332   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1333   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1334   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1335   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1336   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1337   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1338   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1339   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1340   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1341   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1342   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1343   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1344   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1345   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1346   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1347   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1348   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1349   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1350   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1351   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1352   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1353   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1354   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1355   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1356   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1357   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1358   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1359   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1360   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1361   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1362   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1363   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1364   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1365   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1366   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1367   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1368   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1369   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1370   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1371   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1372   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1373   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1374   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1375   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1376   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1377   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1378   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1379   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1380   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1381   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1382   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1383   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1384   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1385   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1386   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1387   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1388   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1389   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1390   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1391   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1392   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1393   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1394   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1395   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1396   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1397   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1398   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1399   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1400   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1401   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1402   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1403   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1404   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1405   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1406   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1407   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1408   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1409   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1410   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1411   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1412   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1413   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1414   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1415   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1416   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1417   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1418   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1419   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1420   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1421   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1422   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1423   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1424   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1425   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1426   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1427   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1428   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1429   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1430
1431   /* Core FPA instruction set (V1).  */
1432   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1433   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1434   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1435   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1436
1437   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1438   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1439   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1440   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1441
1442   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1443   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1444   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1445   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1446
1447   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1448   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1449   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1450   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1457   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459
1460   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1463   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1470   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472
1473   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1476   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1483   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485
1486   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1489   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1496   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498
1499   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1502   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1509   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511
1512   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1515   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1522   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524
1525   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1528   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1535   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537
1538   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1541   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1548   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550
1551   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1554   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1561   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563
1564   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1567   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1574   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576
1577   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1580   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1587   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1588   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1589
1590   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1591   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1592   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1593   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1594   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1595   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1596   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1597   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1598   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1599   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1600   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1601   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1602
1603   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1604   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1605   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1606   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1607   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1608   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1609   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1610   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1611   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1612   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1613   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1614   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1615
1616   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1617   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1618   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1619   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1620   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1621   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1622   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1623   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1624   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1625   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1626   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1627   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1628
1629   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1630   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1631   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1632   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1633   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1634   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1635   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1636   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1637   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1638   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1639   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1640   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1641
1642   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1643   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1644   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1645   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1646   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1647   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1648   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1649   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1650   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1651   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1652   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1653   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1654
1655   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1656   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1657   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1658   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1665   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667
1668   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1671   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1678   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680
1681   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1684   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1691   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693
1694   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1697   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1704   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706
1707   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1710   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1717   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719
1720   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1723   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1730   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732
1733   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1736   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1743   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745
1746   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1749   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1756   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1757   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1758
1759   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1760   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1761   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1762   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1763   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1764   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1765   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1766   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1767   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1768   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1769   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1770   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1771
1772   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1773   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1774   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1775   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1776   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1777   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1778   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1779   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1780   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1781   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1782   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1783   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1784
1785   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1786   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1787   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1788   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1789   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1790   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1791   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1792   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1793   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1794   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1795   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1796   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1797
1798   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1799   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1800   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1801   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1802   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1803   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1804   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1805   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1806   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1807   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1808   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1809   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1810
1811   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1812   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1813   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1814   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1815   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1816   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1817   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1818   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1819   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1820   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1821   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1822   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1823
1824   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1825   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1826   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1827   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1828   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1829      not be an optional suffix, but part of the instruction.  To be
1830      compatible, we accept either.  */
1831   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1832   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1833
1834   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1835   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1836   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1837   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1838   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1839   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1840   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1841   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1842   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1843   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1844   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1845   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1846
1847   /* The implementation of the FIX instruction is broken on some
1848      assemblers, in that it accepts a precision specifier as well as a
1849      rounding specifier, despite the fact that this is meaningless.
1850      To be more compatible, we accept it as well, though of course it
1851      does not set any bits.  */
1852   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1853   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1854   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1855   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1856   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1857   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1858   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1859   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1860   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1861   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1862   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1863   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1864   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1865
1866   /* Instructions that were new with the real FPA, call them V2.  */
1867   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1868   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1869   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1870   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1871   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1872   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1873
1874   /* VFP V1xD (single precision).  */
1875   /* Moves and type conversions.  */
1876   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1877   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1878   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1879   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1880   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1881   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1882   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1883   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1884   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1885   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1886   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1887   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1888
1889   /* Memory operations.  */
1890   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1891   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1892   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1893   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1894   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1895   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1896   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1897   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1898   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1899   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1900   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1901   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1902   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1903   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1904   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1905   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1906   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1907   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1908
1909   /* Monadic operations.  */
1910   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1911   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1912   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1913
1914   /* Dyadic operations.  */
1915   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1916   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1917   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1918   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1922   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1923   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1924
1925   /* Comparisons.  */
1926   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1927   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1928   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1929   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1930
1931   /* VFP V1 (Double precision).  */
1932   /* Moves and type conversions.  */
1933   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1934   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1935   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1936   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1937   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1938   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1939   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1940   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1941   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1942   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1943   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1944   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1945   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1946
1947   /* Memory operations.  */
1948   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1949   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1950   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1951   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1952   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1953   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1954   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1955   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1956   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1957   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1958
1959   /* Monadic operations.  */
1960   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1961   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1962   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1963
1964   /* Dyadic operations.  */
1965   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1966   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1967   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1968   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1969   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1970   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1971   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1972   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1973   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1974
1975   /* Comparisons.  */
1976   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1977   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1978   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1979   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1980
1981   /* VFP V2.  */
1982   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
1983   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
1984   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1985   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1986
1987   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1988   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1989   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1990   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1991   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1992   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1993   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1994   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1995   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1996
1997   /* Intel Wireless MMX technology instructions.  */
1998   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1999   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2000   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2001   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2002   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2003   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2004   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2005   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2006   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2007   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2008   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2009   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2010   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2011   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2012   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2013   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2014   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2015   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2016   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2017   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2018   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2019   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2020   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2021   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2022   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2023   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2024   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2025   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2026   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2027   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2028   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2029   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2030   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2031   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2032   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2033   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2034   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2035   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2036   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2045   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2062   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2063   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2065   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2066   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2067   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2068   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2069   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2084   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2087   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2097   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2099   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2100   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2101   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2102   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2103   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2104   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2105   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2106   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2107   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2108   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2109   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2110   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2111   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2112   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2113   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2114   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2115   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2116   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2117   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2118   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2119   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2120   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2121   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2122   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2123   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2124   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2125   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2126   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2127   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2128   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2129   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2130   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2131   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2132   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2133   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2134   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2138   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2139   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2140   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2141   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2142   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2143   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2144   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2145   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2146   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2147   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2148   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2149   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2150   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2151   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2152   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2153   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2154   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2155   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2156   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2157   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2158   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2159   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2160
2161   /* Cirrus Maverick instructions.  */
2162   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2163   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2164   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2165   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2166   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2167   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2168   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2169   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2170   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2171   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2172   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2173   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2174   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2175   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2176   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2177   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2178   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2179   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2180   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2181   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2182   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2183   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2184   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2185   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2186   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2187   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2188   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2189   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2190   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2191   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2192   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2193   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2194   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2195   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2196   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2197   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2198   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2199   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2200   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2201   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2202   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2203   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2204   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2205   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2206   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2207   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2208   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2209   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2210   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2211   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2212   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2213   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2214   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2215   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2216   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2217   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2218   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2219   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2220   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2221   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2222   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2223   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2224   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2225   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2226   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2227   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2228   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2229   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2230   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2231   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2232   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2233   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2234   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2235   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2236   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2237   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2238 };
2239
2240 /* Defines for various bits that we will want to toggle.  */
2241 #define INST_IMMEDIATE  0x02000000
2242 #define OFFSET_REG      0x02000000
2243 #define HWOFFSET_IMM    0x00400000
2244 #define SHIFT_BY_REG    0x00000010
2245 #define PRE_INDEX       0x01000000
2246 #define INDEX_UP        0x00800000
2247 #define WRITE_BACK      0x00200000
2248 #define LDM_TYPE_2_OR_3 0x00400000
2249
2250 #define LITERAL_MASK    0xf000f000
2251 #define OPCODE_MASK     0xfe1fffff
2252 #define V4_STR_BIT      0x00000020
2253
2254 #define DATA_OP_SHIFT   21
2255
2256 /* Codes to distinguish the arithmetic instructions.  */
2257 #define OPCODE_AND      0
2258 #define OPCODE_EOR      1
2259 #define OPCODE_SUB      2
2260 #define OPCODE_RSB      3
2261 #define OPCODE_ADD      4
2262 #define OPCODE_ADC      5
2263 #define OPCODE_SBC      6
2264 #define OPCODE_RSC      7
2265 #define OPCODE_TST      8
2266 #define OPCODE_TEQ      9
2267 #define OPCODE_CMP      10
2268 #define OPCODE_CMN      11
2269 #define OPCODE_ORR      12
2270 #define OPCODE_MOV      13
2271 #define OPCODE_BIC      14
2272 #define OPCODE_MVN      15
2273
2274 /* Thumb v1 (ARMv4T).  */
2275 static void do_t_nop            PARAMS ((char *));
2276 static void do_t_arit           PARAMS ((char *));
2277 static void do_t_add            PARAMS ((char *));
2278 static void do_t_asr            PARAMS ((char *));
2279 static void do_t_branch9        PARAMS ((char *));
2280 static void do_t_branch12       PARAMS ((char *));
2281 static void do_t_branch23       PARAMS ((char *));
2282 static void do_t_bx             PARAMS ((char *));
2283 static void do_t_compare        PARAMS ((char *));
2284 static void do_t_ldmstm         PARAMS ((char *));
2285 static void do_t_ldr            PARAMS ((char *));
2286 static void do_t_ldrb           PARAMS ((char *));
2287 static void do_t_ldrh           PARAMS ((char *));
2288 static void do_t_lds            PARAMS ((char *));
2289 static void do_t_lsl            PARAMS ((char *));
2290 static void do_t_lsr            PARAMS ((char *));
2291 static void do_t_mov            PARAMS ((char *));
2292 static void do_t_push_pop       PARAMS ((char *));
2293 static void do_t_str            PARAMS ((char *));
2294 static void do_t_strb           PARAMS ((char *));
2295 static void do_t_strh           PARAMS ((char *));
2296 static void do_t_sub            PARAMS ((char *));
2297 static void do_t_swi            PARAMS ((char *));
2298 static void do_t_adr            PARAMS ((char *));
2299
2300 /* Thumb v2 (ARMv5T).  */
2301 static void do_t_blx            PARAMS ((char *));
2302 static void do_t_bkpt           PARAMS ((char *));
2303
2304 /* ARM V6.  */
2305 static void do_t_cps            PARAMS ((char *));
2306 static void do_t_cpy            PARAMS ((char *));
2307 static void do_t_setend         PARAMS ((char *));;
2308
2309 #define T_OPCODE_MUL 0x4340
2310 #define T_OPCODE_TST 0x4200
2311 #define T_OPCODE_CMN 0x42c0
2312 #define T_OPCODE_NEG 0x4240
2313 #define T_OPCODE_MVN 0x43c0
2314
2315 #define T_OPCODE_ADD_R3 0x1800
2316 #define T_OPCODE_SUB_R3 0x1a00
2317 #define T_OPCODE_ADD_HI 0x4400
2318 #define T_OPCODE_ADD_ST 0xb000
2319 #define T_OPCODE_SUB_ST 0xb080
2320 #define T_OPCODE_ADD_SP 0xa800
2321 #define T_OPCODE_ADD_PC 0xa000
2322 #define T_OPCODE_ADD_I8 0x3000
2323 #define T_OPCODE_SUB_I8 0x3800
2324 #define T_OPCODE_ADD_I3 0x1c00
2325 #define T_OPCODE_SUB_I3 0x1e00
2326
2327 #define T_OPCODE_ASR_R  0x4100
2328 #define T_OPCODE_LSL_R  0x4080
2329 #define T_OPCODE_LSR_R  0x40c0
2330 #define T_OPCODE_ASR_I  0x1000
2331 #define T_OPCODE_LSL_I  0x0000
2332 #define T_OPCODE_LSR_I  0x0800
2333
2334 #define T_OPCODE_MOV_I8 0x2000
2335 #define T_OPCODE_CMP_I8 0x2800
2336 #define T_OPCODE_CMP_LR 0x4280
2337 #define T_OPCODE_MOV_HR 0x4600
2338 #define T_OPCODE_CMP_HR 0x4500
2339
2340 #define T_OPCODE_LDR_PC 0x4800
2341 #define T_OPCODE_LDR_SP 0x9800
2342 #define T_OPCODE_STR_SP 0x9000
2343 #define T_OPCODE_LDR_IW 0x6800
2344 #define T_OPCODE_STR_IW 0x6000
2345 #define T_OPCODE_LDR_IH 0x8800
2346 #define T_OPCODE_STR_IH 0x8000
2347 #define T_OPCODE_LDR_IB 0x7800
2348 #define T_OPCODE_STR_IB 0x7000
2349 #define T_OPCODE_LDR_RW 0x5800
2350 #define T_OPCODE_STR_RW 0x5000
2351 #define T_OPCODE_LDR_RH 0x5a00
2352 #define T_OPCODE_STR_RH 0x5200
2353 #define T_OPCODE_LDR_RB 0x5c00
2354 #define T_OPCODE_STR_RB 0x5400
2355
2356 #define T_OPCODE_PUSH   0xb400
2357 #define T_OPCODE_POP    0xbc00
2358
2359 #define T_OPCODE_BRANCH 0xe7fe
2360
2361 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
2362
2363 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
2364 #define THUMB_REG_LO    0x1
2365 #define THUMB_REG_HI    0x2
2366 #define THUMB_REG_ANY   0x3
2367
2368 #define THUMB_H1        0x0080
2369 #define THUMB_H2        0x0040
2370
2371 #define THUMB_ASR 0
2372 #define THUMB_LSL 1
2373 #define THUMB_LSR 2
2374
2375 #define THUMB_MOVE 0
2376 #define THUMB_COMPARE 1
2377 #define THUMB_CPY 2
2378
2379 #define THUMB_LOAD 0
2380 #define THUMB_STORE 1
2381
2382 #define THUMB_PP_PC_LR 0x0100
2383
2384 /* These three are used for immediate shifts, do not alter.  */
2385 #define THUMB_WORD 2
2386 #define THUMB_HALFWORD 1
2387 #define THUMB_BYTE 0
2388
2389 struct thumb_opcode
2390 {
2391   /* Basic string to match.  */
2392   const char * template;
2393
2394   /* Basic instruction code.  */
2395   unsigned long value;
2396
2397   int size;
2398
2399   /* Which CPU variants this exists for.  */
2400   unsigned long variant;
2401
2402   /* Function to call to parse args.  */
2403   void (* parms) PARAMS ((char *));
2404 };
2405
2406 static const struct thumb_opcode tinsns[] =
2407 {
2408   /* Thumb v1 (ARMv4T).  */
2409   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
2410   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
2411   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
2412   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
2413   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
2414   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
2415   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
2416   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2417   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2418   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2419   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2420   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2421   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
2422   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
2423   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
2424   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
2425   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
2426   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
2427   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
2428   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
2429   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
2430   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
2431   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
2432   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
2433   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
2434   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
2435   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2436   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2437   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2438   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2439   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2440   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2441   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2442   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2443   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2444   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2445   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2446   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2447   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2448   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2449   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2450   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2451   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2452   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2453   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2454   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2455   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2456   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2457   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2458   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2459   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2460   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2461   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2462   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2463   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2464   /* Pseudo ops:  */
2465   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2466   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2467   /* Thumb v2 (ARMv5T).  */
2468   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2469   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2470
2471   /* ARM V6.  */
2472   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
2473   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
2474   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
2475   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
2476   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
2477   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
2478   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
2479   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
2480   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
2481   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
2482   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
2483 };
2484
2485 #define BAD_ARGS        _("bad arguments to instruction")
2486 #define BAD_PC          _("r15 not allowed here")
2487 #define BAD_COND        _("instruction is not conditional")
2488 #define ERR_NO_ACCUM    _("acc0 expected")
2489
2490 static struct hash_control * arm_ops_hsh   = NULL;
2491 static struct hash_control * arm_tops_hsh  = NULL;
2492 static struct hash_control * arm_cond_hsh  = NULL;
2493 static struct hash_control * arm_shift_hsh = NULL;
2494 static struct hash_control * arm_psr_hsh   = NULL;
2495
2496 /* This table describes all the machine specific pseudo-ops the assembler
2497    has to support.  The fields are:
2498      pseudo-op name without dot
2499      function to call to execute this pseudo-op
2500      Integer arg to pass to the function.  */
2501
2502 static void s_req PARAMS ((int));
2503 static void s_unreq PARAMS ((int));
2504 static void s_align PARAMS ((int));
2505 static void s_bss PARAMS ((int));
2506 static void s_even PARAMS ((int));
2507 static void s_ltorg PARAMS ((int));
2508 static void s_arm PARAMS ((int));
2509 static void s_thumb PARAMS ((int));
2510 static void s_code PARAMS ((int));
2511 static void s_force_thumb PARAMS ((int));
2512 static void s_thumb_func PARAMS ((int));
2513 static void s_thumb_set PARAMS ((int));
2514 #ifdef OBJ_ELF
2515 static void s_arm_elf_cons PARAMS ((int));
2516 #endif
2517
2518 static int my_get_expression PARAMS ((expressionS *, char **));
2519
2520 const pseudo_typeS md_pseudo_table[] =
2521 {
2522   /* Never called because '.req' does not start a line.  */
2523   { "req",         s_req,         0 },
2524   { "unreq",       s_unreq,       0 },
2525   { "bss",         s_bss,         0 },
2526   { "align",       s_align,       0 },
2527   { "arm",         s_arm,         0 },
2528   { "thumb",       s_thumb,       0 },
2529   { "code",        s_code,        0 },
2530   { "force_thumb", s_force_thumb, 0 },
2531   { "thumb_func",  s_thumb_func,  0 },
2532   { "thumb_set",   s_thumb_set,   0 },
2533   { "even",        s_even,        0 },
2534   { "ltorg",       s_ltorg,       0 },
2535   { "pool",        s_ltorg,       0 },
2536 #ifdef OBJ_ELF
2537   { "word",        s_arm_elf_cons, 4 },
2538   { "long",        s_arm_elf_cons, 4 },
2539 #else
2540   { "word",        cons, 4},
2541 #endif
2542   { "extend",      float_cons, 'x' },
2543   { "ldouble",     float_cons, 'x' },
2544   { "packed",      float_cons, 'p' },
2545   { 0, 0, 0 }
2546 };
2547
2548 /* Other internal functions.  */
2549 static int arm_parse_extension PARAMS ((char *, int *));
2550 static int arm_parse_cpu PARAMS ((char *));
2551 static int arm_parse_arch PARAMS ((char *));
2552 static int arm_parse_fpu PARAMS ((char *));
2553 static int arm_parse_float_abi PARAMS ((char *));
2554 #if 0 /* Suppressed - for now.  */
2555 #if defined OBJ_COFF || defined OBJ_ELF
2556 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2557 #endif
2558 #endif
2559
2560 /* Stuff needed to resolve the label ambiguity
2561    As:
2562      ...
2563      label:   <insn>
2564    may differ from:
2565      ...
2566      label:
2567               <insn>
2568 */
2569
2570 symbolS *  last_label_seen;
2571 static int label_is_thumb_function_name = FALSE;
2572
2573 /* Literal Pool stuff.  */
2574
2575 #define MAX_LITERAL_POOL_SIZE 1024
2576
2577 /* Literal pool structure.  Held on a per-section
2578    and per-sub-section basis.  */
2579 typedef struct literal_pool
2580 {
2581   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2582   unsigned int   next_free_entry;
2583   unsigned int   id;
2584   symbolS *      symbol;
2585   segT           section;
2586   subsegT        sub_section;
2587   struct literal_pool * next;
2588 } literal_pool;
2589
2590 /* Pointer to a linked list of literal pools.  */
2591 literal_pool * list_of_pools = NULL;
2592
2593 static literal_pool * find_literal_pool PARAMS ((void));
2594 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2595
2596 static literal_pool *
2597 find_literal_pool ()
2598 {
2599   literal_pool * pool;
2600
2601   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2602     {
2603       if (pool->section == now_seg
2604           && pool->sub_section == now_subseg)
2605         break;
2606     }
2607
2608   return pool;
2609 }
2610
2611 static literal_pool *
2612 find_or_make_literal_pool ()
2613 {
2614   /* Next literal pool ID number.  */
2615   static unsigned int latest_pool_num = 1;
2616   literal_pool *      pool;
2617
2618   pool = find_literal_pool ();
2619
2620   if (pool == NULL)
2621     {
2622       /* Create a new pool.  */
2623       pool = (literal_pool *) xmalloc (sizeof (* pool));
2624       if (! pool)
2625         return NULL;
2626
2627       pool->next_free_entry = 0;
2628       pool->section         = now_seg;
2629       pool->sub_section     = now_subseg;
2630       pool->next            = list_of_pools;
2631       pool->symbol          = NULL;
2632
2633       /* Add it to the list.  */
2634       list_of_pools = pool;
2635     }
2636
2637   /* New pools, and emptied pools, will have a NULL symbol.  */
2638   if (pool->symbol == NULL)
2639     {
2640       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2641                                     (valueT) 0, &zero_address_frag);
2642       pool->id = latest_pool_num ++;
2643     }
2644
2645   /* Done.  */
2646   return pool;
2647 }
2648
2649 /* Add the literal in the global 'inst'
2650    structure to the relevent literal pool.  */
2651 static int
2652 add_to_lit_pool ()
2653 {
2654   literal_pool * pool;
2655   unsigned int entry;
2656
2657   pool = find_or_make_literal_pool ();
2658
2659   /* Check if this literal value is already in the pool.  */
2660   for (entry = 0; entry < pool->next_free_entry; entry ++)
2661     {
2662       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2663           && (inst.reloc.exp.X_op == O_constant)
2664           && (pool->literals[entry].X_add_number
2665               == inst.reloc.exp.X_add_number)
2666           && (pool->literals[entry].X_unsigned
2667               == inst.reloc.exp.X_unsigned))
2668         break;
2669
2670       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2671           && (inst.reloc.exp.X_op == O_symbol)
2672           && (pool->literals[entry].X_add_number
2673               == inst.reloc.exp.X_add_number)
2674           && (pool->literals[entry].X_add_symbol
2675               == inst.reloc.exp.X_add_symbol)
2676           && (pool->literals[entry].X_op_symbol
2677               == inst.reloc.exp.X_op_symbol))
2678         break;
2679     }
2680
2681   /* Do we need to create a new entry?  */
2682   if (entry == pool->next_free_entry)
2683     {
2684       if (entry >= MAX_LITERAL_POOL_SIZE)
2685         {
2686           inst.error = _("literal pool overflow");
2687           return FAIL;
2688         }
2689
2690       pool->literals[entry] = inst.reloc.exp;
2691       pool->next_free_entry += 1;
2692     }
2693
2694   inst.reloc.exp.X_op         = O_symbol;
2695   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2696   inst.reloc.exp.X_add_symbol = pool->symbol;
2697
2698   return SUCCESS;
2699 }
2700
2701 /* Can't use symbol_new here, so have to create a symbol and then at
2702    a later date assign it a value. Thats what these functions do.  */
2703
2704 static void
2705 symbol_locate (symbolP, name, segment, valu, frag)
2706      symbolS *    symbolP;
2707      const char * name;         /* It is copied, the caller can modify.  */
2708      segT         segment;      /* Segment identifier (SEG_<something>).  */
2709      valueT       valu;         /* Symbol value.  */
2710      fragS *      frag;         /* Associated fragment.  */
2711 {
2712   unsigned int name_length;
2713   char * preserved_copy_of_name;
2714
2715   name_length = strlen (name) + 1;   /* +1 for \0.  */
2716   obstack_grow (&notes, name, name_length);
2717   preserved_copy_of_name = obstack_finish (&notes);
2718 #ifdef STRIP_UNDERSCORE
2719   if (preserved_copy_of_name[0] == '_')
2720     preserved_copy_of_name++;
2721 #endif
2722
2723 #ifdef tc_canonicalize_symbol_name
2724   preserved_copy_of_name =
2725     tc_canonicalize_symbol_name (preserved_copy_of_name);
2726 #endif
2727
2728   S_SET_NAME (symbolP, preserved_copy_of_name);
2729
2730   S_SET_SEGMENT (symbolP, segment);
2731   S_SET_VALUE (symbolP, valu);
2732   symbol_clear_list_pointers (symbolP);
2733
2734   symbol_set_frag (symbolP, frag);
2735
2736   /* Link to end of symbol chain.  */
2737   {
2738     extern int symbol_table_frozen;
2739     if (symbol_table_frozen)
2740       abort ();
2741   }
2742
2743   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2744
2745   obj_symbol_new_hook (symbolP);
2746
2747 #ifdef tc_symbol_new_hook
2748   tc_symbol_new_hook (symbolP);
2749 #endif
2750
2751 #ifdef DEBUG_SYMS
2752   verify_symbol_chain (symbol_rootP, symbol_lastP);
2753 #endif /* DEBUG_SYMS  */
2754 }
2755
2756 /* Check that an immediate is valid.
2757    If so, convert it to the right format.  */
2758
2759 static unsigned int
2760 validate_immediate (val)
2761      unsigned int val;
2762 {
2763   unsigned int a;
2764   unsigned int i;
2765
2766 #define rotate_left(v, n) (v << n | v >> (32 - n))
2767
2768   for (i = 0; i < 32; i += 2)
2769     if ((a = rotate_left (val, i)) <= 0xff)
2770       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2771
2772   return FAIL;
2773 }
2774
2775 /* Check to see if an immediate can be computed as two separate immediate
2776    values, added together.  We already know that this value cannot be
2777    computed by just one ARM instruction.  */
2778
2779 static unsigned int
2780 validate_immediate_twopart (val, highpart)
2781      unsigned int   val;
2782      unsigned int * highpart;
2783 {
2784   unsigned int a;
2785   unsigned int i;
2786
2787   for (i = 0; i < 32; i += 2)
2788     if (((a = rotate_left (val, i)) & 0xff) != 0)
2789       {
2790         if (a & 0xff00)
2791           {
2792             if (a & ~ 0xffff)
2793               continue;
2794             * highpart = (a  >> 8) | ((i + 24) << 7);
2795           }
2796         else if (a & 0xff0000)
2797           {
2798             if (a & 0xff000000)
2799               continue;
2800             * highpart = (a >> 16) | ((i + 16) << 7);
2801           }
2802         else
2803           {
2804             assert (a & 0xff000000);
2805             * highpart = (a >> 24) | ((i + 8) << 7);
2806           }
2807
2808         return (a & 0xff) | (i << 7);
2809       }
2810
2811   return FAIL;
2812 }
2813
2814 static int
2815 validate_offset_imm (val, hwse)
2816      unsigned int val;
2817      int hwse;
2818 {
2819   if ((hwse && val > 255) || val > 4095)
2820     return FAIL;
2821   return val;
2822 }
2823
2824 \f
2825 #ifdef OBJ_ELF
2826 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2827    (This text is taken from version B-02 of the spec):
2828
2829       4.4.7 Mapping and tagging symbols
2830
2831       A section of an ARM ELF file can contain a mixture of ARM code,
2832       Thumb code, and data.  There are inline transitions between code
2833       and data at literal pool boundaries. There can also be inline
2834       transitions between ARM code and Thumb code, for example in
2835       ARM-Thumb inter-working veneers.  Linkers, machine-level
2836       debuggers, profiling tools, and disassembly tools need to map
2837       images accurately. For example, setting an ARM breakpoint on a
2838       Thumb location, or in a literal pool, can crash the program
2839       being debugged, ruining the debugging session.
2840
2841       ARM ELF entities are mapped (see section 4.4.7.1 below) and
2842       tagged (see section 4.4.7.2 below) using local symbols (with
2843       binding STB_LOCAL).  To assist consumers, mapping and tagging
2844       symbols should be collated first in the symbol table, before
2845       other symbols with binding STB_LOCAL.
2846
2847       To allow properly collated mapping and tagging symbols to be
2848       skipped by consumers that have no interest in them, the first
2849       such symbol should have the name $m and its st_value field equal
2850       to the total number of mapping and tagging symbols (including
2851       the $m) in the symbol table.
2852
2853       4.4.7.1 Mapping symbols
2854
2855       $a    Labels the first byte of a sequence of ARM instructions.
2856             Its type is STT_FUNC.
2857
2858       $d    Labels the first byte of a sequence of data items.
2859             Its type is STT_OBJECT.
2860
2861       $t    Labels the first byte of a sequence of Thumb instructions.
2862             Its type is STT_FUNC.
2863
2864       This list of mapping symbols may be extended in the future.
2865
2866       Section-relative mapping symbols
2867
2868       Mapping symbols defined in a section define a sequence of
2869       half-open address intervals that cover the address range of the
2870       section. Each interval starts at the address defined by a
2871       mapping symbol, and continues up to, but not including, the
2872       address defined by the next (in address order) mapping symbol or
2873       the end of the section. A corollary is that there must be a
2874       mapping symbol defined at the beginning of each section.
2875       Consumers can ignore the size of a section-relative mapping
2876       symbol. Producers can set it to 0.
2877
2878       Absolute mapping symbols
2879
2880       Because of the need to crystallize a Thumb address with the
2881       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2882       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2883       or $t.
2884
2885       The extent of a mapping symbol defined in SHN_ABS is [st_value,
2886       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2887       where [x, y) denotes the half-open address range from x,
2888       inclusive, to y, exclusive.
2889
2890       In the absence of a mapping symbol, a consumer can interpret a
2891       function symbol with an odd value as the Thumb code address
2892       obtained by clearing the least significant bit of the
2893       value. This interpretation is deprecated, and it may not work in
2894       the future.
2895
2896    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2897    the EABI (which is still under development), so they are not
2898    implemented here.  */
2899
2900 static enum mstate mapstate = MAP_UNDEFINED;
2901
2902 static void
2903 mapping_state (enum mstate state)
2904 {
2905   symbolS * symbolP;
2906   const char * symname;
2907   int type;
2908
2909   if (mapstate == state)
2910     /* The mapping symbol has already been emitted.
2911        There is nothing else to do.  */
2912     return;
2913
2914   mapstate = state;
2915
2916   switch (state)
2917     {
2918     case MAP_DATA:
2919       symname = "$d";
2920       type = BSF_OBJECT;
2921       break;
2922     case MAP_ARM:
2923       symname = "$a";
2924       type = BSF_FUNCTION;
2925       break;
2926     case MAP_THUMB:
2927       symname = "$t";
2928       type = BSF_FUNCTION;
2929       break;
2930     case MAP_UNDEFINED:
2931       return;     
2932     default:
2933       abort ();
2934     }
2935
2936   seg_info (now_seg)->tc_segment_info_data = state;
2937
2938   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2939   symbol_table_insert (symbolP);
2940   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2941   
2942   switch (state)
2943     {
2944     case MAP_ARM:
2945       THUMB_SET_FUNC (symbolP, 0);
2946       ARM_SET_THUMB (symbolP, 0);
2947       ARM_SET_INTERWORK (symbolP, support_interwork);
2948       break;
2949       
2950     case MAP_THUMB:
2951       THUMB_SET_FUNC (symbolP, 1);
2952       ARM_SET_THUMB (symbolP, 1);
2953       ARM_SET_INTERWORK (symbolP, support_interwork);
2954       break;
2955       
2956     case MAP_DATA:
2957     default:
2958       return;
2959     }
2960 }
2961
2962 /* When we change sections we need to issue a new mapping symbol.  */
2963
2964 void
2965 arm_elf_change_section (void)
2966 {
2967   flagword flags;
2968
2969   if (!SEG_NORMAL (now_seg))
2970     return;
2971
2972   flags = bfd_get_section_flags (stdoutput, now_seg);
2973
2974   /* We can ignore sections that only contain debug info.  */
2975   if ((flags & SEC_ALLOC) == 0)
2976     return;
2977
2978   mapstate = seg_info (now_seg)->tc_segment_info_data;
2979 }
2980 #else
2981 #define mapping_state(a)
2982 #endif /* OBJ_ELF */
2983 \f
2984
2985 static void
2986 s_req (a)
2987      int a ATTRIBUTE_UNUSED;
2988 {
2989   as_bad (_("invalid syntax for .req directive"));
2990 }
2991
2992 /* The .unreq directive deletes an alias which was previously defined
2993    by .req.  For example:
2994
2995        my_alias .req r11
2996        .unreq my_alias    */
2997
2998 static void
2999 s_unreq (int a ATTRIBUTE_UNUSED)
3000 {
3001   char *name;
3002   char saved_char;
3003
3004   skip_whitespace (input_line_pointer);
3005   name = input_line_pointer;
3006
3007   while (*input_line_pointer != 0
3008          && *input_line_pointer != ' '
3009          && *input_line_pointer != '\n')
3010     ++input_line_pointer;
3011
3012   saved_char = *input_line_pointer;
3013   *input_line_pointer = 0;
3014
3015   if (*name)
3016     {
3017       enum arm_reg_type req_type = arm_reg_parse_any (name);
3018
3019       if (req_type != REG_TYPE_MAX)
3020         {
3021           char *temp_name = name;
3022           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3023
3024           if (req_no != FAIL)
3025             {
3026               struct reg_entry *req_entry;
3027
3028               /* Check to see if this alias is a builtin one.  */
3029               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3030
3031               if (!req_entry)
3032                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
3033               else if (req_entry->builtin)
3034                 /* FIXME: We are deleting a built in register alias which
3035                    points to a const data structure, so we only need to
3036                    free up the memory used by the key in the hash table.
3037                    Unfortunately we have not recorded this value, so this
3038                    is a memory leak.  */
3039                   /* FIXME: Should we issue a warning message ?  */
3040                 ;
3041               else
3042                 {
3043                   /* Deleting a user defined alias.  We need to free the
3044                      key and the value, but fortunately the key is the same
3045                      as the value->name field.  */
3046                   free ((char *) req_entry->name);
3047                   free (req_entry);
3048                 }
3049             }
3050           else
3051             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3052         }
3053       else
3054         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3055     }
3056   else
3057     as_bad (_("invalid syntax for .unreq directive"));
3058
3059   *input_line_pointer = saved_char;
3060   demand_empty_rest_of_line ();
3061 }
3062
3063 static void
3064 s_bss (ignore)
3065      int ignore ATTRIBUTE_UNUSED;
3066 {
3067   /* We don't support putting frags in the BSS segment, we fake it by
3068      marking in_bss, then looking at s_skip for clues.  */
3069   subseg_set (bss_section, 0);
3070   demand_empty_rest_of_line ();
3071   mapping_state (MAP_DATA);
3072 }
3073
3074 static void
3075 s_even (ignore)
3076      int ignore ATTRIBUTE_UNUSED;
3077 {
3078   /* Never make frag if expect extra pass.  */
3079   if (!need_pass_2)
3080     frag_align (1, 0, 0);
3081
3082   record_alignment (now_seg, 1);
3083
3084   demand_empty_rest_of_line ();
3085 }
3086
3087 static void
3088 s_ltorg (ignored)
3089      int ignored ATTRIBUTE_UNUSED;
3090 {
3091   unsigned int entry;
3092   literal_pool * pool;
3093   char sym_name[20];
3094
3095   pool = find_literal_pool ();
3096   if (pool == NULL
3097       || pool->symbol == NULL
3098       || pool->next_free_entry == 0)
3099     return;
3100
3101   mapping_state (MAP_DATA);
3102
3103   /* Align pool as you have word accesses.
3104      Only make a frag if we have to.  */
3105   if (!need_pass_2)
3106     frag_align (2, 0, 0);
3107
3108   record_alignment (now_seg, 2);
3109
3110   sprintf (sym_name, "$$lit_\002%x", pool->id);
3111
3112   symbol_locate (pool->symbol, sym_name, now_seg,
3113                  (valueT) frag_now_fix (), frag_now);
3114   symbol_table_insert (pool->symbol);
3115
3116   ARM_SET_THUMB (pool->symbol, thumb_mode);
3117
3118 #if defined OBJ_COFF || defined OBJ_ELF
3119   ARM_SET_INTERWORK (pool->symbol, support_interwork);
3120 #endif
3121
3122   for (entry = 0; entry < pool->next_free_entry; entry ++)
3123     /* First output the expression in the instruction to the pool.  */
3124     emit_expr (&(pool->literals[entry]), 4); /* .word  */
3125
3126   /* Mark the pool as empty.  */
3127   pool->next_free_entry = 0;
3128   pool->symbol = NULL;
3129 }
3130
3131 /* Same as s_align_ptwo but align 0 => align 2.  */
3132
3133 static void
3134 s_align (unused)
3135      int unused ATTRIBUTE_UNUSED;
3136 {
3137   register int temp;
3138   register long temp_fill;
3139   long max_alignment = 15;
3140
3141   temp = get_absolute_expression ();
3142   if (temp > max_alignment)
3143     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3144   else if (temp < 0)
3145     {
3146       as_bad (_("alignment negative. 0 assumed."));
3147       temp = 0;
3148     }
3149
3150   if (*input_line_pointer == ',')
3151     {
3152       input_line_pointer++;
3153       temp_fill = get_absolute_expression ();
3154     }
3155   else
3156     temp_fill = 0;
3157
3158   if (!temp)
3159     temp = 2;
3160
3161   /* Only make a frag if we HAVE to.  */
3162   if (temp && !need_pass_2)
3163     frag_align (temp, (int) temp_fill, 0);
3164   demand_empty_rest_of_line ();
3165
3166   record_alignment (now_seg, temp);
3167 }
3168
3169 static void
3170 s_force_thumb (ignore)
3171      int ignore ATTRIBUTE_UNUSED;
3172 {
3173   /* If we are not already in thumb mode go into it, EVEN if
3174      the target processor does not support thumb instructions.
3175      This is used by gcc/config/arm/lib1funcs.asm for example
3176      to compile interworking support functions even if the
3177      target processor should not support interworking.  */
3178   if (! thumb_mode)
3179     {
3180       thumb_mode = 2;
3181
3182       record_alignment (now_seg, 1);
3183     }
3184
3185   demand_empty_rest_of_line ();
3186 }
3187
3188 static void
3189 s_thumb_func (ignore)
3190      int ignore ATTRIBUTE_UNUSED;
3191 {
3192   if (! thumb_mode)
3193     opcode_select (16);
3194
3195   /* The following label is the name/address of the start of a Thumb function.
3196      We need to know this for the interworking support.  */
3197   label_is_thumb_function_name = TRUE;
3198
3199   demand_empty_rest_of_line ();
3200 }
3201
3202 /* Perform a .set directive, but also mark the alias as
3203    being a thumb function.  */
3204
3205 static void
3206 s_thumb_set (equiv)
3207      int equiv;
3208 {
3209   /* XXX the following is a duplicate of the code for s_set() in read.c
3210      We cannot just call that code as we need to get at the symbol that
3211      is created.  */
3212   register char *    name;
3213   register char      delim;
3214   register char *    end_name;
3215   register symbolS * symbolP;
3216
3217   /* Especial apologies for the random logic:
3218      This just grew, and could be parsed much more simply!
3219      Dean - in haste.  */
3220   name      = input_line_pointer;
3221   delim     = get_symbol_end ();
3222   end_name  = input_line_pointer;
3223   *end_name = delim;
3224
3225   SKIP_WHITESPACE ();
3226
3227   if (*input_line_pointer != ',')
3228     {
3229       *end_name = 0;
3230       as_bad (_("expected comma after name \"%s\""), name);
3231       *end_name = delim;
3232       ignore_rest_of_line ();
3233       return;
3234     }
3235
3236   input_line_pointer++;
3237   *end_name = 0;
3238
3239   if (name[0] == '.' && name[1] == '\0')
3240     {
3241       /* XXX - this should not happen to .thumb_set.  */
3242       abort ();
3243     }
3244
3245   if ((symbolP = symbol_find (name)) == NULL
3246       && (symbolP = md_undefined_symbol (name)) == NULL)
3247     {
3248 #ifndef NO_LISTING
3249       /* When doing symbol listings, play games with dummy fragments living
3250          outside the normal fragment chain to record the file and line info
3251          for this symbol.  */
3252       if (listing & LISTING_SYMBOLS)
3253         {
3254           extern struct list_info_struct * listing_tail;
3255           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3256
3257           memset (dummy_frag, 0, sizeof (fragS));
3258           dummy_frag->fr_type = rs_fill;
3259           dummy_frag->line = listing_tail;
3260           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3261           dummy_frag->fr_symbol = symbolP;
3262         }
3263       else
3264 #endif
3265         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3266
3267 #ifdef OBJ_COFF
3268       /* "set" symbols are local unless otherwise specified.  */
3269       SF_SET_LOCAL (symbolP);
3270 #endif /* OBJ_COFF  */
3271     }                           /* Make a new symbol.  */
3272
3273   symbol_table_insert (symbolP);
3274
3275   * end_name = delim;
3276
3277   if (equiv
3278       && S_IS_DEFINED (symbolP)
3279       && S_GET_SEGMENT (symbolP) != reg_section)
3280     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3281
3282   pseudo_set (symbolP);
3283
3284   demand_empty_rest_of_line ();
3285
3286   /* XXX Now we come to the Thumb specific bit of code.  */
3287
3288   THUMB_SET_FUNC (symbolP, 1);
3289   ARM_SET_THUMB (symbolP, 1);
3290 #if defined OBJ_ELF || defined OBJ_COFF
3291   ARM_SET_INTERWORK (symbolP, support_interwork);
3292 #endif
3293 }
3294
3295 static void
3296 opcode_select (width)
3297      int width;
3298 {
3299   switch (width)
3300     {
3301     case 16:
3302       if (! thumb_mode)
3303         {
3304           if (! (cpu_variant & ARM_EXT_V4T))
3305             as_bad (_("selected processor does not support THUMB opcodes"));
3306
3307           thumb_mode = 1;
3308           /* No need to force the alignment, since we will have been
3309              coming from ARM mode, which is word-aligned.  */
3310           record_alignment (now_seg, 1);
3311         }
3312       mapping_state (MAP_THUMB);
3313       break;
3314
3315     case 32:
3316       if (thumb_mode)
3317         {
3318           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3319             as_bad (_("selected processor does not support ARM opcodes"));
3320
3321           thumb_mode = 0;
3322
3323           if (!need_pass_2)
3324             frag_align (2, 0, 0);
3325
3326           record_alignment (now_seg, 1);
3327         }
3328       mapping_state (MAP_ARM);
3329       break;
3330
3331     default:
3332       as_bad (_("invalid instruction size selected (%d)"), width);
3333     }
3334 }
3335
3336 static void
3337 s_arm (ignore)
3338      int ignore ATTRIBUTE_UNUSED;
3339 {
3340   opcode_select (32);
3341   demand_empty_rest_of_line ();
3342 }
3343
3344 static void
3345 s_thumb (ignore)
3346      int ignore ATTRIBUTE_UNUSED;
3347 {
3348   opcode_select (16);
3349   demand_empty_rest_of_line ();
3350 }
3351
3352 static void
3353 s_code (unused)
3354      int unused ATTRIBUTE_UNUSED;
3355 {
3356   register int temp;
3357
3358   temp = get_absolute_expression ();
3359   switch (temp)
3360     {
3361     case 16:
3362     case 32:
3363       opcode_select (temp);
3364       break;
3365
3366     default:
3367       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3368     }
3369 }
3370
3371 static void
3372 end_of_line (str)
3373      char *str;
3374 {
3375   skip_whitespace (str);
3376
3377   if (*str != '\0' && !inst.error)
3378     inst.error = _("garbage following instruction");
3379 }
3380
3381 static int
3382 skip_past_comma (str)
3383      char ** str;
3384 {
3385   char * p = * str, c;
3386   int comma = 0;
3387
3388   while ((c = *p) == ' ' || c == ',')
3389     {
3390       p++;
3391       if (c == ',' && comma++)
3392         return FAIL;
3393     }
3394
3395   if (c == '\0')
3396     return FAIL;
3397
3398   *str = p;
3399   return comma ? SUCCESS : FAIL;
3400 }
3401
3402 /* A standard register must be given at this point.
3403    SHIFT is the place to put it in inst.instruction.
3404    Restores input start point on error.
3405    Returns the reg#, or FAIL.  */
3406
3407 static int
3408 reg_required_here (str, shift)
3409      char ** str;
3410      int     shift;
3411 {
3412   static char buff [128]; /* XXX  */
3413   int         reg;
3414   char *      start = * str;
3415
3416   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3417     {
3418       if (shift >= 0)
3419         inst.instruction |= reg << shift;
3420       return reg;
3421     }
3422
3423   /* Restore the start point, we may have got a reg of the wrong class.  */
3424   *str = start;
3425
3426   /* In the few cases where we might be able to accept something else
3427      this error can be overridden.  */
3428   sprintf (buff, _("register expected, not '%.100s'"), start);
3429   inst.error = buff;
3430
3431   return FAIL;
3432 }
3433
3434 /* A Intel Wireless MMX technology register
3435    must be given at this point.
3436    Shift is the place to put it in inst.instruction.
3437    Restores input start point on err.
3438    Returns the reg#, or FAIL.  */
3439
3440 static int
3441 wreg_required_here (str, shift, reg_type)
3442      char ** str;
3443      int     shift;
3444      enum wreg_type reg_type;
3445 {
3446   static char buff [128];
3447   int    reg;
3448   char * start = *str;
3449
3450   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3451     {
3452       if (wr_register (reg)
3453           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3454         {
3455           if (shift >= 0)
3456             inst.instruction |= (reg ^ WR_PREFIX) << shift;
3457           return reg;
3458         }
3459       else if (wc_register (reg)
3460                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3461         {
3462           if (shift >= 0)
3463             inst.instruction |= (reg ^ WC_PREFIX) << shift;
3464           return reg;
3465         }
3466       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3467         {
3468           if (shift >= 0)
3469             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3470           return reg;
3471         }
3472     }
3473
3474   /* Restore the start point, we may have got a reg of the wrong class.  */
3475   *str = start;
3476
3477   /* In the few cases where we might be able to accept
3478      something else this error can be overridden.  */
3479   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3480   inst.error = buff;
3481
3482   return FAIL;
3483 }
3484
3485 static const struct asm_psr *
3486 arm_psr_parse (ccp)
3487      register char ** ccp;
3488 {
3489   char * start = * ccp;
3490   char   c;
3491   char * p;
3492   const struct asm_psr * psr;
3493
3494   p = start;
3495
3496   /* Skip to the end of the next word in the input stream.  */
3497   do
3498     {
3499       c = *p++;
3500     }
3501   while (ISALPHA (c) || c == '_');
3502
3503   /* Terminate the word.  */
3504   *--p = 0;
3505
3506   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3507      feature for ease of use and backwards compatibility.  */
3508   if (!strncmp (start, "cpsr", 4))
3509     strncpy (start, "CPSR", 4);
3510   else if (!strncmp (start, "spsr", 4))
3511     strncpy (start, "SPSR", 4);
3512
3513   /* Now locate the word in the psr hash table.  */
3514   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3515
3516   /* Restore the input stream.  */
3517   *p = c;
3518
3519   /* If we found a valid match, advance the
3520      stream pointer past the end of the word.  */
3521   *ccp = p;
3522
3523   return psr;
3524 }
3525
3526 /* Parse the input looking for a PSR flag.  */
3527
3528 static int
3529 psr_required_here (str)
3530      char ** str;
3531 {
3532   char * start = * str;
3533   const struct asm_psr * psr;
3534
3535   psr = arm_psr_parse (str);
3536
3537   if (psr)
3538     {
3539       /* If this is the SPSR that is being modified, set the R bit.  */
3540       if (! psr->cpsr)
3541         inst.instruction |= SPSR_BIT;
3542
3543       /* Set the psr flags in the MSR instruction.  */
3544       inst.instruction |= psr->field << PSR_SHIFT;
3545
3546       return SUCCESS;
3547     }
3548
3549   /* In the few cases where we might be able to accept
3550      something else this error can be overridden.  */
3551   inst.error = _("flag for {c}psr instruction expected");
3552
3553   /* Restore the start point.  */
3554   *str = start;
3555   return FAIL;
3556 }
3557
3558 static int
3559 co_proc_number (str)
3560      char **str;
3561 {
3562   int processor, pchar;
3563   char *start;
3564
3565   skip_whitespace (*str);
3566   start = *str;
3567
3568   /* The data sheet seems to imply that just a number on its own is valid
3569      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3570      accept either.  */
3571   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3572       == FAIL)
3573     {
3574       *str = start;
3575
3576       pchar = *(*str)++;
3577       if (pchar >= '0' && pchar <= '9')
3578         {
3579           processor = pchar - '0';
3580           if (**str >= '0' && **str <= '9')
3581             {
3582               processor = processor * 10 + *(*str)++ - '0';
3583               if (processor > 15)
3584                 {
3585                   inst.error = _("illegal co-processor number");
3586                   return FAIL;
3587                 }
3588             }
3589         }
3590       else
3591         {
3592           inst.error = _("bad or missing co-processor number");
3593           return FAIL;
3594         }
3595     }
3596
3597   inst.instruction |= processor << 8;
3598   return SUCCESS;
3599 }
3600
3601 static int
3602 cp_opc_expr (str, where, length)
3603      char ** str;
3604      int where;
3605      int length;
3606 {
3607   expressionS expr;
3608
3609   skip_whitespace (* str);
3610
3611   memset (&expr, '\0', sizeof (expr));
3612
3613   if (my_get_expression (&expr, str))
3614     return FAIL;
3615   if (expr.X_op != O_constant)
3616     {
3617       inst.error = _("bad or missing expression");
3618       return FAIL;
3619     }
3620
3621   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3622     {
3623       inst.error = _("immediate co-processor expression too large");
3624       return FAIL;
3625     }
3626
3627   inst.instruction |= expr.X_add_number << where;
3628   return SUCCESS;
3629 }
3630
3631 static int
3632 cp_reg_required_here (str, where)
3633      char ** str;
3634      int     where;
3635 {
3636   int    reg;
3637   char * start = *str;
3638
3639   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3640     {
3641       inst.instruction |= reg << where;
3642       return reg;
3643     }
3644
3645   /* In the few cases where we might be able to accept something else
3646      this error can be overridden.  */
3647   inst.error = _("co-processor register expected");
3648
3649   /* Restore the start point.  */
3650   *str = start;
3651   return FAIL;
3652 }
3653
3654 static int
3655 fp_reg_required_here (str, where)
3656      char ** str;
3657      int     where;
3658 {
3659   int    reg;
3660   char * start = * str;
3661
3662   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3663     {
3664       inst.instruction |= reg << where;
3665       return reg;
3666     }
3667
3668   /* In the few cases where we might be able to accept something else
3669      this error can be overridden.  */
3670   inst.error = _("floating point register expected");
3671
3672   /* Restore the start point.  */
3673   *str = start;
3674   return FAIL;
3675 }
3676
3677 static int
3678 cp_address_offset (str)
3679      char ** str;
3680 {
3681   int offset;
3682
3683   skip_whitespace (* str);
3684
3685   if (! is_immediate_prefix (**str))
3686     {
3687       inst.error = _("immediate expression expected");
3688       return FAIL;
3689     }
3690
3691   (*str)++;
3692
3693   if (my_get_expression (& inst.reloc.exp, str))
3694     return FAIL;
3695
3696   if (inst.reloc.exp.X_op == O_constant)
3697     {
3698       offset = inst.reloc.exp.X_add_number;
3699
3700       if (offset & 3)
3701         {
3702           inst.error = _("co-processor address must be word aligned");
3703           return FAIL;
3704         }
3705
3706       if (offset > 1023 || offset < -1023)
3707         {
3708           inst.error = _("offset too large");
3709           return FAIL;
3710         }
3711
3712       if (offset >= 0)
3713         inst.instruction |= INDEX_UP;
3714       else
3715         offset = -offset;
3716
3717       inst.instruction |= offset >> 2;
3718     }
3719   else
3720     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3721
3722   return SUCCESS;
3723 }
3724
3725 static int
3726 cp_address_required_here (str, wb_ok)
3727      char ** str;
3728      int wb_ok;
3729 {
3730   char * p = * str;
3731   int    pre_inc = 0;
3732   int    write_back = 0;
3733
3734   if (*p == '[')
3735     {
3736       int reg;
3737
3738       p++;
3739       skip_whitespace (p);
3740
3741       if ((reg = reg_required_here (& p, 16)) == FAIL)
3742         return FAIL;
3743
3744       skip_whitespace (p);
3745
3746       if (*p == ']')
3747         {
3748           p++;
3749
3750           skip_whitespace (p);
3751
3752           if (*p == '\0')
3753             {
3754               /* As an extension to the official ARM syntax we allow:
3755                  
3756                    [Rn]
3757                    
3758                  as a short hand for:
3759
3760                    [Rn,#0]  */
3761               inst.instruction |= PRE_INDEX | INDEX_UP;
3762               *str = p;
3763               return SUCCESS;
3764             }
3765           
3766           if (skip_past_comma (& p) == FAIL)
3767             {
3768               inst.error = _("comma expected after closing square bracket");
3769               return FAIL;
3770             }
3771
3772           skip_whitespace (p);
3773
3774           if (*p == '#')
3775             {
3776               if (wb_ok)
3777                 {
3778                   /* [Rn], #expr  */
3779                   write_back = WRITE_BACK;
3780
3781                   if (reg == REG_PC)
3782                     {
3783                       inst.error = _("pc may not be used in post-increment");
3784                       return FAIL;
3785                     }
3786
3787                   if (cp_address_offset (& p) == FAIL)
3788                     return FAIL;
3789                 }
3790               else
3791                 pre_inc = PRE_INDEX | INDEX_UP;
3792             }
3793           else if (*p == '{')
3794             {
3795               int option;
3796
3797               /* [Rn], {<expr>}  */
3798               p++;
3799
3800               skip_whitespace (p);
3801
3802               if (my_get_expression (& inst.reloc.exp, & p))
3803                 return FAIL;
3804
3805               if (inst.reloc.exp.X_op == O_constant)
3806                 {
3807                   option = inst.reloc.exp.X_add_number;
3808
3809                   if (option > 255 || option < 0)
3810                     {
3811                       inst.error = _("'option' field too large");
3812                       return FAIL;
3813                     }
3814
3815                   skip_whitespace (p);
3816
3817                   if (*p != '}')
3818                     {
3819                       inst.error = _("'}' expected at end of 'option' field");
3820                       return FAIL;
3821                     }
3822                   else
3823                     {
3824                       p++;
3825                       inst.instruction |= option;
3826                       inst.instruction |= INDEX_UP;
3827                     }
3828                 }
3829               else
3830                 {
3831                   inst.error = _("non-constant expressions for 'option' field not supported");
3832                   return FAIL;
3833                 }
3834             }
3835           else
3836             {
3837               inst.error = _("# or { expected after comma");
3838               return FAIL;            
3839             }
3840         }
3841       else
3842         {
3843           /* '['Rn, #expr']'[!]  */
3844
3845           if (skip_past_comma (& p) == FAIL)
3846             {
3847               inst.error = _("pre-indexed expression expected");
3848               return FAIL;
3849             }
3850
3851           pre_inc = PRE_INDEX;
3852
3853           if (cp_address_offset (& p) == FAIL)
3854             return FAIL;
3855
3856           skip_whitespace (p);
3857
3858           if (*p++ != ']')
3859             {
3860               inst.error = _("missing ]");
3861               return FAIL;
3862             }
3863
3864           skip_whitespace (p);
3865
3866           if (wb_ok && *p == '!')
3867             {
3868               if (reg == REG_PC)
3869                 {
3870                   inst.error = _("pc may not be used with write-back");
3871                   return FAIL;
3872                 }
3873
3874               p++;
3875               write_back = WRITE_BACK;
3876             }
3877         }
3878     }
3879   else
3880     {
3881       if (my_get_expression (&inst.reloc.exp, &p))
3882         return FAIL;
3883
3884       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3885       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3886       inst.reloc.pc_rel = 1;
3887       inst.instruction |= (REG_PC << 16);
3888       pre_inc = PRE_INDEX;
3889     }
3890
3891   inst.instruction |= write_back | pre_inc;
3892   *str = p;
3893   return SUCCESS;
3894 }
3895
3896 static int
3897 cp_byte_address_offset (str)
3898      char ** str;
3899 {
3900   int offset;
3901
3902   skip_whitespace (* str);
3903
3904   if (! is_immediate_prefix (**str))
3905     {
3906       inst.error = _("immediate expression expected");
3907       return FAIL;
3908     }
3909
3910   (*str)++;
3911   
3912   if (my_get_expression (& inst.reloc.exp, str))
3913     return FAIL;
3914   
3915   if (inst.reloc.exp.X_op == O_constant)
3916     {
3917       offset = inst.reloc.exp.X_add_number;
3918       
3919       if (offset > 255 || offset < -255)
3920         {
3921           inst.error = _("offset too large");
3922           return FAIL;
3923         }
3924
3925       if (offset >= 0)
3926         inst.instruction |= INDEX_UP;
3927       else
3928         offset = -offset;
3929
3930       inst.instruction |= offset;
3931     }
3932   else
3933     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3934
3935   return SUCCESS;
3936 }
3937
3938 static int
3939 cp_byte_address_required_here (str)
3940      char ** str;
3941 {
3942   char * p = * str;
3943   int    pre_inc = 0;
3944   int    write_back = 0;
3945
3946   if (*p == '[')
3947     {
3948       int reg;
3949
3950       p++;
3951       skip_whitespace (p);
3952
3953       if ((reg = reg_required_here (& p, 16)) == FAIL)
3954         return FAIL;
3955
3956       skip_whitespace (p);
3957
3958       if (*p == ']')
3959         {
3960           p++;
3961           
3962           if (skip_past_comma (& p) == SUCCESS)
3963             {
3964               /* [Rn], #expr */
3965               write_back = WRITE_BACK;
3966               
3967               if (reg == REG_PC)
3968                 {
3969                   inst.error = _("pc may not be used in post-increment");
3970                   return FAIL;
3971                 }
3972
3973               if (cp_byte_address_offset (& p) == FAIL)
3974                 return FAIL;
3975             }
3976           else
3977             pre_inc = PRE_INDEX | INDEX_UP;
3978         }
3979       else
3980         {
3981           /* '['Rn, #expr']'[!] */
3982
3983           if (skip_past_comma (& p) == FAIL)
3984             {
3985               inst.error = _("pre-indexed expression expected");
3986               return FAIL;
3987             }
3988
3989           pre_inc = PRE_INDEX;
3990           
3991           if (cp_byte_address_offset (& p) == FAIL)
3992             return FAIL;
3993
3994           skip_whitespace (p);
3995
3996           if (*p++ != ']')
3997             {
3998               inst.error = _("missing ]");
3999               return FAIL;
4000             }
4001
4002           skip_whitespace (p);
4003
4004           if (*p == '!')
4005             {
4006               if (reg == REG_PC)
4007                 {
4008                   inst.error = _("pc may not be used with write-back");
4009                   return FAIL;
4010                 }
4011
4012               p++;
4013               write_back = WRITE_BACK;
4014             }
4015         }
4016     }
4017   else
4018     {
4019       if (my_get_expression (&inst.reloc.exp, &p))
4020         return FAIL;
4021
4022       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4023       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
4024       inst.reloc.pc_rel = 1;
4025       inst.instruction |= (REG_PC << 16);
4026       pre_inc = PRE_INDEX;
4027     }
4028
4029   inst.instruction |= write_back | pre_inc;
4030   *str = p;
4031   return SUCCESS;
4032 }
4033
4034 static void
4035 do_empty (str)
4036      char * str;
4037 {
4038   /* Do nothing really.  */
4039   end_of_line (str);
4040 }
4041
4042 static void
4043 do_mrs (str)
4044      char *str;
4045 {
4046   int skip = 0;
4047
4048   /* Only one syntax.  */
4049   skip_whitespace (str);
4050
4051   if (reg_required_here (&str, 12) == FAIL)
4052     {
4053       inst.error = BAD_ARGS;
4054       return;
4055     }
4056
4057   if (skip_past_comma (&str) == FAIL)
4058     {
4059       inst.error = _("comma expected after register name");
4060       return;
4061     }
4062
4063   skip_whitespace (str);
4064
4065   if (   strcmp (str, "CPSR") == 0
4066       || strcmp (str, "SPSR") == 0
4067          /* Lower case versions for backwards compatibility.  */
4068       || strcmp (str, "cpsr") == 0
4069       || strcmp (str, "spsr") == 0)
4070     skip = 4;
4071
4072   /* This is for backwards compatibility with older toolchains.  */
4073   else if (   strcmp (str, "cpsr_all") == 0
4074            || strcmp (str, "spsr_all") == 0)
4075     skip = 8;
4076   else
4077     {
4078       inst.error = _("CPSR or SPSR expected");
4079       return;
4080     }
4081
4082   if (* str == 's' || * str == 'S')
4083     inst.instruction |= SPSR_BIT;
4084   str += skip;
4085
4086   end_of_line (str);
4087 }
4088
4089 /* Two possible forms:
4090       "{C|S}PSR_<field>, Rm",
4091       "{C|S}PSR_f, #expression".  */
4092
4093 static void
4094 do_msr (str)
4095      char * str;
4096 {
4097   skip_whitespace (str);
4098
4099   if (psr_required_here (& str) == FAIL)
4100     return;
4101
4102   if (skip_past_comma (& str) == FAIL)
4103     {
4104       inst.error = _("comma missing after psr flags");
4105       return;
4106     }
4107
4108   skip_whitespace (str);
4109
4110   if (reg_required_here (& str, 0) != FAIL)
4111     {
4112       inst.error = NULL;
4113       end_of_line (str);
4114       return;
4115     }
4116
4117   if (! is_immediate_prefix (* str))
4118     {
4119       inst.error =
4120         _("only a register or immediate value can follow a psr flag");
4121       return;
4122     }
4123
4124   str ++;
4125   inst.error = NULL;
4126
4127   if (my_get_expression (& inst.reloc.exp, & str))
4128     {
4129       inst.error =
4130         _("only a register or immediate value can follow a psr flag");
4131       return;
4132     }
4133
4134 #if 0  /* The first edition of the ARM architecture manual stated that
4135           writing anything other than the flags with an immediate operation
4136           had UNPREDICTABLE effects.  This constraint was removed in the
4137           second edition of the specification.  */
4138   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4139       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4140     {
4141       inst.error = _("immediate value cannot be used to set this field");
4142       return;
4143     }
4144 #endif
4145
4146   inst.instruction |= INST_IMMEDIATE;
4147
4148   if (inst.reloc.exp.X_add_symbol)
4149     {
4150       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4151       inst.reloc.pc_rel = 0;
4152     }
4153   else
4154     {
4155       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4156
4157       if (value == (unsigned) FAIL)
4158         {
4159           inst.error = _("invalid constant");
4160           return;
4161         }
4162
4163       inst.instruction |= value;
4164     }
4165
4166   inst.error = NULL;
4167   end_of_line (str);
4168 }
4169
4170 /* Long Multiply Parser
4171    UMULL RdLo, RdHi, Rm, Rs
4172    SMULL RdLo, RdHi, Rm, Rs
4173    UMLAL RdLo, RdHi, Rm, Rs
4174    SMLAL RdLo, RdHi, Rm, Rs.  */
4175
4176 static void
4177 do_mull (str)
4178      char * str;
4179 {
4180   int rdlo, rdhi, rm, rs;
4181
4182   /* Only one format "rdlo, rdhi, rm, rs".  */
4183   skip_whitespace (str);
4184
4185   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4186     {
4187       inst.error = BAD_ARGS;
4188       return;
4189     }
4190
4191   if (skip_past_comma (&str) == FAIL
4192       || (rdhi = reg_required_here (&str, 16)) == FAIL)
4193     {
4194       inst.error = BAD_ARGS;
4195       return;
4196     }
4197
4198   if (skip_past_comma (&str) == FAIL
4199       || (rm = reg_required_here (&str, 0)) == FAIL)
4200     {
4201       inst.error = BAD_ARGS;
4202       return;
4203     }
4204
4205   /* rdhi, rdlo and rm must all be different.  */
4206   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4207     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4208
4209   if (skip_past_comma (&str) == FAIL
4210       || (rs = reg_required_here (&str, 8)) == FAIL)
4211     {
4212       inst.error = BAD_ARGS;
4213       return;
4214     }
4215
4216   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4217     {
4218       inst.error = BAD_PC;
4219       return;
4220     }
4221
4222   end_of_line (str);
4223 }
4224
4225 static void
4226 do_mul (str)
4227      char * str;
4228 {
4229   int rd, rm;
4230
4231   /* Only one format "rd, rm, rs".  */
4232   skip_whitespace (str);
4233
4234   if ((rd = reg_required_here (&str, 16)) == FAIL)
4235     {
4236       inst.error = BAD_ARGS;
4237       return;
4238     }
4239
4240   if (rd == REG_PC)
4241     {
4242       inst.error = BAD_PC;
4243       return;
4244     }
4245
4246   if (skip_past_comma (&str) == FAIL
4247       || (rm = reg_required_here (&str, 0)) == FAIL)
4248     {
4249       inst.error = BAD_ARGS;
4250       return;
4251     }
4252
4253   if (rm == REG_PC)
4254     {
4255       inst.error = BAD_PC;
4256       return;
4257     }
4258
4259   if (rm == rd)
4260     as_tsktsk (_("rd and rm should be different in mul"));
4261
4262   if (skip_past_comma (&str) == FAIL
4263       || (rm = reg_required_here (&str, 8)) == FAIL)
4264     {
4265       inst.error = BAD_ARGS;
4266       return;
4267     }
4268
4269   if (rm == REG_PC)
4270     {
4271       inst.error = BAD_PC;
4272       return;
4273     }
4274
4275   end_of_line (str);
4276 }
4277
4278 static void
4279 do_mla (str)
4280      char * str;
4281 {
4282   int rd, rm;
4283
4284   /* Only one format "rd, rm, rs, rn".  */
4285   skip_whitespace (str);
4286
4287   if ((rd = reg_required_here (&str, 16)) == FAIL)
4288     {
4289       inst.error = BAD_ARGS;
4290       return;
4291     }
4292
4293   if (rd == REG_PC)
4294     {
4295       inst.error = BAD_PC;
4296       return;
4297     }
4298
4299   if (skip_past_comma (&str) == FAIL
4300       || (rm = reg_required_here (&str, 0)) == FAIL)
4301     {
4302       inst.error = BAD_ARGS;
4303       return;
4304     }
4305
4306   if (rm == REG_PC)
4307     {
4308       inst.error = BAD_PC;
4309       return;
4310     }
4311
4312   if (rm == rd)
4313     as_tsktsk (_("rd and rm should be different in mla"));
4314
4315   if (skip_past_comma (&str) == FAIL
4316       || (rd = reg_required_here (&str, 8)) == FAIL
4317       || skip_past_comma (&str) == FAIL
4318       || (rm = reg_required_here (&str, 12)) == FAIL)
4319     {
4320       inst.error = BAD_ARGS;
4321       return;
4322     }
4323
4324   if (rd == REG_PC || rm == REG_PC)
4325     {
4326       inst.error = BAD_PC;
4327       return;
4328     }
4329
4330   end_of_line (str);
4331 }
4332
4333 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4334    Advances *str to the next non-alphanumeric.
4335    Returns 0, or else FAIL (in which case sets inst.error).
4336
4337   (In a future XScale, there may be accumulators other than zero.
4338   At that time this routine and its callers can be upgraded to suit.)  */
4339
4340 static int
4341 accum0_required_here (str)
4342      char ** str;
4343 {
4344   static char buff [128];       /* Note the address is taken.  Hence, static.  */
4345   char * p = * str;
4346   char   c;
4347   int result = 0;               /* The accum number.  */
4348
4349   skip_whitespace (p);
4350
4351   *str = p;                     /* Advance caller's string pointer too.  */
4352   c = *p++;
4353   while (ISALNUM (c))
4354     c = *p++;
4355
4356   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
4357
4358   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4359     {
4360       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4361       inst.error = buff;
4362       result = FAIL;
4363     }
4364
4365   *p = c;                       /* Unzap.  */
4366   *str = p;                     /* Caller's string pointer to after match.  */
4367   return result;
4368 }
4369
4370 /* Expects **str -> after a comma. May be leading blanks.
4371    Advances *str, recognizing a load  mode, and setting inst.instruction.
4372    Returns rn, or else FAIL (in which case may set inst.error
4373    and not advance str)
4374
4375    Note: doesn't know Rd, so no err checks that require such knowledge.  */
4376
4377 static int
4378 ld_mode_required_here (string)
4379      char ** string;
4380 {
4381   char * str = * string;
4382   int    rn;
4383   int    pre_inc = 0;
4384
4385   skip_whitespace (str);
4386
4387   if (* str == '[')
4388     {
4389       str++;
4390
4391       skip_whitespace (str);
4392
4393       if ((rn = reg_required_here (& str, 16)) == FAIL)
4394         return FAIL;
4395
4396       skip_whitespace (str);
4397
4398       if (* str == ']')
4399         {
4400           str ++;
4401
4402           if (skip_past_comma (& str) == SUCCESS)
4403             {
4404               /* [Rn],... (post inc) */
4405               if (ldst_extend_v4 (&str) == FAIL)
4406                 return FAIL;
4407             }
4408           else        /* [Rn] */
4409             {
4410               skip_whitespace (str);
4411
4412               if (* str == '!')
4413                 {
4414                   str ++;
4415                   inst.instruction |= WRITE_BACK;
4416                 }
4417
4418               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4419               pre_inc = 1;
4420             }
4421         }
4422       else        /* [Rn,...] */
4423         {
4424           if (skip_past_comma (& str) == FAIL)
4425             {
4426               inst.error = _("pre-indexed expression expected");
4427               return FAIL;
4428             }
4429
4430           pre_inc = 1;
4431
4432           if (ldst_extend_v4 (&str) == FAIL)
4433             return FAIL;
4434
4435           skip_whitespace (str);
4436
4437           if (* str ++ != ']')
4438             {
4439               inst.error = _("missing ]");
4440               return FAIL;
4441             }
4442
4443           skip_whitespace (str);
4444
4445           if (* str == '!')
4446             {
4447               str ++;
4448               inst.instruction |= WRITE_BACK;
4449             }
4450         }
4451     }
4452   else if (* str == '=')        /* ldr's "r,=label" syntax */
4453     /* We should never reach here, because <text> = <expression> is
4454        caught gas/read.c read_a_source_file() as a .set operation.  */
4455     return FAIL;
4456   else                          /* PC +- 8 bit immediate offset.  */
4457     {
4458       if (my_get_expression (& inst.reloc.exp, & str))
4459         return FAIL;
4460
4461       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
4462       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4463       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
4464       inst.reloc.pc_rel            = 1;
4465       inst.instruction            |= (REG_PC << 16);
4466
4467       rn = REG_PC;
4468       pre_inc = 1;
4469     }
4470
4471   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4472   * string = str;
4473
4474   return rn;
4475 }
4476
4477 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4478    SMLAxy{cond} Rd,Rm,Rs,Rn
4479    SMLAWy{cond} Rd,Rm,Rs,Rn
4480    Error if any register is R15.  */
4481
4482 static void
4483 do_smla (str)
4484      char *        str;
4485 {
4486   int rd, rm, rs, rn;
4487
4488   skip_whitespace (str);
4489
4490   if ((rd = reg_required_here (& str, 16)) == FAIL
4491       || skip_past_comma (& str) == FAIL
4492       || (rm = reg_required_here (& str, 0)) == FAIL
4493       || skip_past_comma (& str) == FAIL
4494       || (rs = reg_required_here (& str, 8)) == FAIL
4495       || skip_past_comma (& str) == FAIL
4496       || (rn = reg_required_here (& str, 12)) == FAIL)
4497     inst.error = BAD_ARGS;
4498
4499   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4500     inst.error = BAD_PC;
4501
4502   else
4503     end_of_line (str);
4504 }
4505
4506 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4507    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4508    Error if any register is R15.
4509    Warning if Rdlo == Rdhi.  */
4510
4511 static void
4512 do_smlal (str)
4513      char *        str;
4514 {
4515   int rdlo, rdhi, rm, rs;
4516
4517   skip_whitespace (str);
4518
4519   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4520       || skip_past_comma (& str) == FAIL
4521       || (rdhi = reg_required_here (& str, 16)) == FAIL
4522       || skip_past_comma (& str) == FAIL
4523       || (rm = reg_required_here (& str, 0)) == FAIL
4524       || skip_past_comma (& str) == FAIL
4525       || (rs = reg_required_here (& str, 8)) == FAIL)
4526     {
4527       inst.error = BAD_ARGS;
4528       return;
4529     }
4530
4531   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4532     {
4533       inst.error = BAD_PC;
4534       return;
4535     }
4536
4537   if (rdlo == rdhi)
4538     as_tsktsk (_("rdhi and rdlo must be different"));
4539
4540   end_of_line (str);
4541 }
4542
4543 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4544    SMULxy{cond} Rd,Rm,Rs
4545    Error if any register is R15.  */
4546
4547 static void
4548 do_smul (str)
4549      char *        str;
4550 {
4551   int rd, rm, rs;
4552
4553   skip_whitespace (str);
4554
4555   if ((rd = reg_required_here (& str, 16)) == FAIL
4556       || skip_past_comma (& str) == FAIL
4557       || (rm = reg_required_here (& str, 0)) == FAIL
4558       || skip_past_comma (& str) == FAIL
4559       || (rs = reg_required_here (& str, 8)) == FAIL)
4560     inst.error = BAD_ARGS;
4561
4562   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4563     inst.error = BAD_PC;
4564
4565   else
4566     end_of_line (str);
4567 }
4568
4569 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4570    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4571    Error if any register is R15.  */
4572
4573 static void
4574 do_qadd (str)
4575      char *        str;
4576 {
4577   int rd, rm, rn;
4578
4579   skip_whitespace (str);
4580
4581   if ((rd = reg_required_here (& str, 12)) == FAIL
4582       || skip_past_comma (& str) == FAIL
4583       || (rm = reg_required_here (& str, 0)) == FAIL
4584       || skip_past_comma (& str) == FAIL
4585       || (rn = reg_required_here (& str, 16)) == FAIL)
4586     inst.error = BAD_ARGS;
4587
4588   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4589     inst.error = BAD_PC;
4590
4591   else
4592     end_of_line (str);
4593 }
4594
4595 /* ARM V5E (el Segundo)
4596    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4597    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4598
4599    These are equivalent to the XScale instructions MAR and MRA,
4600    respectively, when coproc == 0, opcode == 0, and CRm == 0.
4601
4602    Result unpredicatable if Rd or Rn is R15.  */
4603
4604 static void
4605 do_co_reg2c (str)
4606      char *        str;
4607 {
4608   int rd, rn;
4609
4610   skip_whitespace (str);
4611
4612   if (co_proc_number (& str) == FAIL)
4613     {
4614       if (!inst.error)
4615         inst.error = BAD_ARGS;
4616       return;
4617     }
4618
4619   if (skip_past_comma (& str) == FAIL
4620       || cp_opc_expr (& str, 4, 4) == FAIL)
4621     {
4622       if (!inst.error)
4623         inst.error = BAD_ARGS;
4624       return;
4625     }
4626
4627   if (skip_past_comma (& str) == FAIL
4628       || (rd = reg_required_here (& str, 12)) == FAIL)
4629     {
4630       if (!inst.error)
4631         inst.error = BAD_ARGS;
4632       return;
4633     }
4634
4635   if (skip_past_comma (& str) == FAIL
4636       || (rn = reg_required_here (& str, 16)) == FAIL)
4637     {
4638       if (!inst.error)
4639         inst.error = BAD_ARGS;
4640       return;
4641     }
4642
4643   /* Unpredictable result if rd or rn is R15.  */
4644   if (rd == REG_PC || rn == REG_PC)
4645     as_tsktsk
4646       (_("Warning: instruction unpredictable when using r15"));
4647
4648   if (skip_past_comma (& str) == FAIL
4649       || cp_reg_required_here (& str, 0) == FAIL)
4650     {
4651       if (!inst.error)
4652         inst.error = BAD_ARGS;
4653       return;
4654     }
4655
4656   end_of_line (str);
4657 }
4658
4659 /* ARM V5 count-leading-zeroes instruction (argument parse)
4660      CLZ{<cond>} <Rd>, <Rm>
4661      Condition defaults to COND_ALWAYS.
4662      Error if Rd or Rm are R15.  */
4663
4664 static void
4665 do_clz (str)
4666      char *        str;
4667 {
4668   int rd, rm;
4669
4670   skip_whitespace (str);
4671
4672   if (((rd = reg_required_here (& str, 12)) == FAIL)
4673       || (skip_past_comma (& str) == FAIL)
4674       || ((rm = reg_required_here (& str, 0)) == FAIL))
4675     inst.error = BAD_ARGS;
4676
4677   else if (rd == REG_PC || rm == REG_PC )
4678     inst.error = BAD_PC;
4679
4680   else
4681     end_of_line (str);
4682 }
4683
4684 /* ARM V5 (argument parse)
4685      LDC2{L} <coproc>, <CRd>, <addressing mode>
4686      STC2{L} <coproc>, <CRd>, <addressing mode>
4687      Instruction is not conditional, and has 0xf in the condition field.
4688      Otherwise, it's the same as LDC/STC.  */
4689
4690 static void
4691 do_lstc2 (str)
4692      char *        str;
4693 {
4694   skip_whitespace (str);
4695
4696   if (co_proc_number (& str) == FAIL)
4697     {
4698       if (!inst.error)
4699         inst.error = BAD_ARGS;
4700     }
4701   else if (skip_past_comma (& str) == FAIL
4702            || cp_reg_required_here (& str, 12) == FAIL)
4703     {
4704       if (!inst.error)
4705         inst.error = BAD_ARGS;
4706     }
4707   else if (skip_past_comma (& str) == FAIL
4708            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4709     {
4710       if (! inst.error)
4711         inst.error = BAD_ARGS;
4712     }
4713   else
4714     end_of_line (str);
4715 }
4716
4717 /* ARM V5 (argument parse)
4718      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4719      Instruction is not conditional, and has 0xf in the condition field.
4720      Otherwise, it's the same as CDP.  */
4721
4722 static void
4723 do_cdp2 (str)
4724      char *        str;
4725 {
4726   skip_whitespace (str);
4727
4728   if (co_proc_number (& str) == FAIL)
4729     {
4730       if (!inst.error)
4731         inst.error = BAD_ARGS;
4732       return;
4733     }
4734
4735   if (skip_past_comma (& str) == FAIL
4736       || cp_opc_expr (& str, 20,4) == FAIL)
4737     {
4738       if (!inst.error)
4739         inst.error = BAD_ARGS;
4740       return;
4741     }
4742
4743   if (skip_past_comma (& str) == FAIL
4744       || cp_reg_required_here (& str, 12) == FAIL)
4745     {
4746       if (!inst.error)
4747         inst.error = BAD_ARGS;
4748       return;
4749     }
4750
4751   if (skip_past_comma (& str) == FAIL
4752       || cp_reg_required_here (& str, 16) == FAIL)
4753     {
4754       if (!inst.error)
4755         inst.error = BAD_ARGS;
4756       return;
4757     }
4758
4759   if (skip_past_comma (& str) == FAIL
4760       || cp_reg_required_here (& str, 0) == FAIL)
4761     {
4762       if (!inst.error)
4763         inst.error = BAD_ARGS;
4764       return;
4765     }
4766
4767   if (skip_past_comma (& str) == SUCCESS)
4768     {
4769       if (cp_opc_expr (& str, 5, 3) == FAIL)
4770         {
4771           if (!inst.error)
4772             inst.error = BAD_ARGS;
4773           return;
4774         }
4775     }
4776
4777   end_of_line (str);
4778 }
4779
4780 /* ARM V5 (argument parse)
4781      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4782      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4783      Instruction is not conditional, and has 0xf in the condition field.
4784      Otherwise, it's the same as MCR/MRC.  */
4785
4786 static void
4787 do_co_reg2 (str)
4788      char *        str;
4789 {
4790   skip_whitespace (str);
4791
4792   if (co_proc_number (& str) == FAIL)
4793     {
4794       if (!inst.error)
4795         inst.error = BAD_ARGS;
4796       return;
4797     }
4798
4799   if (skip_past_comma (& str) == FAIL
4800       || cp_opc_expr (& str, 21, 3) == FAIL)
4801     {
4802       if (!inst.error)
4803         inst.error = BAD_ARGS;
4804       return;
4805     }
4806
4807   if (skip_past_comma (& str) == FAIL
4808       || reg_required_here (& str, 12) == FAIL)
4809     {
4810       if (!inst.error)
4811         inst.error = BAD_ARGS;
4812       return;
4813     }
4814
4815   if (skip_past_comma (& str) == FAIL
4816       || cp_reg_required_here (& str, 16) == FAIL)
4817     {
4818       if (!inst.error)
4819         inst.error = BAD_ARGS;
4820       return;
4821     }
4822
4823   if (skip_past_comma (& str) == FAIL
4824       || cp_reg_required_here (& str, 0) == FAIL)
4825     {
4826       if (!inst.error)
4827         inst.error = BAD_ARGS;
4828       return;
4829     }
4830
4831   if (skip_past_comma (& str) == SUCCESS)
4832     {
4833       if (cp_opc_expr (& str, 5, 3) == FAIL)
4834         {
4835           if (!inst.error)
4836             inst.error = BAD_ARGS;
4837           return;
4838         }
4839     }
4840
4841   end_of_line (str);
4842 }
4843
4844 /* ARM v5TEJ.  Jump to Jazelle code.  */
4845 static void
4846 do_bxj (str)
4847      char * str;
4848 {
4849   int reg;
4850
4851   skip_whitespace (str);
4852
4853   if ((reg = reg_required_here (&str, 0)) == FAIL)
4854     {
4855       inst.error = BAD_ARGS;
4856       return;
4857     }
4858
4859   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4860   if (reg == REG_PC)
4861     as_tsktsk (_("use of r15 in bxj is not really useful"));
4862
4863   end_of_line (str);
4864 }
4865
4866 /* ARM V6 umaal (argument parse). */
4867
4868 static void
4869 do_umaal (str)
4870      char *str;
4871 {
4872
4873   int rdlo, rdhi, rm, rs;
4874
4875   skip_whitespace (str);
4876   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4877       || skip_past_comma (& str) == FAIL
4878       || (rdhi = reg_required_here (& str, 16)) == FAIL
4879       || skip_past_comma (& str) == FAIL
4880       || (rm = reg_required_here (& str, 0)) == FAIL
4881       || skip_past_comma (& str) == FAIL
4882       || (rs = reg_required_here (& str, 8)) == FAIL)
4883     {
4884       inst.error = BAD_ARGS;
4885       return;      
4886     }
4887
4888   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4889     {
4890       inst.error = BAD_PC;
4891       return;
4892     }
4893
4894   end_of_line (str);
4895 }
4896
4897 /* ARM V6 strex (argument parse). */
4898
4899 static void 
4900 do_strex (str)
4901      char *str;
4902 {
4903   int rd, rm, rn;
4904
4905   /* Parse Rd, Rm,. */
4906   skip_whitespace (str);
4907   if ((rd = reg_required_here (& str, 12)) == FAIL
4908       || skip_past_comma (& str) == FAIL
4909       || (rm = reg_required_here (& str, 0)) == FAIL
4910       || skip_past_comma (& str) == FAIL)
4911     {
4912       inst.error = BAD_ARGS;
4913       return;
4914     }
4915   if (rd == REG_PC || rm == REG_PC)
4916     {
4917       inst.error = BAD_PC;
4918       return;
4919     }
4920   if (rd == rm)
4921     {
4922       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4923       return;
4924     }
4925
4926   /* Skip past '['. */
4927   if ((strlen (str) >= 1) 
4928       && strncmp (str, "[", 1) == 0)
4929     str+=1;
4930   skip_whitespace (str);  
4931
4932   /* Parse Rn. */
4933   if ((rn = reg_required_here (& str, 16)) == FAIL)
4934     {
4935       inst.error = BAD_ARGS;
4936       return;
4937     }
4938   else if (rn == REG_PC)
4939     {
4940       inst.error = BAD_PC;
4941       return;
4942     }
4943   if (rd == rn)
4944     {
4945       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4946       return;
4947     }
4948   skip_whitespace (str);  
4949
4950   /* Skip past ']'. */
4951   if ((strlen (str) >= 1) 
4952       && strncmp (str, "]", 1) == 0)
4953     str+=1;
4954   
4955   end_of_line (str);
4956 }
4957
4958 /* ARM V6 ssat (argument parse). */
4959
4960 static void
4961 do_ssat (str)
4962      char* str;
4963 {
4964   do_sat (&str, /*bias=*/-1);
4965   end_of_line (str);
4966 }
4967
4968 /* ARM V6 usat (argument parse). */
4969
4970 static void
4971 do_usat (str)
4972      char* str;
4973 {
4974   do_sat (&str, /*bias=*/0);
4975   end_of_line (str);
4976 }
4977
4978 static void
4979 do_sat (str, bias)
4980      char **str;
4981      int    bias;
4982 {
4983   int rd, rm;
4984   expressionS expr;
4985
4986   skip_whitespace (*str);
4987   
4988   /* Parse <Rd>, field. */
4989   if ((rd = reg_required_here (str, 12)) == FAIL
4990       || skip_past_comma (str) == FAIL)
4991     {
4992       inst.error = BAD_ARGS;
4993       return;
4994     }
4995   if (rd == REG_PC)
4996     {
4997       inst.error = BAD_PC;
4998       return;
4999     }
5000
5001   /* Parse #<immed>,  field. */
5002   if (is_immediate_prefix (**str))
5003     (*str)++;
5004   else
5005     {
5006       inst.error = _("immediate expression expected");
5007       return;
5008     }
5009   if (my_get_expression (&expr, str))
5010     {
5011       inst.error = _("bad expression");
5012       return;
5013     }
5014   if (expr.X_op != O_constant)
5015     {
5016       inst.error = _("constant expression expected");
5017       return;
5018     }
5019   if (expr.X_add_number + bias < 0
5020       || expr.X_add_number + bias > 31)
5021     {
5022       inst.error = _("immediate value out of range");
5023       return;
5024     }
5025   inst.instruction |= (expr.X_add_number + bias) << 16;
5026   if (skip_past_comma (str) == FAIL)
5027     {
5028       inst.error = BAD_ARGS;
5029       return;
5030     }
5031
5032   /* Parse <Rm> field. */
5033   if ((rm = reg_required_here (str, 0)) == FAIL)
5034     {
5035       inst.error = BAD_ARGS;
5036       return;
5037     }
5038   if (rm == REG_PC)
5039     {
5040       inst.error = BAD_PC;
5041       return;
5042     }
5043
5044   if (skip_past_comma (str) == SUCCESS)
5045     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5046 }
5047
5048 /* ARM V6 ssat16 (argument parse). */
5049
5050 static void
5051 do_ssat16 (str)
5052      char *str;
5053 {
5054   do_sat16 (&str, /*bias=*/-1);
5055   end_of_line (str);
5056 }
5057
5058 static void
5059 do_usat16 (str)
5060      char *str;
5061 {
5062   do_sat16 (&str, /*bias=*/0);
5063   end_of_line (str);
5064 }
5065
5066 static void
5067 do_sat16 (str, bias)
5068      char **str;
5069      int bias;
5070 {
5071   int rd, rm;
5072   expressionS expr;
5073
5074   skip_whitespace (*str);
5075
5076   /* Parse the <Rd> field. */
5077   if ((rd = reg_required_here (str, 12)) == FAIL
5078       || skip_past_comma (str) == FAIL)
5079     {
5080       inst.error = BAD_ARGS;
5081       return;
5082     }
5083   if (rd == REG_PC)
5084     {
5085       inst.error = BAD_PC;
5086       return;
5087     }
5088
5089   /* Parse #<immed>, field. */
5090   if (is_immediate_prefix (**str))
5091     (*str)++;
5092   else
5093     {
5094       inst.error = _("immediate expression expected");
5095       return;
5096     }
5097   if (my_get_expression (&expr, str))
5098     {
5099       inst.error = _("bad expression");
5100       return;
5101     }
5102   if (expr.X_op != O_constant)
5103     {
5104       inst.error = _("constant expression expected");
5105       return;
5106     }
5107   if (expr.X_add_number + bias < 0
5108       || expr.X_add_number + bias > 15)
5109     {
5110       inst.error = _("immediate value out of range");
5111       return;
5112     }
5113   inst.instruction |= (expr.X_add_number + bias) << 16;
5114   if (skip_past_comma (str) == FAIL)
5115     {
5116       inst.error = BAD_ARGS;
5117       return;
5118     }
5119
5120   /* Parse <Rm> field. */
5121   if ((rm = reg_required_here (str, 0)) == FAIL)
5122     {
5123       inst.error = BAD_ARGS;
5124       return;
5125     }
5126   if (rm == REG_PC)
5127     {
5128       inst.error = BAD_PC;
5129       return;
5130     }
5131 }
5132
5133 /* ARM V6 srs (argument parse). */
5134
5135 static void
5136 do_srs (str)
5137      char* str;
5138 {
5139   char *exclam;
5140   skip_whitespace (str);
5141   exclam = strchr (str, '!');
5142   if (exclam)
5143     *exclam = '\0';
5144   do_cps_mode (&str);
5145   if (exclam)
5146     *exclam = '!';
5147   if (*str == '!') 
5148     {
5149       inst.instruction |= WRITE_BACK;
5150       str++;
5151     }
5152   end_of_line (str);
5153 }
5154
5155 /* ARM V6 SMMUL (argument parse). */
5156
5157 static void
5158 do_smmul (str)
5159      char* str;
5160 {
5161   int rd, rm, rs;
5162   
5163   skip_whitespace (str);
5164   if ((rd = reg_required_here (&str, 16)) == FAIL
5165       || skip_past_comma (&str) == FAIL
5166       || (rm = reg_required_here (&str, 0)) == FAIL
5167       || skip_past_comma (&str) == FAIL
5168       || (rs = reg_required_here (&str, 8)) == FAIL)
5169     {
5170       inst.error = BAD_ARGS;
5171       return;
5172     }
5173
5174   if (rd == REG_PC 
5175       || rm == REG_PC
5176       || rs == REG_PC)
5177     {
5178       inst.error = BAD_PC;
5179       return;
5180     }
5181
5182   end_of_line (str);
5183   
5184 }
5185
5186 /* ARM V6 SMLALD (argument parse). */
5187
5188 static void
5189 do_smlald (str)
5190     char* str;
5191 {
5192   int rdlo, rdhi, rm, rs;
5193   skip_whitespace (str);
5194   if ((rdlo = reg_required_here (&str, 12)) == FAIL
5195       || skip_past_comma (&str) == FAIL
5196       || (rdhi = reg_required_here (&str, 16)) == FAIL
5197       || skip_past_comma (&str) == FAIL
5198       || (rm = reg_required_here (&str, 0)) == FAIL
5199       || skip_past_comma (&str) == FAIL
5200       || (rs = reg_required_here (&str, 8)) == FAIL)
5201     {
5202       inst.error = BAD_ARGS;
5203       return;
5204     }
5205
5206   if (rdlo == REG_PC 
5207       || rdhi == REG_PC 
5208       || rm == REG_PC
5209       || rs == REG_PC)
5210     {
5211       inst.error = BAD_PC;
5212       return;
5213     }
5214
5215   end_of_line (str);
5216 }
5217
5218 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
5219    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5220
5221 static void 
5222 do_smlad (str)
5223      char *str;
5224 {
5225   int rd, rm, rs, rn;
5226   
5227   skip_whitespace (str);
5228   if ((rd = reg_required_here (&str, 16)) == FAIL
5229       || skip_past_comma (&str) == FAIL
5230       || (rm = reg_required_here (&str, 0)) == FAIL
5231       || skip_past_comma (&str) == FAIL
5232       || (rs = reg_required_here (&str, 8)) == FAIL
5233       || skip_past_comma (&str) == FAIL
5234       || (rn = reg_required_here (&str, 12)) == FAIL)
5235     {
5236       inst.error = BAD_ARGS;
5237       return;
5238     }
5239   
5240   if (rd == REG_PC 
5241       || rn == REG_PC 
5242       || rs == REG_PC
5243       || rm == REG_PC)
5244     {
5245       inst.error = BAD_PC;
5246       return;
5247     }
5248
5249   end_of_line (str);
5250
5251
5252 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5253    preserving the other bits.
5254
5255    setend <endian_specifier>, where <endian_specifier> is either 
5256    BE or LE. */
5257
5258 static void 
5259 do_setend (str)
5260      char *str;
5261 {
5262   if (do_endian_specifier (str))
5263     inst.instruction |= 0x200;
5264 }
5265
5266 /* Returns true if the endian-specifier indicates big-endianness.  */
5267
5268 static int
5269 do_endian_specifier (str)
5270      char *str;
5271 {
5272   int big_endian = 0;
5273
5274   skip_whitespace (str);
5275   if (strlen (str) < 2)
5276     inst.error = _("missing endian specifier");
5277   else if (strncasecmp (str, "BE", 2) == 0)
5278     {
5279       str += 2;
5280       big_endian = 1;
5281     }
5282   else if (strncasecmp (str, "LE", 2) == 0)
5283     str += 2;
5284   else
5285     inst.error = _("valid endian specifiers are be or le");
5286
5287   end_of_line (str);
5288
5289   return big_endian;
5290 }
5291
5292 /* ARM V6 SXTH.
5293
5294    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5295    Condition defaults to COND_ALWAYS.
5296    Error if any register uses R15. */
5297
5298 static void 
5299 do_sxth (str)
5300      char *str;
5301 {
5302   int rd, rm;
5303   expressionS expr;
5304   int rotation_clear_mask = 0xfffff3ff;
5305   int rotation_eight_mask = 0x00000400;
5306   int rotation_sixteen_mask = 0x00000800;
5307   int rotation_twenty_four_mask = 0x00000c00;
5308   
5309   skip_whitespace (str);
5310   if ((rd = reg_required_here (&str, 12)) == FAIL
5311       || skip_past_comma (&str) == FAIL
5312       || (rm = reg_required_here (&str, 0)) == FAIL)
5313     {
5314       inst.error = BAD_ARGS;
5315       return;
5316     }
5317
5318   else if (rd == REG_PC || rm == REG_PC)
5319     {
5320       inst.error = BAD_PC;
5321       return;
5322     }
5323   
5324   /* Zero out the rotation field. */
5325   inst.instruction &= rotation_clear_mask;
5326   
5327   /* Check for lack of optional rotation field. */
5328   if (skip_past_comma (&str) == FAIL)
5329     {
5330       end_of_line (str);
5331       return;
5332     }
5333   
5334   /* Move past 'ROR'. */
5335   skip_whitespace (str);
5336   if (strncasecmp (str, "ROR", 3) == 0)
5337     str+=3;
5338   else
5339     {
5340       inst.error = _("missing rotation field after comma");
5341       return;
5342     }
5343   
5344   /* Get the immediate constant. */
5345   skip_whitespace (str);
5346   if (is_immediate_prefix (* str))
5347     str++;
5348   else
5349     {
5350       inst.error = _("immediate expression expected");
5351       return;
5352     }
5353   
5354   if (my_get_expression (&expr, &str))
5355     {
5356       inst.error = _("bad expression");
5357       return;
5358     }
5359
5360   if (expr.X_op != O_constant)
5361     {
5362       inst.error = _("constant expression expected");
5363       return;
5364     }
5365   
5366   switch (expr.X_add_number) 
5367     {
5368     case 0:
5369       /* Rotation field has already been zeroed. */
5370       break;
5371     case 8:
5372       inst.instruction |= rotation_eight_mask;
5373       break;
5374
5375     case 16:
5376       inst.instruction |= rotation_sixteen_mask;
5377       break;
5378       
5379     case 24:
5380       inst.instruction |= rotation_twenty_four_mask;
5381       break;
5382
5383     default:
5384       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5385       break;
5386     }
5387
5388   end_of_line (str);
5389   
5390 }
5391
5392 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5393    extends it to 32-bits, and adds the result to a value in another
5394    register.  You can specify a rotation by 0, 8, 16, or 24 bits
5395    before extracting the 16-bit value.
5396    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5397    Condition defaults to COND_ALWAYS.
5398    Error if any register uses R15. */
5399
5400 static void 
5401 do_sxtah (str)
5402      char *str;
5403 {
5404   int rd, rn, rm;
5405   expressionS expr;
5406   int rotation_clear_mask = 0xfffff3ff;
5407   int rotation_eight_mask = 0x00000400;
5408   int rotation_sixteen_mask = 0x00000800;
5409   int rotation_twenty_four_mask = 0x00000c00;
5410   
5411   skip_whitespace (str);
5412   if ((rd = reg_required_here (&str, 12)) == FAIL
5413       || skip_past_comma (&str) == FAIL
5414       || (rn = reg_required_here (&str, 16)) == FAIL
5415       || skip_past_comma (&str) == FAIL
5416       || (rm = reg_required_here (&str, 0)) == FAIL)
5417     {
5418       inst.error = BAD_ARGS;
5419       return;
5420     }
5421
5422   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5423     {
5424       inst.error = BAD_PC;
5425       return;
5426     }
5427   
5428   /* Zero out the rotation field. */
5429   inst.instruction &= rotation_clear_mask;
5430   
5431   /* Check for lack of optional rotation field. */
5432   if (skip_past_comma (&str) == FAIL)
5433     {
5434       end_of_line (str);
5435       return;
5436     }
5437   
5438   /* Move past 'ROR'. */
5439   skip_whitespace (str);
5440   if (strncasecmp (str, "ROR", 3) == 0)
5441     str+=3;
5442   else
5443     {
5444       inst.error = _("missing rotation field after comma");
5445       return;
5446     }
5447   
5448   /* Get the immediate constant. */
5449   skip_whitespace (str);
5450   if (is_immediate_prefix (* str))
5451     str++;
5452   else
5453     {
5454       inst.error = _("immediate expression expected");
5455       return;
5456     }
5457   
5458   if (my_get_expression (&expr, &str))
5459     {
5460       inst.error = _("bad expression");
5461       return;
5462     }
5463
5464   if (expr.X_op != O_constant)
5465     {
5466       inst.error = _("constant expression expected");
5467       return;
5468     }
5469   
5470   switch (expr.X_add_number) 
5471     {
5472     case 0:
5473       /* Rotation field has already been zeroed. */
5474       break;
5475
5476     case 8:
5477       inst.instruction |= rotation_eight_mask;
5478       break;
5479
5480     case 16:
5481       inst.instruction |= rotation_sixteen_mask;
5482       break;
5483       
5484     case 24:
5485       inst.instruction |= rotation_twenty_four_mask;
5486       break;
5487
5488     default:
5489       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5490       break;
5491     }
5492
5493   end_of_line (str);
5494   
5495 }
5496    
5497
5498 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5499    word at the specified address and the following word
5500    respectively. 
5501    Unconditionally executed.
5502    Error if Rn is R15.   
5503 */
5504
5505 static void
5506 do_rfe (str)
5507      char *str;
5508 {
5509   int rn;
5510
5511   skip_whitespace (str);
5512   
5513   if ((rn = reg_required_here (&str, 16)) == FAIL)
5514     return;
5515
5516   if (rn == REG_PC)
5517     {
5518       inst.error = BAD_PC;
5519       return;
5520     }
5521
5522   skip_whitespace (str);
5523   
5524   if (*str == '!')
5525     {
5526       inst.instruction |= WRITE_BACK;
5527       str++;
5528     }
5529   end_of_line (str);
5530 }
5531
5532 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5533    register (argument parse).
5534    REV{<cond>} Rd, Rm.
5535    Condition defaults to COND_ALWAYS.
5536    Error if Rd or Rm are R15. */ 
5537
5538 static void
5539 do_rev (str)
5540      char* str;
5541 {
5542   int rd, rm;
5543
5544   skip_whitespace (str);
5545
5546   if ((rd = reg_required_here (&str, 12)) == FAIL
5547       || skip_past_comma (&str) == FAIL
5548       || (rm = reg_required_here (&str, 0)) == FAIL)
5549     inst.error = BAD_ARGS;
5550
5551   else if (rd == REG_PC || rm == REG_PC)
5552     inst.error = BAD_PC;
5553
5554   else
5555     end_of_line (str);
5556 }
5557
5558 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5559    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
5560    Condition defaults to COND_ALWAYS.
5561    Error if Rd, Rn or Rm are R15.  */
5562
5563 static void
5564 do_qadd16 (str) 
5565      char* str;
5566 {
5567   int rd, rm, rn;
5568
5569   skip_whitespace (str);
5570
5571   if ((rd = reg_required_here (&str, 12)) == FAIL
5572       || skip_past_comma (&str) == FAIL
5573       || (rn = reg_required_here (&str, 16)) == FAIL
5574       || skip_past_comma (&str) == FAIL
5575       || (rm = reg_required_here (&str, 0)) == FAIL)
5576     inst.error = BAD_ARGS;
5577
5578   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5579     inst.error = BAD_PC;
5580
5581   else
5582     end_of_line (str);
5583 }
5584
5585 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5586    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
5587    Condition defaults to COND_ALWAYS.
5588    Error if Rd, Rn or Rm are R15.  */
5589
5590 static void 
5591 do_pkhbt (str)
5592      char* str;
5593 {
5594   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5595 }
5596
5597 /* ARM V6 PKHTB (Argument Parse). */
5598
5599 static void 
5600 do_pkhtb (str)
5601      char* str;
5602 {
5603   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5604 }
5605
5606 static void
5607 do_pkh_core (str, shift)
5608      char* str;
5609      int shift;
5610 {
5611   int rd, rn, rm;
5612
5613   skip_whitespace (str);
5614   if (((rd = reg_required_here (&str, 12)) == FAIL)
5615       || (skip_past_comma (&str) == FAIL)
5616       || ((rn = reg_required_here (&str, 16)) == FAIL)
5617       || (skip_past_comma (&str) == FAIL)
5618       || ((rm = reg_required_here (&str, 0)) == FAIL))
5619     {
5620       inst.error = BAD_ARGS;
5621       return;
5622     }
5623
5624   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5625     {
5626       inst.error = BAD_PC;
5627       return;
5628     }
5629
5630   /* Check for optional shift immediate constant. */
5631   if (skip_past_comma (&str) == FAIL) 
5632     {
5633       if (shift == SHIFT_ASR_IMMEDIATE)
5634         {
5635           /* If the shift specifier is ommited, turn the instruction
5636              into pkhbt rd, rm, rn.  First, switch the instruction
5637              code, and clear the rn and rm fields.  */
5638           inst.instruction &= 0xfff0f010;
5639           /* Now, re-encode the registers.  */
5640           inst.instruction |= (rm << 16) | rn;
5641         }
5642       return;
5643     }
5644
5645   decode_shift (&str, shift);
5646 }
5647
5648 /* ARM V6 Load Register Exclusive instruction (argument parse).
5649    LDREX{<cond>} <Rd, [<Rn>]
5650    Condition defaults to COND_ALWAYS.
5651    Error if Rd or Rn are R15. 
5652    See ARMARMv6 A4.1.27: LDREX. */
5653
5654
5655 static void
5656 do_ldrex (str)
5657      char * str;
5658 {
5659   int rd, rn;
5660
5661   skip_whitespace (str);
5662
5663   /* Parse Rd. */
5664   if (((rd = reg_required_here (&str, 12)) == FAIL)
5665       || (skip_past_comma (&str) == FAIL))
5666     {
5667       inst.error = BAD_ARGS;
5668       return;
5669     }
5670   else if (rd == REG_PC)
5671     {
5672       inst.error = BAD_PC;
5673       return;
5674     }
5675   skip_whitespace (str);  
5676
5677   /* Skip past '['. */
5678   if ((strlen (str) >= 1) 
5679       &&strncmp (str, "[", 1) == 0)
5680     str+=1;
5681   skip_whitespace (str);  
5682
5683   /* Parse Rn. */
5684   if ((rn = reg_required_here (&str, 16)) == FAIL)
5685     {
5686       inst.error = BAD_ARGS;
5687       return;
5688     }
5689   else if (rn == REG_PC)
5690     {
5691       inst.error = BAD_PC;
5692       return;
5693     }
5694   skip_whitespace (str);  
5695
5696   /* Skip past ']'. */
5697   if ((strlen (str) >= 1) 
5698       && strncmp (str, "]", 1) == 0)
5699     str+=1;
5700   
5701   end_of_line (str);
5702 }
5703
5704 /* ARM V6 change processor state instruction (argument parse)
5705       CPS, CPSIE, CSPID . */
5706
5707 static void
5708 do_cps (str)
5709      char * str;
5710 {
5711   do_cps_mode (&str);
5712   end_of_line (str);
5713 }
5714
5715 static void
5716 do_cpsi (str)
5717      char * str;
5718 {
5719   do_cps_flags (&str, /*thumb_p=*/0);
5720
5721   if (skip_past_comma (&str) == SUCCESS)
5722     {
5723       skip_whitespace (str);
5724       do_cps_mode (&str);
5725     }
5726   end_of_line (str);
5727 }
5728
5729 static void
5730 do_cps_mode (str)
5731      char **str;
5732 {
5733   expressionS expr;
5734
5735   skip_whitespace (*str);
5736
5737   if (! is_immediate_prefix (**str))
5738     {
5739       inst.error = _("immediate expression expected");
5740       return;
5741     }
5742
5743   (*str)++; /* Strip off the immediate signifier. */
5744   if (my_get_expression (&expr, str))
5745     {
5746       inst.error = _("bad expression");
5747       return;
5748     }
5749
5750   if (expr.X_op != O_constant)
5751     {
5752       inst.error = _("constant expression expected");
5753       return;
5754     }
5755   
5756   /* The mode is a 5 bit field.  Valid values are 0-31. */
5757   if (((unsigned) expr.X_add_number) > 31
5758       || (inst.reloc.exp.X_add_number) < 0)
5759     {
5760       inst.error = _("invalid constant");
5761       return;
5762     }
5763   
5764   inst.instruction |= expr.X_add_number;
5765 }
5766
5767 static void
5768 do_cps_flags (str, thumb_p)
5769      char **str;
5770      int    thumb_p;
5771 {
5772   struct cps_flag { 
5773     char character;
5774     unsigned long arm_value;
5775     unsigned long thumb_value;
5776   };
5777   static struct cps_flag flag_table[] = {
5778     {'a', 0x100, 0x4 },
5779     {'i', 0x080, 0x2 },
5780     {'f', 0x040, 0x1 }
5781   };
5782
5783   int saw_a_flag = 0;
5784
5785   skip_whitespace (*str);
5786
5787   /* Get the a, f and i flags. */
5788   while (**str && **str != ',')
5789     {
5790       struct cps_flag *p;
5791       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5792       for (p = flag_table; p < q; ++p)
5793         if (strncasecmp (*str, &p->character, 1) == 0)
5794           {
5795             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5796             saw_a_flag = 1;
5797             break;
5798           }
5799       if (p == q)
5800         {
5801           inst.error = _("unrecognized flag");
5802           return;
5803         }
5804       (*str)++;
5805     }
5806   if (!saw_a_flag) 
5807     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5808 }
5809
5810 /* THUMB V5 breakpoint instruction (argument parse)
5811         BKPT <immed_8>.  */
5812
5813 static void
5814 do_t_bkpt (str)
5815      char * str;
5816 {
5817   expressionS expr;
5818   unsigned long number;
5819
5820   skip_whitespace (str);
5821
5822   /* Allow optional leading '#'.  */
5823   if (is_immediate_prefix (*str))
5824     str ++;
5825
5826   memset (& expr, '\0', sizeof (expr));
5827   if (my_get_expression (& expr, & str)
5828       || (expr.X_op != O_constant
5829           /* As a convenience we allow 'bkpt' without an operand.  */
5830           && expr.X_op != O_absent))
5831     {
5832       inst.error = _("bad expression");
5833       return;
5834     }
5835
5836   number = expr.X_add_number;
5837
5838   /* Check it fits an 8 bit unsigned.  */
5839   if (number != (number & 0xff))
5840     {
5841       inst.error = _("immediate value out of range");
5842       return;
5843     }
5844
5845   inst.instruction |= number;
5846
5847   end_of_line (str);
5848 }
5849
5850 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5851    Expects inst.instruction is set for BLX(1).
5852    Note: this is cloned from do_branch, and the reloc changed to be a
5853         new one that can cope with setting one extra bit (the H bit).  */
5854
5855 static void
5856 do_branch25 (str)
5857      char *        str;
5858 {
5859   if (my_get_expression (& inst.reloc.exp, & str))
5860     return;
5861
5862 #ifdef OBJ_ELF
5863   {
5864     char * save_in;
5865
5866     /* ScottB: February 5, 1998 */
5867     /* Check to see of PLT32 reloc required for the instruction.  */
5868
5869     /* arm_parse_reloc() works on input_line_pointer.
5870        We actually want to parse the operands to the branch instruction
5871        passed in 'str'.  Save the input pointer and restore it later.  */
5872     save_in = input_line_pointer;
5873     input_line_pointer = str;
5874
5875     if (inst.reloc.exp.X_op == O_symbol
5876         && *str == '('
5877         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5878       {
5879         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5880         inst.reloc.pc_rel = 0;
5881         /* Modify str to point to after parsed operands, otherwise
5882            end_of_line() will complain about the (PLT) left in str.  */
5883         str = input_line_pointer;
5884       }
5885     else
5886       {
5887         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5888         inst.reloc.pc_rel = 1;
5889       }
5890
5891     input_line_pointer = save_in;
5892   }
5893 #else
5894   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5895   inst.reloc.pc_rel = 1;
5896 #endif /* OBJ_ELF */
5897
5898   end_of_line (str);
5899 }
5900
5901 /* ARM V5 branch-link-exchange instruction (argument parse)
5902      BLX <target_addr>          ie BLX(1)
5903      BLX{<condition>} <Rm>      ie BLX(2)
5904    Unfortunately, there are two different opcodes for this mnemonic.
5905    So, the insns[].value is not used, and the code here zaps values
5906         into inst.instruction.
5907    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5908
5909 static void
5910 do_blx (str)
5911      char *        str;
5912 {
5913   char * mystr = str;
5914   int rm;
5915
5916   skip_whitespace (mystr);
5917   rm = reg_required_here (& mystr, 0);
5918
5919   /* The above may set inst.error.  Ignore his opinion.  */
5920   inst.error = 0;
5921
5922   if (rm != FAIL)
5923     {
5924       /* Arg is a register.
5925          Use the condition code our caller put in inst.instruction.
5926          Pass ourselves off as a BX with a funny opcode.  */
5927       inst.instruction |= 0x012fff30;
5928       do_bx (str);
5929     }
5930   else
5931     {
5932       /* This must be is BLX <target address>, no condition allowed.  */
5933       if (inst.instruction != COND_ALWAYS)
5934         {
5935           inst.error = BAD_COND;
5936           return;
5937         }
5938
5939       inst.instruction = 0xfafffffe;
5940
5941       /* Process like a B/BL, but with a different reloc.
5942          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5943       do_branch25 (str);
5944     }
5945 }
5946
5947 /* ARM V5 Thumb BLX (argument parse)
5948         BLX <target_addr>       which is BLX(1)
5949         BLX <Rm>                which is BLX(2)
5950    Unfortunately, there are two different opcodes for this mnemonic.
5951    So, the tinsns[].value is not used, and the code here zaps values
5952         into inst.instruction.  */
5953
5954 static void
5955 do_t_blx (str)
5956      char * str;
5957 {
5958   char * mystr = str;
5959   int rm;
5960
5961   skip_whitespace (mystr);
5962   inst.instruction = 0x4780;
5963
5964   /* Note that this call is to the ARM register recognizer.  BLX(2)
5965      uses the ARM register space, not the Thumb one, so a call to
5966      thumb_reg() would be wrong.  */
5967   rm = reg_required_here (& mystr, 3);
5968   inst.error = 0;
5969
5970   if (rm != FAIL)
5971     {
5972       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5973       inst.size = 2;
5974     }
5975   else
5976     {
5977       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5978       inst.instruction = 0xf7ffeffe;
5979       inst.size = 4;
5980
5981       if (my_get_expression (& inst.reloc.exp, & mystr))
5982         return;
5983
5984       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5985       inst.reloc.pc_rel = 1;
5986     }
5987
5988   end_of_line (mystr);
5989 }
5990
5991 /* ARM V5 breakpoint instruction (argument parse)
5992      BKPT <16 bit unsigned immediate>
5993      Instruction is not conditional.
5994         The bit pattern given in insns[] has the COND_ALWAYS condition,
5995         and it is an error if the caller tried to override that.  */
5996
5997 static void
5998 do_bkpt (str)
5999      char *        str;
6000 {
6001   expressionS expr;
6002   unsigned long number;
6003
6004   skip_whitespace (str);
6005
6006   /* Allow optional leading '#'.  */
6007   if (is_immediate_prefix (* str))
6008     str++;
6009
6010   memset (& expr, '\0', sizeof (expr));
6011
6012   if (my_get_expression (& expr, & str)
6013       || (expr.X_op != O_constant
6014           /* As a convenience we allow 'bkpt' without an operand.  */
6015           && expr.X_op != O_absent))
6016     {
6017       inst.error = _("bad expression");
6018       return;
6019     }
6020
6021   number = expr.X_add_number;
6022
6023   /* Check it fits a 16 bit unsigned.  */
6024   if (number != (number & 0xffff))
6025     {
6026       inst.error = _("immediate value out of range");
6027       return;
6028     }
6029
6030   /* Top 12 of 16 bits to bits 19:8.  */
6031   inst.instruction |= (number & 0xfff0) << 4;
6032
6033   /* Bottom 4 of 16 bits to bits 3:0.  */
6034   inst.instruction |= number & 0xf;
6035
6036   end_of_line (str);
6037 }
6038
6039 /* THUMB CPS instruction (argument parse).  */
6040
6041 static void
6042 do_t_cps (str)
6043      char *str;
6044 {
6045   do_cps_flags (&str, /*thumb_p=*/1);
6046   end_of_line (str);
6047 }
6048
6049 /* THUMB CPY instruction (argument parse).  */
6050
6051 static void
6052 do_t_cpy (str)
6053      char *str;
6054 {
6055   thumb_mov_compare (str, THUMB_CPY);
6056 }
6057
6058 /* THUMB SETEND instruction (argument parse).  */
6059
6060 static void
6061 do_t_setend (str)
6062      char *str;
6063 {
6064   if (do_endian_specifier (str))
6065     inst.instruction |= 0x8;
6066 }
6067
6068 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6069
6070 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6071
6072 static unsigned long
6073 check_iwmmxt_insn (str, insn_type, immediate_size)
6074      char * str;
6075      enum iwmmxt_insn_type insn_type;
6076      int immediate_size;
6077 {
6078   int reg = 0;
6079   const char *  inst_error;
6080   expressionS expr;
6081   unsigned long number;
6082
6083   inst_error = inst.error;
6084   if (!inst.error)
6085     inst.error = BAD_ARGS;
6086   skip_whitespace (str);
6087
6088   switch (insn_type)
6089     {
6090     case check_rd:
6091       if ((reg = reg_required_here (&str, 12)) == FAIL)
6092         return FAIL;
6093       break;
6094       
6095     case check_wr:
6096        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6097          return FAIL;
6098        break;
6099        
6100     case check_wrwr:
6101       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6102            || skip_past_comma (&str) == FAIL
6103            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6104         return FAIL;
6105       break;
6106       
6107     case check_wrwrwr:
6108       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6109            || skip_past_comma (&str) == FAIL
6110            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6111            || skip_past_comma (&str) == FAIL
6112            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6113         return FAIL;
6114       break;
6115       
6116     case check_wrwrwcg:
6117       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6118            || skip_past_comma (&str) == FAIL
6119            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6120            || skip_past_comma (&str) == FAIL
6121            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6122         return FAIL;
6123       break;
6124       
6125     case check_tbcst:
6126       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6127            || skip_past_comma (&str) == FAIL
6128            || reg_required_here (&str, 12) == FAIL))
6129         return FAIL;
6130       break;
6131       
6132     case check_tmovmsk:
6133       if ((reg_required_here (&str, 12) == FAIL
6134            || skip_past_comma (&str) == FAIL
6135            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6136         return FAIL;
6137       break;
6138       
6139     case check_tmia:
6140       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6141            || skip_past_comma (&str) == FAIL
6142            || reg_required_here (&str, 0) == FAIL
6143            || skip_past_comma (&str) == FAIL
6144            || reg_required_here (&str, 12) == FAIL))
6145         return FAIL;
6146       break;
6147       
6148     case check_tmcrr:
6149       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6150            || skip_past_comma (&str) == FAIL
6151            || reg_required_here (&str, 12) == FAIL
6152            || skip_past_comma (&str) == FAIL
6153            || reg_required_here (&str, 16) == FAIL))
6154         return FAIL;
6155       break;
6156       
6157     case check_tmrrc:
6158       if ((reg_required_here (&str, 12) == FAIL
6159            || skip_past_comma (&str) == FAIL
6160            || reg_required_here (&str, 16) == FAIL
6161            || skip_past_comma (&str) == FAIL
6162            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6163         return FAIL;
6164       break;
6165       
6166     case check_tmcr:
6167       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6168            || skip_past_comma (&str) == FAIL
6169            || reg_required_here (&str, 12) == FAIL))
6170         return FAIL;
6171       break;
6172       
6173     case check_tmrc:
6174       if ((reg_required_here (&str, 12) == FAIL
6175            || skip_past_comma (&str) == FAIL
6176            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6177         return FAIL;
6178       break;
6179       
6180     case check_tinsr:
6181       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6182            || skip_past_comma (&str) == FAIL
6183            || reg_required_here (&str, 12) == FAIL
6184            || skip_past_comma (&str) == FAIL))
6185         return FAIL;
6186       break;
6187       
6188     case check_textrc:
6189       if ((reg_required_here (&str, 12) == FAIL
6190            || skip_past_comma (&str) == FAIL))
6191         return FAIL;
6192       break;
6193       
6194     case check_waligni:
6195       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6196            || skip_past_comma (&str) == FAIL
6197            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6198            || skip_past_comma (&str) == FAIL
6199            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6200            || skip_past_comma (&str) == FAIL))
6201         return FAIL;
6202       break;
6203       
6204     case check_textrm:
6205       if ((reg_required_here (&str, 12) == FAIL
6206            || skip_past_comma (&str) == FAIL
6207            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6208            || skip_past_comma (&str) == FAIL))
6209         return FAIL;
6210       break;
6211       
6212     case check_wshufh:
6213       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6214            || skip_past_comma (&str) == FAIL
6215            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6216            || skip_past_comma (&str) == FAIL))
6217         return FAIL;
6218       break;
6219     }
6220   
6221   if (immediate_size == 0)
6222     {
6223       end_of_line (str);
6224       inst.error = inst_error;
6225       return reg;
6226     }
6227   else
6228     {
6229       skip_whitespace (str);      
6230   
6231       /* Allow optional leading '#'. */
6232       if (is_immediate_prefix (* str))
6233         str++;
6234
6235       memset (& expr, '\0', sizeof (expr));
6236   
6237       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6238         {
6239           inst.error = _("bad or missing expression");
6240           return FAIL;
6241         }
6242   
6243       number = expr.X_add_number;
6244   
6245       if (number != (number & immediate_size))
6246         {
6247           inst.error = _("immediate value out of range");
6248           return FAIL;
6249         }
6250       end_of_line (str);
6251       inst.error = inst_error;
6252       return number;
6253     }
6254 }
6255
6256 static void
6257 do_iwmmxt_byte_addr (str)
6258      char * str;
6259 {
6260   int op = (inst.instruction & 0x300) >> 8;
6261   int reg;
6262
6263   inst.instruction &= ~0x300;
6264   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6265
6266   skip_whitespace (str);
6267
6268   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6269       || skip_past_comma (& str) == FAIL
6270       || cp_byte_address_required_here (&str) == FAIL)
6271     {
6272       if (! inst.error)
6273         inst.error = BAD_ARGS;
6274     }
6275   else
6276     end_of_line (str);
6277
6278   if (wc_register (reg))
6279     {
6280       as_bad (_("non-word size not supported with control register"));
6281       inst.instruction |=  0xf0000100;
6282       inst.instruction &= ~0x00400000;
6283     }
6284 }
6285
6286 static void
6287 do_iwmmxt_tandc (str)
6288      char * str;
6289 {
6290   int reg;
6291
6292   reg = check_iwmmxt_insn (str, check_rd, 0);
6293
6294   if (reg != REG_PC && !inst.error)
6295     inst.error = _("only r15 allowed here");
6296 }
6297
6298 static void
6299 do_iwmmxt_tbcst (str)
6300      char * str;
6301 {
6302   check_iwmmxt_insn (str, check_tbcst, 0);
6303 }
6304
6305 static void
6306 do_iwmmxt_textrc (str)
6307      char * str;
6308 {
6309   unsigned long number;
6310
6311   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6312     return;
6313
6314   inst.instruction |= number & 0x7;
6315 }
6316
6317 static void
6318 do_iwmmxt_textrm (str)
6319      char * str;
6320 {
6321   unsigned long number;
6322
6323   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6324     return;
6325
6326   inst.instruction |= number & 0x7;
6327 }
6328
6329 static void
6330 do_iwmmxt_tinsr (str)
6331      char * str;
6332 {
6333   unsigned long number;
6334
6335   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6336     return;
6337
6338   inst.instruction |= number & 0x7;
6339 }
6340
6341 static void
6342 do_iwmmxt_tmcr (str)
6343      char * str;
6344 {
6345   check_iwmmxt_insn (str, check_tmcr, 0);
6346 }
6347
6348 static void
6349 do_iwmmxt_tmcrr (str)
6350      char * str;
6351 {
6352   check_iwmmxt_insn (str, check_tmcrr, 0);
6353 }
6354
6355 static void
6356 do_iwmmxt_tmia (str)
6357      char * str;
6358 {
6359   check_iwmmxt_insn (str, check_tmia, 0);
6360 }
6361
6362 static void
6363 do_iwmmxt_tmovmsk (str)
6364      char * str;
6365 {
6366   check_iwmmxt_insn (str, check_tmovmsk, 0);
6367 }
6368
6369 static void
6370 do_iwmmxt_tmrc (str)
6371      char * str;
6372 {
6373   check_iwmmxt_insn (str, check_tmrc, 0);
6374 }
6375
6376 static void
6377 do_iwmmxt_tmrrc (str)
6378      char * str;
6379 {
6380   check_iwmmxt_insn (str, check_tmrrc, 0);
6381 }
6382
6383 static void
6384 do_iwmmxt_torc (str)
6385      char * str;
6386 {
6387   check_iwmmxt_insn (str, check_rd, 0);
6388 }
6389
6390 static void
6391 do_iwmmxt_waligni (str)
6392      char * str;
6393 {
6394   unsigned long number;
6395
6396   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6397     return;
6398
6399   inst.instruction |= ((number & 0x7) << 20);
6400 }
6401
6402 static void
6403 do_iwmmxt_wmov (str)
6404      char * str;
6405 {
6406   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6407     return;
6408   
6409   inst.instruction |= ((inst.instruction >> 16) & 0xf);
6410 }
6411
6412 static void
6413 do_iwmmxt_word_addr (str)
6414      char * str;
6415 {
6416   int op = (inst.instruction & 0x300) >> 8;
6417   int reg;
6418
6419   inst.instruction &= ~0x300;
6420   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6421
6422   skip_whitespace (str);
6423
6424   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6425       || skip_past_comma (& str) == FAIL
6426       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6427     {
6428       if (! inst.error)
6429         inst.error = BAD_ARGS;
6430     }
6431   else
6432     end_of_line (str);
6433
6434   if (wc_register (reg))
6435     {
6436       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6437         as_bad (_("conditional execution not supported with control register"));
6438       if (op != 2)
6439         as_bad (_("non-word size not supported with control register"));
6440       inst.instruction |=  0xf0000100;
6441       inst.instruction &= ~0x00400000;
6442     }
6443 }
6444
6445 static void
6446 do_iwmmxt_wrwr (str)
6447      char * str;
6448 {
6449   check_iwmmxt_insn (str, check_wrwr, 0);
6450 }
6451
6452 static void
6453 do_iwmmxt_wrwrwcg (str)
6454      char * str;
6455 {
6456   check_iwmmxt_insn (str, check_wrwrwcg, 0);
6457 }
6458
6459 static void
6460 do_iwmmxt_wrwrwr (str)
6461      char * str;
6462 {
6463   check_iwmmxt_insn (str, check_wrwrwr, 0);
6464 }
6465
6466 static void
6467 do_iwmmxt_wshufh (str)
6468      char * str;
6469 {
6470   unsigned long number;
6471
6472   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6473     return;
6474
6475   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6476 }
6477
6478 static void
6479 do_iwmmxt_wzero (str)
6480      char * str;
6481 {
6482   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6483     return;
6484
6485   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6486 }
6487
6488 /* Xscale multiply-accumulate (argument parse)
6489      MIAcc   acc0,Rm,Rs
6490      MIAPHcc acc0,Rm,Rs
6491      MIAxycc acc0,Rm,Rs.  */
6492
6493 static void
6494 do_xsc_mia (str)
6495      char * str;
6496 {
6497   int rs;
6498   int rm;
6499
6500   if (accum0_required_here (& str) == FAIL)
6501     inst.error = ERR_NO_ACCUM;
6502
6503   else if (skip_past_comma (& str) == FAIL
6504            || (rm = reg_required_here (& str, 0)) == FAIL)
6505     inst.error = BAD_ARGS;
6506
6507   else if (skip_past_comma (& str) == FAIL
6508            || (rs = reg_required_here (& str, 12)) == FAIL)
6509     inst.error = BAD_ARGS;
6510
6511   /* inst.instruction has now been zapped with both rm and rs.  */
6512   else if (rm == REG_PC || rs == REG_PC)
6513     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
6514
6515   else
6516     end_of_line (str);
6517 }
6518
6519 /* Xscale move-accumulator-register (argument parse)
6520
6521      MARcc   acc0,RdLo,RdHi.  */
6522
6523 static void
6524 do_xsc_mar (str)
6525      char * str;
6526 {
6527   int rdlo, rdhi;
6528
6529   if (accum0_required_here (& str) == FAIL)
6530     inst.error = ERR_NO_ACCUM;
6531
6532   else if (skip_past_comma (& str) == FAIL
6533            || (rdlo = reg_required_here (& str, 12)) == FAIL)
6534     inst.error = BAD_ARGS;
6535
6536   else if (skip_past_comma (& str) == FAIL
6537            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6538     inst.error = BAD_ARGS;
6539
6540   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6541   else if (rdlo == REG_PC || rdhi == REG_PC)
6542     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6543
6544   else
6545     end_of_line (str);
6546 }
6547
6548 /* Xscale move-register-accumulator (argument parse)
6549
6550      MRAcc   RdLo,RdHi,acc0.  */
6551
6552 static void
6553 do_xsc_mra (str)
6554      char * str;
6555 {
6556   int rdlo;
6557   int rdhi;
6558
6559   skip_whitespace (str);
6560
6561   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6562     inst.error = BAD_ARGS;
6563
6564   else if (skip_past_comma (& str) == FAIL
6565            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6566     inst.error = BAD_ARGS;
6567
6568   else if  (skip_past_comma (& str) == FAIL
6569             || accum0_required_here (& str) == FAIL)
6570     inst.error = ERR_NO_ACCUM;
6571
6572   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6573   else if (rdlo == rdhi)
6574     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
6575
6576   else if (rdlo == REG_PC || rdhi == REG_PC)
6577     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6578   else
6579     end_of_line (str);
6580 }
6581
6582 /* ARMv5TE: Preload-Cache
6583
6584     PLD <addr_mode>
6585
6586   Syntactically, like LDR with B=1, W=0, L=1.  */
6587
6588 static void
6589 do_pld (str)
6590      char * str;
6591 {
6592   int rd;
6593
6594   skip_whitespace (str);
6595
6596   if (* str != '[')
6597     {
6598       inst.error = _("'[' expected after PLD mnemonic");
6599       return;
6600     }
6601
6602   ++str;
6603   skip_whitespace (str);
6604
6605   if ((rd = reg_required_here (& str, 16)) == FAIL)
6606     return;
6607
6608   skip_whitespace (str);
6609
6610   if (*str == ']')
6611     {
6612       /* [Rn], ... ?  */
6613       ++str;
6614       skip_whitespace (str);
6615
6616       /* Post-indexed addressing is not allowed with PLD.  */
6617       if (skip_past_comma (&str) == SUCCESS)
6618         {
6619           inst.error
6620             = _("post-indexed expression used in preload instruction");
6621           return;
6622         }
6623       else if (*str == '!') /* [Rn]! */
6624         {
6625           inst.error = _("writeback used in preload instruction");
6626           ++str;
6627         }
6628       else /* [Rn] */
6629         inst.instruction |= INDEX_UP | PRE_INDEX;
6630     }
6631   else /* [Rn, ...] */
6632     {
6633       if (skip_past_comma (& str) == FAIL)
6634         {
6635           inst.error = _("pre-indexed expression expected");
6636           return;
6637         }
6638
6639       if (ldst_extend (&str) == FAIL)
6640         return;
6641
6642       skip_whitespace (str);
6643
6644       if (* str != ']')
6645         {
6646           inst.error = _("missing ]");
6647           return;
6648         }
6649
6650       ++ str;
6651       skip_whitespace (str);
6652
6653       if (* str == '!') /* [Rn]! */
6654         {
6655           inst.error = _("writeback used in preload instruction");
6656           ++ str;
6657         }
6658
6659       inst.instruction |= PRE_INDEX;
6660     }
6661
6662   end_of_line (str);
6663 }
6664
6665 /* ARMv5TE load-consecutive (argument parse)
6666    Mode is like LDRH.
6667
6668      LDRccD R, mode
6669      STRccD R, mode.  */
6670
6671 static void
6672 do_ldrd (str)
6673      char * str;
6674 {
6675   int rd;
6676   int rn;
6677
6678   skip_whitespace (str);
6679
6680   if ((rd = reg_required_here (& str, 12)) == FAIL)
6681     {
6682       inst.error = BAD_ARGS;
6683       return;
6684     }
6685
6686   if (skip_past_comma (& str) == FAIL
6687       || (rn = ld_mode_required_here (& str)) == FAIL)
6688     {
6689       if (!inst.error)
6690         inst.error = BAD_ARGS;
6691       return;
6692     }
6693
6694   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6695   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
6696     {
6697       inst.error = _("destination register must be even");
6698       return;
6699     }
6700
6701   if (rd == REG_LR)
6702     {
6703       inst.error = _("r14 not allowed here");
6704       return;
6705     }
6706
6707   if (((rd == rn) || (rd + 1 == rn))
6708       && ((inst.instruction & WRITE_BACK)
6709           || (!(inst.instruction & PRE_INDEX))))
6710     as_warn (_("pre/post-indexing used when modified address register is destination"));
6711
6712   /* For an index-register load, the index register must not overlap the
6713      destination (even if not write-back).  */
6714   if ((inst.instruction & V4_STR_BIT) == 0
6715       && (inst.instruction & HWOFFSET_IMM) == 0)
6716     {
6717       int rm = inst.instruction & 0x0000000f;
6718
6719       if (rm == rd || (rm == rd + 1))
6720         as_warn (_("ldrd destination registers must not overlap index register"));
6721     }
6722
6723   end_of_line (str);
6724 }
6725
6726 /* Returns the index into fp_values of a floating point number,
6727    or -1 if not in the table.  */
6728
6729 static int
6730 my_get_float_expression (str)
6731      char ** str;
6732 {
6733   LITTLENUM_TYPE words[MAX_LITTLENUMS];
6734   char *         save_in;
6735   expressionS    exp;
6736   int            i;
6737   int            j;
6738
6739   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6740
6741   /* Look for a raw floating point number.  */
6742   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6743       && is_end_of_line[(unsigned char) *save_in])
6744     {
6745       for (i = 0; i < NUM_FLOAT_VALS; i++)
6746         {
6747           for (j = 0; j < MAX_LITTLENUMS; j++)
6748             {
6749               if (words[j] != fp_values[i][j])
6750                 break;
6751             }
6752
6753           if (j == MAX_LITTLENUMS)
6754             {
6755               *str = save_in;
6756               return i;
6757             }
6758         }
6759     }
6760
6761   /* Try and parse a more complex expression, this will probably fail
6762      unless the code uses a floating point prefix (eg "0f").  */
6763   save_in = input_line_pointer;
6764   input_line_pointer = *str;
6765   if (expression (&exp) == absolute_section
6766       && exp.X_op == O_big
6767       && exp.X_add_number < 0)
6768     {
6769       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6770          Ditto for 15.  */
6771       if (gen_to_words (words, 5, (long) 15) == 0)
6772         {
6773           for (i = 0; i < NUM_FLOAT_VALS; i++)
6774             {
6775               for (j = 0; j < MAX_LITTLENUMS; j++)
6776                 {
6777                   if (words[j] != fp_values[i][j])
6778                     break;
6779                 }
6780
6781               if (j == MAX_LITTLENUMS)
6782                 {
6783                   *str = input_line_pointer;
6784                   input_line_pointer = save_in;
6785                   return i;
6786                 }
6787             }
6788         }
6789     }
6790
6791   *str = input_line_pointer;
6792   input_line_pointer = save_in;
6793   return -1;
6794 }
6795
6796 /* Return TRUE if anything in the expression is a bignum.  */
6797
6798 static int
6799 walk_no_bignums (sp)
6800      symbolS * sp;
6801 {
6802   if (symbol_get_value_expression (sp)->X_op == O_big)
6803     return 1;
6804
6805   if (symbol_get_value_expression (sp)->X_add_symbol)
6806     {
6807       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6808               || (symbol_get_value_expression (sp)->X_op_symbol
6809                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6810     }
6811
6812   return 0;
6813 }
6814
6815 static int in_my_get_expression = 0;
6816
6817 static int
6818 my_get_expression (ep, str)
6819      expressionS * ep;
6820      char ** str;
6821 {
6822   char * save_in;
6823   segT   seg;
6824
6825   save_in = input_line_pointer;
6826   input_line_pointer = *str;
6827   in_my_get_expression = 1;
6828   seg = expression (ep);
6829   in_my_get_expression = 0;
6830
6831   if (ep->X_op == O_illegal)
6832     {
6833       /* We found a bad expression in md_operand().  */
6834       *str = input_line_pointer;
6835       input_line_pointer = save_in;
6836       return 1;
6837     }
6838
6839 #ifdef OBJ_AOUT
6840   if (seg != absolute_section
6841       && seg != text_section
6842       && seg != data_section
6843       && seg != bss_section
6844       && seg != undefined_section)
6845     {
6846       inst.error = _("bad_segment");
6847       *str = input_line_pointer;
6848       input_line_pointer = save_in;
6849       return 1;
6850     }
6851 #endif
6852
6853   /* Get rid of any bignums now, so that we don't generate an error for which
6854      we can't establish a line number later on.  Big numbers are never valid
6855      in instructions, which is where this routine is always called.  */
6856   if (ep->X_op == O_big
6857       || (ep->X_add_symbol
6858           && (walk_no_bignums (ep->X_add_symbol)
6859               || (ep->X_op_symbol
6860                   && walk_no_bignums (ep->X_op_symbol)))))
6861     {
6862       inst.error = _("invalid constant");
6863       *str = input_line_pointer;
6864       input_line_pointer = save_in;
6865       return 1;
6866     }
6867
6868   *str = input_line_pointer;
6869   input_line_pointer = save_in;
6870   return 0;
6871 }
6872
6873 /* We handle all bad expressions here, so that we can report the faulty
6874    instruction in the error message.  */
6875 void
6876 md_operand (expr)
6877      expressionS *expr;
6878 {
6879   if (in_my_get_expression)
6880     {
6881       expr->X_op = O_illegal;
6882       if (inst.error == NULL)
6883         inst.error = _("bad expression");
6884     }
6885 }
6886
6887 /* KIND indicates what kind of shifts are accepted.  */
6888
6889 static int
6890 decode_shift (str, kind)
6891      char ** str;
6892      int     kind;
6893 {
6894   const struct asm_shift_name * shift;
6895   char * p;
6896   char   c;
6897
6898   skip_whitespace (* str);
6899
6900   for (p = * str; ISALPHA (* p); p ++)
6901     ;
6902
6903   if (p == * str)
6904     {
6905       inst.error = _("shift expression expected");
6906       return FAIL;
6907     }
6908
6909   c = * p;
6910   * p = '\0';
6911   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6912   * p = c;
6913
6914   if (shift == NULL)
6915     {
6916       inst.error = _("shift expression expected");
6917       return FAIL;
6918     }
6919
6920   assert (shift->properties->index == shift_properties[shift->properties->index].index);
6921
6922   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6923       && shift->properties->index != SHIFT_LSL
6924       && shift->properties->index != SHIFT_ASR)
6925     {
6926       inst.error = _("'LSL' or 'ASR' required");
6927       return FAIL;
6928     }
6929   else if (kind == SHIFT_LSL_IMMEDIATE
6930            && shift->properties->index != SHIFT_LSL)
6931     {
6932       inst.error = _("'LSL' required");
6933       return FAIL;
6934     }
6935   else if (kind == SHIFT_ASR_IMMEDIATE
6936            && shift->properties->index != SHIFT_ASR)
6937     {
6938       inst.error = _("'ASR' required");
6939       return FAIL;
6940     }
6941     
6942   if (shift->properties->index == SHIFT_RRX)
6943     {
6944       * str = p;
6945       inst.instruction |= shift->properties->bit_field;
6946       return SUCCESS;
6947     }
6948
6949   skip_whitespace (p);
6950
6951   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6952     {
6953       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6954       * str = p;
6955       return SUCCESS;
6956     }
6957   else if (! is_immediate_prefix (* p))
6958     {
6959       inst.error = (NO_SHIFT_RESTRICT
6960                     ? _("shift requires register or #expression")
6961                     : _("shift requires #expression"));
6962       * str = p;
6963       return FAIL;
6964     }
6965
6966   inst.error = NULL;
6967   p ++;
6968
6969   if (my_get_expression (& inst.reloc.exp, & p))
6970     return FAIL;
6971
6972   /* Validate some simple #expressions.  */
6973   if (inst.reloc.exp.X_op == O_constant)
6974     {
6975       unsigned num = inst.reloc.exp.X_add_number;
6976
6977       /* Reject operations greater than 32.  */
6978       if (num > 32
6979           /* Reject a shift of 0 unless the mode allows it.  */
6980           || (num == 0 && shift->properties->allows_0 == 0)
6981           /* Reject a shift of 32 unless the mode allows it.  */
6982           || (num == 32 && shift->properties->allows_32 == 0)
6983           )
6984         {
6985           /* As a special case we allow a shift of zero for
6986              modes that do not support it to be recoded as an
6987              logical shift left of zero (ie nothing).  We warn
6988              about this though.  */
6989           if (num == 0)
6990             {
6991               as_warn (_("shift of 0 ignored."));
6992               shift = & shift_names[0];
6993               assert (shift->properties->index == SHIFT_LSL);
6994             }
6995           else
6996             {
6997               inst.error = _("invalid immediate shift");
6998               return FAIL;
6999             }
7000         }
7001
7002       /* Shifts of 32 are encoded as 0, for those shifts that
7003          support it.  */
7004       if (num == 32)
7005         num = 0;
7006
7007       inst.instruction |= (num << 7) | shift->properties->bit_field;
7008     }
7009   else
7010     {
7011       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
7012       inst.reloc.pc_rel = 0;
7013       inst.instruction |= shift->properties->bit_field;
7014     }
7015
7016   * str = p;
7017   return SUCCESS;
7018 }
7019
7020 /* Do those data_ops which can take a negative immediate constant
7021    by altering the instruction.  A bit of a hack really.
7022         MOV <-> MVN
7023         AND <-> BIC
7024         ADC <-> SBC
7025         by inverting the second operand, and
7026         ADD <-> SUB
7027         CMP <-> CMN
7028         by negating the second operand.  */
7029
7030 static int
7031 negate_data_op (instruction, value)
7032      unsigned long * instruction;
7033      unsigned long   value;
7034 {
7035   int op, new_inst;
7036   unsigned long negated, inverted;
7037
7038   negated = validate_immediate (-value);
7039   inverted = validate_immediate (~value);
7040
7041   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7042   switch (op)
7043     {
7044       /* First negates.  */
7045     case OPCODE_SUB:             /* ADD <-> SUB  */
7046       new_inst = OPCODE_ADD;
7047       value = negated;
7048       break;
7049
7050     case OPCODE_ADD:
7051       new_inst = OPCODE_SUB;
7052       value = negated;
7053       break;
7054
7055     case OPCODE_CMP:             /* CMP <-> CMN  */
7056       new_inst = OPCODE_CMN;
7057       value = negated;
7058       break;
7059
7060     case OPCODE_CMN:
7061       new_inst = OPCODE_CMP;
7062       value = negated;
7063       break;
7064
7065       /* Now Inverted ops.  */
7066     case OPCODE_MOV:             /* MOV <-> MVN  */
7067       new_inst = OPCODE_MVN;
7068       value = inverted;
7069       break;
7070
7071     case OPCODE_MVN:
7072       new_inst = OPCODE_MOV;
7073       value = inverted;
7074       break;
7075
7076     case OPCODE_AND:             /* AND <-> BIC  */
7077       new_inst = OPCODE_BIC;
7078       value = inverted;
7079       break;
7080
7081     case OPCODE_BIC:
7082       new_inst = OPCODE_AND;
7083       value = inverted;
7084       break;
7085
7086     case OPCODE_ADC:              /* ADC <-> SBC  */
7087       new_inst = OPCODE_SBC;
7088       value = inverted;
7089       break;
7090
7091     case OPCODE_SBC:
7092       new_inst = OPCODE_ADC;
7093       value = inverted;
7094       break;
7095
7096       /* We cannot do anything.  */
7097     default:
7098       return FAIL;
7099     }
7100
7101   if (value == (unsigned) FAIL)
7102     return FAIL;
7103
7104   *instruction &= OPCODE_MASK;
7105   *instruction |= new_inst << DATA_OP_SHIFT;
7106   return value;
7107 }
7108
7109 static int
7110 data_op2 (str)
7111      char ** str;
7112 {
7113   int value;
7114   expressionS expr;
7115
7116   skip_whitespace (* str);
7117
7118   if (reg_required_here (str, 0) != FAIL)
7119     {
7120       if (skip_past_comma (str) == SUCCESS)
7121         /* Shift operation on register.  */
7122         return decode_shift (str, NO_SHIFT_RESTRICT);
7123
7124       return SUCCESS;
7125     }
7126   else
7127     {
7128       /* Immediate expression.  */
7129       if (is_immediate_prefix (**str))
7130         {
7131           (*str)++;
7132           inst.error = NULL;
7133
7134           if (my_get_expression (&inst.reloc.exp, str))
7135             return FAIL;
7136
7137           if (inst.reloc.exp.X_add_symbol)
7138             {
7139               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7140               inst.reloc.pc_rel = 0;
7141             }
7142           else
7143             {
7144               if (skip_past_comma (str) == SUCCESS)
7145                 {
7146                   /* #x, y -- ie explicit rotation by Y.  */
7147                   if (my_get_expression (&expr, str))
7148                     return FAIL;
7149
7150                   if (expr.X_op != O_constant)
7151                     {
7152                       inst.error = _("constant expression expected");
7153                       return FAIL;
7154                     }
7155
7156                   /* Rotate must be a multiple of 2.  */
7157                   if (((unsigned) expr.X_add_number) > 30
7158                       || (expr.X_add_number & 1) != 0
7159                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7160                     {
7161                       inst.error = _("invalid constant");
7162                       return FAIL;
7163                     }
7164                   inst.instruction |= INST_IMMEDIATE;
7165                   inst.instruction |= inst.reloc.exp.X_add_number;
7166                   inst.instruction |= expr.X_add_number << 7;
7167                   return SUCCESS;
7168                 }
7169
7170               /* Implicit rotation, select a suitable one.  */
7171               value = validate_immediate (inst.reloc.exp.X_add_number);
7172
7173               if (value == FAIL)
7174                 {
7175                   /* Can't be done.  Perhaps the code reads something like
7176                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7177                   if ((value = negate_data_op (&inst.instruction,
7178                                                inst.reloc.exp.X_add_number))
7179                       == FAIL)
7180                     {
7181                       inst.error = _("invalid constant");
7182                       return FAIL;
7183                     }
7184                 }
7185
7186               inst.instruction |= value;
7187             }
7188
7189           inst.instruction |= INST_IMMEDIATE;
7190           return SUCCESS;
7191         }
7192
7193       (*str)++;
7194       inst.error = _("register or shift expression expected");
7195       return FAIL;
7196     }
7197 }
7198
7199 static int
7200 fp_op2 (str)
7201      char ** str;
7202 {
7203   skip_whitespace (* str);
7204
7205   if (fp_reg_required_here (str, 0) != FAIL)
7206     return SUCCESS;
7207   else
7208     {
7209       /* Immediate expression.  */
7210       if (*((*str)++) == '#')
7211         {
7212           int i;
7213
7214           inst.error = NULL;
7215
7216           skip_whitespace (* str);
7217
7218           /* First try and match exact strings, this is to guarantee
7219              that some formats will work even for cross assembly.  */
7220
7221           for (i = 0; fp_const[i]; i++)
7222             {
7223               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7224                 {
7225                   char *start = *str;
7226
7227                   *str += strlen (fp_const[i]);
7228                   if (is_end_of_line[(unsigned char) **str])
7229                     {
7230                       inst.instruction |= i + 8;
7231                       return SUCCESS;
7232                     }
7233                   *str = start;
7234                 }
7235             }
7236
7237           /* Just because we didn't get a match doesn't mean that the
7238              constant isn't valid, just that it is in a format that we
7239              don't automatically recognize.  Try parsing it with
7240              the standard expression routines.  */
7241           if ((i = my_get_float_expression (str)) >= 0)
7242             {
7243               inst.instruction |= i + 8;
7244               return SUCCESS;
7245             }
7246
7247           inst.error = _("invalid floating point immediate expression");
7248           return FAIL;
7249         }
7250       inst.error =
7251         _("floating point register or immediate expression expected");
7252       return FAIL;
7253     }
7254 }
7255
7256 static void
7257 do_arit (str)
7258      char * str;
7259 {
7260   skip_whitespace (str);
7261
7262   if (reg_required_here (&str, 12) == FAIL
7263       || skip_past_comma (&str) == FAIL
7264       || reg_required_here (&str, 16) == FAIL
7265       || skip_past_comma (&str) == FAIL
7266       || data_op2 (&str) == FAIL)
7267     {
7268       if (!inst.error)
7269         inst.error = BAD_ARGS;
7270       return;
7271     }
7272
7273   end_of_line (str);
7274 }
7275
7276 static void
7277 do_adr (str)
7278      char * str;
7279 {
7280   /* This is a pseudo-op of the form "adr rd, label" to be converted
7281      into a relative address of the form "add rd, pc, #label-.-8".  */
7282   skip_whitespace (str);
7283
7284   if (reg_required_here (&str, 12) == FAIL
7285       || skip_past_comma (&str) == FAIL
7286       || my_get_expression (&inst.reloc.exp, &str))
7287     {
7288       if (!inst.error)
7289         inst.error = BAD_ARGS;
7290       return;
7291     }
7292
7293   /* Frag hacking will turn this into a sub instruction if the offset turns
7294      out to be negative.  */
7295   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7296 #ifndef TE_WINCE
7297   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7298 #endif
7299   inst.reloc.pc_rel = 1;
7300
7301   end_of_line (str);
7302 }
7303
7304 static void
7305 do_adrl (str)
7306      char * str;
7307 {
7308   /* This is a pseudo-op of the form "adrl rd, label" to be converted
7309      into a relative address of the form:
7310      add rd, pc, #low(label-.-8)"
7311      add rd, rd, #high(label-.-8)"  */
7312
7313   skip_whitespace (str);
7314
7315   if (reg_required_here (&str, 12) == FAIL
7316       || skip_past_comma (&str) == FAIL
7317       || my_get_expression (&inst.reloc.exp, &str))
7318     {
7319       if (!inst.error)
7320         inst.error = BAD_ARGS;
7321
7322       return;
7323     }
7324
7325   end_of_line (str);
7326   /* Frag hacking will turn this into a sub instruction if the offset turns
7327      out to be negative.  */
7328   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7329 #ifndef TE_WINCE  
7330   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7331 #endif
7332   inst.reloc.pc_rel            = 1;
7333   inst.size                    = INSN_SIZE * 2;
7334 }
7335
7336 static void
7337 do_cmp (str)
7338      char * str;
7339 {
7340   skip_whitespace (str);
7341
7342   if (reg_required_here (&str, 16) == FAIL)
7343     {
7344       if (!inst.error)
7345         inst.error = BAD_ARGS;
7346       return;
7347     }
7348
7349   if (skip_past_comma (&str) == FAIL
7350       || data_op2 (&str) == FAIL)
7351     {
7352       if (!inst.error)
7353         inst.error = BAD_ARGS;
7354       return;
7355     }
7356
7357   end_of_line (str);
7358 }
7359
7360 static void
7361 do_mov (str)
7362      char * str;
7363 {
7364   skip_whitespace (str);
7365
7366   if (reg_required_here (&str, 12) == FAIL)
7367     {
7368       if (!inst.error)
7369         inst.error = BAD_ARGS;
7370       return;
7371     }
7372
7373   if (skip_past_comma (&str) == FAIL
7374       || data_op2 (&str) == FAIL)
7375     {
7376       if (!inst.error)
7377         inst.error = BAD_ARGS;
7378       return;
7379     }
7380
7381   end_of_line (str);
7382 }
7383
7384 static int
7385 ldst_extend (str)
7386      char ** str;
7387 {
7388   int add = INDEX_UP;
7389
7390   switch (**str)
7391     {
7392     case '#':
7393     case '$':
7394       (*str)++;
7395       if (my_get_expression (& inst.reloc.exp, str))
7396         return FAIL;
7397
7398       if (inst.reloc.exp.X_op == O_constant)
7399         {
7400           int value = inst.reloc.exp.X_add_number;
7401
7402           if (value < -4095 || value > 4095)
7403             {
7404               inst.error = _("address offset too large");
7405               return FAIL;
7406             }
7407
7408           if (value < 0)
7409             {
7410               value = -value;
7411               add = 0;
7412             }
7413
7414           inst.instruction |= add | value;
7415         }
7416       else
7417         {
7418           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7419           inst.reloc.pc_rel = 0;
7420         }
7421       return SUCCESS;
7422
7423     case '-':
7424       add = 0;
7425       /* Fall through.  */
7426
7427     case '+':
7428       (*str)++;
7429       /* Fall through.  */
7430
7431     default:
7432       if (reg_required_here (str, 0) == FAIL)
7433         return FAIL;
7434
7435       inst.instruction |= add | OFFSET_REG;
7436       if (skip_past_comma (str) == SUCCESS)
7437         return decode_shift (str, SHIFT_IMMEDIATE);
7438
7439       return SUCCESS;
7440     }
7441 }
7442
7443 static void
7444 do_ldst (str)
7445      char *        str;
7446 {
7447   int pre_inc = 0;
7448   int conflict_reg;
7449   int value;
7450
7451   skip_whitespace (str);
7452
7453   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7454     {
7455       if (!inst.error)
7456         inst.error = BAD_ARGS;
7457       return;
7458     }
7459
7460   if (skip_past_comma (&str) == FAIL)
7461     {
7462       inst.error = _("address expected");
7463       return;
7464     }
7465
7466   if (*str == '[')
7467     {
7468       int reg;
7469
7470       str++;
7471
7472       skip_whitespace (str);
7473
7474       if ((reg = reg_required_here (&str, 16)) == FAIL)
7475         return;
7476
7477       /* Conflicts can occur on stores as well as loads.  */
7478       conflict_reg = (conflict_reg == reg);
7479
7480       skip_whitespace (str);
7481
7482       if (*str == ']')
7483         {
7484           str ++;
7485
7486           if (skip_past_comma (&str) == SUCCESS)
7487             {
7488               /* [Rn],... (post inc)  */
7489               if (ldst_extend (&str) == FAIL)
7490                 return;
7491               if (conflict_reg)
7492                 as_warn (_("%s register same as write-back base"),
7493                          ((inst.instruction & LOAD_BIT)
7494                           ? _("destination") : _("source")));
7495             }
7496           else
7497             {
7498               /* [Rn]  */
7499               skip_whitespace (str);
7500
7501               if (*str == '!')
7502                 {
7503                   if (conflict_reg)
7504                     as_warn (_("%s register same as write-back base"),
7505                              ((inst.instruction & LOAD_BIT)
7506                               ? _("destination") : _("source")));
7507                   str++;
7508                   inst.instruction |= WRITE_BACK;
7509                 }
7510
7511               inst.instruction |= INDEX_UP;
7512               pre_inc = 1;
7513             }
7514         }
7515       else
7516         {
7517           /* [Rn,...]  */
7518           if (skip_past_comma (&str) == FAIL)
7519             {
7520               inst.error = _("pre-indexed expression expected");
7521               return;
7522             }
7523
7524           pre_inc = 1;
7525           if (ldst_extend (&str) == FAIL)
7526             return;
7527
7528           skip_whitespace (str);
7529
7530           if (*str++ != ']')
7531             {
7532               inst.error = _("missing ]");
7533               return;
7534             }
7535
7536           skip_whitespace (str);
7537
7538           if (*str == '!')
7539             {
7540               if (conflict_reg)
7541                 as_warn (_("%s register same as write-back base"),
7542                          ((inst.instruction & LOAD_BIT)
7543                           ? _("destination") : _("source")));
7544               str++;
7545               inst.instruction |= WRITE_BACK;
7546             }
7547         }
7548     }
7549   else if (*str == '=')
7550     {
7551       if ((inst.instruction & LOAD_BIT) == 0)
7552         {
7553           inst.error = _("invalid pseudo operation");
7554           return;
7555         }
7556
7557       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7558       str++;
7559
7560       skip_whitespace (str);
7561
7562       if (my_get_expression (&inst.reloc.exp, &str))
7563         return;
7564
7565       if (inst.reloc.exp.X_op != O_constant
7566           && inst.reloc.exp.X_op != O_symbol)
7567         {
7568           inst.error = _("constant expression expected");
7569           return;
7570         }
7571
7572       if (inst.reloc.exp.X_op == O_constant)
7573         {
7574           value = validate_immediate (inst.reloc.exp.X_add_number);
7575
7576           if (value != FAIL)
7577             {
7578               /* This can be done with a mov instruction.  */
7579               inst.instruction &= LITERAL_MASK;
7580               inst.instruction |= (INST_IMMEDIATE
7581                                    | (OPCODE_MOV << DATA_OP_SHIFT));
7582               inst.instruction |= value & 0xfff;
7583               end_of_line (str);
7584               return;
7585             }
7586
7587           value = validate_immediate (~inst.reloc.exp.X_add_number);
7588
7589           if (value != FAIL)
7590             {
7591               /* This can be done with a mvn instruction.  */
7592               inst.instruction &= LITERAL_MASK;
7593               inst.instruction |= (INST_IMMEDIATE
7594                                    | (OPCODE_MVN << DATA_OP_SHIFT));
7595               inst.instruction |= value & 0xfff;
7596               end_of_line (str);
7597               return;
7598             }
7599         }
7600
7601       /* Insert into literal pool.  */
7602       if (add_to_lit_pool () == FAIL)
7603         {
7604           if (!inst.error)
7605             inst.error = _("literal pool insertion failed");
7606           return;
7607         }
7608
7609       /* Change the instruction exp to point to the pool.  */
7610       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7611       inst.reloc.pc_rel = 1;
7612       inst.instruction |= (REG_PC << 16);
7613       pre_inc = 1;
7614     }
7615   else
7616     {
7617       if (my_get_expression (&inst.reloc.exp, &str))
7618         return;
7619
7620       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7621 #ifndef TE_WINCE
7622       /* PC rel adjust.  */
7623       inst.reloc.exp.X_add_number -= 8;
7624 #endif
7625       inst.reloc.pc_rel = 1;
7626       inst.instruction |= (REG_PC << 16);
7627       pre_inc = 1;
7628     }
7629
7630   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7631   end_of_line (str);
7632 }
7633
7634 static void
7635 do_ldstt (str)
7636      char *        str;
7637 {
7638   int conflict_reg;
7639
7640   skip_whitespace (str);
7641
7642   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7643     {
7644       if (!inst.error)
7645         inst.error = BAD_ARGS;
7646       return;
7647     }
7648
7649   if (skip_past_comma (& str) == FAIL)
7650     {
7651       inst.error = _("address expected");
7652       return;
7653     }
7654
7655   if (*str == '[')
7656     {
7657       int reg;
7658
7659       str++;
7660
7661       skip_whitespace (str);
7662
7663       if ((reg = reg_required_here (&str, 16)) == FAIL)
7664         return;
7665
7666       /* ldrt/strt always use post-indexed addressing, so if the base is
7667          the same as Rd, we warn.  */
7668       if (conflict_reg == reg)
7669         as_warn (_("%s register same as write-back base"),
7670                  ((inst.instruction & LOAD_BIT)
7671                   ? _("destination") : _("source")));
7672
7673       skip_whitespace (str);
7674
7675       if (*str == ']')
7676         {
7677           str ++;
7678
7679           if (skip_past_comma (&str) == SUCCESS)
7680             {
7681               /* [Rn],... (post inc)  */
7682               if (ldst_extend (&str) == FAIL)
7683                 return;
7684             }
7685           else
7686             {
7687               /* [Rn]  */
7688               skip_whitespace (str);
7689
7690               /* Skip a write-back '!'.  */
7691               if (*str == '!')
7692                 str++;
7693
7694               inst.instruction |= INDEX_UP;
7695             }
7696         }
7697       else
7698         {
7699           inst.error = _("post-indexed expression expected");
7700           return;
7701         }
7702     }
7703   else
7704     {
7705       inst.error = _("post-indexed expression expected");
7706       return;
7707     }
7708
7709   end_of_line (str);
7710 }
7711
7712 static int
7713 ldst_extend_v4 (str)
7714      char ** str;
7715 {
7716   int add = INDEX_UP;
7717
7718   switch (**str)
7719     {
7720     case '#':
7721     case '$':
7722       (*str)++;
7723       if (my_get_expression (& inst.reloc.exp, str))
7724         return FAIL;
7725
7726       if (inst.reloc.exp.X_op == O_constant)
7727         {
7728           int value = inst.reloc.exp.X_add_number;
7729
7730           if (value < -255 || value > 255)
7731             {
7732               inst.error = _("address offset too large");
7733               return FAIL;
7734             }
7735
7736           if (value < 0)
7737             {
7738               value = -value;
7739               add = 0;
7740             }
7741
7742           /* Halfword and signextension instructions have the
7743              immediate value split across bits 11..8 and bits 3..0.  */
7744           inst.instruction |= (add | HWOFFSET_IMM
7745                                | ((value >> 4) << 8) | (value & 0xF));
7746         }
7747       else
7748         {
7749           inst.instruction |= HWOFFSET_IMM;
7750           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7751           inst.reloc.pc_rel = 0;
7752         }
7753       return SUCCESS;
7754
7755     case '-':
7756       add = 0;
7757       /* Fall through.  */
7758
7759     case '+':
7760       (*str)++;
7761       /* Fall through.  */
7762
7763     default:
7764       if (reg_required_here (str, 0) == FAIL)
7765         return FAIL;
7766
7767       inst.instruction |= add;
7768       return SUCCESS;
7769     }
7770 }
7771
7772 /* Halfword and signed-byte load/store operations.  */
7773 static void
7774 do_ldstv4 (str)
7775      char *        str;
7776 {
7777   int pre_inc = 0;
7778   int conflict_reg;
7779   int value;
7780
7781   skip_whitespace (str);
7782
7783   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7784     {
7785       if (!inst.error)
7786         inst.error = BAD_ARGS;
7787       return;
7788     }
7789
7790   if (skip_past_comma (& str) == FAIL)
7791     {
7792       inst.error = _("address expected");
7793       return;
7794     }
7795
7796   if (*str == '[')
7797     {
7798       int reg;
7799
7800       str++;
7801
7802       skip_whitespace (str);
7803
7804       if ((reg = reg_required_here (&str, 16)) == FAIL)
7805         return;
7806
7807       /* Conflicts can occur on stores as well as loads.  */
7808       conflict_reg = (conflict_reg == reg);
7809
7810       skip_whitespace (str);
7811
7812       if (*str == ']')
7813         {
7814           str ++;
7815
7816           if (skip_past_comma (&str) == SUCCESS)
7817             {
7818               /* [Rn],... (post inc)  */
7819               if (ldst_extend_v4 (&str) == FAIL)
7820                 return;
7821               if (conflict_reg)
7822                 as_warn (_("%s register same as write-back base"),
7823                          ((inst.instruction & LOAD_BIT)
7824                           ? _("destination") : _("source")));
7825             }
7826           else
7827             {
7828               /* [Rn]  */
7829               inst.instruction |= HWOFFSET_IMM;
7830
7831               skip_whitespace (str);
7832
7833               if (*str == '!')
7834                 {
7835                   if (conflict_reg)
7836                     as_warn (_("%s register same as write-back base"),
7837                              ((inst.instruction & LOAD_BIT)
7838                               ? _("destination") : _("source")));
7839                   str++;
7840                   inst.instruction |= WRITE_BACK;
7841                 }
7842
7843               inst.instruction |= INDEX_UP;
7844               pre_inc = 1;
7845             }
7846         }
7847       else
7848         {
7849           /* [Rn,...]  */
7850           if (skip_past_comma (&str) == FAIL)
7851             {
7852               inst.error = _("pre-indexed expression expected");
7853               return;
7854             }
7855
7856           pre_inc = 1;
7857           if (ldst_extend_v4 (&str) == FAIL)
7858             return;
7859
7860           skip_whitespace (str);
7861
7862           if (*str++ != ']')
7863             {
7864               inst.error = _("missing ]");
7865               return;
7866             }
7867
7868           skip_whitespace (str);
7869
7870           if (*str == '!')
7871             {
7872               if (conflict_reg)
7873                 as_warn (_("%s register same as write-back base"),
7874                          ((inst.instruction & LOAD_BIT)
7875                           ? _("destination") : _("source")));
7876               str++;
7877               inst.instruction |= WRITE_BACK;
7878             }
7879         }
7880     }
7881   else if (*str == '=')
7882     {
7883       if ((inst.instruction & LOAD_BIT) == 0)
7884         {
7885           inst.error = _("invalid pseudo operation");
7886           return;
7887         }
7888
7889       /* XXX Does this work correctly for half-word/byte ops?  */
7890       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7891       str++;
7892
7893       skip_whitespace (str);
7894
7895       if (my_get_expression (&inst.reloc.exp, &str))
7896         return;
7897
7898       if (inst.reloc.exp.X_op != O_constant
7899           && inst.reloc.exp.X_op != O_symbol)
7900         {
7901           inst.error = _("constant expression expected");
7902           return;
7903         }
7904
7905       if (inst.reloc.exp.X_op == O_constant)
7906         {
7907           value = validate_immediate (inst.reloc.exp.X_add_number);
7908
7909           if (value != FAIL)
7910             {
7911               /* This can be done with a mov instruction.  */
7912               inst.instruction &= LITERAL_MASK;
7913               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7914               inst.instruction |= value & 0xfff;
7915               end_of_line (str);
7916               return;
7917             }
7918
7919           value = validate_immediate (~ inst.reloc.exp.X_add_number);
7920
7921           if (value != FAIL)
7922             {
7923               /* This can be done with a mvn instruction.  */
7924               inst.instruction &= LITERAL_MASK;
7925               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7926               inst.instruction |= value & 0xfff;
7927               end_of_line (str);
7928               return;
7929             }
7930         }
7931
7932       /* Insert into literal pool.  */
7933       if (add_to_lit_pool () == FAIL)
7934         {
7935           if (!inst.error)
7936             inst.error = _("literal pool insertion failed");
7937           return;
7938         }
7939
7940       /* Change the instruction exp to point to the pool.  */
7941       inst.instruction |= HWOFFSET_IMM;
7942       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7943       inst.reloc.pc_rel = 1;
7944       inst.instruction |= (REG_PC << 16);
7945       pre_inc = 1;
7946     }
7947   else
7948     {
7949       if (my_get_expression (&inst.reloc.exp, &str))
7950         return;
7951
7952       inst.instruction |= HWOFFSET_IMM;
7953       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7954 #ifndef TE_WINCE
7955       /* PC rel adjust.  */
7956       inst.reloc.exp.X_add_number -= 8;
7957 #endif
7958       inst.reloc.pc_rel = 1;
7959       inst.instruction |= (REG_PC << 16);
7960       pre_inc = 1;
7961     }
7962
7963   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7964   end_of_line (str);
7965 }
7966
7967 static long
7968 reg_list (strp)
7969      char ** strp;
7970 {
7971   char * str = * strp;
7972   long   range = 0;
7973   int    another_range;
7974
7975   /* We come back here if we get ranges concatenated by '+' or '|'.  */
7976   do
7977     {
7978       another_range = 0;
7979
7980       if (*str == '{')
7981         {
7982           int in_range = 0;
7983           int cur_reg = -1;
7984
7985           str++;
7986           do
7987             {
7988               int reg;
7989
7990               skip_whitespace (str);
7991
7992               if ((reg = reg_required_here (& str, -1)) == FAIL)
7993                 return FAIL;
7994
7995               if (in_range)
7996                 {
7997                   int i;
7998
7999                   if (reg <= cur_reg)
8000                     {
8001                       inst.error = _("bad range in register list");
8002                       return FAIL;
8003                     }
8004
8005                   for (i = cur_reg + 1; i < reg; i++)
8006                     {
8007                       if (range & (1 << i))
8008                         as_tsktsk
8009                           (_("Warning: duplicated register (r%d) in register list"),
8010                            i);
8011                       else
8012                         range |= 1 << i;
8013                     }
8014                   in_range = 0;
8015                 }
8016
8017               if (range & (1 << reg))
8018                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8019                            reg);
8020               else if (reg <= cur_reg)
8021                 as_tsktsk (_("Warning: register range not in ascending order"));
8022
8023               range |= 1 << reg;
8024               cur_reg = reg;
8025             }
8026           while (skip_past_comma (&str) != FAIL
8027                  || (in_range = 1, *str++ == '-'));
8028           str--;
8029           skip_whitespace (str);
8030
8031           if (*str++ != '}')
8032             {
8033               inst.error = _("missing `}'");
8034               return FAIL;
8035             }
8036         }
8037       else
8038         {
8039           expressionS expr;
8040
8041           if (my_get_expression (&expr, &str))
8042             return FAIL;
8043
8044           if (expr.X_op == O_constant)
8045             {
8046               if (expr.X_add_number
8047                   != (expr.X_add_number & 0x0000ffff))
8048                 {
8049                   inst.error = _("invalid register mask");
8050                   return FAIL;
8051                 }
8052
8053               if ((range & expr.X_add_number) != 0)
8054                 {
8055                   int regno = range & expr.X_add_number;
8056
8057                   regno &= -regno;
8058                   regno = (1 << regno) - 1;
8059                   as_tsktsk
8060                     (_("Warning: duplicated register (r%d) in register list"),
8061                      regno);
8062                 }
8063
8064               range |= expr.X_add_number;
8065             }
8066           else
8067             {
8068               if (inst.reloc.type != 0)
8069                 {
8070                   inst.error = _("expression too complex");
8071                   return FAIL;
8072                 }
8073
8074               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8075               inst.reloc.type = BFD_RELOC_ARM_MULTI;
8076               inst.reloc.pc_rel = 0;
8077             }
8078         }
8079
8080       skip_whitespace (str);
8081
8082       if (*str == '|' || *str == '+')
8083         {
8084           str++;
8085           another_range = 1;
8086         }
8087     }
8088   while (another_range);
8089
8090   *strp = str;
8091   return range;
8092 }
8093
8094 static void
8095 do_ldmstm (str)
8096      char * str;
8097 {
8098   int base_reg;
8099   long range;
8100
8101   skip_whitespace (str);
8102
8103   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8104     return;
8105
8106   if (base_reg == REG_PC)
8107     {
8108       inst.error = _("r15 not allowed as base register");
8109       return;
8110     }
8111
8112   skip_whitespace (str);
8113
8114   if (*str == '!')
8115     {
8116       inst.instruction |= WRITE_BACK;
8117       str++;
8118     }
8119
8120   if (skip_past_comma (&str) == FAIL
8121       || (range = reg_list (&str)) == FAIL)
8122     {
8123       if (! inst.error)
8124         inst.error = BAD_ARGS;
8125       return;
8126     }
8127
8128   if (*str == '^')
8129     {
8130       str++;
8131       inst.instruction |= LDM_TYPE_2_OR_3;
8132     }
8133
8134   if (inst.instruction & WRITE_BACK)
8135     {
8136       /* Check for unpredictable uses of writeback.  */
8137       if (inst.instruction & LOAD_BIT)
8138         {
8139           /* Not allowed in LDM type 2.  */
8140           if ((inst.instruction & LDM_TYPE_2_OR_3)
8141               && ((range & (1 << REG_PC)) == 0))
8142             as_warn (_("writeback of base register is UNPREDICTABLE"));
8143           /* Only allowed if base reg not in list for other types.  */
8144           else if (range & (1 << base_reg))
8145             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8146         }
8147       else /* STM.  */
8148         {
8149           /* Not allowed for type 2.  */
8150           if (inst.instruction & LDM_TYPE_2_OR_3)
8151             as_warn (_("writeback of base register is UNPREDICTABLE"));
8152           /* Only allowed if base reg not in list, or first in list.  */
8153           else if ((range & (1 << base_reg))
8154                    && (range & ((1 << base_reg) - 1)))
8155             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8156         }
8157     }
8158
8159   inst.instruction |= range;
8160   end_of_line (str);
8161 }
8162
8163 static void
8164 do_swi (str)
8165      char * str;
8166 {
8167   skip_whitespace (str);
8168
8169   /* Allow optional leading '#'.  */
8170   if (is_immediate_prefix (*str))
8171     str++;
8172
8173   if (my_get_expression (& inst.reloc.exp, & str))
8174     return;
8175
8176   inst.reloc.type = BFD_RELOC_ARM_SWI;
8177   inst.reloc.pc_rel = 0;
8178   end_of_line (str);
8179 }
8180
8181 static void
8182 do_swap (str)
8183      char * str;
8184 {
8185   int reg;
8186
8187   skip_whitespace (str);
8188
8189   if ((reg = reg_required_here (&str, 12)) == FAIL)
8190     return;
8191
8192   if (reg == REG_PC)
8193     {
8194       inst.error = _("r15 not allowed in swap");
8195       return;
8196     }
8197
8198   if (skip_past_comma (&str) == FAIL
8199       || (reg = reg_required_here (&str, 0)) == FAIL)
8200     {
8201       if (!inst.error)
8202         inst.error = BAD_ARGS;
8203       return;
8204     }
8205
8206   if (reg == REG_PC)
8207     {
8208       inst.error = _("r15 not allowed in swap");
8209       return;
8210     }
8211
8212   if (skip_past_comma (&str) == FAIL
8213       || *str++ != '[')
8214     {
8215       inst.error = BAD_ARGS;
8216       return;
8217     }
8218
8219   skip_whitespace (str);
8220
8221   if ((reg = reg_required_here (&str, 16)) == FAIL)
8222     return;
8223
8224   if (reg == REG_PC)
8225     {
8226       inst.error = BAD_PC;
8227       return;
8228     }
8229
8230   skip_whitespace (str);
8231
8232   if (*str++ != ']')
8233     {
8234       inst.error = _("missing ]");
8235       return;
8236     }
8237
8238   end_of_line (str);
8239 }
8240
8241 static void
8242 do_branch (str)
8243      char * str;
8244 {
8245   if (my_get_expression (&inst.reloc.exp, &str))
8246     return;
8247
8248 #ifdef OBJ_ELF
8249   {
8250     char * save_in;
8251
8252     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8253        required for the instruction.  */
8254
8255     /* arm_parse_reloc () works on input_line_pointer.
8256        We actually want to parse the operands to the branch instruction
8257        passed in 'str'.  Save the input pointer and restore it later.  */
8258     save_in = input_line_pointer;
8259     input_line_pointer = str;
8260     if (inst.reloc.exp.X_op == O_symbol
8261         && *str == '('
8262         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8263       {
8264         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8265         inst.reloc.pc_rel = 0;
8266         /* Modify str to point to after parsed operands, otherwise
8267            end_of_line() will complain about the (PLT) left in str.  */
8268         str = input_line_pointer;
8269       }
8270     else
8271       {
8272         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8273         inst.reloc.pc_rel = 1;
8274       }
8275     input_line_pointer = save_in;
8276   }
8277 #else
8278   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8279   inst.reloc.pc_rel = 1;
8280 #endif /* OBJ_ELF  */
8281
8282   end_of_line (str);
8283 }
8284
8285 static void
8286 do_bx (str)
8287      char * str;
8288 {
8289   int reg;
8290
8291   skip_whitespace (str);
8292
8293   if ((reg = reg_required_here (&str, 0)) == FAIL)
8294     {
8295       inst.error = BAD_ARGS;
8296       return;
8297     }
8298
8299   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8300   if (reg == REG_PC)
8301     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8302
8303   end_of_line (str);
8304 }
8305
8306 static void
8307 do_cdp (str)
8308      char * str;
8309 {
8310   /* Co-processor data operation.
8311      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8312   skip_whitespace (str);
8313
8314   if (co_proc_number (&str) == FAIL)
8315     {
8316       if (!inst.error)
8317         inst.error = BAD_ARGS;
8318       return;
8319     }
8320
8321   if (skip_past_comma (&str) == FAIL
8322       || cp_opc_expr (&str, 20,4) == FAIL)
8323     {
8324       if (!inst.error)
8325         inst.error = BAD_ARGS;
8326       return;
8327     }
8328
8329   if (skip_past_comma (&str) == FAIL
8330       || cp_reg_required_here (&str, 12) == FAIL)
8331     {
8332       if (!inst.error)
8333         inst.error = BAD_ARGS;
8334       return;
8335     }
8336
8337   if (skip_past_comma (&str) == FAIL
8338       || cp_reg_required_here (&str, 16) == FAIL)
8339     {
8340       if (!inst.error)
8341         inst.error = BAD_ARGS;
8342       return;
8343     }
8344
8345   if (skip_past_comma (&str) == FAIL
8346       || cp_reg_required_here (&str, 0) == FAIL)
8347     {
8348       if (!inst.error)
8349         inst.error = BAD_ARGS;
8350       return;
8351     }
8352
8353   if (skip_past_comma (&str) == SUCCESS)
8354     {
8355       if (cp_opc_expr (&str, 5, 3) == FAIL)
8356         {
8357           if (!inst.error)
8358             inst.error = BAD_ARGS;
8359           return;
8360         }
8361     }
8362
8363   end_of_line (str);
8364 }
8365
8366 static void
8367 do_lstc (str)
8368      char * str;
8369 {
8370   /* Co-processor register load/store.
8371      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8372
8373   skip_whitespace (str);
8374
8375   if (co_proc_number (&str) == FAIL)
8376     {
8377       if (!inst.error)
8378         inst.error = BAD_ARGS;
8379       return;
8380     }
8381
8382   if (skip_past_comma (&str) == FAIL
8383       || cp_reg_required_here (&str, 12) == FAIL)
8384     {
8385       if (!inst.error)
8386         inst.error = BAD_ARGS;
8387       return;
8388     }
8389
8390   if (skip_past_comma (&str) == FAIL
8391       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8392     {
8393       if (! inst.error)
8394         inst.error = BAD_ARGS;
8395       return;
8396     }
8397
8398   end_of_line (str);
8399 }
8400
8401 static void
8402 do_co_reg (str)
8403      char * str;
8404 {
8405   /* Co-processor register transfer.
8406      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8407
8408   skip_whitespace (str);
8409
8410   if (co_proc_number (&str) == FAIL)
8411     {
8412       if (!inst.error)
8413         inst.error = BAD_ARGS;
8414       return;
8415     }
8416
8417   if (skip_past_comma (&str) == FAIL
8418       || cp_opc_expr (&str, 21, 3) == FAIL)
8419     {
8420       if (!inst.error)
8421         inst.error = BAD_ARGS;
8422       return;
8423     }
8424
8425   if (skip_past_comma (&str) == FAIL
8426       || reg_required_here (&str, 12) == FAIL)
8427     {
8428       if (!inst.error)
8429         inst.error = BAD_ARGS;
8430       return;
8431     }
8432
8433   if (skip_past_comma (&str) == FAIL
8434       || cp_reg_required_here (&str, 16) == FAIL)
8435     {
8436       if (!inst.error)
8437         inst.error = BAD_ARGS;
8438       return;
8439     }
8440
8441   if (skip_past_comma (&str) == FAIL
8442       || cp_reg_required_here (&str, 0) == FAIL)
8443     {
8444       if (!inst.error)
8445         inst.error = BAD_ARGS;
8446       return;
8447     }
8448
8449   if (skip_past_comma (&str) == SUCCESS)
8450     {
8451       if (cp_opc_expr (&str, 5, 3) == FAIL)
8452         {
8453           if (!inst.error)
8454             inst.error = BAD_ARGS;
8455           return;
8456         }
8457     }
8458
8459   end_of_line (str);
8460 }
8461
8462 static void
8463 do_fpa_ctrl (str)
8464      char * str;
8465 {
8466   /* FP control registers.
8467      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8468
8469   skip_whitespace (str);
8470
8471   if (reg_required_here (&str, 12) == FAIL)
8472     {
8473       if (!inst.error)
8474         inst.error = BAD_ARGS;
8475       return;
8476     }
8477
8478   end_of_line (str);
8479 }
8480
8481 static void
8482 do_fpa_ldst (str)
8483      char * str;
8484 {
8485   skip_whitespace (str);
8486
8487   if (fp_reg_required_here (&str, 12) == FAIL)
8488     {
8489       if (!inst.error)
8490         inst.error = BAD_ARGS;
8491       return;
8492     }
8493
8494   if (skip_past_comma (&str) == FAIL
8495       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8496     {
8497       if (!inst.error)
8498         inst.error = BAD_ARGS;
8499       return;
8500     }
8501
8502   end_of_line (str);
8503 }
8504
8505 static void
8506 do_fpa_ldmstm (str)
8507      char * str;
8508 {
8509   int num_regs;
8510
8511   skip_whitespace (str);
8512
8513   if (fp_reg_required_here (&str, 12) == FAIL)
8514     {
8515       if (! inst.error)
8516         inst.error = BAD_ARGS;
8517       return;
8518     }
8519
8520   /* Get Number of registers to transfer.  */
8521   if (skip_past_comma (&str) == FAIL
8522       || my_get_expression (&inst.reloc.exp, &str))
8523     {
8524       if (! inst.error)
8525         inst.error = _("constant expression expected");
8526       return;
8527     }
8528
8529   if (inst.reloc.exp.X_op != O_constant)
8530     {
8531       inst.error = _("constant value required for number of registers");
8532       return;
8533     }
8534
8535   num_regs = inst.reloc.exp.X_add_number;
8536
8537   if (num_regs < 1 || num_regs > 4)
8538     {
8539       inst.error = _("number of registers must be in the range [1:4]");
8540       return;
8541     }
8542
8543   switch (num_regs)
8544     {
8545     case 1:
8546       inst.instruction |= CP_T_X;
8547       break;
8548     case 2:
8549       inst.instruction |= CP_T_Y;
8550       break;
8551     case 3:
8552       inst.instruction |= CP_T_Y | CP_T_X;
8553       break;
8554     case 4:
8555       break;
8556     default:
8557       abort ();
8558     }
8559
8560   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8561     {
8562       int reg;
8563       int write_back;
8564       int offset;
8565
8566       /* The instruction specified "ea" or "fd", so we can only accept
8567          [Rn]{!}.  The instruction does not really support stacking or
8568          unstacking, so we have to emulate these by setting appropriate
8569          bits and offsets.  */
8570       if (skip_past_comma (&str) == FAIL
8571           || *str != '[')
8572         {
8573           if (! inst.error)
8574             inst.error = BAD_ARGS;
8575           return;
8576         }
8577
8578       str++;
8579       skip_whitespace (str);
8580
8581       if ((reg = reg_required_here (&str, 16)) == FAIL)
8582         return;
8583
8584       skip_whitespace (str);
8585
8586       if (*str != ']')
8587         {
8588           inst.error = BAD_ARGS;
8589           return;
8590         }
8591
8592       str++;
8593       if (*str == '!')
8594         {
8595           write_back = 1;
8596           str++;
8597           if (reg == REG_PC)
8598             {
8599               inst.error =
8600                 _("r15 not allowed as base register with write-back");
8601               return;
8602             }
8603         }
8604       else
8605         write_back = 0;
8606
8607       if (inst.instruction & CP_T_Pre)
8608         {
8609           /* Pre-decrement.  */
8610           offset = 3 * num_regs;
8611           if (write_back)
8612             inst.instruction |= CP_T_WB;
8613         }
8614       else
8615         {
8616           /* Post-increment.  */
8617           if (write_back)
8618             {
8619               inst.instruction |= CP_T_WB;
8620               offset = 3 * num_regs;
8621             }
8622           else
8623             {
8624               /* No write-back, so convert this into a standard pre-increment
8625                  instruction -- aesthetically more pleasing.  */
8626               inst.instruction |= CP_T_Pre | CP_T_UD;
8627               offset = 0;
8628             }
8629         }
8630
8631       inst.instruction |= offset;
8632     }
8633   else if (skip_past_comma (&str) == FAIL
8634            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8635     {
8636       if (! inst.error)
8637         inst.error = BAD_ARGS;
8638       return;
8639     }
8640
8641   end_of_line (str);
8642 }
8643
8644 static void
8645 do_fpa_dyadic (str)
8646      char * str;
8647 {
8648   skip_whitespace (str);
8649
8650   if (fp_reg_required_here (&str, 12) == FAIL)
8651     {
8652       if (! inst.error)
8653         inst.error = BAD_ARGS;
8654       return;
8655     }
8656
8657   if (skip_past_comma (&str) == FAIL
8658       || fp_reg_required_here (&str, 16) == FAIL)
8659     {
8660       if (! inst.error)
8661         inst.error = BAD_ARGS;
8662       return;
8663     }
8664
8665   if (skip_past_comma (&str) == FAIL
8666       || fp_op2 (&str) == FAIL)
8667     {
8668       if (! inst.error)
8669         inst.error = BAD_ARGS;
8670       return;
8671     }
8672
8673   end_of_line (str);
8674 }
8675
8676 static void
8677 do_fpa_monadic (str)
8678      char * str;
8679 {
8680   skip_whitespace (str);
8681
8682   if (fp_reg_required_here (&str, 12) == FAIL)
8683     {
8684       if (! inst.error)
8685         inst.error = BAD_ARGS;
8686       return;
8687     }
8688
8689   if (skip_past_comma (&str) == FAIL
8690       || fp_op2 (&str) == FAIL)
8691     {
8692       if (! inst.error)
8693         inst.error = BAD_ARGS;
8694       return;
8695     }
8696
8697   end_of_line (str);
8698 }
8699
8700 static void
8701 do_fpa_cmp (str)
8702      char * str;
8703 {
8704   skip_whitespace (str);
8705
8706   if (fp_reg_required_here (&str, 16) == FAIL)
8707     {
8708       if (! inst.error)
8709         inst.error = BAD_ARGS;
8710       return;
8711     }
8712
8713   if (skip_past_comma (&str) == FAIL
8714       || fp_op2 (&str) == FAIL)
8715     {
8716       if (! inst.error)
8717         inst.error = BAD_ARGS;
8718       return;
8719     }
8720
8721   end_of_line (str);
8722 }
8723
8724 static void
8725 do_fpa_from_reg (str)
8726      char * str;
8727 {
8728   skip_whitespace (str);
8729
8730   if (fp_reg_required_here (&str, 16) == FAIL)
8731     {
8732       if (! inst.error)
8733         inst.error = BAD_ARGS;
8734       return;
8735     }
8736
8737   if (skip_past_comma (&str) == FAIL
8738       || reg_required_here (&str, 12) == FAIL)
8739     {
8740       if (! inst.error)
8741         inst.error = BAD_ARGS;
8742       return;
8743     }
8744
8745   end_of_line (str);
8746 }
8747
8748 static void
8749 do_fpa_to_reg (str)
8750      char * str;
8751 {
8752   skip_whitespace (str);
8753
8754   if (reg_required_here (&str, 12) == FAIL)
8755     return;
8756
8757   if (skip_past_comma (&str) == FAIL
8758       || fp_reg_required_here (&str, 0) == FAIL)
8759     {
8760       if (! inst.error)
8761         inst.error = BAD_ARGS;
8762       return;
8763     }
8764
8765   end_of_line (str);
8766 }
8767
8768 static int
8769 vfp_sp_reg_required_here (str, pos)
8770      char **str;
8771      enum vfp_sp_reg_pos pos;
8772 {
8773   int    reg;
8774   char *start = *str;
8775
8776   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8777     {
8778       switch (pos)
8779         {
8780         case VFP_REG_Sd:
8781           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8782           break;
8783
8784         case VFP_REG_Sn:
8785           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8786           break;
8787
8788         case VFP_REG_Sm:
8789           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8790           break;
8791
8792         default:
8793           abort ();
8794         }
8795       return reg;
8796     }
8797
8798   /* In the few cases where we might be able to accept something else
8799      this error can be overridden.  */
8800   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8801
8802   /* Restore the start point.  */
8803   *str = start;
8804   return FAIL;
8805 }
8806
8807 static int
8808 vfp_dp_reg_required_here (str, pos)
8809      char **str;
8810      enum vfp_dp_reg_pos pos;
8811 {
8812   int   reg;
8813   char *start = *str;
8814
8815   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8816     {
8817       switch (pos)
8818         {
8819         case VFP_REG_Dd:
8820           inst.instruction |= reg << 12;
8821           break;
8822
8823         case VFP_REG_Dn:
8824           inst.instruction |= reg << 16;
8825           break;
8826
8827         case VFP_REG_Dm:
8828           inst.instruction |= reg << 0;
8829           break;
8830
8831         default:
8832           abort ();
8833         }
8834       return reg;
8835     }
8836
8837   /* In the few cases where we might be able to accept something else
8838      this error can be overridden.  */
8839   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8840
8841   /* Restore the start point.  */
8842   *str = start;
8843   return FAIL;
8844 }
8845
8846 static void
8847 do_vfp_sp_monadic (str)
8848      char *str;
8849 {
8850   skip_whitespace (str);
8851
8852   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8853     return;
8854
8855   if (skip_past_comma (&str) == FAIL
8856       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8857     {
8858       if (! inst.error)
8859         inst.error = BAD_ARGS;
8860       return;
8861     }
8862
8863   end_of_line (str);
8864 }
8865
8866 static void
8867 do_vfp_dp_monadic (str)
8868      char *str;
8869 {
8870   skip_whitespace (str);
8871
8872   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8873     return;
8874
8875   if (skip_past_comma (&str) == FAIL
8876       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8877     {
8878       if (! inst.error)
8879         inst.error = BAD_ARGS;
8880       return;
8881     }
8882
8883   end_of_line (str);
8884 }
8885
8886 static void
8887 do_vfp_sp_dyadic (str)
8888      char *str;
8889 {
8890   skip_whitespace (str);
8891
8892   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8893     return;
8894
8895   if (skip_past_comma (&str) == FAIL
8896       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8897       || skip_past_comma (&str) == FAIL
8898       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8899     {
8900       if (! inst.error)
8901         inst.error = BAD_ARGS;
8902       return;
8903     }
8904
8905   end_of_line (str);
8906 }
8907
8908 static void
8909 do_vfp_dp_dyadic (str)
8910      char *str;
8911 {
8912   skip_whitespace (str);
8913
8914   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8915     return;
8916
8917   if (skip_past_comma (&str) == FAIL
8918       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8919       || skip_past_comma (&str) == FAIL
8920       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8921     {
8922       if (! inst.error)
8923         inst.error = BAD_ARGS;
8924       return;
8925     }
8926
8927   end_of_line (str);
8928 }
8929
8930 static void
8931 do_vfp_reg_from_sp (str)
8932      char *str;
8933 {
8934   skip_whitespace (str);
8935
8936   if (reg_required_here (&str, 12) == FAIL)
8937     return;
8938
8939   if (skip_past_comma (&str) == FAIL
8940       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8941     {
8942       if (! inst.error)
8943         inst.error = BAD_ARGS;
8944       return;
8945     }
8946
8947   end_of_line (str);
8948 }
8949
8950 static void
8951 do_vfp_reg2_from_sp2 (str)
8952      char *str;
8953 {
8954   skip_whitespace (str);
8955
8956   if (reg_required_here (&str, 12) == FAIL
8957       || skip_past_comma (&str) == FAIL
8958       || reg_required_here (&str, 16) == FAIL
8959       || skip_past_comma (&str) == FAIL)
8960     {
8961       if (! inst.error)
8962         inst.error = BAD_ARGS;
8963       return;
8964     }
8965
8966   /* We require exactly two consecutive SP registers.  */
8967   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8968     {
8969       if (! inst.error)
8970         inst.error = _("only two consecutive VFP SP registers allowed here");
8971     }
8972
8973   end_of_line (str);
8974 }
8975
8976 static void
8977 do_vfp_sp_from_reg (str)
8978      char *str;
8979 {
8980   skip_whitespace (str);
8981
8982   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8983     return;
8984
8985   if (skip_past_comma (&str) == FAIL
8986       || reg_required_here (&str, 12) == FAIL)
8987     {
8988       if (! inst.error)
8989         inst.error = BAD_ARGS;
8990       return;
8991     }
8992
8993   end_of_line (str);
8994 }
8995
8996 static void
8997 do_vfp_sp2_from_reg2 (str)
8998      char *str;
8999 {
9000   skip_whitespace (str);
9001
9002   /* We require exactly two consecutive SP registers.  */
9003   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
9004     {
9005       if (! inst.error)
9006         inst.error = _("only two consecutive VFP SP registers allowed here");
9007     }
9008
9009   if (skip_past_comma (&str) == FAIL
9010       || reg_required_here (&str, 12) == FAIL
9011       || skip_past_comma (&str) == FAIL
9012       || reg_required_here (&str, 16) == FAIL)
9013     {
9014       if (! inst.error)
9015         inst.error = BAD_ARGS;
9016       return;
9017     }
9018
9019   end_of_line (str);
9020 }
9021
9022 static void
9023 do_vfp_reg_from_dp (str)
9024      char *str;
9025 {
9026   skip_whitespace (str);
9027
9028   if (reg_required_here (&str, 12) == FAIL)
9029     return;
9030
9031   if (skip_past_comma (&str) == FAIL
9032       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9033     {
9034       if (! inst.error)
9035         inst.error = BAD_ARGS;
9036       return;
9037     }
9038
9039   end_of_line (str);
9040 }
9041
9042 static void
9043 do_vfp_reg2_from_dp (str)
9044      char *str;
9045 {
9046   skip_whitespace (str);
9047
9048   if (reg_required_here (&str, 12) == FAIL)
9049     return;
9050
9051   if (skip_past_comma (&str) == FAIL
9052       || reg_required_here (&str, 16) == FAIL
9053       || skip_past_comma (&str) == FAIL
9054       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9055     {
9056       if (! inst.error)
9057         inst.error = BAD_ARGS;
9058       return;
9059     }
9060
9061   end_of_line (str);
9062 }
9063
9064 static void
9065 do_vfp_dp_from_reg (str)
9066      char *str;
9067 {
9068   skip_whitespace (str);
9069
9070   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9071     return;
9072
9073   if (skip_past_comma (&str) == FAIL
9074       || reg_required_here (&str, 12) == FAIL)
9075     {
9076       if (! inst.error)
9077         inst.error = BAD_ARGS;
9078       return;
9079     }
9080
9081   end_of_line (str);
9082 }
9083
9084 static void
9085 do_vfp_dp_from_reg2 (str)
9086      char *str;
9087 {
9088   skip_whitespace (str);
9089
9090   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9091     return;
9092
9093   if (skip_past_comma (&str) == FAIL
9094       || reg_required_here (&str, 12) == FAIL
9095       || skip_past_comma (&str) == FAIL
9096       || reg_required_here (&str, 16) == FAIL)
9097     {
9098       if (! inst.error)
9099         inst.error = BAD_ARGS;
9100       return;
9101     }
9102
9103   end_of_line (str);
9104 }
9105
9106 static const struct vfp_reg *
9107 vfp_psr_parse (str)
9108      char **str;
9109 {
9110   char *start = *str;
9111   char  c;
9112   char *p;
9113   const struct vfp_reg *vreg;
9114
9115   p = start;
9116
9117   /* Find the end of the current token.  */
9118   do
9119     {
9120       c = *p++;
9121     }
9122   while (ISALPHA (c));
9123
9124   /* Mark it.  */
9125   *--p = 0;
9126
9127   for (vreg = vfp_regs + 0;
9128        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9129        vreg++)
9130     {
9131       if (strcmp (start, vreg->name) == 0)
9132         {
9133           *p = c;
9134           *str = p;
9135           return vreg;
9136         }
9137     }
9138
9139   *p = c;
9140   return NULL;
9141 }
9142
9143 static int
9144 vfp_psr_required_here (str)
9145      char **str;
9146 {
9147   char *start = *str;
9148   const struct vfp_reg *vreg;
9149
9150   vreg = vfp_psr_parse (str);
9151
9152   if (vreg)
9153     {
9154       inst.instruction |= vreg->regno;
9155       return SUCCESS;
9156     }
9157
9158   inst.error = _("VFP system register expected");
9159
9160   *str = start;
9161   return FAIL;
9162 }
9163
9164 static void
9165 do_vfp_reg_from_ctrl (str)
9166      char *str;
9167 {
9168   skip_whitespace (str);
9169
9170   if (reg_required_here (&str, 12) == FAIL)
9171     return;
9172
9173   if (skip_past_comma (&str) == FAIL
9174       || vfp_psr_required_here (&str) == FAIL)
9175     {
9176       if (! inst.error)
9177         inst.error = BAD_ARGS;
9178       return;
9179     }
9180
9181   end_of_line (str);
9182 }
9183
9184 static void
9185 do_vfp_ctrl_from_reg (str)
9186      char *str;
9187 {
9188   skip_whitespace (str);
9189
9190   if (vfp_psr_required_here (&str) == FAIL)
9191     return;
9192
9193   if (skip_past_comma (&str) == FAIL
9194       || reg_required_here (&str, 12) == FAIL)
9195     {
9196       if (! inst.error)
9197         inst.error = BAD_ARGS;
9198       return;
9199     }
9200
9201   end_of_line (str);
9202 }
9203
9204 static void
9205 do_vfp_sp_ldst (str)
9206      char *str;
9207 {
9208   skip_whitespace (str);
9209
9210   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9211     {
9212       if (!inst.error)
9213         inst.error = BAD_ARGS;
9214       return;
9215     }
9216
9217   if (skip_past_comma (&str) == FAIL
9218       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9219     {
9220       if (!inst.error)
9221         inst.error = BAD_ARGS;
9222       return;
9223     }
9224
9225   end_of_line (str);
9226 }
9227
9228 static void
9229 do_vfp_dp_ldst (str)
9230      char *str;
9231 {
9232   skip_whitespace (str);
9233
9234   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9235     {
9236       if (!inst.error)
9237         inst.error = BAD_ARGS;
9238       return;
9239     }
9240
9241   if (skip_past_comma (&str) == FAIL
9242       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9243     {
9244       if (!inst.error)
9245         inst.error = BAD_ARGS;
9246       return;
9247     }
9248
9249   end_of_line (str);
9250 }
9251
9252 /* Parse and encode a VFP SP register list, storing the initial
9253    register in position POS and returning the range as the result.  If
9254    the string is invalid return FAIL (an invalid range).  */
9255 static long
9256 vfp_sp_reg_list (str, pos)
9257      char **str;
9258      enum vfp_sp_reg_pos pos;
9259 {
9260   long range = 0;
9261   int base_reg = 0;
9262   int new_base;
9263   long base_bits = 0;
9264   int count = 0;
9265   long tempinst;
9266   unsigned long mask = 0;
9267   int warned = 0;
9268
9269   if (**str != '{')
9270     return FAIL;
9271
9272   (*str)++;
9273   skip_whitespace (*str);
9274
9275   tempinst = inst.instruction;
9276
9277   do
9278     {
9279       inst.instruction = 0;
9280
9281       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9282         return FAIL;
9283
9284       if (count == 0 || base_reg > new_base)
9285         {
9286           base_reg = new_base;
9287           base_bits = inst.instruction;
9288         }
9289
9290       if (mask & (1 << new_base))
9291         {
9292           inst.error = _("invalid register list");
9293           return FAIL;
9294         }
9295
9296       if ((mask >> new_base) != 0 && ! warned)
9297         {
9298           as_tsktsk (_("register list not in ascending order"));
9299           warned = 1;
9300         }
9301
9302       mask |= 1 << new_base;
9303       count++;
9304
9305       skip_whitespace (*str);
9306
9307       if (**str == '-') /* We have the start of a range expression */
9308         {
9309           int high_range;
9310
9311           (*str)++;
9312
9313           if ((high_range
9314                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9315               == FAIL)
9316             {
9317               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9318               return FAIL;
9319             }
9320
9321           if (high_range <= new_base)
9322             {
9323               inst.error = _("register range not in ascending order");
9324               return FAIL;
9325             }
9326
9327           for (new_base++; new_base <= high_range; new_base++)
9328             {
9329               if (mask & (1 << new_base))
9330                 {
9331                   inst.error = _("invalid register list");
9332                   return FAIL;
9333                 }
9334
9335               mask |= 1 << new_base;
9336               count++;
9337             }
9338         }
9339     }
9340   while (skip_past_comma (str) != FAIL);
9341
9342   if (**str != '}')
9343     {
9344       inst.error = _("invalid register list");
9345       return FAIL;
9346     }
9347
9348   (*str)++;
9349
9350   range = count;
9351
9352   /* Sanity check -- should have raised a parse error above.  */
9353   if (count == 0 || count > 32)
9354     abort ();
9355
9356   /* Final test -- the registers must be consecutive.  */
9357   while (count--)
9358     {
9359       if ((mask & (1 << base_reg++)) == 0)
9360         {
9361           inst.error = _("non-contiguous register range");
9362           return FAIL;
9363         }
9364     }
9365
9366   inst.instruction = tempinst | base_bits;
9367   return range;
9368 }
9369
9370 static long
9371 vfp_dp_reg_list (str)
9372      char **str;
9373 {
9374   long range = 0;
9375   int base_reg = 0;
9376   int new_base;
9377   int count = 0;
9378   long tempinst;
9379   unsigned long mask = 0;
9380   int warned = 0;
9381
9382   if (**str != '{')
9383     return FAIL;
9384
9385   (*str)++;
9386   skip_whitespace (*str);
9387
9388   tempinst = inst.instruction;
9389
9390   do
9391     {
9392       inst.instruction = 0;
9393
9394       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9395         return FAIL;
9396
9397       if (count == 0 || base_reg > new_base)
9398         {
9399           base_reg = new_base;
9400           range = inst.instruction;
9401         }
9402
9403       if (mask & (1 << new_base))
9404         {
9405           inst.error = _("invalid register list");
9406           return FAIL;
9407         }
9408
9409       if ((mask >> new_base) != 0 && ! warned)
9410         {
9411           as_tsktsk (_("register list not in ascending order"));
9412           warned = 1;
9413         }
9414
9415       mask |= 1 << new_base;
9416       count++;
9417
9418       skip_whitespace (*str);
9419
9420       if (**str == '-') /* We have the start of a range expression */
9421         {
9422           int high_range;
9423
9424           (*str)++;
9425
9426           if ((high_range
9427                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9428               == FAIL)
9429             {
9430               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9431               return FAIL;
9432             }
9433
9434           if (high_range <= new_base)
9435             {
9436               inst.error = _("register range not in ascending order");
9437               return FAIL;
9438             }
9439
9440           for (new_base++; new_base <= high_range; new_base++)
9441             {
9442               if (mask & (1 << new_base))
9443                 {
9444                   inst.error = _("invalid register list");
9445                   return FAIL;
9446                 }
9447
9448               mask |= 1 << new_base;
9449               count++;
9450             }
9451         }
9452     }
9453   while (skip_past_comma (str) != FAIL);
9454
9455   if (**str != '}')
9456     {
9457       inst.error = _("invalid register list");
9458       return FAIL;
9459     }
9460
9461   (*str)++;
9462
9463   range |= 2 * count;
9464
9465   /* Sanity check -- should have raised a parse error above.  */
9466   if (count == 0 || count > 16)
9467     abort ();
9468
9469   /* Final test -- the registers must be consecutive.  */
9470   while (count--)
9471     {
9472       if ((mask & (1 << base_reg++)) == 0)
9473         {
9474           inst.error = _("non-contiguous register range");
9475           return FAIL;
9476         }
9477     }
9478
9479   inst.instruction = tempinst;
9480   return range;
9481 }
9482
9483 static void
9484 vfp_sp_ldstm (str, ldstm_type)
9485      char *str;
9486      enum vfp_ldstm_type ldstm_type;
9487 {
9488   long range;
9489
9490   skip_whitespace (str);
9491
9492   if (reg_required_here (&str, 16) == FAIL)
9493     return;
9494
9495   skip_whitespace (str);
9496
9497   if (*str == '!')
9498     {
9499       inst.instruction |= WRITE_BACK;
9500       str++;
9501     }
9502   else if (ldstm_type != VFP_LDSTMIA)
9503     {
9504       inst.error = _("this addressing mode requires base-register writeback");
9505       return;
9506     }
9507
9508   if (skip_past_comma (&str) == FAIL
9509       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9510     {
9511       if (!inst.error)
9512         inst.error = BAD_ARGS;
9513       return;
9514     }
9515
9516   inst.instruction |= range;
9517   end_of_line (str);
9518 }
9519
9520 static void
9521 vfp_dp_ldstm (str, ldstm_type)
9522      char *str;
9523      enum vfp_ldstm_type ldstm_type;
9524 {
9525   long range;
9526
9527   skip_whitespace (str);
9528
9529   if (reg_required_here (&str, 16) == FAIL)
9530     return;
9531
9532   skip_whitespace (str);
9533
9534   if (*str == '!')
9535     {
9536       inst.instruction |= WRITE_BACK;
9537       str++;
9538     }
9539   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9540     {
9541       inst.error = _("this addressing mode requires base-register writeback");
9542       return;
9543     }
9544
9545   if (skip_past_comma (&str) == FAIL
9546       || (range = vfp_dp_reg_list (&str)) == FAIL)
9547     {
9548       if (!inst.error)
9549         inst.error = BAD_ARGS;
9550       return;
9551     }
9552
9553   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9554     range += 1;
9555
9556   inst.instruction |= range;
9557   end_of_line (str);
9558 }
9559
9560 static void
9561 do_vfp_sp_ldstmia (str)
9562      char *str;
9563 {
9564   vfp_sp_ldstm (str, VFP_LDSTMIA);
9565 }
9566
9567 static void
9568 do_vfp_sp_ldstmdb (str)
9569      char *str;
9570 {
9571   vfp_sp_ldstm (str, VFP_LDSTMDB);
9572 }
9573
9574 static void
9575 do_vfp_dp_ldstmia (str)
9576      char *str;
9577 {
9578   vfp_dp_ldstm (str, VFP_LDSTMIA);
9579 }
9580
9581 static void
9582 do_vfp_dp_ldstmdb (str)
9583      char *str;
9584 {
9585   vfp_dp_ldstm (str, VFP_LDSTMDB);
9586 }
9587
9588 static void
9589 do_vfp_xp_ldstmia (str)
9590      char *str;
9591 {
9592   vfp_dp_ldstm (str, VFP_LDSTMIAX);
9593 }
9594
9595 static void
9596 do_vfp_xp_ldstmdb (str)
9597      char *str;
9598 {
9599   vfp_dp_ldstm (str, VFP_LDSTMDBX);
9600 }
9601
9602 static void
9603 do_vfp_sp_compare_z (str)
9604      char *str;
9605 {
9606   skip_whitespace (str);
9607
9608   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9609     {
9610       if (!inst.error)
9611         inst.error = BAD_ARGS;
9612       return;
9613     }
9614
9615   end_of_line (str);
9616 }
9617
9618 static void
9619 do_vfp_dp_compare_z (str)
9620      char *str;
9621 {
9622   skip_whitespace (str);
9623
9624   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9625     {
9626       if (!inst.error)
9627         inst.error = BAD_ARGS;
9628       return;
9629     }
9630
9631   end_of_line (str);
9632 }
9633
9634 static void
9635 do_vfp_dp_sp_cvt (str)
9636      char *str;
9637 {
9638   skip_whitespace (str);
9639
9640   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9641     return;
9642
9643   if (skip_past_comma (&str) == FAIL
9644       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9645     {
9646       if (! inst.error)
9647         inst.error = BAD_ARGS;
9648       return;
9649     }
9650
9651   end_of_line (str);
9652 }
9653
9654 static void
9655 do_vfp_sp_dp_cvt (str)
9656      char *str;
9657 {
9658   skip_whitespace (str);
9659
9660   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9661     return;
9662
9663   if (skip_past_comma (&str) == FAIL
9664       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9665     {
9666       if (! inst.error)
9667         inst.error = BAD_ARGS;
9668       return;
9669     }
9670
9671   end_of_line (str);
9672 }
9673
9674 /* Thumb specific routines.  */
9675
9676 /* Parse and validate that a register is of the right form, this saves
9677    repeated checking of this information in many similar cases.
9678    Unlike the 32-bit case we do not insert the register into the opcode
9679    here, since the position is often unknown until the full instruction
9680    has been parsed.  */
9681
9682 static int
9683 thumb_reg (strp, hi_lo)
9684      char ** strp;
9685      int     hi_lo;
9686 {
9687   int reg;
9688
9689   if ((reg = reg_required_here (strp, -1)) == FAIL)
9690     return FAIL;
9691
9692   switch (hi_lo)
9693     {
9694     case THUMB_REG_LO:
9695       if (reg > 7)
9696         {
9697           inst.error = _("lo register required");
9698           return FAIL;
9699         }
9700       break;
9701
9702     case THUMB_REG_HI:
9703       if (reg < 8)
9704         {
9705           inst.error = _("hi register required");
9706           return FAIL;
9707         }
9708       break;
9709
9710     default:
9711       break;
9712     }
9713
9714   return reg;
9715 }
9716
9717 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9718    was SUB.  */
9719
9720 static void
9721 thumb_add_sub (str, subtract)
9722      char * str;
9723      int    subtract;
9724 {
9725   int Rd, Rs, Rn = FAIL;
9726
9727   skip_whitespace (str);
9728
9729   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9730       || skip_past_comma (&str) == FAIL)
9731     {
9732       if (! inst.error)
9733         inst.error = BAD_ARGS;
9734       return;
9735     }
9736
9737   if (is_immediate_prefix (*str))
9738     {
9739       Rs = Rd;
9740       str++;
9741       if (my_get_expression (&inst.reloc.exp, &str))
9742         return;
9743     }
9744   else
9745     {
9746       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9747         return;
9748
9749       if (skip_past_comma (&str) == FAIL)
9750         {
9751           /* Two operand format, shuffle the registers
9752              and pretend there are 3.  */
9753           Rn = Rs;
9754           Rs = Rd;
9755         }
9756       else if (is_immediate_prefix (*str))
9757         {
9758           str++;
9759           if (my_get_expression (&inst.reloc.exp, &str))
9760             return;
9761         }
9762       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9763         return;
9764     }
9765
9766   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9767      for the latter case, EXPR contains the immediate that was found.  */
9768   if (Rn != FAIL)
9769     {
9770       /* All register format.  */
9771       if (Rd > 7 || Rs > 7 || Rn > 7)
9772         {
9773           if (Rs != Rd)
9774             {
9775               inst.error = _("dest and source1 must be the same register");
9776               return;
9777             }
9778
9779           /* Can't do this for SUB.  */
9780           if (subtract)
9781             {
9782               inst.error = _("subtract valid only on lo regs");
9783               return;
9784             }
9785
9786           inst.instruction = (T_OPCODE_ADD_HI
9787                               | (Rd > 7 ? THUMB_H1 : 0)
9788                               | (Rn > 7 ? THUMB_H2 : 0));
9789           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9790         }
9791       else
9792         {
9793           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9794           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9795         }
9796     }
9797   else
9798     {
9799       /* Immediate expression, now things start to get nasty.  */
9800
9801       /* First deal with HI regs, only very restricted cases allowed:
9802          Adjusting SP, and using PC or SP to get an address.  */
9803       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9804           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9805         {
9806           inst.error = _("invalid Hi register with immediate");
9807           return;
9808         }
9809
9810       if (inst.reloc.exp.X_op != O_constant)
9811         {
9812           /* Value isn't known yet, all we can do is store all the fragments
9813              we know about in the instruction and let the reloc hacking
9814              work it all out.  */
9815           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9816           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9817         }
9818       else
9819         {
9820           int offset = inst.reloc.exp.X_add_number;
9821
9822           if (subtract)
9823             offset = - offset;
9824
9825           if (offset < 0)
9826             {
9827               offset = - offset;
9828               subtract = 1;
9829
9830               /* Quick check, in case offset is MIN_INT.  */
9831               if (offset < 0)
9832                 {
9833                   inst.error = _("immediate value out of range");
9834                   return;
9835                 }
9836             }
9837           /* Note - you cannot convert a subtract of 0 into an
9838              add of 0 because the carry flag is set differently.  */
9839           else if (offset > 0)
9840             subtract = 0;
9841
9842           if (Rd == REG_SP)
9843             {
9844               if (offset & ~0x1fc)
9845                 {
9846                   inst.error = _("invalid immediate value for stack adjust");
9847                   return;
9848                 }
9849               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9850               inst.instruction |= offset >> 2;
9851             }
9852           else if (Rs == REG_PC || Rs == REG_SP)
9853             {
9854               if (subtract
9855                   || (offset & ~0x3fc))
9856                 {
9857                   inst.error = _("invalid immediate for address calculation");
9858                   return;
9859                 }
9860               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9861                                   : T_OPCODE_ADD_SP);
9862               inst.instruction |= (Rd << 8) | (offset >> 2);
9863             }
9864           else if (Rs == Rd)
9865             {
9866               if (offset & ~0xff)
9867                 {
9868                   inst.error = _("immediate value out of range");
9869                   return;
9870                 }
9871               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9872               inst.instruction |= (Rd << 8) | offset;
9873             }
9874           else
9875             {
9876               if (offset & ~0x7)
9877                 {
9878                   inst.error = _("immediate value out of range");
9879                   return;
9880                 }
9881               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9882               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9883             }
9884         }
9885     }
9886
9887   end_of_line (str);
9888 }
9889
9890 static void
9891 thumb_shift (str, shift)
9892      char * str;
9893      int    shift;
9894 {
9895   int Rd, Rs, Rn = FAIL;
9896
9897   skip_whitespace (str);
9898
9899   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9900       || skip_past_comma (&str) == FAIL)
9901     {
9902       if (! inst.error)
9903         inst.error = BAD_ARGS;
9904       return;
9905     }
9906
9907   if (is_immediate_prefix (*str))
9908     {
9909       /* Two operand immediate format, set Rs to Rd.  */
9910       Rs = Rd;
9911       str ++;
9912       if (my_get_expression (&inst.reloc.exp, &str))
9913         return;
9914     }
9915   else
9916     {
9917       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9918         return;
9919
9920       if (skip_past_comma (&str) == FAIL)
9921         {
9922           /* Two operand format, shuffle the registers
9923              and pretend there are 3.  */
9924           Rn = Rs;
9925           Rs = Rd;
9926         }
9927       else if (is_immediate_prefix (*str))
9928         {
9929           str++;
9930           if (my_get_expression (&inst.reloc.exp, &str))
9931             return;
9932         }
9933       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9934         return;
9935     }
9936
9937   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9938      for the latter case, EXPR contains the immediate that was found.  */
9939
9940   if (Rn != FAIL)
9941     {
9942       if (Rs != Rd)
9943         {
9944           inst.error = _("source1 and dest must be same register");
9945           return;
9946         }
9947
9948       switch (shift)
9949         {
9950         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9951         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9952         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9953         }
9954
9955       inst.instruction |= Rd | (Rn << 3);
9956     }
9957   else
9958     {
9959       switch (shift)
9960         {
9961         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9962         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9963         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9964         }
9965
9966       if (inst.reloc.exp.X_op != O_constant)
9967         {
9968           /* Value isn't known yet, create a dummy reloc and let reloc
9969              hacking fix it up.  */
9970           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9971         }
9972       else
9973         {
9974           unsigned shift_value = inst.reloc.exp.X_add_number;
9975
9976           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9977             {
9978               inst.error = _("invalid immediate for shift");
9979               return;
9980             }
9981
9982           /* Shifts of zero are handled by converting to LSL.  */
9983           if (shift_value == 0)
9984             inst.instruction = T_OPCODE_LSL_I;
9985
9986           /* Shifts of 32 are encoded as a shift of zero.  */
9987           if (shift_value == 32)
9988             shift_value = 0;
9989
9990           inst.instruction |= shift_value << 6;
9991         }
9992
9993       inst.instruction |= Rd | (Rs << 3);
9994     }
9995
9996   end_of_line (str);
9997 }
9998
9999 static void
10000 thumb_mov_compare (str, move)
10001      char * str;
10002      int    move;
10003 {
10004   int Rd, Rs = FAIL;
10005
10006   skip_whitespace (str);
10007
10008   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
10009       || skip_past_comma (&str) == FAIL)
10010     {
10011       if (! inst.error)
10012         inst.error = BAD_ARGS;
10013       return;
10014     }
10015
10016   if (move != THUMB_CPY && is_immediate_prefix (*str))
10017     {
10018       str++;
10019       if (my_get_expression (&inst.reloc.exp, &str))
10020         return;
10021     }
10022   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10023     return;
10024
10025   if (Rs != FAIL)
10026     {
10027       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10028         {
10029           if (move == THUMB_MOVE)
10030             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10031                since a MOV instruction produces unpredictable results.  */
10032             inst.instruction = T_OPCODE_ADD_I3;
10033           else
10034             inst.instruction = T_OPCODE_CMP_LR;
10035           inst.instruction |= Rd | (Rs << 3);
10036         }
10037       else
10038         {
10039           if (move == THUMB_MOVE)
10040             inst.instruction = T_OPCODE_MOV_HR;
10041           else if (move != THUMB_CPY)
10042             inst.instruction = T_OPCODE_CMP_HR;
10043
10044           if (Rd > 7)
10045             inst.instruction |= THUMB_H1;
10046
10047           if (Rs > 7)
10048             inst.instruction |= THUMB_H2;
10049
10050           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10051         }
10052     }
10053   else
10054     {
10055       if (Rd > 7)
10056         {
10057           inst.error = _("only lo regs allowed with immediate");
10058           return;
10059         }
10060
10061       if (move == THUMB_MOVE)
10062         inst.instruction = T_OPCODE_MOV_I8;
10063       else
10064         inst.instruction = T_OPCODE_CMP_I8;
10065
10066       inst.instruction |= Rd << 8;
10067
10068       if (inst.reloc.exp.X_op != O_constant)
10069         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10070       else
10071         {
10072           unsigned value = inst.reloc.exp.X_add_number;
10073
10074           if (value > 255)
10075             {
10076               inst.error = _("invalid immediate");
10077               return;
10078             }
10079
10080           inst.instruction |= value;
10081         }
10082     }
10083
10084   end_of_line (str);
10085 }
10086
10087 static void
10088 thumb_load_store (str, load_store, size)
10089      char * str;
10090      int    load_store;
10091      int    size;
10092 {
10093   int Rd, Rb, Ro = FAIL;
10094
10095   skip_whitespace (str);
10096
10097   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10098       || skip_past_comma (&str) == FAIL)
10099     {
10100       if (! inst.error)
10101         inst.error = BAD_ARGS;
10102       return;
10103     }
10104
10105   if (*str == '[')
10106     {
10107       str++;
10108       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10109         return;
10110
10111       if (skip_past_comma (&str) != FAIL)
10112         {
10113           if (is_immediate_prefix (*str))
10114             {
10115               str++;
10116               if (my_get_expression (&inst.reloc.exp, &str))
10117                 return;
10118             }
10119           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10120             return;
10121         }
10122       else
10123         {
10124           inst.reloc.exp.X_op = O_constant;
10125           inst.reloc.exp.X_add_number = 0;
10126         }
10127
10128       if (*str != ']')
10129         {
10130           inst.error = _("expected ']'");
10131           return;
10132         }
10133       str++;
10134     }
10135   else if (*str == '=')
10136     {
10137       if (load_store != THUMB_LOAD)
10138         {
10139           inst.error = _("invalid pseudo operation");
10140           return;
10141         }
10142
10143       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10144       str++;
10145
10146       skip_whitespace (str);
10147
10148       if (my_get_expression (& inst.reloc.exp, & str))
10149         return;
10150
10151       end_of_line (str);
10152
10153       if (   inst.reloc.exp.X_op != O_constant
10154           && inst.reloc.exp.X_op != O_symbol)
10155         {
10156           inst.error = "Constant expression expected";
10157           return;
10158         }
10159
10160       if (inst.reloc.exp.X_op == O_constant
10161           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10162         {
10163           /* This can be done with a mov instruction.  */
10164
10165           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10166           inst.instruction |= inst.reloc.exp.X_add_number;
10167           return;
10168         }
10169
10170       /* Insert into literal pool.  */
10171       if (add_to_lit_pool () == FAIL)
10172         {
10173           if (!inst.error)
10174             inst.error = "literal pool insertion failed";
10175           return;
10176         }
10177
10178       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10179       inst.reloc.pc_rel = 1;
10180       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10181       /* Adjust ARM pipeline offset to Thumb.  */
10182       inst.reloc.exp.X_add_number += 4;
10183
10184       return;
10185     }
10186   else
10187     {
10188       if (my_get_expression (&inst.reloc.exp, &str))
10189         return;
10190
10191       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10192       inst.reloc.pc_rel = 1;
10193       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10194       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10195       end_of_line (str);
10196       return;
10197     }
10198
10199   if (Rb == REG_PC || Rb == REG_SP)
10200     {
10201       if (size != THUMB_WORD)
10202         {
10203           inst.error = _("byte or halfword not valid for base register");
10204           return;
10205         }
10206       else if (Rb == REG_PC && load_store != THUMB_LOAD)
10207         {
10208           inst.error = _("r15 based store not allowed");
10209           return;
10210         }
10211       else if (Ro != FAIL)
10212         {
10213           inst.error = _("invalid base register for register offset");
10214           return;
10215         }
10216
10217       if (Rb == REG_PC)
10218         inst.instruction = T_OPCODE_LDR_PC;
10219       else if (load_store == THUMB_LOAD)
10220         inst.instruction = T_OPCODE_LDR_SP;
10221       else
10222         inst.instruction = T_OPCODE_STR_SP;
10223
10224       inst.instruction |= Rd << 8;
10225       if (inst.reloc.exp.X_op == O_constant)
10226         {
10227           unsigned offset = inst.reloc.exp.X_add_number;
10228
10229           if (offset & ~0x3fc)
10230             {
10231               inst.error = _("invalid offset");
10232               return;
10233             }
10234
10235           inst.instruction |= offset >> 2;
10236         }
10237       else
10238         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10239     }
10240   else if (Rb > 7)
10241     {
10242       inst.error = _("invalid base register in load/store");
10243       return;
10244     }
10245   else if (Ro == FAIL)
10246     {
10247       /* Immediate offset.  */
10248       if (size == THUMB_WORD)
10249         inst.instruction = (load_store == THUMB_LOAD
10250                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10251       else if (size == THUMB_HALFWORD)
10252         inst.instruction = (load_store == THUMB_LOAD
10253                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10254       else
10255         inst.instruction = (load_store == THUMB_LOAD
10256                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10257
10258       inst.instruction |= Rd | (Rb << 3);
10259
10260       if (inst.reloc.exp.X_op == O_constant)
10261         {
10262           unsigned offset = inst.reloc.exp.X_add_number;
10263
10264           if (offset & ~(0x1f << size))
10265             {
10266               inst.error = _("invalid offset");
10267               return;
10268             }
10269           inst.instruction |= (offset >> size) << 6;
10270         }
10271       else
10272         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10273     }
10274   else
10275     {
10276       /* Register offset.  */
10277       if (size == THUMB_WORD)
10278         inst.instruction = (load_store == THUMB_LOAD
10279                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10280       else if (size == THUMB_HALFWORD)
10281         inst.instruction = (load_store == THUMB_LOAD
10282                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10283       else
10284         inst.instruction = (load_store == THUMB_LOAD
10285                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10286
10287       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10288     }
10289
10290   end_of_line (str);
10291 }
10292
10293 /* A register must be given at this point.
10294
10295    Shift is the place to put it in inst.instruction.
10296
10297    Restores input start point on err.
10298    Returns the reg#, or FAIL.  */
10299
10300 static int
10301 mav_reg_required_here (str, shift, regtype)
10302      char ** str;
10303      int shift;
10304      enum arm_reg_type regtype;
10305 {
10306   int   reg;
10307   char *start = *str;
10308
10309   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10310     {
10311       if (shift >= 0)
10312         inst.instruction |= reg << shift;
10313
10314       return reg;
10315     }
10316
10317   /* Restore the start point.  */
10318   *str = start;
10319
10320   /* In the few cases where we might be able to accept something else
10321      this error can be overridden.  */
10322   inst.error = _(all_reg_maps[regtype].expected);
10323
10324   return FAIL;
10325 }
10326
10327 /* Cirrus Maverick Instructions.  */
10328
10329 /* Wrapper functions.  */
10330
10331 static void
10332 do_mav_binops_1a (str)
10333      char * str;
10334 {
10335   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10336 }
10337
10338 static void
10339 do_mav_binops_1b (str)
10340      char * str;
10341 {
10342   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10343 }
10344
10345 static void
10346 do_mav_binops_1c (str)
10347      char * str;
10348 {
10349   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10350 }
10351
10352 static void
10353 do_mav_binops_1d (str)
10354      char * str;
10355 {
10356   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10357 }
10358
10359 static void
10360 do_mav_binops_1e (str)
10361      char * str;
10362 {
10363   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10364 }
10365
10366 static void
10367 do_mav_binops_1f (str)
10368      char * str;
10369 {
10370   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10371 }
10372
10373 static void
10374 do_mav_binops_1g (str)
10375      char * str;
10376 {
10377   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10378 }
10379
10380 static void
10381 do_mav_binops_1h (str)
10382      char * str;
10383 {
10384   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10385 }
10386
10387 static void
10388 do_mav_binops_1i (str)
10389      char * str;
10390 {
10391   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10392 }
10393
10394 static void
10395 do_mav_binops_1j (str)
10396      char * str;
10397 {
10398   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10399 }
10400
10401 static void
10402 do_mav_binops_1k (str)
10403      char * str;
10404 {
10405   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10406 }
10407
10408 static void
10409 do_mav_binops_1l (str)
10410      char * str;
10411 {
10412   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10413 }
10414
10415 static void
10416 do_mav_binops_1m (str)
10417      char * str;
10418 {
10419   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10420 }
10421
10422 static void
10423 do_mav_binops_1n (str)
10424      char * str;
10425 {
10426   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10427 }
10428
10429 static void
10430 do_mav_binops_1o (str)
10431      char * str;
10432 {
10433   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10434 }
10435
10436 static void
10437 do_mav_binops_2a (str)
10438      char * str;
10439 {
10440   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10441 }
10442
10443 static void
10444 do_mav_binops_2b (str)
10445      char * str;
10446 {
10447   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10448 }
10449
10450 static void
10451 do_mav_binops_2c (str)
10452      char * str;
10453 {
10454   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10455 }
10456
10457 static void
10458 do_mav_binops_3a (str)
10459      char * str;
10460 {
10461   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10462 }
10463
10464 static void
10465 do_mav_binops_3b (str)
10466      char * str;
10467 {
10468   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10469 }
10470
10471 static void
10472 do_mav_binops_3c (str)
10473      char * str;
10474 {
10475   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10476 }
10477
10478 static void
10479 do_mav_binops_3d (str)
10480      char * str;
10481 {
10482   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10483 }
10484
10485 static void
10486 do_mav_triple_4a (str)
10487      char * str;
10488 {
10489   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10490 }
10491
10492 static void
10493 do_mav_triple_4b (str)
10494      char * str;
10495 {
10496   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10497 }
10498
10499 static void
10500 do_mav_triple_5a (str)
10501      char * str;
10502 {
10503   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10504 }
10505
10506 static void
10507 do_mav_triple_5b (str)
10508      char * str;
10509 {
10510   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10511 }
10512
10513 static void
10514 do_mav_triple_5c (str)
10515      char * str;
10516 {
10517   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10518 }
10519
10520 static void
10521 do_mav_triple_5d (str)
10522      char * str;
10523 {
10524   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10525 }
10526
10527 static void
10528 do_mav_triple_5e (str)
10529      char * str;
10530 {
10531   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10532 }
10533
10534 static void
10535 do_mav_triple_5f (str)
10536      char * str;
10537 {
10538   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10539 }
10540
10541 static void
10542 do_mav_triple_5g (str)
10543      char * str;
10544 {
10545   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10546 }
10547
10548 static void
10549 do_mav_triple_5h (str)
10550      char * str;
10551 {
10552   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10553 }
10554
10555 static void
10556 do_mav_quad_6a (str)
10557      char * str;
10558 {
10559   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10560              REG_TYPE_MVFX);
10561 }
10562
10563 static void
10564 do_mav_quad_6b (str)
10565      char * str;
10566 {
10567   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10568              REG_TYPE_MVFX);
10569 }
10570
10571 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
10572 static void
10573 do_mav_dspsc_1 (str)
10574      char * str;
10575 {
10576   skip_whitespace (str);
10577
10578   /* cfmvsc32.  */
10579   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10580       || skip_past_comma (&str) == FAIL
10581       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10582     {
10583       if (!inst.error)
10584         inst.error = BAD_ARGS;
10585
10586       return;
10587     }
10588
10589   end_of_line (str);
10590 }
10591
10592 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
10593 static void
10594 do_mav_dspsc_2 (str)
10595      char * str;
10596 {
10597   skip_whitespace (str);
10598
10599   /* cfmv32sc.  */
10600   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10601       || skip_past_comma (&str) == FAIL
10602       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10603     {
10604       if (!inst.error)
10605         inst.error = BAD_ARGS;
10606
10607       return;
10608     }
10609
10610   end_of_line (str);
10611 }
10612
10613 static void
10614 do_mav_shift_1 (str)
10615      char * str;
10616 {
10617   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10618 }
10619
10620 static void
10621 do_mav_shift_2 (str)
10622      char * str;
10623 {
10624   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10625 }
10626
10627 static void
10628 do_mav_ldst_1 (str)
10629      char * str;
10630 {
10631   do_mav_ldst (str, REG_TYPE_MVF);
10632 }
10633
10634 static void
10635 do_mav_ldst_2 (str)
10636      char * str;
10637 {
10638   do_mav_ldst (str, REG_TYPE_MVD);
10639 }
10640
10641 static void
10642 do_mav_ldst_3 (str)
10643      char * str;
10644 {
10645   do_mav_ldst (str, REG_TYPE_MVFX);
10646 }
10647
10648 static void
10649 do_mav_ldst_4 (str)
10650      char * str;
10651 {
10652   do_mav_ldst (str, REG_TYPE_MVDX);
10653 }
10654
10655 /* Isnsn like "foo X,Y".  */
10656
10657 static void
10658 do_mav_binops (str, mode, reg0, reg1)
10659      char * str;
10660      int mode;
10661      enum arm_reg_type reg0;
10662      enum arm_reg_type reg1;
10663 {
10664   int shift0, shift1;
10665
10666   shift0 = mode & 0xff;
10667   shift1 = (mode >> 8) & 0xff;
10668
10669   skip_whitespace (str);
10670
10671   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10672       || skip_past_comma (&str) == FAIL
10673       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10674     {
10675       if (!inst.error)
10676         inst.error = BAD_ARGS;
10677     }
10678   else
10679     end_of_line (str);
10680 }
10681
10682 /* Isnsn like "foo X,Y,Z".  */
10683
10684 static void
10685 do_mav_triple (str, mode, reg0, reg1, reg2)
10686      char * str;
10687      int mode;
10688      enum arm_reg_type reg0;
10689      enum arm_reg_type reg1;
10690      enum arm_reg_type reg2;
10691 {
10692   int shift0, shift1, shift2;
10693
10694   shift0 = mode & 0xff;
10695   shift1 = (mode >> 8) & 0xff;
10696   shift2 = (mode >> 16) & 0xff;
10697
10698   skip_whitespace (str);
10699
10700   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10701       || skip_past_comma (&str) == FAIL
10702       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10703       || skip_past_comma (&str) == FAIL
10704       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10705     {
10706       if (!inst.error)
10707         inst.error = BAD_ARGS;
10708     }
10709   else
10710     end_of_line (str);
10711 }
10712
10713 /* Isnsn like "foo W,X,Y,Z".
10714     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10715
10716 static void
10717 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10718      char * str;
10719      int mode;
10720      enum arm_reg_type reg0;
10721      enum arm_reg_type reg1;
10722      enum arm_reg_type reg2;
10723      enum arm_reg_type reg3;
10724 {
10725   int shift0, shift1, shift2, shift3;
10726
10727   shift0= mode & 0xff;
10728   shift1 = (mode >> 8) & 0xff;
10729   shift2 = (mode >> 16) & 0xff;
10730   shift3 = (mode >> 24) & 0xff;
10731
10732   skip_whitespace (str);
10733
10734   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10735       || skip_past_comma (&str) == FAIL
10736       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10737       || skip_past_comma (&str) == FAIL
10738       || mav_reg_required_here (&str, shift2, reg2) == FAIL
10739       || skip_past_comma (&str) == FAIL
10740       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10741     {
10742       if (!inst.error)
10743         inst.error = BAD_ARGS;
10744     }
10745   else
10746     end_of_line (str);
10747 }
10748
10749 /* Maverick shift immediate instructions.
10750    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10751    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10752
10753 static void
10754 do_mav_shift (str, reg0, reg1)
10755      char * str;
10756      enum arm_reg_type reg0;
10757      enum arm_reg_type reg1;
10758 {
10759   int error;
10760   int imm, neg = 0;
10761
10762   skip_whitespace (str);
10763
10764   error = 0;
10765
10766   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10767       || skip_past_comma (&str) == FAIL
10768       || mav_reg_required_here (&str, 16, reg1) == FAIL
10769       || skip_past_comma  (&str) == FAIL)
10770     {
10771       if (!inst.error)
10772         inst.error = BAD_ARGS;
10773       return;
10774     }
10775
10776   /* Calculate the immediate operand.
10777      The operand is a 7bit signed number.  */
10778   skip_whitespace (str);
10779
10780   if (*str == '#')
10781     ++str;
10782
10783   if (!ISDIGIT (*str) && *str != '-')
10784     {
10785       inst.error = _("expecting immediate, 7bit operand");
10786       return;
10787     }
10788
10789   if (*str == '-')
10790     {
10791       neg = 1;
10792       ++str;
10793     }
10794
10795   for (imm = 0; *str && ISDIGIT (*str); ++str)
10796     imm = imm * 10 + *str - '0';
10797
10798   if (imm > 64)
10799     {
10800       inst.error = _("immediate out of range");
10801       return;
10802     }
10803
10804   /* Make negative imm's into 7bit signed numbers.  */
10805   if (neg)
10806     {
10807       imm = -imm;
10808       imm &= 0x0000007f;
10809     }
10810
10811   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10812      Bits 5-7 of the insn should have bits 4-6 of the immediate.
10813      Bit 4 should be 0.  */
10814   imm = (imm & 0xf) | ((imm & 0x70) << 1);
10815
10816   inst.instruction |= imm;
10817   end_of_line (str);
10818 }
10819
10820 static int
10821 mav_parse_offset (str, negative)
10822      char ** str;
10823      int *negative;
10824 {
10825   char * p = *str;
10826   int offset;
10827
10828   *negative = 0;
10829
10830   skip_whitespace (p);
10831
10832   if (*p == '#')
10833     ++p;
10834
10835   if (*p == '-')
10836     {
10837       *negative = 1;
10838       ++p;
10839     }
10840
10841   if (!ISDIGIT (*p))
10842     {
10843       inst.error = _("offset expected");
10844       return 0;
10845     }
10846
10847   for (offset = 0; *p && ISDIGIT (*p); ++p)
10848     offset = offset * 10 + *p - '0';
10849
10850   if (offset > 0xff)
10851     {
10852       inst.error = _("offset out of range");
10853       return 0;
10854     }
10855
10856   *str = p;
10857
10858   return *negative ? -offset : offset;
10859 }
10860
10861 /* Maverick load/store instructions.
10862   <insn><cond> CRd,[Rn,<offset>]{!}.
10863   <insn><cond> CRd,[Rn],<offset>.  */
10864
10865 static void
10866 do_mav_ldst (str, reg0)
10867      char * str;
10868      enum arm_reg_type reg0;
10869 {
10870   int offset, negative;
10871
10872   skip_whitespace (str);
10873
10874   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10875       || skip_past_comma (&str) == FAIL
10876       || *str++ != '['
10877       || reg_required_here (&str, 16) == FAIL)
10878     goto fail_ldst;
10879
10880   if (skip_past_comma (&str) == SUCCESS)
10881     {
10882       /* You are here: "<offset>]{!}".  */
10883       inst.instruction |= PRE_INDEX;
10884
10885       offset = mav_parse_offset (&str, &negative);
10886
10887       if (inst.error)
10888         return;
10889
10890       if (*str++ != ']')
10891         {
10892           inst.error = _("missing ]");
10893           return;
10894         }
10895
10896       if (*str == '!')
10897         {
10898           inst.instruction |= WRITE_BACK;
10899           ++str;
10900         }
10901     }
10902   else
10903     {
10904       /* You are here: "], <offset>".  */
10905       if (*str++ != ']')
10906         {
10907           inst.error = _("missing ]");
10908           return;
10909         }
10910
10911       if (skip_past_comma (&str) == FAIL
10912           || (offset = mav_parse_offset (&str, &negative), inst.error))
10913         goto fail_ldst;
10914
10915       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10916     }
10917
10918   if (negative)
10919     offset = -offset;
10920   else
10921     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10922
10923   inst.instruction |= offset >> 2;
10924   end_of_line (str);
10925   return;
10926
10927 fail_ldst:
10928   if (!inst.error)
10929      inst.error = BAD_ARGS;
10930 }
10931
10932 static void
10933 do_t_nop (str)
10934      char * str;
10935 {
10936   /* Do nothing.  */
10937   end_of_line (str);
10938 }
10939
10940 /* Handle the Format 4 instructions that do not have equivalents in other
10941    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10942    BIC and MVN.  */
10943
10944 static void
10945 do_t_arit (str)
10946      char * str;
10947 {
10948   int Rd, Rs, Rn;
10949
10950   skip_whitespace (str);
10951
10952   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10953       || skip_past_comma (&str) == FAIL
10954       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10955     {
10956       inst.error = BAD_ARGS;
10957       return;
10958     }
10959
10960   if (skip_past_comma (&str) != FAIL)
10961     {
10962       /* Three operand format not allowed for TST, CMN, NEG and MVN.
10963          (It isn't allowed for CMP either, but that isn't handled by this
10964          function.)  */
10965       if (inst.instruction == T_OPCODE_TST
10966           || inst.instruction == T_OPCODE_CMN
10967           || inst.instruction == T_OPCODE_NEG
10968           || inst.instruction == T_OPCODE_MVN)
10969         {
10970           inst.error = BAD_ARGS;
10971           return;
10972         }
10973
10974       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10975         return;
10976
10977       if (Rs != Rd)
10978         {
10979           inst.error = _("dest and source1 must be the same register");
10980           return;
10981         }
10982       Rs = Rn;
10983     }
10984
10985   if (inst.instruction == T_OPCODE_MUL
10986       && Rs == Rd)
10987     as_tsktsk (_("Rs and Rd must be different in MUL"));
10988
10989   inst.instruction |= Rd | (Rs << 3);
10990   end_of_line (str);
10991 }
10992
10993 static void
10994 do_t_add (str)
10995      char * str;
10996 {
10997   thumb_add_sub (str, 0);
10998 }
10999
11000 static void
11001 do_t_asr (str)
11002      char * str;
11003 {
11004   thumb_shift (str, THUMB_ASR);
11005 }
11006
11007 static void
11008 do_t_branch9 (str)
11009      char * str;
11010 {
11011   if (my_get_expression (&inst.reloc.exp, &str))
11012     return;
11013   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
11014   inst.reloc.pc_rel = 1;
11015   end_of_line (str);
11016 }
11017
11018 static void
11019 do_t_branch12 (str)
11020      char * str;
11021 {
11022   if (my_get_expression (&inst.reloc.exp, &str))
11023     return;
11024   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11025   inst.reloc.pc_rel = 1;
11026   end_of_line (str);
11027 }
11028
11029 /* Find the real, Thumb encoded start of a Thumb function.  */
11030
11031 static symbolS *
11032 find_real_start (symbolP)
11033      symbolS * symbolP;
11034 {
11035   char *       real_start;
11036   const char * name = S_GET_NAME (symbolP);
11037   symbolS *    new_target;
11038
11039   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11040 #define STUB_NAME ".real_start_of"
11041
11042   if (name == NULL)
11043     abort ();
11044
11045   /* Names that start with '.' are local labels, not function entry points.
11046      The compiler may generate BL instructions to these labels because it
11047      needs to perform a branch to a far away location.  */
11048   if (name[0] == '.')
11049     return symbolP;
11050
11051   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11052   sprintf (real_start, "%s%s", STUB_NAME, name);
11053
11054   new_target = symbol_find (real_start);
11055
11056   if (new_target == NULL)
11057     {
11058       as_warn ("Failed to find real start of function: %s\n", name);
11059       new_target = symbolP;
11060     }
11061
11062   free (real_start);
11063
11064   return new_target;
11065 }
11066
11067 static void
11068 do_t_branch23 (str)
11069      char * str;
11070 {
11071   if (my_get_expression (& inst.reloc.exp, & str))
11072     return;
11073
11074   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11075   inst.reloc.pc_rel = 1;
11076   end_of_line (str);
11077
11078   /* If the destination of the branch is a defined symbol which does not have
11079      the THUMB_FUNC attribute, then we must be calling a function which has
11080      the (interfacearm) attribute.  We look for the Thumb entry point to that
11081      function and change the branch to refer to that function instead.  */
11082   if (   inst.reloc.exp.X_op == O_symbol
11083       && inst.reloc.exp.X_add_symbol != NULL
11084       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11085       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11086     inst.reloc.exp.X_add_symbol =
11087       find_real_start (inst.reloc.exp.X_add_symbol);
11088 }
11089
11090 static void
11091 do_t_bx (str)
11092      char * str;
11093 {
11094   int reg;
11095
11096   skip_whitespace (str);
11097
11098   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11099     return;
11100
11101   /* This sets THUMB_H2 from the top bit of reg.  */
11102   inst.instruction |= reg << 3;
11103
11104   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11105      should cause the alignment to be checked once it is known.  This is
11106      because BX PC only works if the instruction is word aligned.  */
11107
11108   end_of_line (str);
11109 }
11110
11111 static void
11112 do_t_compare (str)
11113      char * str;
11114 {
11115   thumb_mov_compare (str, THUMB_COMPARE);
11116 }
11117
11118 static void
11119 do_t_ldmstm (str)
11120      char * str;
11121 {
11122   int Rb;
11123   long range;
11124
11125   skip_whitespace (str);
11126
11127   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11128     return;
11129
11130   if (*str != '!')
11131     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11132   else
11133     str++;
11134
11135   if (skip_past_comma (&str) == FAIL
11136       || (range = reg_list (&str)) == FAIL)
11137     {
11138       if (! inst.error)
11139         inst.error = BAD_ARGS;
11140       return;
11141     }
11142
11143   if (inst.reloc.type != BFD_RELOC_NONE)
11144     {
11145       /* This really doesn't seem worth it.  */
11146       inst.reloc.type = BFD_RELOC_NONE;
11147       inst.error = _("expression too complex");
11148       return;
11149     }
11150
11151   if (range & ~0xff)
11152     {
11153       inst.error = _("only lo-regs valid in load/store multiple");
11154       return;
11155     }
11156
11157   inst.instruction |= (Rb << 8) | range;
11158   end_of_line (str);
11159 }
11160
11161 static void
11162 do_t_ldr (str)
11163      char * str;
11164 {
11165   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11166 }
11167
11168 static void
11169 do_t_ldrb (str)
11170      char * str;
11171 {
11172   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11173 }
11174
11175 static void
11176 do_t_ldrh (str)
11177      char * str;
11178 {
11179   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11180 }
11181
11182 static void
11183 do_t_lds (str)
11184      char * str;
11185 {
11186   int Rd, Rb, Ro;
11187
11188   skip_whitespace (str);
11189
11190   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11191       || skip_past_comma (&str) == FAIL
11192       || *str++ != '['
11193       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11194       || skip_past_comma (&str) == FAIL
11195       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11196       || *str++ != ']')
11197     {
11198       if (! inst.error)
11199         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11200       return;
11201     }
11202
11203   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11204   end_of_line (str);
11205 }
11206
11207 static void
11208 do_t_lsl (str)
11209      char * str;
11210 {
11211   thumb_shift (str, THUMB_LSL);
11212 }
11213
11214 static void
11215 do_t_lsr (str)
11216      char * str;
11217 {
11218   thumb_shift (str, THUMB_LSR);
11219 }
11220
11221 static void
11222 do_t_mov (str)
11223      char * str;
11224 {
11225   thumb_mov_compare (str, THUMB_MOVE);
11226 }
11227
11228 static void
11229 do_t_push_pop (str)
11230      char * str;
11231 {
11232   long range;
11233
11234   skip_whitespace (str);
11235
11236   if ((range = reg_list (&str)) == FAIL)
11237     {
11238       if (! inst.error)
11239         inst.error = BAD_ARGS;
11240       return;
11241     }
11242
11243   if (inst.reloc.type != BFD_RELOC_NONE)
11244     {
11245       /* This really doesn't seem worth it.  */
11246       inst.reloc.type = BFD_RELOC_NONE;
11247       inst.error = _("expression too complex");
11248       return;
11249     }
11250
11251   if (range & ~0xff)
11252     {
11253       if ((inst.instruction == T_OPCODE_PUSH
11254            && (range & ~0xff) == 1 << REG_LR)
11255           || (inst.instruction == T_OPCODE_POP
11256               && (range & ~0xff) == 1 << REG_PC))
11257         {
11258           inst.instruction |= THUMB_PP_PC_LR;
11259           range &= 0xff;
11260         }
11261       else
11262         {
11263           inst.error = _("invalid register list to push/pop instruction");
11264           return;
11265         }
11266     }
11267
11268   inst.instruction |= range;
11269   end_of_line (str);
11270 }
11271
11272 static void
11273 do_t_str (str)
11274      char * str;
11275 {
11276   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11277 }
11278
11279 static void
11280 do_t_strb (str)
11281      char * str;
11282 {
11283   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11284 }
11285
11286 static void
11287 do_t_strh (str)
11288      char * str;
11289 {
11290   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11291 }
11292
11293 static void
11294 do_t_sub (str)
11295      char * str;
11296 {
11297   thumb_add_sub (str, 1);
11298 }
11299
11300 static void
11301 do_t_swi (str)
11302      char * str;
11303 {
11304   skip_whitespace (str);
11305
11306   if (my_get_expression (&inst.reloc.exp, &str))
11307     return;
11308
11309   inst.reloc.type = BFD_RELOC_ARM_SWI;
11310   end_of_line (str);
11311 }
11312
11313 static void
11314 do_t_adr (str)
11315      char * str;
11316 {
11317   int reg;
11318
11319   /* This is a pseudo-op of the form "adr rd, label" to be converted
11320      into a relative address of the form "add rd, pc, #label-.-4".  */
11321   skip_whitespace (str);
11322
11323   /* Store Rd in temporary location inside instruction.  */
11324   if ((reg = reg_required_here (&str, 4)) == FAIL
11325       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11326       || skip_past_comma (&str) == FAIL
11327       || my_get_expression (&inst.reloc.exp, &str))
11328     {
11329       if (!inst.error)
11330         inst.error = BAD_ARGS;
11331       return;
11332     }
11333
11334   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11335   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11336   inst.reloc.pc_rel = 1;
11337   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11338
11339   end_of_line (str);
11340 }
11341
11342 static void
11343 insert_reg (r, htab)
11344      const struct reg_entry *r;
11345      struct hash_control *htab;
11346 {
11347   int    len  = strlen (r->name) + 2;
11348   char * buf  = (char *) xmalloc (len);
11349   char * buf2 = (char *) xmalloc (len);
11350   int    i    = 0;
11351
11352 #ifdef REGISTER_PREFIX
11353   buf[i++] = REGISTER_PREFIX;
11354 #endif
11355
11356   strcpy (buf + i, r->name);
11357
11358   for (i = 0; buf[i]; i++)
11359     buf2[i] = TOUPPER (buf[i]);
11360
11361   buf2[i] = '\0';
11362
11363   hash_insert (htab, buf,  (PTR) r);
11364   hash_insert (htab, buf2, (PTR) r);
11365 }
11366
11367 static void
11368 build_reg_hsh (map)
11369      struct reg_map *map;
11370 {
11371   const struct reg_entry *r;
11372
11373   if ((map->htab = hash_new ()) == NULL)
11374     as_fatal (_("virtual memory exhausted"));
11375
11376   for (r = map->names; r->name != NULL; r++)
11377     insert_reg (r, map->htab);
11378 }
11379
11380 static void
11381 insert_reg_alias (str, regnum, htab)
11382      char *str;
11383      int regnum;
11384      struct hash_control *htab;
11385 {
11386   const char *error;
11387   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11388   const char *name = xmalloc (strlen (str) + 1);
11389   
11390   strcpy ((char *) name, str);
11391   
11392   new->name = name;
11393   new->number = regnum;
11394   new->builtin = FALSE;
11395
11396   error = hash_insert (htab, name, (PTR) new);
11397   if (error)
11398     {
11399       as_bad (_("failed to create an alias for %s, reason: %s"),
11400             str, error);
11401       free ((char *) name);
11402       free (new);
11403     }
11404 }
11405
11406 /* Look for the .req directive.  This is of the form:
11407
11408         new_register_name .req existing_register_name
11409
11410    If we find one, or if it looks sufficiently like one that we want to
11411    handle any error here, return non-zero.  Otherwise return zero.  */
11412 static int
11413 create_register_alias (newname, p)
11414      char *newname;
11415      char *p;
11416 {
11417   char *q;
11418   char c;
11419
11420   q = p;
11421   skip_whitespace (q);
11422
11423   c = *p;
11424   *p = '\0';
11425
11426   if (*q && !strncmp (q, ".req ", 5))
11427     {
11428       char *copy_of_str;
11429       char *r;
11430
11431 #ifdef IGNORE_OPCODE_CASE
11432       newname = original_case_string;
11433 #endif
11434       copy_of_str = newname;
11435
11436       q += 4;
11437       skip_whitespace (q);
11438
11439       for (r = q; *r != '\0'; r++)
11440         if (*r == ' ')
11441           break;
11442
11443       if (r != q)
11444         {
11445           enum arm_reg_type new_type, old_type;
11446           int old_regno;
11447           char d = *r;
11448
11449           *r = '\0';
11450           old_type = arm_reg_parse_any (q);
11451           *r = d;
11452
11453           new_type = arm_reg_parse_any (newname);
11454
11455           if (new_type == REG_TYPE_MAX)
11456             {
11457               if (old_type != REG_TYPE_MAX)
11458                 {
11459                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11460                   insert_reg_alias (newname, old_regno,
11461                                     all_reg_maps[old_type].htab);
11462                 }
11463               else
11464                 as_warn (_("register '%s' does not exist\n"), q);
11465             }
11466           else if (old_type == REG_TYPE_MAX)
11467             {
11468               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11469                        copy_of_str, q);
11470             }
11471           else
11472             {
11473               /* Do not warn about redefinitions to the same alias.  */
11474               if (new_type != old_type
11475                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11476                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11477                 as_warn (_("ignoring redefinition of register alias '%s'"),
11478                          copy_of_str);
11479
11480             }
11481         }
11482       else
11483         as_warn (_("ignoring incomplete .req pseuso op"));
11484
11485       *p = c;
11486       return 1;
11487     }
11488   
11489   *p = c;
11490   return 0;
11491 }
11492
11493 static void
11494 set_constant_flonums ()
11495 {
11496   int i;
11497
11498   for (i = 0; i < NUM_FLOAT_VALS; i++)
11499     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11500       abort ();
11501 }
11502
11503 /* Iterate over the base tables to create the instruction patterns.  */
11504 static void
11505 build_arm_ops_hsh ()
11506 {
11507   unsigned int i;
11508   unsigned int j;
11509   static struct obstack insn_obstack;
11510
11511   obstack_begin (&insn_obstack, 4000);
11512
11513   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11514     {
11515       const struct asm_opcode *insn = insns + i;
11516
11517       if (insn->cond_offset != 0)
11518         {
11519           /* Insn supports conditional execution.  Build the varaints
11520              and insert them in the hash table.  */
11521           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11522             {
11523               unsigned len = strlen (insn->template);
11524               struct asm_opcode *new;
11525               char *template;
11526
11527               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11528               /* All condition codes are two characters.  */
11529               template = obstack_alloc (&insn_obstack, len + 3);
11530
11531               strncpy (template, insn->template, insn->cond_offset);
11532               strcpy (template + insn->cond_offset, conds[j].template);
11533               if (len > insn->cond_offset)
11534                 strcpy (template + insn->cond_offset + 2,
11535                         insn->template + insn->cond_offset);
11536               new->template = template;
11537               new->cond_offset = 0;
11538               new->variant = insn->variant;
11539               new->parms = insn->parms;
11540               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11541
11542               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11543             }
11544         }
11545       /* Finally, insert the unconditional insn in the table directly;
11546          no need to build a copy.  */
11547       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11548     }
11549 }
11550
11551 #if 0 /* Suppressed - for now.  */
11552 #if defined OBJ_ELF || defined OBJ_COFF
11553
11554 #ifdef OBJ_ELF
11555 #define arm_Note Elf_External_Note
11556 #else
11557 typedef struct
11558 {
11559   unsigned char namesz[4];      /* Size of entry's owner string.  */
11560   unsigned char descsz[4];      /* Size of the note descriptor.  */
11561   unsigned char type[4];        /* Interpretation of the descriptor.  */
11562   char          name[1];        /* Start of the name+desc data.  */
11563 } arm_Note;
11564 #endif
11565
11566 /* The description is kept to a fix sized in order to make updating
11567    it and merging it easier.  */
11568 #define ARM_NOTE_DESCRIPTION_LENGTH     8
11569
11570 static void
11571 arm_add_note (name, description, type)
11572      const char * name;
11573      const char * description;
11574      unsigned int type;
11575 {
11576   arm_Note     note ATTRIBUTE_UNUSED;
11577   char *       p;
11578   unsigned int name_len;
11579
11580   name_len = (strlen (name) + 1 + 3) & ~3;
11581   
11582   p = frag_more (sizeof (note.namesz));
11583   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11584
11585   p = frag_more (sizeof (note.descsz));
11586   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11587
11588   p = frag_more (sizeof (note.type));
11589   md_number_to_chars (p, (valueT) type, sizeof (note.type));
11590
11591   p = frag_more (name_len);
11592   strcpy (p, name);
11593
11594   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11595   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11596   frag_align (2, 0, 0);
11597 }
11598 #endif
11599 #endif
11600
11601 void
11602 md_begin ()
11603 {
11604   unsigned mach;
11605   unsigned int i;
11606
11607   if (   (arm_ops_hsh = hash_new ()) == NULL
11608       || (arm_tops_hsh = hash_new ()) == NULL
11609       || (arm_cond_hsh = hash_new ()) == NULL
11610       || (arm_shift_hsh = hash_new ()) == NULL
11611       || (arm_psr_hsh = hash_new ()) == NULL)
11612     as_fatal (_("virtual memory exhausted"));
11613
11614   build_arm_ops_hsh ();
11615   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11616     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11617   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11618     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11619   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11620     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11621   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11622     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11623
11624   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11625     build_reg_hsh (all_reg_maps + i);
11626
11627   set_constant_flonums ();
11628
11629   /* Set the cpu variant based on the command-line options.  We prefer
11630      -mcpu= over -march= if both are set (as for GCC); and we prefer
11631      -mfpu= over any other way of setting the floating point unit.
11632      Use of legacy options with new options are faulted.  */
11633   if (legacy_cpu != -1)
11634     {
11635       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11636         as_bad (_("use of old and new-style options to set CPU type"));
11637
11638       mcpu_cpu_opt = legacy_cpu;
11639     }
11640   else if (mcpu_cpu_opt == -1)
11641     mcpu_cpu_opt = march_cpu_opt;
11642
11643   if (legacy_fpu != -1)
11644     {
11645       if (mfpu_opt != -1)
11646         as_bad (_("use of old and new-style options to set FPU type"));
11647
11648       mfpu_opt = legacy_fpu;
11649     }
11650   else if (mfpu_opt == -1)
11651     {
11652 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11653       /* Some environments specify a default FPU.  If they don't, infer it
11654          from the processor.  */
11655       if (mcpu_fpu_opt != -1)
11656         mfpu_opt = mcpu_fpu_opt;
11657       else
11658         mfpu_opt = march_fpu_opt;
11659 #else
11660       mfpu_opt = FPU_DEFAULT;
11661 #endif
11662     }
11663
11664   if (mfpu_opt == -1)
11665     {
11666       if (mcpu_cpu_opt == -1)
11667         mfpu_opt = FPU_DEFAULT;
11668       else if (mcpu_cpu_opt & ARM_EXT_V5)
11669         mfpu_opt = FPU_ARCH_VFP_V2;
11670       else
11671         mfpu_opt = FPU_ARCH_FPA;
11672     }
11673
11674   if (mcpu_cpu_opt == -1)
11675     mcpu_cpu_opt = CPU_DEFAULT;
11676
11677   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11678
11679 #if defined OBJ_COFF || defined OBJ_ELF
11680   {
11681     unsigned int flags = 0;
11682
11683     /* Set the flags in the private structure.  */
11684     if (uses_apcs_26)      flags |= F_APCS26;
11685     if (support_interwork) flags |= F_INTERWORK;
11686     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11687     if (pic_code)          flags |= F_PIC;
11688     if ((cpu_variant & FPU_ANY) == FPU_NONE
11689          || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11690       {
11691         flags |= F_SOFT_FLOAT;
11692       }
11693     switch (mfloat_abi_opt)
11694       {
11695       case ARM_FLOAT_ABI_SOFT:
11696       case ARM_FLOAT_ABI_SOFTFP:
11697         flags |= F_SOFT_FLOAT;
11698         break;
11699
11700       case ARM_FLOAT_ABI_HARD:
11701         if (flags & F_SOFT_FLOAT)
11702           as_bad (_("hard-float conflicts with specified fpu"));
11703         break;
11704       }
11705     /* Using VFP conventions (even if soft-float).  */
11706     if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
11707
11708 #if defined OBJ_ELF
11709     if (cpu_variant & FPU_ARCH_MAVERICK)
11710         flags |= EF_ARM_MAVERICK_FLOAT;
11711 #endif
11712
11713     bfd_set_private_flags (stdoutput, flags);
11714
11715     /* We have run out flags in the COFF header to encode the
11716        status of ATPCS support, so instead we create a dummy,
11717        empty, debug section called .arm.atpcs.  */
11718     if (atpcs)
11719       {
11720         asection * sec;
11721
11722         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11723
11724         if (sec != NULL)
11725           {
11726             bfd_set_section_flags
11727               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11728             bfd_set_section_size (stdoutput, sec, 0);
11729             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11730           }
11731       }
11732   }
11733 #endif
11734
11735   /* Record the CPU type as well.  */
11736   switch (cpu_variant & ARM_CPU_MASK)
11737     {
11738     case ARM_2:
11739       mach = bfd_mach_arm_2;
11740       break;
11741
11742     case ARM_3:                 /* Also ARM_250.  */
11743       mach = bfd_mach_arm_2a;
11744       break;
11745
11746     case ARM_6:                 /* Also ARM_7.  */
11747       mach = bfd_mach_arm_3;
11748       break;
11749
11750     default:
11751       mach = bfd_mach_arm_unknown;
11752       break;
11753     }
11754
11755   /* Catch special cases.  */
11756   if (cpu_variant & ARM_CEXT_IWMMXT)
11757     mach = bfd_mach_arm_iWMMXt;
11758   else if (cpu_variant & ARM_CEXT_XSCALE)
11759     mach = bfd_mach_arm_XScale;
11760   else if (cpu_variant & ARM_CEXT_MAVERICK)
11761     mach = bfd_mach_arm_ep9312;
11762   else if (cpu_variant & ARM_EXT_V5E)
11763     mach = bfd_mach_arm_5TE;
11764   else if (cpu_variant & ARM_EXT_V5)
11765     {
11766       if (cpu_variant & ARM_EXT_V4T)
11767         mach = bfd_mach_arm_5T;
11768       else
11769         mach = bfd_mach_arm_5;
11770     }
11771   else if (cpu_variant & ARM_EXT_V4)
11772     {
11773       if (cpu_variant & ARM_EXT_V4T)
11774         mach = bfd_mach_arm_4T;
11775       else
11776         mach = bfd_mach_arm_4;
11777     }
11778   else if (cpu_variant & ARM_EXT_V3M)
11779     mach = bfd_mach_arm_3M;
11780
11781 #if 0 /* Suppressed - for now.  */
11782 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11783
11784   /* Create a .note section to fully identify this arm binary.  */
11785
11786 #define NOTE_ARCH_STRING        "arch: "
11787
11788 #if defined OBJ_COFF && ! defined NT_VERSION
11789 #define NT_VERSION  1
11790 #define NT_ARCH     2
11791 #endif
11792   
11793   {
11794     segT current_seg = now_seg;
11795     subsegT current_subseg = now_subseg;
11796     asection * arm_arch;
11797     const char * arch_string;
11798
11799     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11800
11801 #ifdef OBJ_COFF
11802     bfd_set_section_flags (stdoutput, arm_arch,
11803                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11804                            | SEC_HAS_CONTENTS);
11805 #else
11806     bfd_set_section_flags (stdoutput, arm_arch,
11807                            SEC_READONLY | SEC_HAS_CONTENTS);
11808 #endif
11809     arm_arch->output_section = arm_arch;
11810     subseg_set (arm_arch, 0);
11811
11812     switch (mach)
11813       {
11814       default:
11815       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11816       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11817       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11818       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11819       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11820       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11821       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11822       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11823       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11824       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11825       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11826       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11827       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break; 
11828       }
11829
11830     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11831
11832     subseg_set (current_seg, current_subseg);
11833   }
11834 #endif
11835 #endif /* Suppressed code.  */
11836   
11837   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11838 }
11839
11840 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11841    for use in the a.out file, and stores them in the array pointed to by buf.
11842    This knows about the endian-ness of the target machine and does
11843    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11844    2 (short) and 4 (long)  Floating numbers are put out as a series of
11845    LITTLENUMS (shorts, here at least).  */
11846
11847 void
11848 md_number_to_chars (buf, val, n)
11849      char * buf;
11850      valueT val;
11851      int    n;
11852 {
11853   if (target_big_endian)
11854     number_to_chars_bigendian (buf, val, n);
11855   else
11856     number_to_chars_littleendian (buf, val, n);
11857 }
11858
11859 static valueT
11860 md_chars_to_number (buf, n)
11861      char * buf;
11862      int    n;
11863 {
11864   valueT result = 0;
11865   unsigned char * where = (unsigned char *) buf;
11866
11867   if (target_big_endian)
11868     {
11869       while (n--)
11870         {
11871           result <<= 8;
11872           result |= (*where++ & 255);
11873         }
11874     }
11875   else
11876     {
11877       while (n--)
11878         {
11879           result <<= 8;
11880           result |= (where[n] & 255);
11881         }
11882     }
11883
11884   return result;
11885 }
11886
11887 /* Turn a string in input_line_pointer into a floating point constant
11888    of type TYPE, and store the appropriate bytes in *LITP.  The number
11889    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11890    returned, or NULL on OK.
11891
11892    Note that fp constants aren't represent in the normal way on the ARM.
11893    In big endian mode, things are as expected.  However, in little endian
11894    mode fp constants are big-endian word-wise, and little-endian byte-wise
11895    within the words.  For example, (double) 1.1 in big endian mode is
11896    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11897    the byte sequence 99 99 f1 3f 9a 99 99 99.
11898
11899    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11900
11901 char *
11902 md_atof (type, litP, sizeP)
11903      char   type;
11904      char * litP;
11905      int *  sizeP;
11906 {
11907   int prec;
11908   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11909   char *t;
11910   int i;
11911
11912   switch (type)
11913     {
11914     case 'f':
11915     case 'F':
11916     case 's':
11917     case 'S':
11918       prec = 2;
11919       break;
11920
11921     case 'd':
11922     case 'D':
11923     case 'r':
11924     case 'R':
11925       prec = 4;
11926       break;
11927
11928     case 'x':
11929     case 'X':
11930       prec = 6;
11931       break;
11932
11933     case 'p':
11934     case 'P':
11935       prec = 6;
11936       break;
11937
11938     default:
11939       *sizeP = 0;
11940       return _("bad call to MD_ATOF()");
11941     }
11942
11943   t = atof_ieee (input_line_pointer, type, words);
11944   if (t)
11945     input_line_pointer = t;
11946   *sizeP = prec * 2;
11947
11948   if (target_big_endian)
11949     {
11950       for (i = 0; i < prec; i++)
11951         {
11952           md_number_to_chars (litP, (valueT) words[i], 2);
11953           litP += 2;
11954         }
11955     }
11956   else
11957     {
11958       if (cpu_variant & FPU_ARCH_VFP)
11959         for (i = prec - 1; i >= 0; i--)
11960           {
11961             md_number_to_chars (litP, (valueT) words[i], 2);
11962             litP += 2;
11963           }
11964       else
11965         /* For a 4 byte float the order of elements in `words' is 1 0.
11966            For an 8 byte float the order is 1 0 3 2.  */
11967         for (i = 0; i < prec; i += 2)
11968           {
11969             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11970             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11971             litP += 4;
11972           }
11973     }
11974
11975   return 0;
11976 }
11977
11978 /* The knowledge of the PC's pipeline offset is built into the insns
11979    themselves.  */
11980
11981 long
11982 md_pcrel_from (fixP)
11983      fixS * fixP;
11984 {
11985   if (fixP->fx_addsy
11986       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11987       && fixP->fx_subsy == NULL)
11988     return 0;
11989
11990   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11991     {
11992       /* PC relative addressing on the Thumb is slightly odd
11993          as the bottom two bits of the PC are forced to zero
11994          for the calculation.  */
11995       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11996     }
11997
11998 #ifdef TE_WINCE
11999   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12000      so we un-adjust here to compensate for the accommodation.  */
12001   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
12002 #else
12003   return fixP->fx_where + fixP->fx_frag->fr_address;
12004 #endif
12005 }
12006
12007 /* Round up a section size to the appropriate boundary.  */
12008
12009 valueT
12010 md_section_align (segment, size)
12011      segT   segment ATTRIBUTE_UNUSED;
12012      valueT size;
12013 {
12014 #ifdef OBJ_ELF
12015   return size;
12016 #else
12017   /* Round all sects to multiple of 4.  */
12018   return (size + 3) & ~3;
12019 #endif
12020 }
12021
12022 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12023    Otherwise we have no need to default values of symbols.  */
12024
12025 symbolS *
12026 md_undefined_symbol (name)
12027      char * name ATTRIBUTE_UNUSED;
12028 {
12029 #ifdef OBJ_ELF
12030   if (name[0] == '_' && name[1] == 'G'
12031       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12032     {
12033       if (!GOT_symbol)
12034         {
12035           if (symbol_find (name))
12036             as_bad ("GOT already in the symbol table");
12037
12038           GOT_symbol = symbol_new (name, undefined_section,
12039                                    (valueT) 0, & zero_address_frag);
12040         }
12041
12042       return GOT_symbol;
12043     }
12044 #endif
12045
12046   return 0;
12047 }
12048
12049 /* arm_reg_parse () := if it looks like a register, return its token and
12050    advance the pointer.  */
12051
12052 static int
12053 arm_reg_parse (ccp, htab)
12054      register char ** ccp;
12055      struct hash_control *htab;
12056 {
12057   char * start = * ccp;
12058   char   c;
12059   char * p;
12060   struct reg_entry * reg;
12061
12062 #ifdef REGISTER_PREFIX
12063   if (*start != REGISTER_PREFIX)
12064     return FAIL;
12065   p = start + 1;
12066 #else
12067   p = start;
12068 #ifdef OPTIONAL_REGISTER_PREFIX
12069   if (*p == OPTIONAL_REGISTER_PREFIX)
12070     p++, start++;
12071 #endif
12072 #endif
12073   if (!ISALPHA (*p) || !is_name_beginner (*p))
12074     return FAIL;
12075
12076   c = *p++;
12077   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12078     c = *p++;
12079
12080   *--p = 0;
12081   reg = (struct reg_entry *) hash_find (htab, start);
12082   *p = c;
12083
12084   if (reg)
12085     {
12086       *ccp = p;
12087       return reg->number;
12088     }
12089
12090   return FAIL;
12091 }
12092
12093 /* Search for the following register name in each of the possible reg name
12094    tables.  Return the classification if found, or REG_TYPE_MAX if not
12095    present.  */
12096 static enum arm_reg_type
12097 arm_reg_parse_any (cp)
12098      char *cp;
12099 {
12100   int i;
12101
12102   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12103     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12104       return (enum arm_reg_type) i;
12105
12106   return REG_TYPE_MAX;
12107 }
12108
12109 void
12110 md_apply_fix3 (fixP, valP, seg)
12111      fixS *   fixP;
12112      valueT * valP;
12113      segT     seg;
12114 {
12115   offsetT        value = * valP;
12116   offsetT        newval;
12117   unsigned int   newimm;
12118   unsigned long  temp;
12119   int            sign;
12120   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12121   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12122
12123   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12124
12125   /* Note whether this will delete the relocation.  */
12126 #if 0
12127   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12128      doesn't work fully.)  */
12129   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12130       && !fixP->fx_pcrel)
12131 #else
12132   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12133 #endif
12134     fixP->fx_done = 1;
12135
12136   /* If this symbol is in a different section then we need to leave it for
12137      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12138      so we have to undo it's effects here.  */
12139   if (fixP->fx_pcrel)
12140     {
12141       if (fixP->fx_addsy != NULL
12142           && S_IS_DEFINED (fixP->fx_addsy)
12143           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12144         {
12145           if (target_oabi
12146               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12147                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12148                   ))
12149             value = 0;
12150           else
12151             value += md_pcrel_from (fixP);
12152         }
12153     }
12154
12155   /* Remember value for emit_reloc.  */
12156   fixP->fx_addnumber = value;
12157
12158   switch (fixP->fx_r_type)
12159     {
12160     case BFD_RELOC_ARM_IMMEDIATE:
12161       newimm = validate_immediate (value);
12162       temp = md_chars_to_number (buf, INSN_SIZE);
12163
12164       /* If the instruction will fail, see if we can fix things up by
12165          changing the opcode.  */
12166       if (newimm == (unsigned int) FAIL
12167           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12168         {
12169           as_bad_where (fixP->fx_file, fixP->fx_line,
12170                         _("invalid constant (%lx) after fixup"),
12171                         (unsigned long) value);
12172           break;
12173         }
12174
12175       newimm |= (temp & 0xfffff000);
12176       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12177       fixP->fx_done = 1;
12178       break;
12179
12180     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12181       {
12182         unsigned int highpart = 0;
12183         unsigned int newinsn  = 0xe1a00000; /* nop.  */
12184
12185         newimm = validate_immediate (value);
12186         temp = md_chars_to_number (buf, INSN_SIZE);
12187
12188         /* If the instruction will fail, see if we can fix things up by
12189            changing the opcode.  */
12190         if (newimm == (unsigned int) FAIL
12191             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12192           {
12193             /* No ?  OK - try using two ADD instructions to generate
12194                the value.  */
12195             newimm = validate_immediate_twopart (value, & highpart);
12196
12197             /* Yes - then make sure that the second instruction is
12198                also an add.  */
12199             if (newimm != (unsigned int) FAIL)
12200               newinsn = temp;
12201             /* Still No ?  Try using a negated value.  */
12202             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12203               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12204             /* Otherwise - give up.  */
12205             else
12206               {
12207                 as_bad_where (fixP->fx_file, fixP->fx_line,
12208                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12209                               (long) value);
12210                 break;
12211               }
12212
12213             /* Replace the first operand in the 2nd instruction (which
12214                is the PC) with the destination register.  We have
12215                already added in the PC in the first instruction and we
12216                do not want to do it again.  */
12217             newinsn &= ~ 0xf0000;
12218             newinsn |= ((newinsn & 0x0f000) << 4);
12219           }
12220
12221         newimm |= (temp & 0xfffff000);
12222         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12223
12224         highpart |= (newinsn & 0xfffff000);
12225         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12226       }
12227       break;
12228
12229     case BFD_RELOC_ARM_OFFSET_IMM:
12230       sign = value >= 0;
12231
12232       if (value < 0)
12233         value = - value;
12234
12235       if (validate_offset_imm (value, 0) == FAIL)
12236         {
12237           as_bad_where (fixP->fx_file, fixP->fx_line,
12238                         _("bad immediate value for offset (%ld)"),
12239                         (long) value);
12240           break;
12241         }
12242
12243       newval = md_chars_to_number (buf, INSN_SIZE);
12244       newval &= 0xff7ff000;
12245       newval |= value | (sign ? INDEX_UP : 0);
12246       md_number_to_chars (buf, newval, INSN_SIZE);
12247       break;
12248
12249     case BFD_RELOC_ARM_OFFSET_IMM8:
12250     case BFD_RELOC_ARM_HWLITERAL:
12251       sign = value >= 0;
12252
12253       if (value < 0)
12254         value = - value;
12255
12256       if (validate_offset_imm (value, 1) == FAIL)
12257         {
12258           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12259             as_bad_where (fixP->fx_file, fixP->fx_line,
12260                           _("invalid literal constant: pool needs to be closer"));
12261           else
12262             as_bad (_("bad immediate value for half-word offset (%ld)"),
12263                     (long) value);
12264           break;
12265         }
12266
12267       newval = md_chars_to_number (buf, INSN_SIZE);
12268       newval &= 0xff7ff0f0;
12269       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12270       md_number_to_chars (buf, newval, INSN_SIZE);
12271       break;
12272
12273     case BFD_RELOC_ARM_LITERAL:
12274       sign = value >= 0;
12275
12276       if (value < 0)
12277         value = - value;
12278
12279       if (validate_offset_imm (value, 0) == FAIL)
12280         {
12281           as_bad_where (fixP->fx_file, fixP->fx_line,
12282                         _("invalid literal constant: pool needs to be closer"));
12283           break;
12284         }
12285
12286       newval = md_chars_to_number (buf, INSN_SIZE);
12287       newval &= 0xff7ff000;
12288       newval |= value | (sign ? INDEX_UP : 0);
12289       md_number_to_chars (buf, newval, INSN_SIZE);
12290       break;
12291
12292     case BFD_RELOC_ARM_SHIFT_IMM:
12293       newval = md_chars_to_number (buf, INSN_SIZE);
12294       if (((unsigned long) value) > 32
12295           || (value == 32
12296               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12297         {
12298           as_bad_where (fixP->fx_file, fixP->fx_line,
12299                         _("shift expression is too large"));
12300           break;
12301         }
12302
12303       if (value == 0)
12304         /* Shifts of zero must be done as lsl.  */
12305         newval &= ~0x60;
12306       else if (value == 32)
12307         value = 0;
12308       newval &= 0xfffff07f;
12309       newval |= (value & 0x1f) << 7;
12310       md_number_to_chars (buf, newval, INSN_SIZE);
12311       break;
12312
12313     case BFD_RELOC_ARM_SWI:
12314       if (arm_data->thumb_mode)
12315         {
12316           if (((unsigned long) value) > 0xff)
12317             as_bad_where (fixP->fx_file, fixP->fx_line,
12318                           _("invalid swi expression"));
12319           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12320           newval |= value;
12321           md_number_to_chars (buf, newval, THUMB_SIZE);
12322         }
12323       else
12324         {
12325           if (((unsigned long) value) > 0x00ffffff)
12326             as_bad_where (fixP->fx_file, fixP->fx_line,
12327                           _("invalid swi expression"));
12328           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12329           newval |= value;
12330           md_number_to_chars (buf, newval, INSN_SIZE);
12331         }
12332       break;
12333
12334     case BFD_RELOC_ARM_MULTI:
12335       if (((unsigned long) value) > 0xffff)
12336         as_bad_where (fixP->fx_file, fixP->fx_line,
12337                       _("invalid expression in load/store multiple"));
12338       newval = value | md_chars_to_number (buf, INSN_SIZE);
12339       md_number_to_chars (buf, newval, INSN_SIZE);
12340       break;
12341
12342     case BFD_RELOC_ARM_PCREL_BRANCH:
12343       newval = md_chars_to_number (buf, INSN_SIZE);
12344
12345       /* Sign-extend a 24-bit number.  */
12346 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12347
12348 #ifdef OBJ_ELF
12349       if (! target_oabi)
12350         value = fixP->fx_offset;
12351 #endif
12352
12353       /* We are going to store value (shifted right by two) in the
12354          instruction, in a 24 bit, signed field.  Thus we need to check
12355          that none of the top 8 bits of the shifted value (top 7 bits of
12356          the unshifted, unsigned value) are set, or that they are all set.  */
12357       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12358           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12359         {
12360 #ifdef OBJ_ELF
12361           /* Normally we would be stuck at this point, since we cannot store
12362              the absolute address that is the destination of the branch in the
12363              24 bits of the branch instruction.  If however, we happen to know
12364              that the destination of the branch is in the same section as the
12365              branch instruction itself, then we can compute the relocation for
12366              ourselves and not have to bother the linker with it.
12367
12368              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12369              because I have not worked out how to do this for OBJ_COFF or
12370              target_oabi.  */
12371           if (! target_oabi
12372               && fixP->fx_addsy != NULL
12373               && S_IS_DEFINED (fixP->fx_addsy)
12374               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12375             {
12376               /* Get pc relative value to go into the branch.  */
12377               value = * valP;
12378
12379               /* Permit a backward branch provided that enough bits
12380                  are set.  Allow a forwards branch, provided that
12381                  enough bits are clear.  */
12382               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12383                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12384                 fixP->fx_done = 1;
12385             }
12386
12387           if (! fixP->fx_done)
12388 #endif
12389             as_bad_where (fixP->fx_file, fixP->fx_line,
12390                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12391         }
12392
12393       value >>= 2;
12394       value += SEXT24 (newval);
12395
12396       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12397           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12398         as_bad_where (fixP->fx_file, fixP->fx_line,
12399                       _("out of range branch"));
12400
12401       newval = (value & 0x00ffffff) | (newval & 0xff000000);
12402       md_number_to_chars (buf, newval, INSN_SIZE);
12403       break;
12404
12405     case BFD_RELOC_ARM_PCREL_BLX:
12406       {
12407         offsetT hbit;
12408         newval = md_chars_to_number (buf, INSN_SIZE);
12409
12410 #ifdef OBJ_ELF
12411         if (! target_oabi)
12412           value = fixP->fx_offset;
12413 #endif
12414         hbit   = (value >> 1) & 1;
12415         value  = (value >> 2) & 0x00ffffff;
12416         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12417         newval = value | (newval & 0xfe000000) | (hbit << 24);
12418         md_number_to_chars (buf, newval, INSN_SIZE);
12419       }
12420       break;
12421
12422     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12423       newval = md_chars_to_number (buf, THUMB_SIZE);
12424       {
12425         addressT diff = (newval & 0xff) << 1;
12426         if (diff & 0x100)
12427           diff |= ~0xff;
12428
12429         value += diff;
12430         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12431           as_bad_where (fixP->fx_file, fixP->fx_line,
12432                         _("branch out of range"));
12433         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12434       }
12435       md_number_to_chars (buf, newval, THUMB_SIZE);
12436       break;
12437
12438     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12439       newval = md_chars_to_number (buf, THUMB_SIZE);
12440       {
12441         addressT diff = (newval & 0x7ff) << 1;
12442         if (diff & 0x800)
12443           diff |= ~0x7ff;
12444
12445         value += diff;
12446         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12447           as_bad_where (fixP->fx_file, fixP->fx_line,
12448                         _("branch out of range"));
12449         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12450       }
12451       md_number_to_chars (buf, newval, THUMB_SIZE);
12452       break;
12453
12454     case BFD_RELOC_THUMB_PCREL_BLX:
12455     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12456       {
12457         offsetT newval2;
12458         addressT diff;
12459
12460         newval  = md_chars_to_number (buf, THUMB_SIZE);
12461         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12462         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12463         if (diff & 0x400000)
12464           diff |= ~0x3fffff;
12465 #ifdef OBJ_ELF
12466         value = fixP->fx_offset;
12467 #endif
12468         value += diff;
12469
12470         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12471           as_bad_where (fixP->fx_file, fixP->fx_line,
12472                         _("branch with link out of range"));
12473
12474         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12475         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12476         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12477           /* For a BLX instruction, make sure that the relocation is rounded up
12478              to a word boundary.  This follows the semantics of the instruction
12479              which specifies that bit 1 of the target address will come from bit
12480              1 of the base address.  */
12481           newval2 = (newval2 + 1) & ~ 1;
12482         md_number_to_chars (buf, newval, THUMB_SIZE);
12483         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12484       }
12485       break;
12486
12487     case BFD_RELOC_8:
12488       if (fixP->fx_done || fixP->fx_pcrel)
12489         md_number_to_chars (buf, value, 1);
12490 #ifdef OBJ_ELF
12491       else if (!target_oabi)
12492         {
12493           value = fixP->fx_offset;
12494           md_number_to_chars (buf, value, 1);
12495         }
12496 #endif
12497       break;
12498
12499     case BFD_RELOC_16:
12500       if (fixP->fx_done || fixP->fx_pcrel)
12501         md_number_to_chars (buf, value, 2);
12502 #ifdef OBJ_ELF
12503       else if (!target_oabi)
12504         {
12505           value = fixP->fx_offset;
12506           md_number_to_chars (buf, value, 2);
12507         }
12508 #endif
12509       break;
12510
12511 #ifdef OBJ_ELF
12512     case BFD_RELOC_ARM_GOT32:
12513     case BFD_RELOC_ARM_GOTOFF:
12514       md_number_to_chars (buf, 0, 4);
12515       break;
12516 #endif
12517
12518     case BFD_RELOC_RVA:
12519     case BFD_RELOC_32:
12520       if (fixP->fx_done || fixP->fx_pcrel)
12521         md_number_to_chars (buf, value, 4);
12522 #ifdef OBJ_ELF
12523       else if (!target_oabi)
12524         {
12525           value = fixP->fx_offset;
12526           md_number_to_chars (buf, value, 4);
12527         }
12528 #endif
12529       break;
12530
12531 #ifdef OBJ_ELF
12532     case BFD_RELOC_ARM_PLT32:
12533       /* It appears the instruction is fully prepared at this point.  */
12534       break;
12535 #endif
12536
12537     case BFD_RELOC_ARM_CP_OFF_IMM:
12538       sign = value >= 0;
12539       if (value < -1023 || value > 1023 || (value & 3))
12540         as_bad_where (fixP->fx_file, fixP->fx_line,
12541                       _("illegal value for co-processor offset"));
12542       if (value < 0)
12543         value = -value;
12544       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12545       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12546       md_number_to_chars (buf, newval, INSN_SIZE);
12547       break;
12548
12549     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12550       sign = value >= 0;
12551       if (value < -255 || value > 255)
12552         as_bad_where (fixP->fx_file, fixP->fx_line,
12553                       _("Illegal value for co-processor offset"));
12554       if (value < 0)
12555         value = -value;
12556       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12557       newval |= value | (sign ?  INDEX_UP : 0);
12558       md_number_to_chars (buf, newval , INSN_SIZE);
12559       break;
12560
12561     case BFD_RELOC_ARM_THUMB_OFFSET:
12562       newval = md_chars_to_number (buf, THUMB_SIZE);
12563       /* Exactly what ranges, and where the offset is inserted depends
12564          on the type of instruction, we can establish this from the
12565          top 4 bits.  */
12566       switch (newval >> 12)
12567         {
12568         case 4: /* PC load.  */
12569           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12570              forced to zero for these loads, so we will need to round
12571              up the offset if the instruction address is not word
12572              aligned (since the final address produced must be, and
12573              we can only describe word-aligned immediate offsets).  */
12574
12575           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12576             as_bad_where (fixP->fx_file, fixP->fx_line,
12577                           _("invalid offset, target not word aligned (0x%08X)"),
12578                           (unsigned int) (fixP->fx_frag->fr_address
12579                                           + fixP->fx_where + value));
12580
12581           if ((value + 2) & ~0x3fe)
12582             as_bad_where (fixP->fx_file, fixP->fx_line,
12583                           _("invalid offset, value too big (0x%08lX)"),
12584                           (long) value);
12585
12586           /* Round up, since pc will be rounded down.  */
12587           newval |= (value + 2) >> 2;
12588           break;
12589
12590         case 9: /* SP load/store.  */
12591           if (value & ~0x3fc)
12592             as_bad_where (fixP->fx_file, fixP->fx_line,
12593                           _("invalid offset, value too big (0x%08lX)"),
12594                           (long) value);
12595           newval |= value >> 2;
12596           break;
12597
12598         case 6: /* Word load/store.  */
12599           if (value & ~0x7c)
12600             as_bad_where (fixP->fx_file, fixP->fx_line,
12601                           _("invalid offset, value too big (0x%08lX)"),
12602                           (long) value);
12603           newval |= value << 4; /* 6 - 2.  */
12604           break;
12605
12606         case 7: /* Byte load/store.  */
12607           if (value & ~0x1f)
12608             as_bad_where (fixP->fx_file, fixP->fx_line,
12609                           _("invalid offset, value too big (0x%08lX)"),
12610                           (long) value);
12611           newval |= value << 6;
12612           break;
12613
12614         case 8: /* Halfword load/store.  */
12615           if (value & ~0x3e)
12616             as_bad_where (fixP->fx_file, fixP->fx_line,
12617                           _("invalid offset, value too big (0x%08lX)"),
12618                           (long) value);
12619           newval |= value << 5; /* 6 - 1.  */
12620           break;
12621
12622         default:
12623           as_bad_where (fixP->fx_file, fixP->fx_line,
12624                         "Unable to process relocation for thumb opcode: %lx",
12625                         (unsigned long) newval);
12626           break;
12627         }
12628       md_number_to_chars (buf, newval, THUMB_SIZE);
12629       break;
12630
12631     case BFD_RELOC_ARM_THUMB_ADD:
12632       /* This is a complicated relocation, since we use it for all of
12633          the following immediate relocations:
12634
12635             3bit ADD/SUB
12636             8bit ADD/SUB
12637             9bit ADD/SUB SP word-aligned
12638            10bit ADD PC/SP word-aligned
12639
12640          The type of instruction being processed is encoded in the
12641          instruction field:
12642
12643            0x8000  SUB
12644            0x00F0  Rd
12645            0x000F  Rs
12646       */
12647       newval = md_chars_to_number (buf, THUMB_SIZE);
12648       {
12649         int rd = (newval >> 4) & 0xf;
12650         int rs = newval & 0xf;
12651         int subtract = newval & 0x8000;
12652
12653         if (rd == REG_SP)
12654           {
12655             if (value & ~0x1fc)
12656               as_bad_where (fixP->fx_file, fixP->fx_line,
12657                             _("invalid immediate for stack address calculation"));
12658             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12659             newval |= value >> 2;
12660           }
12661         else if (rs == REG_PC || rs == REG_SP)
12662           {
12663             if (subtract ||
12664                 value & ~0x3fc)
12665               as_bad_where (fixP->fx_file, fixP->fx_line,
12666                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12667                             (unsigned long) value);
12668             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12669             newval |= rd << 8;
12670             newval |= value >> 2;
12671           }
12672         else if (rs == rd)
12673           {
12674             if (value & ~0xff)
12675               as_bad_where (fixP->fx_file, fixP->fx_line,
12676                             _("invalid 8bit immediate"));
12677             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12678             newval |= (rd << 8) | value;
12679           }
12680         else
12681           {
12682             if (value & ~0x7)
12683               as_bad_where (fixP->fx_file, fixP->fx_line,
12684                             _("invalid 3bit immediate"));
12685             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12686             newval |= rd | (rs << 3) | (value << 6);
12687           }
12688       }
12689       md_number_to_chars (buf, newval, THUMB_SIZE);
12690       break;
12691
12692     case BFD_RELOC_ARM_THUMB_IMM:
12693       newval = md_chars_to_number (buf, THUMB_SIZE);
12694       switch (newval >> 11)
12695         {
12696         case 0x04: /* 8bit immediate MOV.  */
12697         case 0x05: /* 8bit immediate CMP.  */
12698           if (value < 0 || value > 255)
12699             as_bad_where (fixP->fx_file, fixP->fx_line,
12700                           _("invalid immediate: %ld is too large"),
12701                           (long) value);
12702           newval |= value;
12703           break;
12704
12705         default:
12706           abort ();
12707         }
12708       md_number_to_chars (buf, newval, THUMB_SIZE);
12709       break;
12710
12711     case BFD_RELOC_ARM_THUMB_SHIFT:
12712       /* 5bit shift value (0..31).  */
12713       if (value < 0 || value > 31)
12714         as_bad_where (fixP->fx_file, fixP->fx_line,
12715                       _("illegal Thumb shift value: %ld"), (long) value);
12716       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12717       newval |= value << 6;
12718       md_number_to_chars (buf, newval, THUMB_SIZE);
12719       break;
12720
12721     case BFD_RELOC_VTABLE_INHERIT:
12722     case BFD_RELOC_VTABLE_ENTRY:
12723       fixP->fx_done = 0;
12724       return;
12725
12726     case BFD_RELOC_NONE:
12727     default:
12728       as_bad_where (fixP->fx_file, fixP->fx_line,
12729                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12730     }
12731 }
12732
12733 /* Translate internal representation of relocation info to BFD target
12734    format.  */
12735
12736 arelent *
12737 tc_gen_reloc (section, fixp)
12738      asection * section ATTRIBUTE_UNUSED;
12739      fixS * fixp;
12740 {
12741   arelent * reloc;
12742   bfd_reloc_code_real_type code;
12743
12744   reloc = (arelent *) xmalloc (sizeof (arelent));
12745
12746   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12747   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12748   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12749
12750   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12751 #ifndef OBJ_ELF
12752   if (fixp->fx_pcrel == 0)
12753     reloc->addend = fixp->fx_offset;
12754   else
12755     reloc->addend = fixp->fx_offset = reloc->address;
12756 #else  /* OBJ_ELF */
12757   reloc->addend = fixp->fx_offset;
12758 #endif
12759
12760   switch (fixp->fx_r_type)
12761     {
12762     case BFD_RELOC_8:
12763       if (fixp->fx_pcrel)
12764         {
12765           code = BFD_RELOC_8_PCREL;
12766           break;
12767         }
12768
12769     case BFD_RELOC_16:
12770       if (fixp->fx_pcrel)
12771         {
12772           code = BFD_RELOC_16_PCREL;
12773           break;
12774         }
12775
12776     case BFD_RELOC_32:
12777       if (fixp->fx_pcrel)
12778         {
12779           code = BFD_RELOC_32_PCREL;
12780           break;
12781         }
12782
12783     case BFD_RELOC_ARM_PCREL_BRANCH:
12784     case BFD_RELOC_ARM_PCREL_BLX:
12785     case BFD_RELOC_RVA:
12786     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12787     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12788     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12789     case BFD_RELOC_THUMB_PCREL_BLX:
12790     case BFD_RELOC_VTABLE_ENTRY:
12791     case BFD_RELOC_VTABLE_INHERIT:
12792       code = fixp->fx_r_type;
12793       break;
12794
12795     case BFD_RELOC_ARM_LITERAL:
12796     case BFD_RELOC_ARM_HWLITERAL:
12797       /* If this is called then the a literal has
12798          been referenced across a section boundary.  */
12799       as_bad_where (fixp->fx_file, fixp->fx_line,
12800                     _("literal referenced across section boundary"));
12801       return NULL;
12802
12803 #ifdef OBJ_ELF
12804     case BFD_RELOC_ARM_GOT32:
12805     case BFD_RELOC_ARM_GOTOFF:
12806     case BFD_RELOC_ARM_PLT32:
12807       code = fixp->fx_r_type;
12808       break;
12809 #endif
12810
12811     case BFD_RELOC_ARM_IMMEDIATE:
12812       as_bad_where (fixp->fx_file, fixp->fx_line,
12813                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12814       return NULL;
12815
12816     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12817       as_bad_where (fixp->fx_file, fixp->fx_line,
12818                     _("ADRL used for a symbol not defined in the same file"));
12819       return NULL;
12820
12821     case BFD_RELOC_ARM_OFFSET_IMM:
12822       if (fixp->fx_addsy != NULL
12823           && !S_IS_DEFINED (fixp->fx_addsy)
12824           && S_IS_LOCAL (fixp->fx_addsy))
12825         {
12826           as_bad_where (fixp->fx_file, fixp->fx_line,
12827                         _("undefined local label `%s'"),
12828                         S_GET_NAME (fixp->fx_addsy));
12829           return NULL;
12830         }
12831
12832       as_bad_where (fixp->fx_file, fixp->fx_line,
12833                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12834       return NULL;
12835
12836     default:
12837       {
12838         char * type;
12839
12840         switch (fixp->fx_r_type)
12841           {
12842           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12843           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12844           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12845           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12846           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12847           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12848           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12849           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12850           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12851           default:                         type = _("<unknown>"); break;
12852           }
12853         as_bad_where (fixp->fx_file, fixp->fx_line,
12854                       _("cannot represent %s relocation in this object file format"),
12855                       type);
12856         return NULL;
12857       }
12858     }
12859
12860 #ifdef OBJ_ELF
12861   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12862       && GOT_symbol
12863       && fixp->fx_addsy == GOT_symbol)
12864     {
12865       code = BFD_RELOC_ARM_GOTPC;
12866       reloc->addend = fixp->fx_offset = reloc->address;
12867     }
12868 #endif
12869
12870   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12871
12872   if (reloc->howto == NULL)
12873     {
12874       as_bad_where (fixp->fx_file, fixp->fx_line,
12875                     _("cannot represent %s relocation in this object file format"),
12876                     bfd_get_reloc_code_name (code));
12877       return NULL;
12878     }
12879
12880   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12881      vtable entry to be used in the relocation's section offset.  */
12882   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12883     reloc->address = fixp->fx_offset;
12884
12885   return reloc;
12886 }
12887
12888 int
12889 md_estimate_size_before_relax (fragP, segtype)
12890      fragS * fragP ATTRIBUTE_UNUSED;
12891      segT    segtype ATTRIBUTE_UNUSED;
12892 {
12893   as_fatal (_("md_estimate_size_before_relax\n"));
12894   return 1;
12895 }
12896
12897 static void
12898 output_inst (str)
12899      const char *str;
12900 {
12901   char * to = NULL;
12902
12903   if (inst.error)
12904     {
12905       as_bad ("%s -- `%s'", inst.error, str);
12906       return;
12907     }
12908
12909   to = frag_more (inst.size);
12910
12911   if (thumb_mode && (inst.size > THUMB_SIZE))
12912     {
12913       assert (inst.size == (2 * THUMB_SIZE));
12914       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12915       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12916     }
12917   else if (inst.size > INSN_SIZE)
12918     {
12919       assert (inst.size == (2 * INSN_SIZE));
12920       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12921       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12922     }
12923   else
12924     md_number_to_chars (to, inst.instruction, inst.size);
12925
12926   if (inst.reloc.type != BFD_RELOC_NONE)
12927     fix_new_arm (frag_now, to - frag_now->fr_literal,
12928                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12929                  inst.reloc.type);
12930
12931 #ifdef OBJ_ELF
12932   dwarf2_emit_insn (inst.size);
12933 #endif
12934 }
12935
12936 void
12937 md_assemble (str)
12938      char * str;
12939 {
12940   char  c;
12941   char *p;
12942   char *start;
12943
12944   /* Align the instruction.
12945      This may not be the right thing to do but ...  */
12946 #if 0
12947   arm_align (2, 0);
12948 #endif
12949
12950   /* Align the previous label if needed.  */
12951   if (last_label_seen != NULL)
12952     {
12953       symbol_set_frag (last_label_seen, frag_now);
12954       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12955       S_SET_SEGMENT (last_label_seen, now_seg);
12956     }
12957
12958   memset (&inst, '\0', sizeof (inst));
12959   inst.reloc.type = BFD_RELOC_NONE;
12960
12961   skip_whitespace (str);
12962
12963   /* Scan up to the end of the op-code, which must end in white space or
12964      end of string.  */
12965   for (start = p = str; *p != '\0'; p++)
12966     if (*p == ' ')
12967       break;
12968
12969   if (p == str)
12970     {
12971       as_bad (_("no operator -- statement `%s'\n"), str);
12972       return;
12973     }
12974
12975   if (thumb_mode)
12976     {
12977       const struct thumb_opcode * opcode;
12978
12979       c = *p;
12980       *p = '\0';
12981       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12982       *p = c;
12983
12984       if (opcode)
12985         {
12986           /* Check that this instruction is supported for this CPU.  */
12987           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12988             {
12989               as_bad (_("selected processor does not support `%s'"), str);
12990               return;
12991             }
12992
12993           mapping_state (MAP_THUMB);
12994           inst.instruction = opcode->value;
12995           inst.size = opcode->size;
12996           (*opcode->parms) (p);
12997           output_inst (str);
12998           return;
12999         }
13000     }
13001   else
13002     {
13003       const struct asm_opcode * opcode;
13004
13005       c = *p;
13006       *p = '\0';
13007       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13008       *p = c;
13009
13010       if (opcode)
13011         {
13012           /* Check that this instruction is supported for this CPU.  */
13013           if ((opcode->variant & cpu_variant) == 0)
13014             {
13015               as_bad (_("selected processor does not support `%s'"), str);
13016               return;
13017             }
13018
13019           mapping_state (MAP_ARM);
13020           inst.instruction = opcode->value;
13021           inst.size = INSN_SIZE;
13022           (*opcode->parms) (p);
13023           output_inst (str);
13024           return;
13025         }
13026     }
13027
13028   /* It wasn't an instruction, but it might be a register alias of the form
13029      alias .req reg.  */
13030   if (create_register_alias (str, p))
13031     return;
13032
13033   as_bad (_("bad instruction `%s'"), start);
13034 }
13035
13036 /* md_parse_option
13037       Invocation line includes a switch not recognized by the base assembler.
13038       See if it's a processor-specific option.
13039
13040       This routine is somewhat complicated by the need for backwards
13041       compatibility (since older releases of gcc can't be changed).
13042       The new options try to make the interface as compatible as
13043       possible with GCC.
13044
13045       New options (supported) are:
13046
13047               -mcpu=<cpu name>           Assemble for selected processor
13048               -march=<architecture name> Assemble for selected architecture
13049               -mfpu=<fpu architecture>   Assemble for selected FPU.
13050               -EB/-mbig-endian           Big-endian
13051               -EL/-mlittle-endian        Little-endian
13052               -k                         Generate PIC code
13053               -mthumb                    Start in Thumb mode
13054               -mthumb-interwork          Code supports ARM/Thumb interworking
13055
13056       For now we will also provide support for:
13057
13058               -mapcs-32                  32-bit Program counter
13059               -mapcs-26                  26-bit Program counter
13060               -macps-float               Floats passed in FP registers
13061               -mapcs-reentrant           Reentrant code
13062               -matpcs
13063       (sometime these will probably be replaced with -mapcs=<list of options>
13064       and -matpcs=<list of options>)
13065
13066       The remaining options are only supported for back-wards compatibility.
13067       Cpu variants, the arm part is optional:
13068               -m[arm]1                Currently not supported.
13069               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13070               -m[arm]3                Arm 3 processor
13071               -m[arm]6[xx],           Arm 6 processors
13072               -m[arm]7[xx][t][[d]m]   Arm 7 processors
13073               -m[arm]8[10]            Arm 8 processors
13074               -m[arm]9[20][tdmi]      Arm 9 processors
13075               -mstrongarm[110[0]]     StrongARM processors
13076               -mxscale                XScale processors
13077               -m[arm]v[2345[t[e]]]    Arm architectures
13078               -mall                   All (except the ARM1)
13079       FP variants:
13080               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13081               -mfpe-old               (No float load/store multiples)
13082               -mvfpxd                 VFP Single precision
13083               -mvfp                   All VFP
13084               -mno-fpu                Disable all floating point instructions
13085
13086       The following CPU names are recognized:
13087               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13088               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13089               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13090               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13091               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13092               arm10t arm10e, arm1020t, arm1020e, arm10200e,
13093               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13094
13095       */
13096
13097 const char * md_shortopts = "m:k";
13098
13099 #ifdef ARM_BI_ENDIAN
13100 #define OPTION_EB (OPTION_MD_BASE + 0)
13101 #define OPTION_EL (OPTION_MD_BASE + 1)
13102 #else
13103 #if TARGET_BYTES_BIG_ENDIAN
13104 #define OPTION_EB (OPTION_MD_BASE + 0)
13105 #else
13106 #define OPTION_EL (OPTION_MD_BASE + 1)
13107 #endif
13108 #endif
13109
13110 struct option md_longopts[] =
13111 {
13112 #ifdef OPTION_EB
13113   {"EB", no_argument, NULL, OPTION_EB},
13114 #endif
13115 #ifdef OPTION_EL
13116   {"EL", no_argument, NULL, OPTION_EL},
13117 #endif
13118   {NULL, no_argument, NULL, 0}
13119 };
13120
13121 size_t md_longopts_size = sizeof (md_longopts);
13122
13123 struct arm_option_table
13124 {
13125   char *option;         /* Option name to match.  */
13126   char *help;           /* Help information.  */
13127   int  *var;            /* Variable to change.  */
13128   int   value;          /* What to change it to.  */
13129   char *deprecated;     /* If non-null, print this message.  */
13130 };
13131
13132 struct arm_option_table arm_opts[] =
13133 {
13134   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13135   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13136   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13137    &support_interwork, 1, NULL},
13138   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13139   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13140   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13141   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13142    1, NULL},
13143   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13144   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13145   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13146   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13147    NULL},
13148
13149   /* These are recognized by the assembler, but have no affect on code.  */
13150   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13151   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13152
13153   /* DON'T add any new processors to this list -- we want the whole list
13154      to go away...  Add them to the processors table instead.  */
13155   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13156   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13157   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13158   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13159   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13160   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13161   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13162   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13163   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13164   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13165   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13166   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13167   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13168   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13169   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13170   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13171   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13172   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13173   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13174   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13175   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13176   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13177   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13178   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13179   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13180   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13181   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13182   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13183   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13184   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13185   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13186   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13187   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13188   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13189   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13190   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13191   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13192   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13193   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13194   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13195   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13196   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13197   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13198   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13199   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13200   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13201   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13202   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13203   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13204   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13205   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13206   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13207   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13208   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13209   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13210   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13211   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13212   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13213   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13214   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13215   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13216   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13217   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13218   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13219   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13220   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13221   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13222   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13223   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13224   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13225    N_("use -mcpu=strongarm110")},
13226   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13227    N_("use -mcpu=strongarm1100")},
13228   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13229    N_("use -mcpu=strongarm1110")},
13230   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13231   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13232   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13233
13234   /* Architecture variants -- don't add any more to this list either.  */
13235   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13236   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13237   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13238   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13239   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13240   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13241   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13242   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13243   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13244   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13245   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13246   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13247   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13248   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13249   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13250   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13251   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13252   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13253
13254   /* Floating point variants -- don't add any more to this list either.  */
13255   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13256   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13257   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13258   {"mno-fpu",  NULL, &legacy_fpu, 0,
13259    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13260
13261   {NULL, NULL, NULL, 0, NULL}
13262 };
13263
13264 struct arm_cpu_option_table
13265 {
13266   char *name;
13267   int   value;
13268   /* For some CPUs we assume an FPU unless the user explicitly sets
13269      -mfpu=...  */
13270   int   default_fpu;
13271 };
13272
13273 /* This list should, at a minimum, contain all the cpu names
13274    recognized by GCC.  */
13275 static struct arm_cpu_option_table arm_cpus[] =
13276 {
13277   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13278   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13279   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13280   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13281   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13282   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13283   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13284   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13285   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13286   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13287   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13288   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13289   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13290   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13291   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13292   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13293   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13294   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13295   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13296   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13297   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13298   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13299   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13300   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13301   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13302   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13303   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13304   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13305   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13306   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13307   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13308   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13309   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13310   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13311   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13312   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13313   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13314   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13315   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13316   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13317   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13318   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13319   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13320   /* For V5 or later processors we default to using VFP; but the user
13321      should really set the FPU type explicitly.  */
13322   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13323   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13324   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13325   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13326   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13327   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13328   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13329   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13330   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13331   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13332   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13333   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13334   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13335   {"arm1026ejs",        ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13336   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13337   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13338   /* ??? XSCALE is really an architecture.  */
13339   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13340   /* ??? iwmmxt is not a processor.  */
13341   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13342   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13343   /* Maverick */
13344   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13345   {NULL, 0, 0}
13346 };
13347
13348 struct arm_arch_option_table
13349 {
13350   char *name;
13351   int   value;
13352   int   default_fpu;
13353 };
13354
13355 /* This list should, at a minimum, contain all the architecture names
13356    recognized by GCC.  */
13357 static struct arm_arch_option_table arm_archs[] =
13358 {
13359   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13360   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13361   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13362   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13363   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13364   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13365   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13366   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13367   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13368   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13369   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13370   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13371   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13372   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13373   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13374   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13375   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13376   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13377   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13378   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13379   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13380   {NULL, 0, 0}
13381 };
13382
13383 /* ISA extensions in the co-processor space.  */
13384 struct arm_arch_extension_table
13385 {
13386   char *name;
13387   int value;
13388 };
13389
13390 static struct arm_arch_extension_table arm_extensions[] =
13391 {
13392   {"maverick",          ARM_CEXT_MAVERICK},
13393   {"xscale",            ARM_CEXT_XSCALE},
13394   {"iwmmxt",            ARM_CEXT_IWMMXT},
13395   {NULL,                0}
13396 };
13397
13398 struct arm_fpu_option_table
13399 {
13400   char *name;
13401   int   value;
13402 };
13403
13404 /* This list should, at a minimum, contain all the fpu names
13405    recognized by GCC.  */
13406 static struct arm_fpu_option_table arm_fpus[] =
13407 {
13408   {"softfpa",           FPU_NONE},
13409   {"fpe",               FPU_ARCH_FPE},
13410   {"fpe2",              FPU_ARCH_FPE},
13411   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13412   {"fpa",               FPU_ARCH_FPA},
13413   {"fpa10",             FPU_ARCH_FPA},
13414   {"fpa11",             FPU_ARCH_FPA},
13415   {"arm7500fe",         FPU_ARCH_FPA},
13416   {"softvfp",           FPU_ARCH_VFP},
13417   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13418   {"vfp",               FPU_ARCH_VFP_V2},
13419   {"vfp9",              FPU_ARCH_VFP_V2},
13420   {"vfp10",             FPU_ARCH_VFP_V2},
13421   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13422   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13423   {"arm1020t",          FPU_ARCH_VFP_V1},
13424   {"arm1020e",          FPU_ARCH_VFP_V2},
13425   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13426   {"maverick",          FPU_ARCH_MAVERICK},
13427   {NULL, 0}
13428 };
13429
13430 struct arm_float_abi_option_table
13431 {
13432   char *name;
13433   int value;
13434 };
13435
13436 static struct arm_float_abi_option_table arm_float_abis[] =
13437 {
13438   {"hard",      ARM_FLOAT_ABI_HARD},
13439   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13440   {"soft",      ARM_FLOAT_ABI_SOFT},
13441   {NULL, 0}
13442 };
13443
13444 struct arm_long_option_table
13445 {
13446   char *option;         /* Substring to match.  */
13447   char *help;           /* Help information.  */
13448   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
13449   char *deprecated;     /* If non-null, print this message.  */
13450 };
13451
13452 static int
13453 arm_parse_extension (str, opt_p)
13454      char *str;
13455      int *opt_p;
13456 {
13457   while (str != NULL && *str != 0)
13458     {
13459       struct arm_arch_extension_table *opt;
13460       char *ext;
13461       int optlen;
13462
13463       if (*str != '+')
13464         {
13465           as_bad (_("invalid architectural extension"));
13466           return 0;
13467         }
13468
13469       str++;
13470       ext = strchr (str, '+');
13471
13472       if (ext != NULL)
13473         optlen = ext - str;
13474       else
13475         optlen = strlen (str);
13476
13477       if (optlen == 0)
13478         {
13479           as_bad (_("missing architectural extension"));
13480           return 0;
13481         }
13482
13483       for (opt = arm_extensions; opt->name != NULL; opt++)
13484         if (strncmp (opt->name, str, optlen) == 0)
13485           {
13486             *opt_p |= opt->value;
13487             break;
13488           }
13489
13490       if (opt->name == NULL)
13491         {
13492           as_bad (_("unknown architectural extnsion `%s'"), str);
13493           return 0;
13494         }
13495
13496       str = ext;
13497     };
13498
13499   return 1;
13500 }
13501
13502 static int
13503 arm_parse_cpu (str)
13504      char *str;
13505 {
13506   struct arm_cpu_option_table *opt;
13507   char *ext = strchr (str, '+');
13508   int optlen;
13509
13510   if (ext != NULL)
13511     optlen = ext - str;
13512   else
13513     optlen = strlen (str);
13514
13515   if (optlen == 0)
13516     {
13517       as_bad (_("missing cpu name `%s'"), str);
13518       return 0;
13519     }
13520
13521   for (opt = arm_cpus; opt->name != NULL; opt++)
13522     if (strncmp (opt->name, str, optlen) == 0)
13523       {
13524         mcpu_cpu_opt = opt->value;
13525         mcpu_fpu_opt = opt->default_fpu;
13526
13527         if (ext != NULL)
13528           return arm_parse_extension (ext, &mcpu_cpu_opt);
13529
13530         return 1;
13531       }
13532
13533   as_bad (_("unknown cpu `%s'"), str);
13534   return 0;
13535 }
13536
13537 static int
13538 arm_parse_arch (str)
13539      char *str;
13540 {
13541   struct arm_arch_option_table *opt;
13542   char *ext = strchr (str, '+');
13543   int optlen;
13544
13545   if (ext != NULL)
13546     optlen = ext - str;
13547   else
13548     optlen = strlen (str);
13549
13550   if (optlen == 0)
13551     {
13552       as_bad (_("missing architecture name `%s'"), str);
13553       return 0;
13554     }
13555
13556
13557   for (opt = arm_archs; opt->name != NULL; opt++)
13558     if (strcmp (opt->name, str) == 0)
13559       {
13560         march_cpu_opt = opt->value;
13561         march_fpu_opt = opt->default_fpu;
13562
13563         if (ext != NULL)
13564           return arm_parse_extension (ext, &march_cpu_opt);
13565
13566         return 1;
13567       }
13568
13569   as_bad (_("unknown architecture `%s'\n"), str);
13570   return 0;
13571 }
13572
13573 static int
13574 arm_parse_fpu (str)
13575      char *str;
13576 {
13577   struct arm_fpu_option_table *opt;
13578
13579   for (opt = arm_fpus; opt->name != NULL; opt++)
13580     if (strcmp (opt->name, str) == 0)
13581       {
13582         mfpu_opt = opt->value;
13583         return 1;
13584       }
13585
13586   as_bad (_("unknown floating point format `%s'\n"), str);
13587   return 0;
13588 }
13589
13590 static int
13591 arm_parse_float_abi (str)
13592      char * str;
13593 {
13594   struct arm_float_abi_option_table *opt;
13595
13596   for (opt = arm_float_abis; opt->name != NULL; opt++)
13597     if (strcmp (opt->name, str) == 0)
13598       {
13599         mfloat_abi_opt = opt->value;
13600         return 1;
13601       }
13602
13603   as_bad (_("unknown floating point abi `%s'\n"), str);
13604   return 0;
13605 }
13606
13607 struct arm_long_option_table arm_long_opts[] =
13608 {
13609   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13610    arm_parse_cpu, NULL},
13611   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13612    arm_parse_arch, NULL},
13613   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13614    arm_parse_fpu, NULL},
13615   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13616    arm_parse_float_abi, NULL},
13617   {NULL, NULL, 0, NULL}
13618 };
13619
13620 int
13621 md_parse_option (c, arg)
13622      int    c;
13623      char * arg;
13624 {
13625   struct arm_option_table *opt;
13626   struct arm_long_option_table *lopt;
13627
13628   switch (c)
13629     {
13630 #ifdef OPTION_EB
13631     case OPTION_EB:
13632       target_big_endian = 1;
13633       break;
13634 #endif
13635
13636 #ifdef OPTION_EL
13637     case OPTION_EL:
13638       target_big_endian = 0;
13639       break;
13640 #endif
13641
13642     case 'a':
13643       /* Listing option.  Just ignore these, we don't support additional
13644          ones.  */
13645       return 0;
13646
13647     default:
13648       for (opt = arm_opts; opt->option != NULL; opt++)
13649         {
13650           if (c == opt->option[0]
13651               && ((arg == NULL && opt->option[1] == 0)
13652                   || strcmp (arg, opt->option + 1) == 0))
13653             {
13654 #if WARN_DEPRECATED
13655               /* If the option is deprecated, tell the user.  */
13656               if (opt->deprecated != NULL)
13657                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13658                            arg ? arg : "", _(opt->deprecated));
13659 #endif
13660
13661               if (opt->var != NULL)
13662                 *opt->var = opt->value;
13663
13664               return 1;
13665             }
13666         }
13667
13668       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13669         {
13670           /* These options are expected to have an argument.  */
13671           if (c == lopt->option[0]
13672               && arg != NULL
13673               && strncmp (arg, lopt->option + 1,
13674                           strlen (lopt->option + 1)) == 0)
13675             {
13676 #if WARN_DEPRECATED
13677               /* If the option is deprecated, tell the user.  */
13678               if (lopt->deprecated != NULL)
13679                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13680                            _(lopt->deprecated));
13681 #endif
13682
13683               /* Call the sup-option parser.  */
13684               return (*lopt->func)(arg + strlen (lopt->option) - 1);
13685             }
13686         }
13687
13688       as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13689       return 0;
13690     }
13691
13692   return 1;
13693 }
13694
13695 void
13696 md_show_usage (fp)
13697      FILE * fp;
13698 {
13699   struct arm_option_table *opt;
13700   struct arm_long_option_table *lopt;
13701
13702   fprintf (fp, _(" ARM-specific assembler options:\n"));
13703
13704   for (opt = arm_opts; opt->option != NULL; opt++)
13705     if (opt->help != NULL)
13706       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13707
13708   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13709     if (lopt->help != NULL)
13710       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13711
13712 #ifdef OPTION_EB
13713   fprintf (fp, _("\
13714   -EB                     assemble code for a big-endian cpu\n"));
13715 #endif
13716
13717 #ifdef OPTION_EL
13718   fprintf (fp, _("\
13719   -EL                     assemble code for a little-endian cpu\n"));
13720 #endif
13721 }
13722
13723 /* We need to be able to fix up arbitrary expressions in some statements.
13724    This is so that we can handle symbols that are an arbitrary distance from
13725    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13726    which returns part of an address in a form which will be valid for
13727    a data instruction.  We do this by pushing the expression into a symbol
13728    in the expr_section, and creating a fix for that.  */
13729
13730 static void
13731 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13732      fragS *       frag;
13733      int           where;
13734      short int     size;
13735      expressionS * exp;
13736      int           pc_rel;
13737      int           reloc;
13738 {
13739   fixS *           new_fix;
13740   arm_fix_data *   arm_data;
13741
13742   switch (exp->X_op)
13743     {
13744     case O_constant:
13745     case O_symbol:
13746     case O_add:
13747     case O_subtract:
13748       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13749       break;
13750
13751     default:
13752       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13753                          pc_rel, reloc);
13754       break;
13755     }
13756
13757   /* Mark whether the fix is to a THUMB instruction, or an ARM
13758      instruction.  */
13759   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13760   new_fix->tc_fix_data = (PTR) arm_data;
13761   arm_data->thumb_mode = thumb_mode;
13762 }
13763
13764 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13765
13766 void
13767 cons_fix_new_arm (frag, where, size, exp)
13768      fragS *       frag;
13769      int           where;
13770      int           size;
13771      expressionS * exp;
13772 {
13773   bfd_reloc_code_real_type type;
13774   int pcrel = 0;
13775
13776   /* Pick a reloc.
13777      FIXME: @@ Should look at CPU word size.  */
13778   switch (size)
13779     {
13780     case 1:
13781       type = BFD_RELOC_8;
13782       break;
13783     case 2:
13784       type = BFD_RELOC_16;
13785       break;
13786     case 4:
13787     default:
13788       type = BFD_RELOC_32;
13789       break;
13790     case 8:
13791       type = BFD_RELOC_64;
13792       break;
13793     }
13794
13795   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13796 }
13797
13798 /* A good place to do this, although this was probably not intended
13799    for this kind of use.  We need to dump the literal pool before
13800    references are made to a null symbol pointer.  */
13801
13802 void
13803 arm_cleanup ()
13804 {
13805   literal_pool * pool;
13806
13807   for (pool = list_of_pools; pool; pool = pool->next)
13808     {
13809       /* Put it at the end of the relevent section.  */
13810       subseg_set (pool->section, pool->sub_section);
13811 #ifdef OBJ_ELF
13812       arm_elf_change_section ();
13813 #endif
13814       s_ltorg (0);
13815     }
13816 }
13817
13818 void
13819 arm_start_line_hook ()
13820 {
13821   last_label_seen = NULL;
13822 }
13823
13824 void
13825 arm_frob_label (sym)
13826      symbolS * sym;
13827 {
13828   last_label_seen = sym;
13829
13830   ARM_SET_THUMB (sym, thumb_mode);
13831
13832 #if defined OBJ_COFF || defined OBJ_ELF
13833   ARM_SET_INTERWORK (sym, support_interwork);
13834 #endif
13835
13836   /* Note - do not allow local symbols (.Lxxx) to be labeled
13837      as Thumb functions.  This is because these labels, whilst
13838      they exist inside Thumb code, are not the entry points for
13839      possible ARM->Thumb calls.  Also, these labels can be used
13840      as part of a computed goto or switch statement.  eg gcc
13841      can generate code that looks like this:
13842
13843                 ldr  r2, [pc, .Laaa]
13844                 lsl  r3, r3, #2
13845                 ldr  r2, [r3, r2]
13846                 mov  pc, r2
13847
13848        .Lbbb:  .word .Lxxx
13849        .Lccc:  .word .Lyyy
13850        ..etc...
13851        .Laaa:   .word Lbbb
13852
13853      The first instruction loads the address of the jump table.
13854      The second instruction converts a table index into a byte offset.
13855      The third instruction gets the jump address out of the table.
13856      The fourth instruction performs the jump.
13857
13858      If the address stored at .Laaa is that of a symbol which has the
13859      Thumb_Func bit set, then the linker will arrange for this address
13860      to have the bottom bit set, which in turn would mean that the
13861      address computation performed by the third instruction would end
13862      up with the bottom bit set.  Since the ARM is capable of unaligned
13863      word loads, the instruction would then load the incorrect address
13864      out of the jump table, and chaos would ensue.  */
13865   if (label_is_thumb_function_name
13866       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13867       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13868     {
13869       /* When the address of a Thumb function is taken the bottom
13870          bit of that address should be set.  This will allow
13871          interworking between Arm and Thumb functions to work
13872          correctly.  */
13873
13874       THUMB_SET_FUNC (sym, 1);
13875
13876       label_is_thumb_function_name = FALSE;
13877     }
13878 }
13879
13880 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13881    ARM ones.  */
13882
13883 void
13884 arm_adjust_symtab ()
13885 {
13886 #ifdef OBJ_COFF
13887   symbolS * sym;
13888
13889   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13890     {
13891       if (ARM_IS_THUMB (sym))
13892         {
13893           if (THUMB_IS_FUNC (sym))
13894             {
13895               /* Mark the symbol as a Thumb function.  */
13896               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13897                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13898                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13899
13900               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13901                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13902               else
13903                 as_bad (_("%s: unexpected function type: %d"),
13904                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13905             }
13906           else switch (S_GET_STORAGE_CLASS (sym))
13907             {
13908             case C_EXT:
13909               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13910               break;
13911             case C_STAT:
13912               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13913               break;
13914             case C_LABEL:
13915               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13916               break;
13917             default:
13918               /* Do nothing.  */
13919               break;
13920             }
13921         }
13922
13923       if (ARM_IS_INTERWORK (sym))
13924         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13925     }
13926 #endif
13927 #ifdef OBJ_ELF
13928   symbolS * sym;
13929   char      bind;
13930
13931   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13932     {
13933       if (ARM_IS_THUMB (sym))
13934         {
13935           elf_symbol_type * elf_sym;
13936
13937           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13938           bind = ELF_ST_BIND (elf_sym);
13939
13940           /* If it's a .thumb_func, declare it as so,
13941              otherwise tag label as .code 16.  */
13942           if (THUMB_IS_FUNC (sym))
13943             elf_sym->internal_elf_sym.st_info =
13944               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13945           else
13946             elf_sym->internal_elf_sym.st_info =
13947               ELF_ST_INFO (bind, STT_ARM_16BIT);
13948         }
13949     }
13950 #endif
13951 }
13952
13953 int
13954 arm_data_in_code ()
13955 {
13956   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13957     {
13958       *input_line_pointer = '/';
13959       input_line_pointer += 5;
13960       *input_line_pointer = 0;
13961       return 1;
13962     }
13963
13964   return 0;
13965 }
13966
13967 char *
13968 arm_canonicalize_symbol_name (name)
13969      char * name;
13970 {
13971   int len;
13972
13973   if (thumb_mode && (len = strlen (name)) > 5
13974       && streq (name + len - 5, "/data"))
13975     *(name + len - 5) = 0;
13976
13977   return name;
13978 }
13979
13980 #if defined OBJ_COFF || defined OBJ_ELF
13981 void
13982 arm_validate_fix (fixP)
13983      fixS * fixP;
13984 {
13985   /* If the destination of the branch is a defined symbol which does not have
13986      the THUMB_FUNC attribute, then we must be calling a function which has
13987      the (interfacearm) attribute.  We look for the Thumb entry point to that
13988      function and change the branch to refer to that function instead.  */
13989   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13990       && fixP->fx_addsy != NULL
13991       && S_IS_DEFINED (fixP->fx_addsy)
13992       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13993     {
13994       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13995     }
13996 }
13997 #endif
13998
13999 int
14000 arm_force_relocation (fixp)
14001      struct fix * fixp;
14002 {
14003 #if defined (OBJ_COFF) && defined (TE_PE)
14004   if (fixp->fx_r_type == BFD_RELOC_RVA)
14005     return 1;
14006 #endif
14007 #ifdef OBJ_ELF
14008   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14009       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14010       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14011       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14012     return 1;
14013 #endif
14014
14015   /* Resolve these relocations even if the symbol is extern or weak.  */
14016   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14017       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14018       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14019     return 0;
14020
14021   return generic_force_reloc (fixp);
14022 }
14023
14024 #ifdef OBJ_COFF
14025 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
14026    local labels from being added to the output symbol table when they
14027    are used with the ADRL pseudo op.  The ADRL relocation should always
14028    be resolved before the binbary is emitted, so it is safe to say that
14029    it is adjustable.  */
14030
14031 bfd_boolean
14032 arm_fix_adjustable (fixP)
14033    fixS * fixP;
14034 {
14035   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14036     return 1;
14037   return 0;
14038 }
14039 #endif
14040
14041 #ifdef OBJ_ELF
14042 /* Relocations against Thumb function names must be left unadjusted,
14043    so that the linker can use this information to correctly set the
14044    bottom bit of their addresses.  The MIPS version of this function
14045    also prevents relocations that are mips-16 specific, but I do not
14046    know why it does this.
14047
14048    FIXME:
14049    There is one other problem that ought to be addressed here, but
14050    which currently is not:  Taking the address of a label (rather
14051    than a function) and then later jumping to that address.  Such
14052    addresses also ought to have their bottom bit set (assuming that
14053    they reside in Thumb code), but at the moment they will not.  */
14054
14055 bfd_boolean
14056 arm_fix_adjustable (fixP)
14057    fixS * fixP;
14058 {
14059   if (fixP->fx_addsy == NULL)
14060     return 1;
14061
14062   if (THUMB_IS_FUNC (fixP->fx_addsy)
14063       && fixP->fx_subsy == NULL)
14064     return 0;
14065
14066   /* We need the symbol name for the VTABLE entries.  */
14067   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14068       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14069     return 0;
14070
14071   /* Don't allow symbols to be discarded on GOT related relocs.  */
14072   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14073       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14074       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14075     return 0;
14076
14077   return 1;
14078 }
14079
14080 const char *
14081 elf32_arm_target_format ()
14082 {
14083   if (target_big_endian)
14084     {
14085       if (target_oabi)
14086         return "elf32-bigarm-oabi";
14087       else
14088         return "elf32-bigarm";
14089     }
14090   else
14091     {
14092       if (target_oabi)
14093         return "elf32-littlearm-oabi";
14094       else
14095         return "elf32-littlearm";
14096     }
14097 }
14098
14099 void
14100 armelf_frob_symbol (symp, puntp)
14101      symbolS * symp;
14102      int *     puntp;
14103 {
14104   elf_frob_symbol (symp, puntp);
14105 }
14106
14107 static bfd_reloc_code_real_type
14108 arm_parse_reloc ()
14109 {
14110   char         id [16];
14111   char *       ip;
14112   unsigned int i;
14113   static struct
14114   {
14115     char * str;
14116     int    len;
14117     bfd_reloc_code_real_type reloc;
14118   }
14119   reloc_map[] =
14120   {
14121 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14122     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14123     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14124     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14125        branch instructions generated by GCC for PLT relocs.  */
14126     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14127     { NULL, 0,         BFD_RELOC_UNUSED }
14128 #undef MAP
14129   };
14130
14131   for (i = 0, ip = input_line_pointer;
14132        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14133        i++, ip++)
14134     id[i] = TOLOWER (*ip);
14135
14136   for (i = 0; reloc_map[i].str; i++)
14137     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14138       break;
14139
14140   input_line_pointer += reloc_map[i].len;
14141
14142   return reloc_map[i].reloc;
14143 }
14144
14145 static void
14146 s_arm_elf_cons (nbytes)
14147      int nbytes;
14148 {
14149   expressionS exp;
14150
14151 #ifdef md_flush_pending_output
14152   md_flush_pending_output ();
14153 #endif
14154
14155   if (is_it_end_of_statement ())
14156     {
14157       demand_empty_rest_of_line ();
14158       return;
14159     }
14160
14161 #ifdef md_cons_align
14162   md_cons_align (nbytes);
14163 #endif
14164
14165   mapping_state (MAP_DATA);
14166   do
14167     {
14168       bfd_reloc_code_real_type reloc;
14169
14170       expression (& exp);
14171
14172       if (exp.X_op == O_symbol
14173           && * input_line_pointer == '('
14174           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14175         {
14176           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14177           int size = bfd_get_reloc_size (howto);
14178
14179           if (size > nbytes)
14180             as_bad ("%s relocations do not fit in %d bytes",
14181                     howto->name, nbytes);
14182           else
14183             {
14184               register char *p = frag_more ((int) nbytes);
14185               int offset = nbytes - size;
14186
14187               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14188                            &exp, 0, reloc);
14189             }
14190         }
14191       else
14192         emit_expr (&exp, (unsigned int) nbytes);
14193     }
14194   while (*input_line_pointer++ == ',');
14195
14196   /* Put terminator back into stream.  */
14197   input_line_pointer --;
14198   demand_empty_rest_of_line ();
14199 }
14200
14201 #endif /* OBJ_ELF */
14202
14203 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14204    of an rs_align_code fragment.  */
14205
14206 void
14207 arm_handle_align (fragP)
14208      fragS *fragP;
14209 {
14210   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14211   static char const thumb_noop[2] = { 0xc0, 0x46 };
14212   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14213   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14214
14215   int bytes, fix, noop_size;
14216   char * p;
14217   const char * noop;
14218
14219   if (fragP->fr_type != rs_align_code)
14220     return;
14221
14222   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14223   p = fragP->fr_literal + fragP->fr_fix;
14224   fix = 0;
14225
14226   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14227     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14228
14229   if (fragP->tc_frag_data)
14230     {
14231       if (target_big_endian)
14232         noop = thumb_bigend_noop;
14233       else
14234         noop = thumb_noop;
14235       noop_size = sizeof (thumb_noop);
14236     }
14237   else
14238     {
14239       if (target_big_endian)
14240         noop = arm_bigend_noop;
14241       else
14242         noop = arm_noop;
14243       noop_size = sizeof (arm_noop);
14244     }
14245
14246   if (bytes & (noop_size - 1))
14247     {
14248       fix = bytes & (noop_size - 1);
14249       memset (p, 0, fix);
14250       p += fix;
14251       bytes -= fix;
14252     }
14253
14254   while (bytes >= noop_size)
14255     {
14256       memcpy (p, noop, noop_size);
14257       p += noop_size;
14258       bytes -= noop_size;
14259       fix += noop_size;
14260     }
14261
14262   fragP->fr_fix += fix;
14263   fragP->fr_var = noop_size;
14264 }
14265
14266 /* Called from md_do_align.  Used to create an alignment
14267    frag in a code section.  */
14268
14269 void
14270 arm_frag_align_code (n, max)
14271      int n;
14272      int max;
14273 {
14274   char * p;
14275
14276   /* We assume that there will never be a requirement
14277      to support alignments greater than 32 bytes.  */
14278   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14279     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14280
14281   p = frag_var (rs_align_code,
14282                 MAX_MEM_FOR_RS_ALIGN_CODE,
14283                 1,
14284                 (relax_substateT) max,
14285                 (symbolS *) NULL,
14286                 (offsetT) n,
14287                 (char *) NULL);
14288   *p = 0;
14289
14290 }
14291
14292 /* Perform target specific initialisation of a frag.  */
14293
14294 void
14295 arm_init_frag (fragP)
14296      fragS *fragP;
14297 {
14298   /* Record whether this frag is in an ARM or a THUMB area.  */
14299   fragP->tc_frag_data = thumb_mode;
14300 }