Fix handling of case sensitive register aliases and add a test for the bug
[external/binutils.git] / 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 #ifdef OBJ_ELF
195 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
196 #endif
197
198 /* This array holds the chars that always start a comment.  If the
199    pre-processor is disabled, these aren't very useful.  */
200 const char comment_chars[] = "@";
201
202 /* This array holds the chars that only start a comment at the beginning of
203    a line.  If the line seems to have the form '# 123 filename'
204    .line and .file directives will appear in the pre-processed output.  */
205 /* Note that input_file.c hand checks for '#' at the beginning of the
206    first line of the input file.  This is because the compiler outputs
207    #NO_APP at the beginning of its output.  */
208 /* Also note that comments like this one will always work.  */
209 const char line_comment_chars[] = "#";
210
211 const char line_separator_chars[] = ";";
212
213 /* Chars that can be used to separate mant
214    from exp in floating point numbers.  */
215 const char EXP_CHARS[] = "eE";
216
217 /* Chars that mean this number is a floating point constant.  */
218 /* As in 0f12.456  */
219 /* or    0d1.2345e12  */
220
221 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
222
223 /* Prefix characters that indicate the start of an immediate
224    value.  */
225 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
226
227 #ifdef OBJ_ELF
228 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
229 symbolS * GOT_symbol;
230 #endif
231
232 /* Size of relocation record.  */
233 const int md_reloc_size = 8;
234
235 /* 0: assemble for ARM,
236    1: assemble for Thumb,
237    2: assemble for Thumb even though target CPU does not support thumb
238       instructions.  */
239 static int thumb_mode = 0;
240
241 typedef struct arm_fix
242 {
243   int thumb_mode;
244 } arm_fix_data;
245
246 struct arm_it
247 {
248   const char *  error;
249   unsigned long instruction;
250   int           size;
251   struct
252   {
253     bfd_reloc_code_real_type type;
254     expressionS              exp;
255     int                      pc_rel;
256   } reloc;
257 };
258
259 struct arm_it inst;
260
261 enum asm_shift_index
262 {
263   SHIFT_LSL = 0,
264   SHIFT_LSR,
265   SHIFT_ASR,
266   SHIFT_ROR,
267   SHIFT_RRX
268 };
269
270 struct asm_shift_properties
271 {
272   enum asm_shift_index index;
273   unsigned long        bit_field;
274   unsigned int         allows_0  : 1;
275   unsigned int         allows_32 : 1;
276 };
277
278 static const struct asm_shift_properties shift_properties [] =
279 {
280   { SHIFT_LSL, 0,    1, 0},
281   { SHIFT_LSR, 0x20, 0, 1},
282   { SHIFT_ASR, 0x40, 0, 1},
283   { SHIFT_ROR, 0x60, 0, 0},
284   { SHIFT_RRX, 0x60, 0, 0}
285 };
286
287 struct asm_shift_name
288 {
289   const char *                        name;
290   const struct asm_shift_properties * properties;
291 };
292
293 static const struct asm_shift_name shift_names [] =
294 {
295   { "asl", shift_properties + SHIFT_LSL },
296   { "lsl", shift_properties + SHIFT_LSL },
297   { "lsr", shift_properties + SHIFT_LSR },
298   { "asr", shift_properties + SHIFT_ASR },
299   { "ror", shift_properties + SHIFT_ROR },
300   { "rrx", shift_properties + SHIFT_RRX },
301   { "ASL", shift_properties + SHIFT_LSL },
302   { "LSL", shift_properties + SHIFT_LSL },
303   { "LSR", shift_properties + SHIFT_LSR },
304   { "ASR", shift_properties + SHIFT_ASR },
305   { "ROR", shift_properties + SHIFT_ROR },
306   { "RRX", shift_properties + SHIFT_RRX }
307 };
308
309 /* Any kind of shift is accepted.  */
310 #define NO_SHIFT_RESTRICT 1
311 /* The shift operand must be an immediate value, not a register.  */
312 #define SHIFT_IMMEDIATE   0
313 /* The shift must be LSL or ASR and the operand must be an immediate.  */
314 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
315 /* The shift must be ASR and the operand must be an immediate.  */
316 #define SHIFT_ASR_IMMEDIATE 3
317 /* The shift must be LSL and the operand must be an immediate.  */
318 #define SHIFT_LSL_IMMEDIATE 4
319
320 #define NUM_FLOAT_VALS 8
321
322 const char * fp_const[] =
323 {
324   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
325 };
326
327 /* Number of littlenums required to hold an extended precision number.  */
328 #define MAX_LITTLENUMS 6
329
330 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
331
332 #define FAIL    (-1)
333 #define SUCCESS (0)
334
335 /* Whether a Co-processor load/store operation accepts write-back forms.  */
336 #define CP_WB_OK 1
337 #define CP_NO_WB 0
338
339 #define SUFF_S 1
340 #define SUFF_D 2
341 #define SUFF_E 3
342 #define SUFF_P 4
343
344 #define CP_T_X   0x00008000
345 #define CP_T_Y   0x00400000
346 #define CP_T_Pre 0x01000000
347 #define CP_T_UD  0x00800000
348 #define CP_T_WB  0x00200000
349
350 #define CONDS_BIT        0x00100000
351 #define LOAD_BIT         0x00100000
352
353 #define DOUBLE_LOAD_FLAG 0x00000001
354
355 struct asm_cond
356 {
357   const char *  template;
358   unsigned long value;
359 };
360
361 #define COND_ALWAYS 0xe0000000
362 #define COND_MASK   0xf0000000
363
364 static const struct asm_cond conds[] =
365 {
366   {"eq", 0x00000000},
367   {"ne", 0x10000000},
368   {"cs", 0x20000000}, {"hs", 0x20000000},
369   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
370   {"mi", 0x40000000},
371   {"pl", 0x50000000},
372   {"vs", 0x60000000},
373   {"vc", 0x70000000},
374   {"hi", 0x80000000},
375   {"ls", 0x90000000},
376   {"ge", 0xa0000000},
377   {"lt", 0xb0000000},
378   {"gt", 0xc0000000},
379   {"le", 0xd0000000},
380   {"al", 0xe0000000},
381   {"nv", 0xf0000000}
382 };
383
384 struct asm_psr
385 {
386   const char *template;
387   bfd_boolean cpsr;
388   unsigned long field;
389 };
390
391 /* The bit that distinguishes CPSR and SPSR.  */
392 #define SPSR_BIT   (1 << 22)
393
394 /* How many bits to shift the PSR_xxx bits up by.  */
395 #define PSR_SHIFT  16
396
397 #define PSR_c   (1 << 0)
398 #define PSR_x   (1 << 1)
399 #define PSR_s   (1 << 2)
400 #define PSR_f   (1 << 3)
401
402 static const struct asm_psr psrs[] =
403 {
404   {"CPSR",      TRUE,  PSR_c | PSR_f},
405   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
406   {"SPSR",      FALSE, PSR_c | PSR_f},
407   {"SPSR_all",  FALSE, PSR_c | PSR_f},
408   {"CPSR_flg",  TRUE,  PSR_f},
409   {"CPSR_f",    TRUE,  PSR_f},
410   {"SPSR_flg",  FALSE, PSR_f},
411   {"SPSR_f",    FALSE, PSR_f},
412   {"CPSR_c",    TRUE,  PSR_c},
413   {"CPSR_ctl",  TRUE,  PSR_c},
414   {"SPSR_c",    FALSE, PSR_c},
415   {"SPSR_ctl",  FALSE, PSR_c},
416   {"CPSR_x",    TRUE,  PSR_x},
417   {"CPSR_s",    TRUE,  PSR_s},
418   {"SPSR_x",    FALSE, PSR_x},
419   {"SPSR_s",    FALSE, PSR_s},
420   /* Combinations of flags.  */
421   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
422   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
423   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
424   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
425   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
426   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
427   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
428   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
429   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
430   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
431   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
432   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
433   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
434   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
435   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
436   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
437   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
438   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
439   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
440   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
441   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
442   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
443   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
444   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
445   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
446   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
447   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
448   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
449   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
450   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
451   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
452   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
453   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
454   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
455   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
456   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
457   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
458   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
459   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
460   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
461   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
462   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
463   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
464   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
465   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
466   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
467   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
468   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
469   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
470   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
471   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
472   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
473   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
474   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
475   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
476   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
477   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
478   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
479   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
480   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
481   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
482   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
483   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
484   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
485   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
486   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
487   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
488   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
489   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
490   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
491   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
492   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
493   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
494   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
495   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
496   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
497   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
498   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
499   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
500   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
501   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
502   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
503   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
504   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
505   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
506   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
507   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
508   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
509   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
510   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
511   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
512   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
513   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
514   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
515   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
516   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
517   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
518   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
519   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
520   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
521   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
522   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
523   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
524   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
525   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
526   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
527   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
528   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
529   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
530   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
531   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
532   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
533   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
534   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
535   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
536   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
537   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
538   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
539   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
540   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
541 };
542
543 enum wreg_type
544   {
545     IWMMXT_REG_WR = 0,
546     IWMMXT_REG_WC = 1,
547     IWMMXT_REG_WR_OR_WC = 2,
548     IWMMXT_REG_WCG
549   };
550
551 enum iwmmxt_insn_type
552 {
553   check_rd,
554   check_wr,
555   check_wrwr,
556   check_wrwrwr,
557   check_wrwrwcg,
558   check_tbcst,
559   check_tmovmsk,
560   check_tmia,
561   check_tmcrr,
562   check_tmrrc,
563   check_tmcr,
564   check_tmrc,
565   check_tinsr,
566   check_textrc,
567   check_waligni,
568   check_textrm,
569   check_wshufh
570 };
571
572 enum vfp_dp_reg_pos
573 {
574   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
575 };
576
577 enum vfp_sp_reg_pos
578 {
579   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
580 };
581
582 enum vfp_ldstm_type
583 {
584   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
585 };
586
587 /* VFP system registers.  */
588 struct vfp_reg
589 {
590   const char *name;
591   unsigned long regno;
592 };
593
594 static const struct vfp_reg vfp_regs[] =
595 {
596   {"fpsid", 0x00000000},
597   {"FPSID", 0x00000000},
598   {"fpscr", 0x00010000},
599   {"FPSCR", 0x00010000},
600   {"fpexc", 0x00080000},
601   {"FPEXC", 0x00080000}
602 };
603
604 /* Structure for a hash table entry for a register.  */
605 struct reg_entry
606 {
607   const char * name;
608   int          number;
609   bfd_boolean  builtin;
610 };
611
612 /* Some well known registers that we refer to directly elsewhere.  */
613 #define REG_SP  13
614 #define REG_LR  14
615 #define REG_PC  15
616
617 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
618 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
619 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
620
621 /* These are the standard names.  Users can add aliases with .req.
622    and delete them with .unreq.  */
623
624 /* Integer Register Numbers.  */
625 static const struct reg_entry rn_table[] =
626 {
627   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
628   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
629   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
630   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
631   /* ATPCS Synonyms.  */
632   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
633   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
634   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
635   /* Well-known aliases.  */
636   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
637   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
638   {NULL, 0, TRUE}
639 };
640
641 #define WR_PREFIX 0x200
642 #define WC_PREFIX 0x400
643
644 static const struct reg_entry iwmmxt_table[] =
645 {
646   /* Intel Wireless MMX technology register names.  */
647   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
648   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
649   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
650   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
651   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
652   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
653   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
654   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
655   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
656   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
657   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
658   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
659
660   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
661   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
662   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
663   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
664   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
665   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
666   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
667   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
668   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
669   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
670   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
671   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
672   {NULL, 0, TRUE}
673 };
674
675 /* Co-processor Numbers.  */
676 static const struct reg_entry cp_table[] =
677 {
678   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
679   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
680   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
681   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
682   {NULL, 0, TRUE}
683 };
684
685 /* Co-processor Register Numbers.  */
686 static const struct reg_entry cn_table[] =
687 {
688   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
689   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
690   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
691   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
692   /* Not really valid, but kept for back-wards compatibility.  */
693   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
694   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
695   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
696   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
697   {NULL, 0, TRUE}
698 };
699
700 /* FPA Registers.  */
701 static const struct reg_entry fn_table[] =
702 {
703   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
704   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
705   {NULL, 0, TRUE}
706 };
707
708 /* VFP SP Registers.  */
709 static const struct reg_entry sn_table[] =
710 {
711   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
712   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
713   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
714   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
715   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
716   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
717   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
718   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
719   {NULL, 0, TRUE}
720 };
721
722 /* VFP DP Registers.  */
723 static const struct reg_entry dn_table[] =
724 {
725   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
726   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
727   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
728   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
729   {NULL, 0, TRUE}
730 };
731
732 /* Maverick DSP coprocessor registers.  */
733 static const struct reg_entry mav_mvf_table[] =
734 {
735   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
736   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
737   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
738   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
739   {NULL, 0, TRUE}
740 };
741
742 static const struct reg_entry mav_mvd_table[] =
743 {
744   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
745   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
746   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
747   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
748   {NULL, 0, TRUE}
749 };
750
751 static const struct reg_entry mav_mvfx_table[] =
752 {
753   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
754   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
755   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
756   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
757   {NULL, 0, TRUE}
758 };
759
760 static const struct reg_entry mav_mvdx_table[] =
761 {
762   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
763   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
764   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
765   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
766   {NULL, 0, TRUE}
767 };
768
769 static const struct reg_entry mav_mvax_table[] =
770 {
771   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
772   {NULL, 0, TRUE}
773 };
774
775 static const struct reg_entry mav_dspsc_table[] =
776 {
777   {"dspsc", 0, TRUE},
778   {NULL, 0, TRUE}
779 };
780
781 struct reg_map
782 {
783   const struct reg_entry *names;
784   int max_regno;
785   struct hash_control *htab;
786   const char *expected;
787 };
788
789 struct reg_map all_reg_maps[] =
790 {
791   {rn_table,        15, NULL, N_("ARM register expected")},
792   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
793   {cn_table,        15, NULL, N_("co-processor register expected")},
794   {fn_table,         7, NULL, N_("FPA register expected")},
795   {sn_table,        31, NULL, N_("VFP single precision register expected")},
796   {dn_table,        15, NULL, N_("VFP double precision register expected")},
797   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
798   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
799   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
800   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
801   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
802   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
803   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
804 };
805
806 /* Enumeration matching entries in table above.  */
807 enum arm_reg_type
808 {
809   REG_TYPE_RN = 0,
810 #define REG_TYPE_FIRST REG_TYPE_RN
811   REG_TYPE_CP = 1,
812   REG_TYPE_CN = 2,
813   REG_TYPE_FN = 3,
814   REG_TYPE_SN = 4,
815   REG_TYPE_DN = 5,
816   REG_TYPE_MVF = 6,
817   REG_TYPE_MVD = 7,
818   REG_TYPE_MVFX = 8,
819   REG_TYPE_MVDX = 9,
820   REG_TYPE_MVAX = 10,
821   REG_TYPE_DSPSC = 11,
822   REG_TYPE_IWMMXT = 12,
823
824   REG_TYPE_MAX = 13
825 };
826
827 /* Functions called by parser.  */
828 /* ARM instructions.  */
829 static void do_arit             PARAMS ((char *));
830 static void do_cmp              PARAMS ((char *));
831 static void do_mov              PARAMS ((char *));
832 static void do_ldst             PARAMS ((char *));
833 static void do_ldstt            PARAMS ((char *));
834 static void do_ldmstm           PARAMS ((char *));
835 static void do_branch           PARAMS ((char *));
836 static void do_swi              PARAMS ((char *));
837
838 /* Pseudo Op codes.  */
839 static void do_adr              PARAMS ((char *));
840 static void do_adrl             PARAMS ((char *));
841 static void do_empty            PARAMS ((char *));
842
843 /* ARM v2.  */
844 static void do_mul              PARAMS ((char *));
845 static void do_mla              PARAMS ((char *));
846
847 /* ARM v2S.  */
848 static void do_swap             PARAMS ((char *));
849
850 /* ARM v3.  */
851 static void do_msr              PARAMS ((char *));
852 static void do_mrs              PARAMS ((char *));
853
854 /* ARM v3M.  */
855 static void do_mull             PARAMS ((char *));
856
857 /* ARM v4.  */
858 static void do_ldstv4           PARAMS ((char *));
859
860 /* ARM v4T.  */
861 static void do_bx               PARAMS ((char *));
862
863 /* ARM v5T.  */
864 static void do_blx              PARAMS ((char *));
865 static void do_bkpt             PARAMS ((char *));
866 static void do_clz              PARAMS ((char *));
867 static void do_lstc2            PARAMS ((char *));
868 static void do_cdp2             PARAMS ((char *));
869 static void do_co_reg2          PARAMS ((char *));
870
871 /* ARM v5TExP.  */
872 static void do_smla             PARAMS ((char *));
873 static void do_smlal            PARAMS ((char *));
874 static void do_smul             PARAMS ((char *));
875 static void do_qadd             PARAMS ((char *));
876
877 /* ARM v5TE.  */
878 static void do_pld              PARAMS ((char *));
879 static void do_ldrd             PARAMS ((char *));
880 static void do_co_reg2c         PARAMS ((char *));
881
882 /* ARM v5TEJ.  */
883 static void do_bxj              PARAMS ((char *));
884
885 /* ARM V6. */
886 static void do_cps              PARAMS ((char *));
887 static void do_cpsi             PARAMS ((char *));
888 static void do_ldrex            PARAMS ((char *));
889 static void do_pkhbt            PARAMS ((char *));
890 static void do_pkhtb            PARAMS ((char *));
891 static void do_qadd16           PARAMS ((char *));
892 static void do_rev              PARAMS ((char *));
893 static void do_rfe              PARAMS ((char *));
894 static void do_sxtah            PARAMS ((char *));
895 static void do_sxth             PARAMS ((char *));
896 static void do_setend           PARAMS ((char *));
897 static void do_smlad            PARAMS ((char *));
898 static void do_smlald           PARAMS ((char *));
899 static void do_smmul            PARAMS ((char *));
900 static void do_ssat             PARAMS ((char *));
901 static void do_usat             PARAMS ((char *));
902 static void do_srs              PARAMS ((char *));
903 static void do_ssat16           PARAMS ((char *));
904 static void do_usat16           PARAMS ((char *));
905 static void do_strex            PARAMS ((char *));
906 static void do_umaal            PARAMS ((char *));
907
908 static void do_cps_mode         PARAMS ((char **));
909 static void do_cps_flags        PARAMS ((char **, int));
910 static int do_endian_specifier  PARAMS ((char *));
911 static void do_pkh_core         PARAMS ((char *, int));
912 static void do_sat              PARAMS ((char **, int));
913 static void do_sat16            PARAMS ((char **, int));
914
915 /* Coprocessor Instructions.  */
916 static void do_cdp              PARAMS ((char *));
917 static void do_lstc             PARAMS ((char *));
918 static void do_co_reg           PARAMS ((char *));
919
920 /* FPA instructions.  */
921 static void do_fpa_ctrl         PARAMS ((char *));
922 static void do_fpa_ldst         PARAMS ((char *));
923 static void do_fpa_ldmstm       PARAMS ((char *));
924 static void do_fpa_dyadic       PARAMS ((char *));
925 static void do_fpa_monadic      PARAMS ((char *));
926 static void do_fpa_cmp          PARAMS ((char *));
927 static void do_fpa_from_reg     PARAMS ((char *));
928 static void do_fpa_to_reg       PARAMS ((char *));
929
930 /* VFP instructions.  */
931 static void do_vfp_sp_monadic   PARAMS ((char *));
932 static void do_vfp_dp_monadic   PARAMS ((char *));
933 static void do_vfp_sp_dyadic    PARAMS ((char *));
934 static void do_vfp_dp_dyadic    PARAMS ((char *));
935 static void do_vfp_reg_from_sp  PARAMS ((char *));
936 static void do_vfp_sp_from_reg  PARAMS ((char *));
937 static void do_vfp_reg2_from_sp2 PARAMS ((char *));
938 static void do_vfp_sp2_from_reg2 PARAMS ((char *));
939 static void do_vfp_reg_from_dp  PARAMS ((char *));
940 static void do_vfp_reg2_from_dp PARAMS ((char *));
941 static void do_vfp_dp_from_reg  PARAMS ((char *));
942 static void do_vfp_dp_from_reg2 PARAMS ((char *));
943 static void do_vfp_reg_from_ctrl PARAMS ((char *));
944 static void do_vfp_ctrl_from_reg PARAMS ((char *));
945 static void do_vfp_sp_ldst      PARAMS ((char *));
946 static void do_vfp_dp_ldst      PARAMS ((char *));
947 static void do_vfp_sp_ldstmia   PARAMS ((char *));
948 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
949 static void do_vfp_dp_ldstmia   PARAMS ((char *));
950 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
951 static void do_vfp_xp_ldstmia   PARAMS ((char *));
952 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
953 static void do_vfp_sp_compare_z PARAMS ((char *));
954 static void do_vfp_dp_compare_z PARAMS ((char *));
955 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
956 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
957
958 /* XScale.  */
959 static void do_xsc_mia          PARAMS ((char *));
960 static void do_xsc_mar          PARAMS ((char *));
961 static void do_xsc_mra          PARAMS ((char *));
962
963 /* Maverick.  */
964 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
965                                          enum arm_reg_type));
966 static void do_mav_binops_1a    PARAMS ((char *));
967 static void do_mav_binops_1b    PARAMS ((char *));
968 static void do_mav_binops_1c    PARAMS ((char *));
969 static void do_mav_binops_1d    PARAMS ((char *));
970 static void do_mav_binops_1e    PARAMS ((char *));
971 static void do_mav_binops_1f    PARAMS ((char *));
972 static void do_mav_binops_1g    PARAMS ((char *));
973 static void do_mav_binops_1h    PARAMS ((char *));
974 static void do_mav_binops_1i    PARAMS ((char *));
975 static void do_mav_binops_1j    PARAMS ((char *));
976 static void do_mav_binops_1k    PARAMS ((char *));
977 static void do_mav_binops_1l    PARAMS ((char *));
978 static void do_mav_binops_1m    PARAMS ((char *));
979 static void do_mav_binops_1n    PARAMS ((char *));
980 static void do_mav_binops_1o    PARAMS ((char *));
981 static void do_mav_binops_2a    PARAMS ((char *));
982 static void do_mav_binops_2b    PARAMS ((char *));
983 static void do_mav_binops_2c    PARAMS ((char *));
984 static void do_mav_binops_3a    PARAMS ((char *));
985 static void do_mav_binops_3b    PARAMS ((char *));
986 static void do_mav_binops_3c    PARAMS ((char *));
987 static void do_mav_binops_3d    PARAMS ((char *));
988 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
989                                          enum arm_reg_type,
990                                          enum arm_reg_type));
991 static void do_mav_triple_4a    PARAMS ((char *));
992 static void do_mav_triple_4b    PARAMS ((char *));
993 static void do_mav_triple_5a    PARAMS ((char *));
994 static void do_mav_triple_5b    PARAMS ((char *));
995 static void do_mav_triple_5c    PARAMS ((char *));
996 static void do_mav_triple_5d    PARAMS ((char *));
997 static void do_mav_triple_5e    PARAMS ((char *));
998 static void do_mav_triple_5f    PARAMS ((char *));
999 static void do_mav_triple_5g    PARAMS ((char *));
1000 static void do_mav_triple_5h    PARAMS ((char *));
1001 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
1002                                          enum arm_reg_type,
1003                                          enum arm_reg_type,
1004                                          enum arm_reg_type));
1005 static void do_mav_quad_6a      PARAMS ((char *));
1006 static void do_mav_quad_6b      PARAMS ((char *));
1007 static void do_mav_dspsc_1      PARAMS ((char *));
1008 static void do_mav_dspsc_2      PARAMS ((char *));
1009 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
1010                                          enum arm_reg_type));
1011 static void do_mav_shift_1      PARAMS ((char *));
1012 static void do_mav_shift_2      PARAMS ((char *));
1013 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
1014 static void do_mav_ldst_1       PARAMS ((char *));
1015 static void do_mav_ldst_2       PARAMS ((char *));
1016 static void do_mav_ldst_3       PARAMS ((char *));
1017 static void do_mav_ldst_4       PARAMS ((char *));
1018
1019 static int mav_reg_required_here        PARAMS ((char **, int,
1020                                                  enum arm_reg_type));
1021 static int mav_parse_offset     PARAMS ((char **, int *));
1022
1023 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
1024                                          int, int));
1025 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
1026 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1027 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1028 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
1029                                          fragS *));
1030 static int add_to_lit_pool      PARAMS ((void));
1031 static unsigned validate_immediate PARAMS ((unsigned));
1032 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1033                                                     unsigned int *));
1034 static int validate_offset_imm  PARAMS ((unsigned int, int));
1035 static void opcode_select       PARAMS ((int));
1036 static void end_of_line         PARAMS ((char *));
1037 static int reg_required_here    PARAMS ((char **, int));
1038 static int psr_required_here    PARAMS ((char **));
1039 static int co_proc_number       PARAMS ((char **));
1040 static int cp_opc_expr          PARAMS ((char **, int, int));
1041 static int cp_reg_required_here PARAMS ((char **, int));
1042 static int fp_reg_required_here PARAMS ((char **, int));
1043 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1044 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1045 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1046 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1047 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
1048 static long vfp_dp_reg_list     PARAMS ((char **));
1049 static int vfp_psr_required_here PARAMS ((char **str));
1050 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1051 static int cp_address_offset    PARAMS ((char **));
1052 static int cp_address_required_here     PARAMS ((char **, int));
1053 static int my_get_float_expression      PARAMS ((char **));
1054 static int skip_past_comma      PARAMS ((char **));
1055 static int walk_no_bignums      PARAMS ((symbolS *));
1056 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
1057 static int data_op2             PARAMS ((char **));
1058 static int fp_op2               PARAMS ((char **));
1059 static long reg_list            PARAMS ((char **));
1060 static void thumb_load_store    PARAMS ((char *, int, int));
1061 static int decode_shift         PARAMS ((char **, int));
1062 static int ldst_extend          PARAMS ((char **));
1063 static int ldst_extend_v4               PARAMS ((char **));
1064 static void thumb_add_sub       PARAMS ((char *, int));
1065 static void insert_reg          PARAMS ((const struct reg_entry *,
1066                                          struct hash_control *));
1067 static void thumb_shift         PARAMS ((char *, int));
1068 static void thumb_mov_compare   PARAMS ((char *, int));
1069 static void build_arm_ops_hsh   PARAMS ((void));
1070 static void set_constant_flonums        PARAMS ((void));
1071 static valueT md_chars_to_number        PARAMS ((char *, int));
1072 static void build_reg_hsh       PARAMS ((struct reg_map *));
1073 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
1074 static int create_register_alias        PARAMS ((char *, char *));
1075 static void output_inst         PARAMS ((const char *));
1076 static int accum0_required_here PARAMS ((char **));
1077 static int ld_mode_required_here PARAMS ((char **));
1078 static void do_branch25         PARAMS ((char *));
1079 static symbolS * find_real_start PARAMS ((symbolS *));
1080 #ifdef OBJ_ELF
1081 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1082 #endif
1083
1084 static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1085 static void do_iwmmxt_byte_addr PARAMS ((char *));
1086 static void do_iwmmxt_tandc     PARAMS ((char *));
1087 static void do_iwmmxt_tbcst     PARAMS ((char *));
1088 static void do_iwmmxt_textrc    PARAMS ((char *));
1089 static void do_iwmmxt_textrm    PARAMS ((char *));
1090 static void do_iwmmxt_tinsr     PARAMS ((char *));
1091 static void do_iwmmxt_tmcr      PARAMS ((char *));
1092 static void do_iwmmxt_tmcrr     PARAMS ((char *));
1093 static void do_iwmmxt_tmia      PARAMS ((char *));
1094 static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1095 static void do_iwmmxt_tmrc      PARAMS ((char *));
1096 static void do_iwmmxt_tmrrc     PARAMS ((char *));
1097 static void do_iwmmxt_torc      PARAMS ((char *));
1098 static void do_iwmmxt_waligni   PARAMS ((char *));
1099 static void do_iwmmxt_wmov      PARAMS ((char *));
1100 static void do_iwmmxt_word_addr PARAMS ((char *));
1101 static void do_iwmmxt_wrwr      PARAMS ((char *));
1102 static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1103 static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1104 static void do_iwmmxt_wshufh    PARAMS ((char *));
1105 static void do_iwmmxt_wzero     PARAMS ((char *));
1106 static int cp_byte_address_offset         PARAMS ((char **));
1107 static int cp_byte_address_required_here  PARAMS ((char **));
1108
1109 /* ARM instructions take 4bytes in the object file, Thumb instructions
1110    take 2:  */
1111 #define INSN_SIZE       4
1112
1113 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1114 #define MAV_MODE1       0x100c
1115
1116 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1117 #define MAV_MODE2       0x0c10
1118
1119 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1120 #define MAV_MODE3       0x100c
1121
1122 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1123 #define MAV_MODE4       0x0c0010
1124
1125 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1126 #define MAV_MODE5       0x00100c
1127
1128 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1129 #define MAV_MODE6       0x00100c05
1130
1131 struct asm_opcode
1132 {
1133   /* Basic string to match.  */
1134   const char * template;
1135
1136   /* Basic instruction code.  */
1137   unsigned long value;
1138
1139   /* Offset into the template where the condition code (if any) will be.
1140      If zero, then the instruction is never conditional.  */
1141   unsigned cond_offset;
1142
1143   /* Which architecture variant provides this instruction.  */
1144   unsigned long variant;
1145
1146   /* Function to call to parse args.  */
1147   void (* parms) PARAMS ((char *));
1148 };
1149
1150 static const struct asm_opcode insns[] =
1151 {
1152   /* Core ARM Instructions.  */
1153   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1154   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1155   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1156   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1157   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1158   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1159   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1160   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1161   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1162   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1163   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1164   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1165   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1166   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1167   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1168   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1169   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1170   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1171   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1172   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1173
1174   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1175   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1176   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1177   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1178   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1179   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1180   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1181   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1182   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1183   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1184   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1185   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1186
1187   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1188   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1189   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1190   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1191
1192   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1193   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1194   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1195   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1196   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1197   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1198   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1199   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1200
1201   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1202   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1203   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1204   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1205   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1206   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1207   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1208   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1209
1210   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1211   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1212   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1213   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1214   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1215   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1216   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1217   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1218
1219   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1220 #ifdef TE_WINCE
1221   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1222   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1223   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1224 #else
1225   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1226   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1227 #endif
1228
1229   /* Pseudo ops.  */
1230   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1231   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1232   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1233
1234   /* ARM 2 multiplies.  */
1235   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1236   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1237   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1238   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1239
1240   /* Generic coprocessor instructions.  */
1241   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1242   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1243   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1244   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1245   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1246   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1247   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1248
1249   /* ARM 3 - swp instructions.  */
1250   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1251   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1252
1253   /* ARM 6 Status register instructions.  */
1254   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1255   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1256   /* ScottB: our code uses     0xe128f000 for msr.
1257      NickC:  but this is wrong because the bits 16 through 19 are
1258              handled by the PSR_xxx defines above.  */
1259
1260   /* ARM 7M long multiplies.  */
1261   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1262   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1263   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1264   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1265   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1266   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1267   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1268   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1269
1270   /* ARM Architecture 4.  */
1271   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1272   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1273   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1274   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1275
1276   /* ARM Architecture 4T.  */
1277   /* Note: bx (and blx) are required on V5, even if the processor does
1278      not support Thumb.  */
1279   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1280
1281   /*  ARM Architecture 5T.  */
1282   /* Note: blx has 2 variants, so the .value is set dynamically.
1283      Only one of the variants has conditional execution.  */
1284   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1285   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1286   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1287   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1288   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1289   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1290   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1291   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1292   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1293   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1294
1295   /*  ARM Architecture 5TExP.  */
1296   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1297   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1298   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1299   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1300
1301   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1302   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1303
1304   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1305   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1306   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1307   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1308
1309   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1310   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1311   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1312   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1313
1314   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1315   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1316
1317   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1318   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1319   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1320   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1321
1322   /*  ARM Architecture 5TE.  */
1323   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1324   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1325   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1326
1327   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1328   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1329
1330   /*  ARM Architecture 5TEJ.  */
1331   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1332
1333   /*  ARM V6.  */
1334   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1335   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1336   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1337   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1338   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1339   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1340   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1341   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1342   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1343   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1344   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1345   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1346   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1347   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1348   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1349   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1350   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1351   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1352   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1353   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1354   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1355   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1356   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1357   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1358   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1359   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1360   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1361   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1362   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1363   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1364   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1365   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1366   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1367   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1368   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1369   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1370   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1371   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1372   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1373   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1374   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1375   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1376   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1377   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1378   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1379   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1380   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1381   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1382   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1383   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1384   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1385   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1386   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1387   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1388   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1389   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1390   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1391   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1392   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1393   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1394   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1395   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1396   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1397   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1398   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1399   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1400   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1401   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1402   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1403   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1404   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1405   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1406   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1407   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1408   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1409   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1410   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1411   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1412   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1413   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1414   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1415   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1416   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1417   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1418   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1419   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1420   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1421   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1422   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1423   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1424   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1425   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1426   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1427   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1428   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1429   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1430   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1431   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1432   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1433
1434   /* Core FPA instruction set (V1).  */
1435   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1436   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1437   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1438   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1439
1440   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1441   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1442   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1443   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1444
1445   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1446   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1447   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1448   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1449
1450   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1457   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1460   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462
1463   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1470   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1473   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475
1476   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1483   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1486   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488
1489   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1496   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1499   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501
1502   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1509   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1512   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514
1515   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1522   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1525   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527
1528   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1535   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1538   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540
1541   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1548   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1551   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553
1554   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1561   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1564   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566
1567   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1574   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1577   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579
1580   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1587   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1588   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1589   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1590   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1591   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1592
1593   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1594   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1595   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1596   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1597   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1598   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1599   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1600   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1601   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1602   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1603   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1604   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1605
1606   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1607   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1608   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1609   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1610   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1611   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1612   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1613   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1614   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1615   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1616   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1617   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1618
1619   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1620   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1621   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1622   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1623   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1624   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1625   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1626   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1627   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1628   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1629   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1630   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1631
1632   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1633   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1634   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1635   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1636   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1637   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1638   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1639   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1640   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1641   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1642   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1643   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1644
1645   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1646   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1647   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1648   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1649   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1650   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1651   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1652   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1653   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1654   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1655   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1656   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1657
1658   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1665   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1668   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670
1671   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1678   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1681   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683
1684   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1691   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1694   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696
1697   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1704   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1707   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709
1710   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1717   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1720   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722
1723   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1730   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1733   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735
1736   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1743   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1746   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748
1749   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1756   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1757   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1758   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1759   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1760   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1761
1762   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1763   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1764   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1765   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1766   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1767   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1768   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1769   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1770   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1771   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1772   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1773   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1774
1775   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1776   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1777   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1778   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1779   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1780   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1781   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1782   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1783   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1784   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1785   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1786   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1787
1788   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1789   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1790   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1791   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1792   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1793   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1794   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1795   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1796   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1797   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1798   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1799   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1800
1801   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1802   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1803   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1804   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1805   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1806   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1807   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1808   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1809   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1810   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1811   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1812   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1813
1814   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1815   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1816   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1817   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1818   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1819   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1820   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1821   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1822   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1823   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1824   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1825   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1826
1827   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1828   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1829   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1830   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1831   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1832      not be an optional suffix, but part of the instruction.  To be
1833      compatible, we accept either.  */
1834   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1835   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1836
1837   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1838   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1839   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1840   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1841   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1842   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1843   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1844   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1845   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1846   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1847   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1848   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1849
1850   /* The implementation of the FIX instruction is broken on some
1851      assemblers, in that it accepts a precision specifier as well as a
1852      rounding specifier, despite the fact that this is meaningless.
1853      To be more compatible, we accept it as well, though of course it
1854      does not set any bits.  */
1855   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1856   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1857   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1858   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1859   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1860   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1861   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1862   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1863   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1864   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1865   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1866   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1867   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1868
1869   /* Instructions that were new with the real FPA, call them V2.  */
1870   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1871   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1872   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1873   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1874   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1875   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1876
1877   /* VFP V1xD (single precision).  */
1878   /* Moves and type conversions.  */
1879   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1880   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1881   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1882   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1883   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1884   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1885   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1886   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1887   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1888   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1889   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1890   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1891
1892   /* Memory operations.  */
1893   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1894   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1895   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1896   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1897   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1898   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1899   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1900   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1901   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1902   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1903   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1904   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1905   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1906   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1907   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1908   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1909   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1910   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1911
1912   /* Monadic operations.  */
1913   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1914   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1915   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1916
1917   /* Dyadic operations.  */
1918   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1922   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1923   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1924   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1925   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1926   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1927
1928   /* Comparisons.  */
1929   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1930   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1931   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1932   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1933
1934   /* VFP V1 (Double precision).  */
1935   /* Moves and type conversions.  */
1936   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1937   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1938   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1939   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1940   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1941   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1942   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1943   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1944   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1945   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1946   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1947   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1948   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1949
1950   /* Memory operations.  */
1951   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1952   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1953   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1954   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1955   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1956   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1957   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1958   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1959   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1960   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1961
1962   /* Monadic operations.  */
1963   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1964   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1965   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1966
1967   /* Dyadic operations.  */
1968   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1969   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1970   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1971   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1972   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1973   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1974   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1975   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1976   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1977
1978   /* Comparisons.  */
1979   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1980   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1981   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1982   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1983
1984   /* VFP V2.  */
1985   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
1986   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
1987   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1988   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1989
1990   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1991   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1992   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1993   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1994   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1995   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1996   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1997   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1998   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1999
2000   /* Intel Wireless MMX technology instructions.  */
2001   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2002   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2003   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2004   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2005   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2006   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2007   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2008   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2009   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2010   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2011   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2012   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2013   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2014   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2015   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2016   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2017   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2018   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2019   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2020   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2021   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2022   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2023   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2024   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2025   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2026   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2027   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2028   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2029   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2030   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2031   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2032   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2033   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2034   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2035   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2036   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2037   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2038   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2045   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2048   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2062   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2063   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2065   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2066   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2067   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2068   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2069   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2070   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2071   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2084   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2087   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2090   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2097   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2099   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2100   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2101   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2102   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2103   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2104   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2105   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2106   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2107   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2108   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2109   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2110   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2111   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2112   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2113   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2114   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2115   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2116   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2117   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2118   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2119   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2120   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2121   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2122   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2123   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2124   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2125   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2126   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2127   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2128   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2129   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2130   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2131   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2132   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2133   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2134   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2138   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2139   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2140   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2141   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2142   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2143   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2144   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2145   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2146   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2147   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2148   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2149   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2150   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2151   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2152   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2153   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2154   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2155   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2156   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2157   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2158   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2159   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2160   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2161   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2162   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2163
2164   /* Cirrus Maverick instructions.  */
2165   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2166   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2167   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2168   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2169   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2170   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2171   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2172   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2173   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2174   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2175   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2176   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2177   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2178   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2179   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2180   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2181   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2182   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2183   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2184   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2185   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2186   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2187   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2188   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2189   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2190   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2191   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2192   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2193   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2194   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2195   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2196   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2197   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2198   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2199   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2200   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2201   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2202   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2203   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2204   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2205   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2206   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2207   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2208   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2209   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2210   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2211   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2212   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2213   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2214   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2215   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2216   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2217   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2218   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2219   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2220   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2221   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2222   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2223   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2224   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2225   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2226   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2227   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2228   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2229   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2230   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2231   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2232   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2233   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2234   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2235   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2236   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2237   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2238   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2239   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2240   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2241 };
2242
2243 /* Defines for various bits that we will want to toggle.  */
2244 #define INST_IMMEDIATE  0x02000000
2245 #define OFFSET_REG      0x02000000
2246 #define HWOFFSET_IMM    0x00400000
2247 #define SHIFT_BY_REG    0x00000010
2248 #define PRE_INDEX       0x01000000
2249 #define INDEX_UP        0x00800000
2250 #define WRITE_BACK      0x00200000
2251 #define LDM_TYPE_2_OR_3 0x00400000
2252
2253 #define LITERAL_MASK    0xf000f000
2254 #define OPCODE_MASK     0xfe1fffff
2255 #define V4_STR_BIT      0x00000020
2256
2257 #define DATA_OP_SHIFT   21
2258
2259 /* Codes to distinguish the arithmetic instructions.  */
2260 #define OPCODE_AND      0
2261 #define OPCODE_EOR      1
2262 #define OPCODE_SUB      2
2263 #define OPCODE_RSB      3
2264 #define OPCODE_ADD      4
2265 #define OPCODE_ADC      5
2266 #define OPCODE_SBC      6
2267 #define OPCODE_RSC      7
2268 #define OPCODE_TST      8
2269 #define OPCODE_TEQ      9
2270 #define OPCODE_CMP      10
2271 #define OPCODE_CMN      11
2272 #define OPCODE_ORR      12
2273 #define OPCODE_MOV      13
2274 #define OPCODE_BIC      14
2275 #define OPCODE_MVN      15
2276
2277 /* Thumb v1 (ARMv4T).  */
2278 static void do_t_nop            PARAMS ((char *));
2279 static void do_t_arit           PARAMS ((char *));
2280 static void do_t_add            PARAMS ((char *));
2281 static void do_t_asr            PARAMS ((char *));
2282 static void do_t_branch9        PARAMS ((char *));
2283 static void do_t_branch12       PARAMS ((char *));
2284 static void do_t_branch23       PARAMS ((char *));
2285 static void do_t_bx             PARAMS ((char *));
2286 static void do_t_compare        PARAMS ((char *));
2287 static void do_t_ldmstm         PARAMS ((char *));
2288 static void do_t_ldr            PARAMS ((char *));
2289 static void do_t_ldrb           PARAMS ((char *));
2290 static void do_t_ldrh           PARAMS ((char *));
2291 static void do_t_lds            PARAMS ((char *));
2292 static void do_t_lsl            PARAMS ((char *));
2293 static void do_t_lsr            PARAMS ((char *));
2294 static void do_t_mov            PARAMS ((char *));
2295 static void do_t_push_pop       PARAMS ((char *));
2296 static void do_t_str            PARAMS ((char *));
2297 static void do_t_strb           PARAMS ((char *));
2298 static void do_t_strh           PARAMS ((char *));
2299 static void do_t_sub            PARAMS ((char *));
2300 static void do_t_swi            PARAMS ((char *));
2301 static void do_t_adr            PARAMS ((char *));
2302
2303 /* Thumb v2 (ARMv5T).  */
2304 static void do_t_blx            PARAMS ((char *));
2305 static void do_t_bkpt           PARAMS ((char *));
2306
2307 /* ARM V6.  */
2308 static void do_t_cps            PARAMS ((char *));
2309 static void do_t_cpy            PARAMS ((char *));
2310 static void do_t_setend         PARAMS ((char *));;
2311
2312 #define T_OPCODE_MUL 0x4340
2313 #define T_OPCODE_TST 0x4200
2314 #define T_OPCODE_CMN 0x42c0
2315 #define T_OPCODE_NEG 0x4240
2316 #define T_OPCODE_MVN 0x43c0
2317
2318 #define T_OPCODE_ADD_R3 0x1800
2319 #define T_OPCODE_SUB_R3 0x1a00
2320 #define T_OPCODE_ADD_HI 0x4400
2321 #define T_OPCODE_ADD_ST 0xb000
2322 #define T_OPCODE_SUB_ST 0xb080
2323 #define T_OPCODE_ADD_SP 0xa800
2324 #define T_OPCODE_ADD_PC 0xa000
2325 #define T_OPCODE_ADD_I8 0x3000
2326 #define T_OPCODE_SUB_I8 0x3800
2327 #define T_OPCODE_ADD_I3 0x1c00
2328 #define T_OPCODE_SUB_I3 0x1e00
2329
2330 #define T_OPCODE_ASR_R  0x4100
2331 #define T_OPCODE_LSL_R  0x4080
2332 #define T_OPCODE_LSR_R  0x40c0
2333 #define T_OPCODE_ASR_I  0x1000
2334 #define T_OPCODE_LSL_I  0x0000
2335 #define T_OPCODE_LSR_I  0x0800
2336
2337 #define T_OPCODE_MOV_I8 0x2000
2338 #define T_OPCODE_CMP_I8 0x2800
2339 #define T_OPCODE_CMP_LR 0x4280
2340 #define T_OPCODE_MOV_HR 0x4600
2341 #define T_OPCODE_CMP_HR 0x4500
2342
2343 #define T_OPCODE_LDR_PC 0x4800
2344 #define T_OPCODE_LDR_SP 0x9800
2345 #define T_OPCODE_STR_SP 0x9000
2346 #define T_OPCODE_LDR_IW 0x6800
2347 #define T_OPCODE_STR_IW 0x6000
2348 #define T_OPCODE_LDR_IH 0x8800
2349 #define T_OPCODE_STR_IH 0x8000
2350 #define T_OPCODE_LDR_IB 0x7800
2351 #define T_OPCODE_STR_IB 0x7000
2352 #define T_OPCODE_LDR_RW 0x5800
2353 #define T_OPCODE_STR_RW 0x5000
2354 #define T_OPCODE_LDR_RH 0x5a00
2355 #define T_OPCODE_STR_RH 0x5200
2356 #define T_OPCODE_LDR_RB 0x5c00
2357 #define T_OPCODE_STR_RB 0x5400
2358
2359 #define T_OPCODE_PUSH   0xb400
2360 #define T_OPCODE_POP    0xbc00
2361
2362 #define T_OPCODE_BRANCH 0xe7fe
2363
2364 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
2365
2366 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
2367 #define THUMB_REG_LO    0x1
2368 #define THUMB_REG_HI    0x2
2369 #define THUMB_REG_ANY   0x3
2370
2371 #define THUMB_H1        0x0080
2372 #define THUMB_H2        0x0040
2373
2374 #define THUMB_ASR 0
2375 #define THUMB_LSL 1
2376 #define THUMB_LSR 2
2377
2378 #define THUMB_MOVE 0
2379 #define THUMB_COMPARE 1
2380 #define THUMB_CPY 2
2381
2382 #define THUMB_LOAD 0
2383 #define THUMB_STORE 1
2384
2385 #define THUMB_PP_PC_LR 0x0100
2386
2387 /* These three are used for immediate shifts, do not alter.  */
2388 #define THUMB_WORD 2
2389 #define THUMB_HALFWORD 1
2390 #define THUMB_BYTE 0
2391
2392 struct thumb_opcode
2393 {
2394   /* Basic string to match.  */
2395   const char * template;
2396
2397   /* Basic instruction code.  */
2398   unsigned long value;
2399
2400   int size;
2401
2402   /* Which CPU variants this exists for.  */
2403   unsigned long variant;
2404
2405   /* Function to call to parse args.  */
2406   void (* parms) PARAMS ((char *));
2407 };
2408
2409 static const struct thumb_opcode tinsns[] =
2410 {
2411   /* Thumb v1 (ARMv4T).  */
2412   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
2413   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
2414   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
2415   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
2416   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
2417   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
2418   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
2419   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2420   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2421   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2422   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2423   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2424   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
2425   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
2426   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
2427   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
2428   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
2429   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
2430   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
2431   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
2432   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
2433   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
2434   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
2435   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
2436   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
2437   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
2438   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2439   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2440   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2441   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2442   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2443   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2444   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2445   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2446   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2447   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2448   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2449   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2450   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2451   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2452   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2453   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2454   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2455   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2456   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2457   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2458   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2459   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2460   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2461   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2462   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2463   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2464   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2465   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2466   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2467   /* Pseudo ops:  */
2468   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2469   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2470   /* Thumb v2 (ARMv5T).  */
2471   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2472   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2473
2474   /* ARM V6.  */
2475   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
2476   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
2477   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
2478   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
2479   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
2480   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
2481   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
2482   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
2483   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
2484   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
2485   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
2486 };
2487
2488 #define BAD_ARGS        _("bad arguments to instruction")
2489 #define BAD_PC          _("r15 not allowed here")
2490 #define BAD_COND        _("instruction is not conditional")
2491 #define ERR_NO_ACCUM    _("acc0 expected")
2492
2493 static struct hash_control * arm_ops_hsh   = NULL;
2494 static struct hash_control * arm_tops_hsh  = NULL;
2495 static struct hash_control * arm_cond_hsh  = NULL;
2496 static struct hash_control * arm_shift_hsh = NULL;
2497 static struct hash_control * arm_psr_hsh   = NULL;
2498
2499 /* This table describes all the machine specific pseudo-ops the assembler
2500    has to support.  The fields are:
2501      pseudo-op name without dot
2502      function to call to execute this pseudo-op
2503      Integer arg to pass to the function.  */
2504
2505 static void s_req PARAMS ((int));
2506 static void s_unreq PARAMS ((int));
2507 static void s_align PARAMS ((int));
2508 static void s_bss PARAMS ((int));
2509 static void s_even PARAMS ((int));
2510 static void s_ltorg PARAMS ((int));
2511 static void s_arm PARAMS ((int));
2512 static void s_thumb PARAMS ((int));
2513 static void s_code PARAMS ((int));
2514 static void s_force_thumb PARAMS ((int));
2515 static void s_thumb_func PARAMS ((int));
2516 static void s_thumb_set PARAMS ((int));
2517 #ifdef OBJ_ELF
2518 static void s_arm_elf_cons PARAMS ((int));
2519 #endif
2520
2521 static int my_get_expression PARAMS ((expressionS *, char **));
2522
2523 const pseudo_typeS md_pseudo_table[] =
2524 {
2525   /* Never called because '.req' does not start a line.  */
2526   { "req",         s_req,         0 },
2527   { "unreq",       s_unreq,       0 },
2528   { "bss",         s_bss,         0 },
2529   { "align",       s_align,       0 },
2530   { "arm",         s_arm,         0 },
2531   { "thumb",       s_thumb,       0 },
2532   { "code",        s_code,        0 },
2533   { "force_thumb", s_force_thumb, 0 },
2534   { "thumb_func",  s_thumb_func,  0 },
2535   { "thumb_set",   s_thumb_set,   0 },
2536   { "even",        s_even,        0 },
2537   { "ltorg",       s_ltorg,       0 },
2538   { "pool",        s_ltorg,       0 },
2539 #ifdef OBJ_ELF
2540   { "word",        s_arm_elf_cons, 4 },
2541   { "long",        s_arm_elf_cons, 4 },
2542 #else
2543   { "word",        cons, 4},
2544 #endif
2545   { "extend",      float_cons, 'x' },
2546   { "ldouble",     float_cons, 'x' },
2547   { "packed",      float_cons, 'p' },
2548   { 0, 0, 0 }
2549 };
2550
2551 /* Other internal functions.  */
2552 static int arm_parse_extension PARAMS ((char *, int *));
2553 static int arm_parse_cpu PARAMS ((char *));
2554 static int arm_parse_arch PARAMS ((char *));
2555 static int arm_parse_fpu PARAMS ((char *));
2556 static int arm_parse_float_abi PARAMS ((char *));
2557 #ifdef OBJ_ELF
2558 static int arm_parse_eabi PARAMS ((char *));
2559 #endif
2560 #if 0 /* Suppressed - for now.  */
2561 #if defined OBJ_COFF || defined OBJ_ELF
2562 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2563 #endif
2564 #endif
2565
2566 /* Stuff needed to resolve the label ambiguity
2567    As:
2568      ...
2569      label:   <insn>
2570    may differ from:
2571      ...
2572      label:
2573               <insn>
2574 */
2575
2576 symbolS *  last_label_seen;
2577 static int label_is_thumb_function_name = FALSE;
2578
2579 /* Literal Pool stuff.  */
2580
2581 #define MAX_LITERAL_POOL_SIZE 1024
2582
2583 /* Literal pool structure.  Held on a per-section
2584    and per-sub-section basis.  */
2585 typedef struct literal_pool
2586 {
2587   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2588   unsigned int   next_free_entry;
2589   unsigned int   id;
2590   symbolS *      symbol;
2591   segT           section;
2592   subsegT        sub_section;
2593   struct literal_pool * next;
2594 } literal_pool;
2595
2596 /* Pointer to a linked list of literal pools.  */
2597 literal_pool * list_of_pools = NULL;
2598
2599 static literal_pool * find_literal_pool PARAMS ((void));
2600 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2601
2602 static literal_pool *
2603 find_literal_pool ()
2604 {
2605   literal_pool * pool;
2606
2607   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2608     {
2609       if (pool->section == now_seg
2610           && pool->sub_section == now_subseg)
2611         break;
2612     }
2613
2614   return pool;
2615 }
2616
2617 static literal_pool *
2618 find_or_make_literal_pool ()
2619 {
2620   /* Next literal pool ID number.  */
2621   static unsigned int latest_pool_num = 1;
2622   literal_pool *      pool;
2623
2624   pool = find_literal_pool ();
2625
2626   if (pool == NULL)
2627     {
2628       /* Create a new pool.  */
2629       pool = (literal_pool *) xmalloc (sizeof (* pool));
2630       if (! pool)
2631         return NULL;
2632
2633       pool->next_free_entry = 0;
2634       pool->section         = now_seg;
2635       pool->sub_section     = now_subseg;
2636       pool->next            = list_of_pools;
2637       pool->symbol          = NULL;
2638
2639       /* Add it to the list.  */
2640       list_of_pools = pool;
2641     }
2642
2643   /* New pools, and emptied pools, will have a NULL symbol.  */
2644   if (pool->symbol == NULL)
2645     {
2646       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2647                                     (valueT) 0, &zero_address_frag);
2648       pool->id = latest_pool_num ++;
2649     }
2650
2651   /* Done.  */
2652   return pool;
2653 }
2654
2655 /* Add the literal in the global 'inst'
2656    structure to the relevent literal pool.  */
2657 static int
2658 add_to_lit_pool ()
2659 {
2660   literal_pool * pool;
2661   unsigned int entry;
2662
2663   pool = find_or_make_literal_pool ();
2664
2665   /* Check if this literal value is already in the pool.  */
2666   for (entry = 0; entry < pool->next_free_entry; entry ++)
2667     {
2668       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2669           && (inst.reloc.exp.X_op == O_constant)
2670           && (pool->literals[entry].X_add_number
2671               == inst.reloc.exp.X_add_number)
2672           && (pool->literals[entry].X_unsigned
2673               == inst.reloc.exp.X_unsigned))
2674         break;
2675
2676       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2677           && (inst.reloc.exp.X_op == O_symbol)
2678           && (pool->literals[entry].X_add_number
2679               == inst.reloc.exp.X_add_number)
2680           && (pool->literals[entry].X_add_symbol
2681               == inst.reloc.exp.X_add_symbol)
2682           && (pool->literals[entry].X_op_symbol
2683               == inst.reloc.exp.X_op_symbol))
2684         break;
2685     }
2686
2687   /* Do we need to create a new entry?  */
2688   if (entry == pool->next_free_entry)
2689     {
2690       if (entry >= MAX_LITERAL_POOL_SIZE)
2691         {
2692           inst.error = _("literal pool overflow");
2693           return FAIL;
2694         }
2695
2696       pool->literals[entry] = inst.reloc.exp;
2697       pool->next_free_entry += 1;
2698     }
2699
2700   inst.reloc.exp.X_op         = O_symbol;
2701   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2702   inst.reloc.exp.X_add_symbol = pool->symbol;
2703
2704   return SUCCESS;
2705 }
2706
2707 /* Can't use symbol_new here, so have to create a symbol and then at
2708    a later date assign it a value. Thats what these functions do.  */
2709
2710 static void
2711 symbol_locate (symbolP, name, segment, valu, frag)
2712      symbolS *    symbolP;
2713      const char * name;         /* It is copied, the caller can modify.  */
2714      segT         segment;      /* Segment identifier (SEG_<something>).  */
2715      valueT       valu;         /* Symbol value.  */
2716      fragS *      frag;         /* Associated fragment.  */
2717 {
2718   unsigned int name_length;
2719   char * preserved_copy_of_name;
2720
2721   name_length = strlen (name) + 1;   /* +1 for \0.  */
2722   obstack_grow (&notes, name, name_length);
2723   preserved_copy_of_name = obstack_finish (&notes);
2724 #ifdef STRIP_UNDERSCORE
2725   if (preserved_copy_of_name[0] == '_')
2726     preserved_copy_of_name++;
2727 #endif
2728
2729 #ifdef tc_canonicalize_symbol_name
2730   preserved_copy_of_name =
2731     tc_canonicalize_symbol_name (preserved_copy_of_name);
2732 #endif
2733
2734   S_SET_NAME (symbolP, preserved_copy_of_name);
2735
2736   S_SET_SEGMENT (symbolP, segment);
2737   S_SET_VALUE (symbolP, valu);
2738   symbol_clear_list_pointers (symbolP);
2739
2740   symbol_set_frag (symbolP, frag);
2741
2742   /* Link to end of symbol chain.  */
2743   {
2744     extern int symbol_table_frozen;
2745     if (symbol_table_frozen)
2746       abort ();
2747   }
2748
2749   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2750
2751   obj_symbol_new_hook (symbolP);
2752
2753 #ifdef tc_symbol_new_hook
2754   tc_symbol_new_hook (symbolP);
2755 #endif
2756
2757 #ifdef DEBUG_SYMS
2758   verify_symbol_chain (symbol_rootP, symbol_lastP);
2759 #endif /* DEBUG_SYMS  */
2760 }
2761
2762 /* Check that an immediate is valid.
2763    If so, convert it to the right format.  */
2764
2765 static unsigned int
2766 validate_immediate (val)
2767      unsigned int val;
2768 {
2769   unsigned int a;
2770   unsigned int i;
2771
2772 #define rotate_left(v, n) (v << n | v >> (32 - n))
2773
2774   for (i = 0; i < 32; i += 2)
2775     if ((a = rotate_left (val, i)) <= 0xff)
2776       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2777
2778   return FAIL;
2779 }
2780
2781 /* Check to see if an immediate can be computed as two separate immediate
2782    values, added together.  We already know that this value cannot be
2783    computed by just one ARM instruction.  */
2784
2785 static unsigned int
2786 validate_immediate_twopart (val, highpart)
2787      unsigned int   val;
2788      unsigned int * highpart;
2789 {
2790   unsigned int a;
2791   unsigned int i;
2792
2793   for (i = 0; i < 32; i += 2)
2794     if (((a = rotate_left (val, i)) & 0xff) != 0)
2795       {
2796         if (a & 0xff00)
2797           {
2798             if (a & ~ 0xffff)
2799               continue;
2800             * highpart = (a  >> 8) | ((i + 24) << 7);
2801           }
2802         else if (a & 0xff0000)
2803           {
2804             if (a & 0xff000000)
2805               continue;
2806             * highpart = (a >> 16) | ((i + 16) << 7);
2807           }
2808         else
2809           {
2810             assert (a & 0xff000000);
2811             * highpart = (a >> 24) | ((i + 8) << 7);
2812           }
2813
2814         return (a & 0xff) | (i << 7);
2815       }
2816
2817   return FAIL;
2818 }
2819
2820 static int
2821 validate_offset_imm (val, hwse)
2822      unsigned int val;
2823      int hwse;
2824 {
2825   if ((hwse && val > 255) || val > 4095)
2826     return FAIL;
2827   return val;
2828 }
2829
2830 \f
2831 #ifdef OBJ_ELF
2832 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2833    (This text is taken from version B-02 of the spec):
2834
2835       4.4.7 Mapping and tagging symbols
2836
2837       A section of an ARM ELF file can contain a mixture of ARM code,
2838       Thumb code, and data.  There are inline transitions between code
2839       and data at literal pool boundaries. There can also be inline
2840       transitions between ARM code and Thumb code, for example in
2841       ARM-Thumb inter-working veneers.  Linkers, machine-level
2842       debuggers, profiling tools, and disassembly tools need to map
2843       images accurately. For example, setting an ARM breakpoint on a
2844       Thumb location, or in a literal pool, can crash the program
2845       being debugged, ruining the debugging session.
2846
2847       ARM ELF entities are mapped (see section 4.4.7.1 below) and
2848       tagged (see section 4.4.7.2 below) using local symbols (with
2849       binding STB_LOCAL).  To assist consumers, mapping and tagging
2850       symbols should be collated first in the symbol table, before
2851       other symbols with binding STB_LOCAL.
2852
2853       To allow properly collated mapping and tagging symbols to be
2854       skipped by consumers that have no interest in them, the first
2855       such symbol should have the name $m and its st_value field equal
2856       to the total number of mapping and tagging symbols (including
2857       the $m) in the symbol table.
2858
2859       4.4.7.1 Mapping symbols
2860
2861       $a    Labels the first byte of a sequence of ARM instructions.
2862             Its type is STT_FUNC.
2863
2864       $d    Labels the first byte of a sequence of data items.
2865             Its type is STT_OBJECT.
2866
2867       $t    Labels the first byte of a sequence of Thumb instructions.
2868             Its type is STT_FUNC.
2869
2870       This list of mapping symbols may be extended in the future.
2871
2872       Section-relative mapping symbols
2873
2874       Mapping symbols defined in a section define a sequence of
2875       half-open address intervals that cover the address range of the
2876       section. Each interval starts at the address defined by a
2877       mapping symbol, and continues up to, but not including, the
2878       address defined by the next (in address order) mapping symbol or
2879       the end of the section. A corollary is that there must be a
2880       mapping symbol defined at the beginning of each section.
2881       Consumers can ignore the size of a section-relative mapping
2882       symbol. Producers can set it to 0.
2883
2884       Absolute mapping symbols
2885
2886       Because of the need to crystallize a Thumb address with the
2887       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2888       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2889       or $t.
2890
2891       The extent of a mapping symbol defined in SHN_ABS is [st_value,
2892       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2893       where [x, y) denotes the half-open address range from x,
2894       inclusive, to y, exclusive.
2895
2896       In the absence of a mapping symbol, a consumer can interpret a
2897       function symbol with an odd value as the Thumb code address
2898       obtained by clearing the least significant bit of the
2899       value. This interpretation is deprecated, and it may not work in
2900       the future.
2901
2902    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2903    the EABI (which is still under development), so they are not
2904    implemented here.  */
2905
2906 static enum mstate mapstate = MAP_UNDEFINED;
2907
2908 static void
2909 mapping_state (enum mstate state)
2910 {
2911   symbolS * symbolP;
2912   const char * symname;
2913   int type;
2914
2915   if (mapstate == state)
2916     /* The mapping symbol has already been emitted.
2917        There is nothing else to do.  */
2918     return;
2919
2920   mapstate = state;
2921
2922   switch (state)
2923     {
2924     case MAP_DATA:
2925       symname = "$d";
2926       type = BSF_OBJECT;
2927       break;
2928     case MAP_ARM:
2929       symname = "$a";
2930       type = BSF_FUNCTION;
2931       break;
2932     case MAP_THUMB:
2933       symname = "$t";
2934       type = BSF_FUNCTION;
2935       break;
2936     case MAP_UNDEFINED:
2937       return;     
2938     default:
2939       abort ();
2940     }
2941
2942   seg_info (now_seg)->tc_segment_info_data = state;
2943
2944   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2945   symbol_table_insert (symbolP);
2946   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2947   
2948   switch (state)
2949     {
2950     case MAP_ARM:
2951       THUMB_SET_FUNC (symbolP, 0);
2952       ARM_SET_THUMB (symbolP, 0);
2953       ARM_SET_INTERWORK (symbolP, support_interwork);
2954       break;
2955       
2956     case MAP_THUMB:
2957       THUMB_SET_FUNC (symbolP, 1);
2958       ARM_SET_THUMB (symbolP, 1);
2959       ARM_SET_INTERWORK (symbolP, support_interwork);
2960       break;
2961       
2962     case MAP_DATA:
2963     default:
2964       return;
2965     }
2966 }
2967
2968 /* When we change sections we need to issue a new mapping symbol.  */
2969
2970 void
2971 arm_elf_change_section (void)
2972 {
2973   flagword flags;
2974
2975   if (!SEG_NORMAL (now_seg))
2976     return;
2977
2978   flags = bfd_get_section_flags (stdoutput, now_seg);
2979
2980   /* We can ignore sections that only contain debug info.  */
2981   if ((flags & SEC_ALLOC) == 0)
2982     return;
2983
2984   mapstate = seg_info (now_seg)->tc_segment_info_data;
2985 }
2986 #else
2987 #define mapping_state(a)
2988 #endif /* OBJ_ELF */
2989 \f
2990
2991 static void
2992 s_req (a)
2993      int a ATTRIBUTE_UNUSED;
2994 {
2995   as_bad (_("invalid syntax for .req directive"));
2996 }
2997
2998 /* The .unreq directive deletes an alias which was previously defined
2999    by .req.  For example:
3000
3001        my_alias .req r11
3002        .unreq my_alias    */
3003
3004 static void
3005 s_unreq (int a ATTRIBUTE_UNUSED)
3006 {
3007   char *name;
3008   char saved_char;
3009
3010   skip_whitespace (input_line_pointer);
3011   name = input_line_pointer;
3012
3013   while (*input_line_pointer != 0
3014          && *input_line_pointer != ' '
3015          && *input_line_pointer != '\n')
3016     ++input_line_pointer;
3017
3018   saved_char = *input_line_pointer;
3019   *input_line_pointer = 0;
3020
3021   if (*name)
3022     {
3023       enum arm_reg_type req_type = arm_reg_parse_any (name);
3024
3025       if (req_type != REG_TYPE_MAX)
3026         {
3027           char *temp_name = name;
3028           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3029
3030           if (req_no != FAIL)
3031             {
3032               struct reg_entry *req_entry;
3033
3034               /* Check to see if this alias is a builtin one.  */
3035               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3036
3037               if (!req_entry)
3038                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
3039               else if (req_entry->builtin)
3040                 /* FIXME: We are deleting a built in register alias which
3041                    points to a const data structure, so we only need to
3042                    free up the memory used by the key in the hash table.
3043                    Unfortunately we have not recorded this value, so this
3044                    is a memory leak.  */
3045                   /* FIXME: Should we issue a warning message ?  */
3046                 ;
3047               else
3048                 {
3049                   /* Deleting a user defined alias.  We need to free the
3050                      key and the value, but fortunately the key is the same
3051                      as the value->name field.  */
3052                   free ((char *) req_entry->name);
3053                   free (req_entry);
3054                 }
3055             }
3056           else
3057             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3058         }
3059       else
3060         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3061     }
3062   else
3063     as_bad (_("invalid syntax for .unreq directive"));
3064
3065   *input_line_pointer = saved_char;
3066   demand_empty_rest_of_line ();
3067 }
3068
3069 static void
3070 s_bss (ignore)
3071      int ignore ATTRIBUTE_UNUSED;
3072 {
3073   /* We don't support putting frags in the BSS segment, we fake it by
3074      marking in_bss, then looking at s_skip for clues.  */
3075   subseg_set (bss_section, 0);
3076   demand_empty_rest_of_line ();
3077   mapping_state (MAP_DATA);
3078 }
3079
3080 static void
3081 s_even (ignore)
3082      int ignore ATTRIBUTE_UNUSED;
3083 {
3084   /* Never make frag if expect extra pass.  */
3085   if (!need_pass_2)
3086     frag_align (1, 0, 0);
3087
3088   record_alignment (now_seg, 1);
3089
3090   demand_empty_rest_of_line ();
3091 }
3092
3093 static void
3094 s_ltorg (ignored)
3095      int ignored ATTRIBUTE_UNUSED;
3096 {
3097   unsigned int entry;
3098   literal_pool * pool;
3099   char sym_name[20];
3100
3101   pool = find_literal_pool ();
3102   if (pool == NULL
3103       || pool->symbol == NULL
3104       || pool->next_free_entry == 0)
3105     return;
3106
3107   mapping_state (MAP_DATA);
3108
3109   /* Align pool as you have word accesses.
3110      Only make a frag if we have to.  */
3111   if (!need_pass_2)
3112     frag_align (2, 0, 0);
3113
3114   record_alignment (now_seg, 2);
3115
3116   sprintf (sym_name, "$$lit_\002%x", pool->id);
3117
3118   symbol_locate (pool->symbol, sym_name, now_seg,
3119                  (valueT) frag_now_fix (), frag_now);
3120   symbol_table_insert (pool->symbol);
3121
3122   ARM_SET_THUMB (pool->symbol, thumb_mode);
3123
3124 #if defined OBJ_COFF || defined OBJ_ELF
3125   ARM_SET_INTERWORK (pool->symbol, support_interwork);
3126 #endif
3127
3128   for (entry = 0; entry < pool->next_free_entry; entry ++)
3129     /* First output the expression in the instruction to the pool.  */
3130     emit_expr (&(pool->literals[entry]), 4); /* .word  */
3131
3132   /* Mark the pool as empty.  */
3133   pool->next_free_entry = 0;
3134   pool->symbol = NULL;
3135 }
3136
3137 /* Same as s_align_ptwo but align 0 => align 2.  */
3138
3139 static void
3140 s_align (unused)
3141      int unused ATTRIBUTE_UNUSED;
3142 {
3143   register int temp;
3144   register long temp_fill;
3145   long max_alignment = 15;
3146
3147   temp = get_absolute_expression ();
3148   if (temp > max_alignment)
3149     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3150   else if (temp < 0)
3151     {
3152       as_bad (_("alignment negative. 0 assumed."));
3153       temp = 0;
3154     }
3155
3156   if (*input_line_pointer == ',')
3157     {
3158       input_line_pointer++;
3159       temp_fill = get_absolute_expression ();
3160     }
3161   else
3162     temp_fill = 0;
3163
3164   if (!temp)
3165     temp = 2;
3166
3167   /* Only make a frag if we HAVE to.  */
3168   if (temp && !need_pass_2)
3169     frag_align (temp, (int) temp_fill, 0);
3170   demand_empty_rest_of_line ();
3171
3172   record_alignment (now_seg, temp);
3173 }
3174
3175 static void
3176 s_force_thumb (ignore)
3177      int ignore ATTRIBUTE_UNUSED;
3178 {
3179   /* If we are not already in thumb mode go into it, EVEN if
3180      the target processor does not support thumb instructions.
3181      This is used by gcc/config/arm/lib1funcs.asm for example
3182      to compile interworking support functions even if the
3183      target processor should not support interworking.  */
3184   if (! thumb_mode)
3185     {
3186       thumb_mode = 2;
3187
3188       record_alignment (now_seg, 1);
3189     }
3190
3191   demand_empty_rest_of_line ();
3192 }
3193
3194 static void
3195 s_thumb_func (ignore)
3196      int ignore ATTRIBUTE_UNUSED;
3197 {
3198   if (! thumb_mode)
3199     opcode_select (16);
3200
3201   /* The following label is the name/address of the start of a Thumb function.
3202      We need to know this for the interworking support.  */
3203   label_is_thumb_function_name = TRUE;
3204
3205   demand_empty_rest_of_line ();
3206 }
3207
3208 /* Perform a .set directive, but also mark the alias as
3209    being a thumb function.  */
3210
3211 static void
3212 s_thumb_set (equiv)
3213      int equiv;
3214 {
3215   /* XXX the following is a duplicate of the code for s_set() in read.c
3216      We cannot just call that code as we need to get at the symbol that
3217      is created.  */
3218   register char *    name;
3219   register char      delim;
3220   register char *    end_name;
3221   register symbolS * symbolP;
3222
3223   /* Especial apologies for the random logic:
3224      This just grew, and could be parsed much more simply!
3225      Dean - in haste.  */
3226   name      = input_line_pointer;
3227   delim     = get_symbol_end ();
3228   end_name  = input_line_pointer;
3229   *end_name = delim;
3230
3231   SKIP_WHITESPACE ();
3232
3233   if (*input_line_pointer != ',')
3234     {
3235       *end_name = 0;
3236       as_bad (_("expected comma after name \"%s\""), name);
3237       *end_name = delim;
3238       ignore_rest_of_line ();
3239       return;
3240     }
3241
3242   input_line_pointer++;
3243   *end_name = 0;
3244
3245   if (name[0] == '.' && name[1] == '\0')
3246     {
3247       /* XXX - this should not happen to .thumb_set.  */
3248       abort ();
3249     }
3250
3251   if ((symbolP = symbol_find (name)) == NULL
3252       && (symbolP = md_undefined_symbol (name)) == NULL)
3253     {
3254 #ifndef NO_LISTING
3255       /* When doing symbol listings, play games with dummy fragments living
3256          outside the normal fragment chain to record the file and line info
3257          for this symbol.  */
3258       if (listing & LISTING_SYMBOLS)
3259         {
3260           extern struct list_info_struct * listing_tail;
3261           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3262
3263           memset (dummy_frag, 0, sizeof (fragS));
3264           dummy_frag->fr_type = rs_fill;
3265           dummy_frag->line = listing_tail;
3266           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3267           dummy_frag->fr_symbol = symbolP;
3268         }
3269       else
3270 #endif
3271         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3272
3273 #ifdef OBJ_COFF
3274       /* "set" symbols are local unless otherwise specified.  */
3275       SF_SET_LOCAL (symbolP);
3276 #endif /* OBJ_COFF  */
3277     }                           /* Make a new symbol.  */
3278
3279   symbol_table_insert (symbolP);
3280
3281   * end_name = delim;
3282
3283   if (equiv
3284       && S_IS_DEFINED (symbolP)
3285       && S_GET_SEGMENT (symbolP) != reg_section)
3286     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3287
3288   pseudo_set (symbolP);
3289
3290   demand_empty_rest_of_line ();
3291
3292   /* XXX Now we come to the Thumb specific bit of code.  */
3293
3294   THUMB_SET_FUNC (symbolP, 1);
3295   ARM_SET_THUMB (symbolP, 1);
3296 #if defined OBJ_ELF || defined OBJ_COFF
3297   ARM_SET_INTERWORK (symbolP, support_interwork);
3298 #endif
3299 }
3300
3301 static void
3302 opcode_select (width)
3303      int width;
3304 {
3305   switch (width)
3306     {
3307     case 16:
3308       if (! thumb_mode)
3309         {
3310           if (! (cpu_variant & ARM_EXT_V4T))
3311             as_bad (_("selected processor does not support THUMB opcodes"));
3312
3313           thumb_mode = 1;
3314           /* No need to force the alignment, since we will have been
3315              coming from ARM mode, which is word-aligned.  */
3316           record_alignment (now_seg, 1);
3317         }
3318       mapping_state (MAP_THUMB);
3319       break;
3320
3321     case 32:
3322       if (thumb_mode)
3323         {
3324           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3325             as_bad (_("selected processor does not support ARM opcodes"));
3326
3327           thumb_mode = 0;
3328
3329           if (!need_pass_2)
3330             frag_align (2, 0, 0);
3331
3332           record_alignment (now_seg, 1);
3333         }
3334       mapping_state (MAP_ARM);
3335       break;
3336
3337     default:
3338       as_bad (_("invalid instruction size selected (%d)"), width);
3339     }
3340 }
3341
3342 static void
3343 s_arm (ignore)
3344      int ignore ATTRIBUTE_UNUSED;
3345 {
3346   opcode_select (32);
3347   demand_empty_rest_of_line ();
3348 }
3349
3350 static void
3351 s_thumb (ignore)
3352      int ignore ATTRIBUTE_UNUSED;
3353 {
3354   opcode_select (16);
3355   demand_empty_rest_of_line ();
3356 }
3357
3358 static void
3359 s_code (unused)
3360      int unused ATTRIBUTE_UNUSED;
3361 {
3362   register int temp;
3363
3364   temp = get_absolute_expression ();
3365   switch (temp)
3366     {
3367     case 16:
3368     case 32:
3369       opcode_select (temp);
3370       break;
3371
3372     default:
3373       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3374     }
3375 }
3376
3377 static void
3378 end_of_line (str)
3379      char *str;
3380 {
3381   skip_whitespace (str);
3382
3383   if (*str != '\0' && !inst.error)
3384     inst.error = _("garbage following instruction");
3385 }
3386
3387 static int
3388 skip_past_comma (str)
3389      char ** str;
3390 {
3391   char * p = * str, c;
3392   int comma = 0;
3393
3394   while ((c = *p) == ' ' || c == ',')
3395     {
3396       p++;
3397       if (c == ',' && comma++)
3398         return FAIL;
3399     }
3400
3401   if (c == '\0')
3402     return FAIL;
3403
3404   *str = p;
3405   return comma ? SUCCESS : FAIL;
3406 }
3407
3408 /* A standard register must be given at this point.
3409    SHIFT is the place to put it in inst.instruction.
3410    Restores input start point on error.
3411    Returns the reg#, or FAIL.  */
3412
3413 static int
3414 reg_required_here (str, shift)
3415      char ** str;
3416      int     shift;
3417 {
3418   static char buff [128]; /* XXX  */
3419   int         reg;
3420   char *      start = * str;
3421
3422   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3423     {
3424       if (shift >= 0)
3425         inst.instruction |= reg << shift;
3426       return reg;
3427     }
3428
3429   /* Restore the start point, we may have got a reg of the wrong class.  */
3430   *str = start;
3431
3432   /* In the few cases where we might be able to accept something else
3433      this error can be overridden.  */
3434   sprintf (buff, _("register expected, not '%.100s'"), start);
3435   inst.error = buff;
3436
3437   return FAIL;
3438 }
3439
3440 /* A Intel Wireless MMX technology register
3441    must be given at this point.
3442    Shift is the place to put it in inst.instruction.
3443    Restores input start point on err.
3444    Returns the reg#, or FAIL.  */
3445
3446 static int
3447 wreg_required_here (str, shift, reg_type)
3448      char ** str;
3449      int     shift;
3450      enum wreg_type reg_type;
3451 {
3452   static char buff [128];
3453   int    reg;
3454   char * start = *str;
3455
3456   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3457     {
3458       if (wr_register (reg)
3459           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3460         {
3461           if (shift >= 0)
3462             inst.instruction |= (reg ^ WR_PREFIX) << shift;
3463           return reg;
3464         }
3465       else if (wc_register (reg)
3466                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3467         {
3468           if (shift >= 0)
3469             inst.instruction |= (reg ^ WC_PREFIX) << shift;
3470           return reg;
3471         }
3472       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3473         {
3474           if (shift >= 0)
3475             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3476           return reg;
3477         }
3478     }
3479
3480   /* Restore the start point, we may have got a reg of the wrong class.  */
3481   *str = start;
3482
3483   /* In the few cases where we might be able to accept
3484      something else this error can be overridden.  */
3485   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3486   inst.error = buff;
3487
3488   return FAIL;
3489 }
3490
3491 static const struct asm_psr *
3492 arm_psr_parse (ccp)
3493      register char ** ccp;
3494 {
3495   char * start = * ccp;
3496   char   c;
3497   char * p;
3498   const struct asm_psr * psr;
3499
3500   p = start;
3501
3502   /* Skip to the end of the next word in the input stream.  */
3503   do
3504     {
3505       c = *p++;
3506     }
3507   while (ISALPHA (c) || c == '_');
3508
3509   /* Terminate the word.  */
3510   *--p = 0;
3511
3512   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3513      feature for ease of use and backwards compatibility.  */
3514   if (!strncmp (start, "cpsr", 4))
3515     strncpy (start, "CPSR", 4);
3516   else if (!strncmp (start, "spsr", 4))
3517     strncpy (start, "SPSR", 4);
3518
3519   /* Now locate the word in the psr hash table.  */
3520   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3521
3522   /* Restore the input stream.  */
3523   *p = c;
3524
3525   /* If we found a valid match, advance the
3526      stream pointer past the end of the word.  */
3527   *ccp = p;
3528
3529   return psr;
3530 }
3531
3532 /* Parse the input looking for a PSR flag.  */
3533
3534 static int
3535 psr_required_here (str)
3536      char ** str;
3537 {
3538   char * start = * str;
3539   const struct asm_psr * psr;
3540
3541   psr = arm_psr_parse (str);
3542
3543   if (psr)
3544     {
3545       /* If this is the SPSR that is being modified, set the R bit.  */
3546       if (! psr->cpsr)
3547         inst.instruction |= SPSR_BIT;
3548
3549       /* Set the psr flags in the MSR instruction.  */
3550       inst.instruction |= psr->field << PSR_SHIFT;
3551
3552       return SUCCESS;
3553     }
3554
3555   /* In the few cases where we might be able to accept
3556      something else this error can be overridden.  */
3557   inst.error = _("flag for {c}psr instruction expected");
3558
3559   /* Restore the start point.  */
3560   *str = start;
3561   return FAIL;
3562 }
3563
3564 static int
3565 co_proc_number (str)
3566      char **str;
3567 {
3568   int processor, pchar;
3569   char *start;
3570
3571   skip_whitespace (*str);
3572   start = *str;
3573
3574   /* The data sheet seems to imply that just a number on its own is valid
3575      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3576      accept either.  */
3577   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3578       == FAIL)
3579     {
3580       *str = start;
3581
3582       pchar = *(*str)++;
3583       if (pchar >= '0' && pchar <= '9')
3584         {
3585           processor = pchar - '0';
3586           if (**str >= '0' && **str <= '9')
3587             {
3588               processor = processor * 10 + *(*str)++ - '0';
3589               if (processor > 15)
3590                 {
3591                   inst.error = _("illegal co-processor number");
3592                   return FAIL;
3593                 }
3594             }
3595         }
3596       else
3597         {
3598           inst.error = all_reg_maps[REG_TYPE_CP].expected;
3599           return FAIL;
3600         }
3601     }
3602
3603   inst.instruction |= processor << 8;
3604   return SUCCESS;
3605 }
3606
3607 static int
3608 cp_opc_expr (str, where, length)
3609      char ** str;
3610      int where;
3611      int length;
3612 {
3613   expressionS expr;
3614
3615   skip_whitespace (* str);
3616
3617   memset (&expr, '\0', sizeof (expr));
3618
3619   if (my_get_expression (&expr, str))
3620     return FAIL;
3621   if (expr.X_op != O_constant)
3622     {
3623       inst.error = _("bad or missing expression");
3624       return FAIL;
3625     }
3626
3627   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3628     {
3629       inst.error = _("immediate co-processor expression too large");
3630       return FAIL;
3631     }
3632
3633   inst.instruction |= expr.X_add_number << where;
3634   return SUCCESS;
3635 }
3636
3637 static int
3638 cp_reg_required_here (str, where)
3639      char ** str;
3640      int     where;
3641 {
3642   int    reg;
3643   char * start = *str;
3644
3645   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3646     {
3647       inst.instruction |= reg << where;
3648       return reg;
3649     }
3650
3651   /* In the few cases where we might be able to accept something else
3652      this error can be overridden.  */
3653   inst.error = all_reg_maps[REG_TYPE_CN].expected;
3654
3655   /* Restore the start point.  */
3656   *str = start;
3657   return FAIL;
3658 }
3659
3660 static int
3661 fp_reg_required_here (str, where)
3662      char ** str;
3663      int     where;
3664 {
3665   int    reg;
3666   char * start = * str;
3667
3668   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3669     {
3670       inst.instruction |= reg << where;
3671       return reg;
3672     }
3673
3674   /* In the few cases where we might be able to accept something else
3675      this error can be overridden.  */
3676   inst.error = all_reg_maps[REG_TYPE_FN].expected;
3677
3678   /* Restore the start point.  */
3679   *str = start;
3680   return FAIL;
3681 }
3682
3683 static int
3684 cp_address_offset (str)
3685      char ** str;
3686 {
3687   int offset;
3688
3689   skip_whitespace (* str);
3690
3691   if (! is_immediate_prefix (**str))
3692     {
3693       inst.error = _("immediate expression expected");
3694       return FAIL;
3695     }
3696
3697   (*str)++;
3698
3699   if (my_get_expression (& inst.reloc.exp, str))
3700     return FAIL;
3701
3702   if (inst.reloc.exp.X_op == O_constant)
3703     {
3704       offset = inst.reloc.exp.X_add_number;
3705
3706       if (offset & 3)
3707         {
3708           inst.error = _("co-processor address must be word aligned");
3709           return FAIL;
3710         }
3711
3712       if (offset > 1023 || offset < -1023)
3713         {
3714           inst.error = _("offset too large");
3715           return FAIL;
3716         }
3717
3718       if (offset >= 0)
3719         inst.instruction |= INDEX_UP;
3720       else
3721         offset = -offset;
3722
3723       inst.instruction |= offset >> 2;
3724     }
3725   else
3726     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3727
3728   return SUCCESS;
3729 }
3730
3731 static int
3732 cp_address_required_here (str, wb_ok)
3733      char ** str;
3734      int wb_ok;
3735 {
3736   char * p = * str;
3737   int    pre_inc = 0;
3738   int    write_back = 0;
3739
3740   if (*p == '[')
3741     {
3742       int reg;
3743
3744       p++;
3745       skip_whitespace (p);
3746
3747       if ((reg = reg_required_here (& p, 16)) == FAIL)
3748         return FAIL;
3749
3750       skip_whitespace (p);
3751
3752       if (*p == ']')
3753         {
3754           p++;
3755
3756           skip_whitespace (p);
3757
3758           if (*p == '\0')
3759             {
3760               /* As an extension to the official ARM syntax we allow:
3761                  
3762                    [Rn]
3763                    
3764                  as a short hand for:
3765
3766                    [Rn,#0]  */
3767               inst.instruction |= PRE_INDEX | INDEX_UP;
3768               *str = p;
3769               return SUCCESS;
3770             }
3771           
3772           if (skip_past_comma (& p) == FAIL)
3773             {
3774               inst.error = _("comma expected after closing square bracket");
3775               return FAIL;
3776             }
3777
3778           skip_whitespace (p);
3779
3780           if (*p == '#')
3781             {
3782               if (wb_ok)
3783                 {
3784                   /* [Rn], #expr  */
3785                   write_back = WRITE_BACK;
3786
3787                   if (reg == REG_PC)
3788                     {
3789                       inst.error = _("pc may not be used in post-increment");
3790                       return FAIL;
3791                     }
3792
3793                   if (cp_address_offset (& p) == FAIL)
3794                     return FAIL;
3795                 }
3796               else
3797                 pre_inc = PRE_INDEX | INDEX_UP;
3798             }
3799           else if (*p == '{')
3800             {
3801               int option;
3802
3803               /* [Rn], {<expr>}  */
3804               p++;
3805
3806               skip_whitespace (p);
3807
3808               if (my_get_expression (& inst.reloc.exp, & p))
3809                 return FAIL;
3810
3811               if (inst.reloc.exp.X_op == O_constant)
3812                 {
3813                   option = inst.reloc.exp.X_add_number;
3814
3815                   if (option > 255 || option < 0)
3816                     {
3817                       inst.error = _("'option' field too large");
3818                       return FAIL;
3819                     }
3820
3821                   skip_whitespace (p);
3822
3823                   if (*p != '}')
3824                     {
3825                       inst.error = _("'}' expected at end of 'option' field");
3826                       return FAIL;
3827                     }
3828                   else
3829                     {
3830                       p++;
3831                       inst.instruction |= option;
3832                       inst.instruction |= INDEX_UP;
3833                     }
3834                 }
3835               else
3836                 {
3837                   inst.error = _("non-constant expressions for 'option' field not supported");
3838                   return FAIL;
3839                 }
3840             }
3841           else
3842             {
3843               inst.error = _("# or { expected after comma");
3844               return FAIL;            
3845             }
3846         }
3847       else
3848         {
3849           /* '['Rn, #expr']'[!]  */
3850
3851           if (skip_past_comma (& p) == FAIL)
3852             {
3853               inst.error = _("pre-indexed expression expected");
3854               return FAIL;
3855             }
3856
3857           pre_inc = PRE_INDEX;
3858
3859           if (cp_address_offset (& p) == FAIL)
3860             return FAIL;
3861
3862           skip_whitespace (p);
3863
3864           if (*p++ != ']')
3865             {
3866               inst.error = _("missing ]");
3867               return FAIL;
3868             }
3869
3870           skip_whitespace (p);
3871
3872           if (wb_ok && *p == '!')
3873             {
3874               if (reg == REG_PC)
3875                 {
3876                   inst.error = _("pc may not be used with write-back");
3877                   return FAIL;
3878                 }
3879
3880               p++;
3881               write_back = WRITE_BACK;
3882             }
3883         }
3884     }
3885   else
3886     {
3887       if (my_get_expression (&inst.reloc.exp, &p))
3888         return FAIL;
3889
3890       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3891       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3892       inst.reloc.pc_rel = 1;
3893       inst.instruction |= (REG_PC << 16);
3894       pre_inc = PRE_INDEX;
3895     }
3896
3897   inst.instruction |= write_back | pre_inc;
3898   *str = p;
3899   return SUCCESS;
3900 }
3901
3902 static int
3903 cp_byte_address_offset (str)
3904      char ** str;
3905 {
3906   int offset;
3907
3908   skip_whitespace (* str);
3909
3910   if (! is_immediate_prefix (**str))
3911     {
3912       inst.error = _("immediate expression expected");
3913       return FAIL;
3914     }
3915
3916   (*str)++;
3917   
3918   if (my_get_expression (& inst.reloc.exp, str))
3919     return FAIL;
3920   
3921   if (inst.reloc.exp.X_op == O_constant)
3922     {
3923       offset = inst.reloc.exp.X_add_number;
3924       
3925       if (offset > 255 || offset < -255)
3926         {
3927           inst.error = _("offset too large");
3928           return FAIL;
3929         }
3930
3931       if (offset >= 0)
3932         inst.instruction |= INDEX_UP;
3933       else
3934         offset = -offset;
3935
3936       inst.instruction |= offset;
3937     }
3938   else
3939     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3940
3941   return SUCCESS;
3942 }
3943
3944 static int
3945 cp_byte_address_required_here (str)
3946      char ** str;
3947 {
3948   char * p = * str;
3949   int    pre_inc = 0;
3950   int    write_back = 0;
3951
3952   if (*p == '[')
3953     {
3954       int reg;
3955
3956       p++;
3957       skip_whitespace (p);
3958
3959       if ((reg = reg_required_here (& p, 16)) == FAIL)
3960         return FAIL;
3961
3962       skip_whitespace (p);
3963
3964       if (*p == ']')
3965         {
3966           p++;
3967           
3968           if (skip_past_comma (& p) == SUCCESS)
3969             {
3970               /* [Rn], #expr */
3971               write_back = WRITE_BACK;
3972               
3973               if (reg == REG_PC)
3974                 {
3975                   inst.error = _("pc may not be used in post-increment");
3976                   return FAIL;
3977                 }
3978
3979               if (cp_byte_address_offset (& p) == FAIL)
3980                 return FAIL;
3981             }
3982           else
3983             pre_inc = PRE_INDEX | INDEX_UP;
3984         }
3985       else
3986         {
3987           /* '['Rn, #expr']'[!] */
3988
3989           if (skip_past_comma (& p) == FAIL)
3990             {
3991               inst.error = _("pre-indexed expression expected");
3992               return FAIL;
3993             }
3994
3995           pre_inc = PRE_INDEX;
3996           
3997           if (cp_byte_address_offset (& p) == FAIL)
3998             return FAIL;
3999
4000           skip_whitespace (p);
4001
4002           if (*p++ != ']')
4003             {
4004               inst.error = _("missing ]");
4005               return FAIL;
4006             }
4007
4008           skip_whitespace (p);
4009
4010           if (*p == '!')
4011             {
4012               if (reg == REG_PC)
4013                 {
4014                   inst.error = _("pc may not be used with write-back");
4015                   return FAIL;
4016                 }
4017
4018               p++;
4019               write_back = WRITE_BACK;
4020             }
4021         }
4022     }
4023   else
4024     {
4025       if (my_get_expression (&inst.reloc.exp, &p))
4026         return FAIL;
4027
4028       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4029       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
4030       inst.reloc.pc_rel = 1;
4031       inst.instruction |= (REG_PC << 16);
4032       pre_inc = PRE_INDEX;
4033     }
4034
4035   inst.instruction |= write_back | pre_inc;
4036   *str = p;
4037   return SUCCESS;
4038 }
4039
4040 static void
4041 do_empty (str)
4042      char * str;
4043 {
4044   /* Do nothing really.  */
4045   end_of_line (str);
4046 }
4047
4048 static void
4049 do_mrs (str)
4050      char *str;
4051 {
4052   int skip = 0;
4053
4054   /* Only one syntax.  */
4055   skip_whitespace (str);
4056
4057   if (reg_required_here (&str, 12) == FAIL)
4058     {
4059       inst.error = BAD_ARGS;
4060       return;
4061     }
4062
4063   if (skip_past_comma (&str) == FAIL)
4064     {
4065       inst.error = _("comma expected after register name");
4066       return;
4067     }
4068
4069   skip_whitespace (str);
4070
4071   if (   strcmp (str, "CPSR") == 0
4072       || strcmp (str, "SPSR") == 0
4073          /* Lower case versions for backwards compatibility.  */
4074       || strcmp (str, "cpsr") == 0
4075       || strcmp (str, "spsr") == 0)
4076     skip = 4;
4077
4078   /* This is for backwards compatibility with older toolchains.  */
4079   else if (   strcmp (str, "cpsr_all") == 0
4080            || strcmp (str, "spsr_all") == 0)
4081     skip = 8;
4082   else
4083     {
4084       inst.error = _("CPSR or SPSR expected");
4085       return;
4086     }
4087
4088   if (* str == 's' || * str == 'S')
4089     inst.instruction |= SPSR_BIT;
4090   str += skip;
4091
4092   end_of_line (str);
4093 }
4094
4095 /* Two possible forms:
4096       "{C|S}PSR_<field>, Rm",
4097       "{C|S}PSR_f, #expression".  */
4098
4099 static void
4100 do_msr (str)
4101      char * str;
4102 {
4103   skip_whitespace (str);
4104
4105   if (psr_required_here (& str) == FAIL)
4106     return;
4107
4108   if (skip_past_comma (& str) == FAIL)
4109     {
4110       inst.error = _("comma missing after psr flags");
4111       return;
4112     }
4113
4114   skip_whitespace (str);
4115
4116   if (reg_required_here (& str, 0) != FAIL)
4117     {
4118       inst.error = NULL;
4119       end_of_line (str);
4120       return;
4121     }
4122
4123   if (! is_immediate_prefix (* str))
4124     {
4125       inst.error =
4126         _("only a register or immediate value can follow a psr flag");
4127       return;
4128     }
4129
4130   str ++;
4131   inst.error = NULL;
4132
4133   if (my_get_expression (& inst.reloc.exp, & str))
4134     {
4135       inst.error =
4136         _("only a register or immediate value can follow a psr flag");
4137       return;
4138     }
4139
4140 #if 0  /* The first edition of the ARM architecture manual stated that
4141           writing anything other than the flags with an immediate operation
4142           had UNPREDICTABLE effects.  This constraint was removed in the
4143           second edition of the specification.  */
4144   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4145       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4146     {
4147       inst.error = _("immediate value cannot be used to set this field");
4148       return;
4149     }
4150 #endif
4151
4152   inst.instruction |= INST_IMMEDIATE;
4153
4154   if (inst.reloc.exp.X_add_symbol)
4155     {
4156       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4157       inst.reloc.pc_rel = 0;
4158     }
4159   else
4160     {
4161       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4162
4163       if (value == (unsigned) FAIL)
4164         {
4165           inst.error = _("invalid constant");
4166           return;
4167         }
4168
4169       inst.instruction |= value;
4170     }
4171
4172   inst.error = NULL;
4173   end_of_line (str);
4174 }
4175
4176 /* Long Multiply Parser
4177    UMULL RdLo, RdHi, Rm, Rs
4178    SMULL RdLo, RdHi, Rm, Rs
4179    UMLAL RdLo, RdHi, Rm, Rs
4180    SMLAL RdLo, RdHi, Rm, Rs.  */
4181
4182 static void
4183 do_mull (str)
4184      char * str;
4185 {
4186   int rdlo, rdhi, rm, rs;
4187
4188   /* Only one format "rdlo, rdhi, rm, rs".  */
4189   skip_whitespace (str);
4190
4191   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4192     {
4193       inst.error = BAD_ARGS;
4194       return;
4195     }
4196
4197   if (skip_past_comma (&str) == FAIL
4198       || (rdhi = reg_required_here (&str, 16)) == FAIL)
4199     {
4200       inst.error = BAD_ARGS;
4201       return;
4202     }
4203
4204   if (skip_past_comma (&str) == FAIL
4205       || (rm = reg_required_here (&str, 0)) == FAIL)
4206     {
4207       inst.error = BAD_ARGS;
4208       return;
4209     }
4210
4211   /* rdhi, rdlo and rm must all be different.  */
4212   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4213     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4214
4215   if (skip_past_comma (&str) == FAIL
4216       || (rs = reg_required_here (&str, 8)) == FAIL)
4217     {
4218       inst.error = BAD_ARGS;
4219       return;
4220     }
4221
4222   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4223     {
4224       inst.error = BAD_PC;
4225       return;
4226     }
4227
4228   end_of_line (str);
4229 }
4230
4231 static void
4232 do_mul (str)
4233      char * str;
4234 {
4235   int rd, rm;
4236
4237   /* Only one format "rd, rm, rs".  */
4238   skip_whitespace (str);
4239
4240   if ((rd = reg_required_here (&str, 16)) == FAIL)
4241     {
4242       inst.error = BAD_ARGS;
4243       return;
4244     }
4245
4246   if (rd == REG_PC)
4247     {
4248       inst.error = BAD_PC;
4249       return;
4250     }
4251
4252   if (skip_past_comma (&str) == FAIL
4253       || (rm = reg_required_here (&str, 0)) == FAIL)
4254     {
4255       inst.error = BAD_ARGS;
4256       return;
4257     }
4258
4259   if (rm == REG_PC)
4260     {
4261       inst.error = BAD_PC;
4262       return;
4263     }
4264
4265   if (rm == rd)
4266     as_tsktsk (_("rd and rm should be different in mul"));
4267
4268   if (skip_past_comma (&str) == FAIL
4269       || (rm = reg_required_here (&str, 8)) == FAIL)
4270     {
4271       inst.error = BAD_ARGS;
4272       return;
4273     }
4274
4275   if (rm == REG_PC)
4276     {
4277       inst.error = BAD_PC;
4278       return;
4279     }
4280
4281   end_of_line (str);
4282 }
4283
4284 static void
4285 do_mla (str)
4286      char * str;
4287 {
4288   int rd, rm;
4289
4290   /* Only one format "rd, rm, rs, rn".  */
4291   skip_whitespace (str);
4292
4293   if ((rd = reg_required_here (&str, 16)) == FAIL)
4294     {
4295       inst.error = BAD_ARGS;
4296       return;
4297     }
4298
4299   if (rd == REG_PC)
4300     {
4301       inst.error = BAD_PC;
4302       return;
4303     }
4304
4305   if (skip_past_comma (&str) == FAIL
4306       || (rm = reg_required_here (&str, 0)) == FAIL)
4307     {
4308       inst.error = BAD_ARGS;
4309       return;
4310     }
4311
4312   if (rm == REG_PC)
4313     {
4314       inst.error = BAD_PC;
4315       return;
4316     }
4317
4318   if (rm == rd)
4319     as_tsktsk (_("rd and rm should be different in mla"));
4320
4321   if (skip_past_comma (&str) == FAIL
4322       || (rd = reg_required_here (&str, 8)) == FAIL
4323       || skip_past_comma (&str) == FAIL
4324       || (rm = reg_required_here (&str, 12)) == FAIL)
4325     {
4326       inst.error = BAD_ARGS;
4327       return;
4328     }
4329
4330   if (rd == REG_PC || rm == REG_PC)
4331     {
4332       inst.error = BAD_PC;
4333       return;
4334     }
4335
4336   end_of_line (str);
4337 }
4338
4339 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4340    Advances *str to the next non-alphanumeric.
4341    Returns 0, or else FAIL (in which case sets inst.error).
4342
4343   (In a future XScale, there may be accumulators other than zero.
4344   At that time this routine and its callers can be upgraded to suit.)  */
4345
4346 static int
4347 accum0_required_here (str)
4348      char ** str;
4349 {
4350   static char buff [128];       /* Note the address is taken.  Hence, static.  */
4351   char * p = * str;
4352   char   c;
4353   int result = 0;               /* The accum number.  */
4354
4355   skip_whitespace (p);
4356
4357   *str = p;                     /* Advance caller's string pointer too.  */
4358   c = *p++;
4359   while (ISALNUM (c))
4360     c = *p++;
4361
4362   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
4363
4364   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4365     {
4366       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4367       inst.error = buff;
4368       result = FAIL;
4369     }
4370
4371   *p = c;                       /* Unzap.  */
4372   *str = p;                     /* Caller's string pointer to after match.  */
4373   return result;
4374 }
4375
4376 /* Expects **str -> after a comma. May be leading blanks.
4377    Advances *str, recognizing a load  mode, and setting inst.instruction.
4378    Returns rn, or else FAIL (in which case may set inst.error
4379    and not advance str)
4380
4381    Note: doesn't know Rd, so no err checks that require such knowledge.  */
4382
4383 static int
4384 ld_mode_required_here (string)
4385      char ** string;
4386 {
4387   char * str = * string;
4388   int    rn;
4389   int    pre_inc = 0;
4390
4391   skip_whitespace (str);
4392
4393   if (* str == '[')
4394     {
4395       str++;
4396
4397       skip_whitespace (str);
4398
4399       if ((rn = reg_required_here (& str, 16)) == FAIL)
4400         return FAIL;
4401
4402       skip_whitespace (str);
4403
4404       if (* str == ']')
4405         {
4406           str ++;
4407
4408           if (skip_past_comma (& str) == SUCCESS)
4409             {
4410               /* [Rn],... (post inc) */
4411               if (ldst_extend_v4 (&str) == FAIL)
4412                 return FAIL;
4413             }
4414           else        /* [Rn] */
4415             {
4416               skip_whitespace (str);
4417
4418               if (* str == '!')
4419                 {
4420                   str ++;
4421                   inst.instruction |= WRITE_BACK;
4422                 }
4423
4424               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4425               pre_inc = 1;
4426             }
4427         }
4428       else        /* [Rn,...] */
4429         {
4430           if (skip_past_comma (& str) == FAIL)
4431             {
4432               inst.error = _("pre-indexed expression expected");
4433               return FAIL;
4434             }
4435
4436           pre_inc = 1;
4437
4438           if (ldst_extend_v4 (&str) == FAIL)
4439             return FAIL;
4440
4441           skip_whitespace (str);
4442
4443           if (* str ++ != ']')
4444             {
4445               inst.error = _("missing ]");
4446               return FAIL;
4447             }
4448
4449           skip_whitespace (str);
4450
4451           if (* str == '!')
4452             {
4453               str ++;
4454               inst.instruction |= WRITE_BACK;
4455             }
4456         }
4457     }
4458   else if (* str == '=')        /* ldr's "r,=label" syntax */
4459     /* We should never reach here, because <text> = <expression> is
4460        caught gas/read.c read_a_source_file() as a .set operation.  */
4461     return FAIL;
4462   else                          /* PC +- 8 bit immediate offset.  */
4463     {
4464       if (my_get_expression (& inst.reloc.exp, & str))
4465         return FAIL;
4466
4467       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
4468       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4469       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
4470       inst.reloc.pc_rel            = 1;
4471       inst.instruction            |= (REG_PC << 16);
4472
4473       rn = REG_PC;
4474       pre_inc = 1;
4475     }
4476
4477   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4478   * string = str;
4479
4480   return rn;
4481 }
4482
4483 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4484    SMLAxy{cond} Rd,Rm,Rs,Rn
4485    SMLAWy{cond} Rd,Rm,Rs,Rn
4486    Error if any register is R15.  */
4487
4488 static void
4489 do_smla (str)
4490      char *        str;
4491 {
4492   int rd, rm, rs, rn;
4493
4494   skip_whitespace (str);
4495
4496   if ((rd = reg_required_here (& str, 16)) == FAIL
4497       || skip_past_comma (& str) == FAIL
4498       || (rm = reg_required_here (& str, 0)) == FAIL
4499       || skip_past_comma (& str) == FAIL
4500       || (rs = reg_required_here (& str, 8)) == FAIL
4501       || skip_past_comma (& str) == FAIL
4502       || (rn = reg_required_here (& str, 12)) == FAIL)
4503     inst.error = BAD_ARGS;
4504
4505   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4506     inst.error = BAD_PC;
4507
4508   else
4509     end_of_line (str);
4510 }
4511
4512 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4513    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4514    Error if any register is R15.
4515    Warning if Rdlo == Rdhi.  */
4516
4517 static void
4518 do_smlal (str)
4519      char *        str;
4520 {
4521   int rdlo, rdhi, rm, rs;
4522
4523   skip_whitespace (str);
4524
4525   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4526       || skip_past_comma (& str) == FAIL
4527       || (rdhi = reg_required_here (& str, 16)) == FAIL
4528       || skip_past_comma (& str) == FAIL
4529       || (rm = reg_required_here (& str, 0)) == FAIL
4530       || skip_past_comma (& str) == FAIL
4531       || (rs = reg_required_here (& str, 8)) == FAIL)
4532     {
4533       inst.error = BAD_ARGS;
4534       return;
4535     }
4536
4537   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4538     {
4539       inst.error = BAD_PC;
4540       return;
4541     }
4542
4543   if (rdlo == rdhi)
4544     as_tsktsk (_("rdhi and rdlo must be different"));
4545
4546   end_of_line (str);
4547 }
4548
4549 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4550    SMULxy{cond} Rd,Rm,Rs
4551    Error if any register is R15.  */
4552
4553 static void
4554 do_smul (str)
4555      char *        str;
4556 {
4557   int rd, rm, rs;
4558
4559   skip_whitespace (str);
4560
4561   if ((rd = reg_required_here (& str, 16)) == FAIL
4562       || skip_past_comma (& str) == FAIL
4563       || (rm = reg_required_here (& str, 0)) == FAIL
4564       || skip_past_comma (& str) == FAIL
4565       || (rs = reg_required_here (& str, 8)) == FAIL)
4566     inst.error = BAD_ARGS;
4567
4568   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4569     inst.error = BAD_PC;
4570
4571   else
4572     end_of_line (str);
4573 }
4574
4575 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4576    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4577    Error if any register is R15.  */
4578
4579 static void
4580 do_qadd (str)
4581      char *        str;
4582 {
4583   int rd, rm, rn;
4584
4585   skip_whitespace (str);
4586
4587   if ((rd = reg_required_here (& str, 12)) == FAIL
4588       || skip_past_comma (& str) == FAIL
4589       || (rm = reg_required_here (& str, 0)) == FAIL
4590       || skip_past_comma (& str) == FAIL
4591       || (rn = reg_required_here (& str, 16)) == FAIL)
4592     inst.error = BAD_ARGS;
4593
4594   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4595     inst.error = BAD_PC;
4596
4597   else
4598     end_of_line (str);
4599 }
4600
4601 /* ARM V5E (el Segundo)
4602    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4603    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4604
4605    These are equivalent to the XScale instructions MAR and MRA,
4606    respectively, when coproc == 0, opcode == 0, and CRm == 0.
4607
4608    Result unpredicatable if Rd or Rn is R15.  */
4609
4610 static void
4611 do_co_reg2c (str)
4612      char *        str;
4613 {
4614   int rd, rn;
4615
4616   skip_whitespace (str);
4617
4618   if (co_proc_number (& str) == FAIL)
4619     {
4620       if (!inst.error)
4621         inst.error = BAD_ARGS;
4622       return;
4623     }
4624
4625   if (skip_past_comma (& str) == FAIL
4626       || cp_opc_expr (& str, 4, 4) == FAIL)
4627     {
4628       if (!inst.error)
4629         inst.error = BAD_ARGS;
4630       return;
4631     }
4632
4633   if (skip_past_comma (& str) == FAIL
4634       || (rd = reg_required_here (& str, 12)) == FAIL)
4635     {
4636       if (!inst.error)
4637         inst.error = BAD_ARGS;
4638       return;
4639     }
4640
4641   if (skip_past_comma (& str) == FAIL
4642       || (rn = reg_required_here (& str, 16)) == FAIL)
4643     {
4644       if (!inst.error)
4645         inst.error = BAD_ARGS;
4646       return;
4647     }
4648
4649   /* Unpredictable result if rd or rn is R15.  */
4650   if (rd == REG_PC || rn == REG_PC)
4651     as_tsktsk
4652       (_("Warning: instruction unpredictable when using r15"));
4653
4654   if (skip_past_comma (& str) == FAIL
4655       || cp_reg_required_here (& str, 0) == FAIL)
4656     {
4657       if (!inst.error)
4658         inst.error = BAD_ARGS;
4659       return;
4660     }
4661
4662   end_of_line (str);
4663 }
4664
4665 /* ARM V5 count-leading-zeroes instruction (argument parse)
4666      CLZ{<cond>} <Rd>, <Rm>
4667      Condition defaults to COND_ALWAYS.
4668      Error if Rd or Rm are R15.  */
4669
4670 static void
4671 do_clz (str)
4672      char *        str;
4673 {
4674   int rd, rm;
4675
4676   skip_whitespace (str);
4677
4678   if (((rd = reg_required_here (& str, 12)) == FAIL)
4679       || (skip_past_comma (& str) == FAIL)
4680       || ((rm = reg_required_here (& str, 0)) == FAIL))
4681     inst.error = BAD_ARGS;
4682
4683   else if (rd == REG_PC || rm == REG_PC )
4684     inst.error = BAD_PC;
4685
4686   else
4687     end_of_line (str);
4688 }
4689
4690 /* ARM V5 (argument parse)
4691      LDC2{L} <coproc>, <CRd>, <addressing mode>
4692      STC2{L} <coproc>, <CRd>, <addressing mode>
4693      Instruction is not conditional, and has 0xf in the condition field.
4694      Otherwise, it's the same as LDC/STC.  */
4695
4696 static void
4697 do_lstc2 (str)
4698      char *        str;
4699 {
4700   skip_whitespace (str);
4701
4702   if (co_proc_number (& str) == FAIL)
4703     {
4704       if (!inst.error)
4705         inst.error = BAD_ARGS;
4706     }
4707   else if (skip_past_comma (& str) == FAIL
4708            || cp_reg_required_here (& str, 12) == FAIL)
4709     {
4710       if (!inst.error)
4711         inst.error = BAD_ARGS;
4712     }
4713   else if (skip_past_comma (& str) == FAIL
4714            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4715     {
4716       if (! inst.error)
4717         inst.error = BAD_ARGS;
4718     }
4719   else
4720     end_of_line (str);
4721 }
4722
4723 /* ARM V5 (argument parse)
4724      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4725      Instruction is not conditional, and has 0xf in the condition field.
4726      Otherwise, it's the same as CDP.  */
4727
4728 static void
4729 do_cdp2 (str)
4730      char *        str;
4731 {
4732   skip_whitespace (str);
4733
4734   if (co_proc_number (& str) == FAIL)
4735     {
4736       if (!inst.error)
4737         inst.error = BAD_ARGS;
4738       return;
4739     }
4740
4741   if (skip_past_comma (& str) == FAIL
4742       || cp_opc_expr (& str, 20,4) == FAIL)
4743     {
4744       if (!inst.error)
4745         inst.error = BAD_ARGS;
4746       return;
4747     }
4748
4749   if (skip_past_comma (& str) == FAIL
4750       || cp_reg_required_here (& str, 12) == FAIL)
4751     {
4752       if (!inst.error)
4753         inst.error = BAD_ARGS;
4754       return;
4755     }
4756
4757   if (skip_past_comma (& str) == FAIL
4758       || cp_reg_required_here (& str, 16) == FAIL)
4759     {
4760       if (!inst.error)
4761         inst.error = BAD_ARGS;
4762       return;
4763     }
4764
4765   if (skip_past_comma (& str) == FAIL
4766       || cp_reg_required_here (& str, 0) == FAIL)
4767     {
4768       if (!inst.error)
4769         inst.error = BAD_ARGS;
4770       return;
4771     }
4772
4773   if (skip_past_comma (& str) == SUCCESS)
4774     {
4775       if (cp_opc_expr (& str, 5, 3) == FAIL)
4776         {
4777           if (!inst.error)
4778             inst.error = BAD_ARGS;
4779           return;
4780         }
4781     }
4782
4783   end_of_line (str);
4784 }
4785
4786 /* ARM V5 (argument parse)
4787      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4788      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4789      Instruction is not conditional, and has 0xf in the condition field.
4790      Otherwise, it's the same as MCR/MRC.  */
4791
4792 static void
4793 do_co_reg2 (str)
4794      char *        str;
4795 {
4796   skip_whitespace (str);
4797
4798   if (co_proc_number (& str) == FAIL)
4799     {
4800       if (!inst.error)
4801         inst.error = BAD_ARGS;
4802       return;
4803     }
4804
4805   if (skip_past_comma (& str) == FAIL
4806       || cp_opc_expr (& str, 21, 3) == FAIL)
4807     {
4808       if (!inst.error)
4809         inst.error = BAD_ARGS;
4810       return;
4811     }
4812
4813   if (skip_past_comma (& str) == FAIL
4814       || reg_required_here (& str, 12) == FAIL)
4815     {
4816       if (!inst.error)
4817         inst.error = BAD_ARGS;
4818       return;
4819     }
4820
4821   if (skip_past_comma (& str) == FAIL
4822       || cp_reg_required_here (& str, 16) == FAIL)
4823     {
4824       if (!inst.error)
4825         inst.error = BAD_ARGS;
4826       return;
4827     }
4828
4829   if (skip_past_comma (& str) == FAIL
4830       || cp_reg_required_here (& str, 0) == FAIL)
4831     {
4832       if (!inst.error)
4833         inst.error = BAD_ARGS;
4834       return;
4835     }
4836
4837   if (skip_past_comma (& str) == SUCCESS)
4838     {
4839       if (cp_opc_expr (& str, 5, 3) == FAIL)
4840         {
4841           if (!inst.error)
4842             inst.error = BAD_ARGS;
4843           return;
4844         }
4845     }
4846
4847   end_of_line (str);
4848 }
4849
4850 /* ARM v5TEJ.  Jump to Jazelle code.  */
4851 static void
4852 do_bxj (str)
4853      char * str;
4854 {
4855   int reg;
4856
4857   skip_whitespace (str);
4858
4859   if ((reg = reg_required_here (&str, 0)) == FAIL)
4860     {
4861       inst.error = BAD_ARGS;
4862       return;
4863     }
4864
4865   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4866   if (reg == REG_PC)
4867     as_tsktsk (_("use of r15 in bxj is not really useful"));
4868
4869   end_of_line (str);
4870 }
4871
4872 /* ARM V6 umaal (argument parse). */
4873
4874 static void
4875 do_umaal (str)
4876      char *str;
4877 {
4878
4879   int rdlo, rdhi, rm, rs;
4880
4881   skip_whitespace (str);
4882   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4883       || skip_past_comma (& str) == FAIL
4884       || (rdhi = reg_required_here (& str, 16)) == FAIL
4885       || skip_past_comma (& str) == FAIL
4886       || (rm = reg_required_here (& str, 0)) == FAIL
4887       || skip_past_comma (& str) == FAIL
4888       || (rs = reg_required_here (& str, 8)) == FAIL)
4889     {
4890       inst.error = BAD_ARGS;
4891       return;      
4892     }
4893
4894   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4895     {
4896       inst.error = BAD_PC;
4897       return;
4898     }
4899
4900   end_of_line (str);
4901 }
4902
4903 /* ARM V6 strex (argument parse). */
4904
4905 static void 
4906 do_strex (str)
4907      char *str;
4908 {
4909   int rd, rm, rn;
4910
4911   /* Parse Rd, Rm,. */
4912   skip_whitespace (str);
4913   if ((rd = reg_required_here (& str, 12)) == FAIL
4914       || skip_past_comma (& str) == FAIL
4915       || (rm = reg_required_here (& str, 0)) == FAIL
4916       || skip_past_comma (& str) == FAIL)
4917     {
4918       inst.error = BAD_ARGS;
4919       return;
4920     }
4921   if (rd == REG_PC || rm == REG_PC)
4922     {
4923       inst.error = BAD_PC;
4924       return;
4925     }
4926   if (rd == rm)
4927     {
4928       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4929       return;
4930     }
4931
4932   /* Skip past '['. */
4933   if ((strlen (str) >= 1) 
4934       && strncmp (str, "[", 1) == 0)
4935     str+=1;
4936   skip_whitespace (str);  
4937
4938   /* Parse Rn. */
4939   if ((rn = reg_required_here (& str, 16)) == FAIL)
4940     {
4941       inst.error = BAD_ARGS;
4942       return;
4943     }
4944   else if (rn == REG_PC)
4945     {
4946       inst.error = BAD_PC;
4947       return;
4948     }
4949   if (rd == rn)
4950     {
4951       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4952       return;
4953     }
4954   skip_whitespace (str);  
4955
4956   /* Skip past ']'. */
4957   if ((strlen (str) >= 1) 
4958       && strncmp (str, "]", 1) == 0)
4959     str+=1;
4960   
4961   end_of_line (str);
4962 }
4963
4964 /* ARM V6 ssat (argument parse). */
4965
4966 static void
4967 do_ssat (str)
4968      char* str;
4969 {
4970   do_sat (&str, /*bias=*/-1);
4971   end_of_line (str);
4972 }
4973
4974 /* ARM V6 usat (argument parse). */
4975
4976 static void
4977 do_usat (str)
4978      char* str;
4979 {
4980   do_sat (&str, /*bias=*/0);
4981   end_of_line (str);
4982 }
4983
4984 static void
4985 do_sat (str, bias)
4986      char **str;
4987      int    bias;
4988 {
4989   int rd, rm;
4990   expressionS expr;
4991
4992   skip_whitespace (*str);
4993   
4994   /* Parse <Rd>, field. */
4995   if ((rd = reg_required_here (str, 12)) == FAIL
4996       || skip_past_comma (str) == FAIL)
4997     {
4998       inst.error = BAD_ARGS;
4999       return;
5000     }
5001   if (rd == REG_PC)
5002     {
5003       inst.error = BAD_PC;
5004       return;
5005     }
5006
5007   /* Parse #<immed>,  field. */
5008   if (is_immediate_prefix (**str))
5009     (*str)++;
5010   else
5011     {
5012       inst.error = _("immediate expression expected");
5013       return;
5014     }
5015   if (my_get_expression (&expr, str))
5016     {
5017       inst.error = _("bad expression");
5018       return;
5019     }
5020   if (expr.X_op != O_constant)
5021     {
5022       inst.error = _("constant expression expected");
5023       return;
5024     }
5025   if (expr.X_add_number + bias < 0
5026       || expr.X_add_number + bias > 31)
5027     {
5028       inst.error = _("immediate value out of range");
5029       return;
5030     }
5031   inst.instruction |= (expr.X_add_number + bias) << 16;
5032   if (skip_past_comma (str) == FAIL)
5033     {
5034       inst.error = BAD_ARGS;
5035       return;
5036     }
5037
5038   /* Parse <Rm> field. */
5039   if ((rm = reg_required_here (str, 0)) == FAIL)
5040     {
5041       inst.error = BAD_ARGS;
5042       return;
5043     }
5044   if (rm == REG_PC)
5045     {
5046       inst.error = BAD_PC;
5047       return;
5048     }
5049
5050   if (skip_past_comma (str) == SUCCESS)
5051     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5052 }
5053
5054 /* ARM V6 ssat16 (argument parse). */
5055
5056 static void
5057 do_ssat16 (str)
5058      char *str;
5059 {
5060   do_sat16 (&str, /*bias=*/-1);
5061   end_of_line (str);
5062 }
5063
5064 static void
5065 do_usat16 (str)
5066      char *str;
5067 {
5068   do_sat16 (&str, /*bias=*/0);
5069   end_of_line (str);
5070 }
5071
5072 static void
5073 do_sat16 (str, bias)
5074      char **str;
5075      int bias;
5076 {
5077   int rd, rm;
5078   expressionS expr;
5079
5080   skip_whitespace (*str);
5081
5082   /* Parse the <Rd> field. */
5083   if ((rd = reg_required_here (str, 12)) == FAIL
5084       || skip_past_comma (str) == FAIL)
5085     {
5086       inst.error = BAD_ARGS;
5087       return;
5088     }
5089   if (rd == REG_PC)
5090     {
5091       inst.error = BAD_PC;
5092       return;
5093     }
5094
5095   /* Parse #<immed>, field. */
5096   if (is_immediate_prefix (**str))
5097     (*str)++;
5098   else
5099     {
5100       inst.error = _("immediate expression expected");
5101       return;
5102     }
5103   if (my_get_expression (&expr, str))
5104     {
5105       inst.error = _("bad expression");
5106       return;
5107     }
5108   if (expr.X_op != O_constant)
5109     {
5110       inst.error = _("constant expression expected");
5111       return;
5112     }
5113   if (expr.X_add_number + bias < 0
5114       || expr.X_add_number + bias > 15)
5115     {
5116       inst.error = _("immediate value out of range");
5117       return;
5118     }
5119   inst.instruction |= (expr.X_add_number + bias) << 16;
5120   if (skip_past_comma (str) == FAIL)
5121     {
5122       inst.error = BAD_ARGS;
5123       return;
5124     }
5125
5126   /* Parse <Rm> field. */
5127   if ((rm = reg_required_here (str, 0)) == FAIL)
5128     {
5129       inst.error = BAD_ARGS;
5130       return;
5131     }
5132   if (rm == REG_PC)
5133     {
5134       inst.error = BAD_PC;
5135       return;
5136     }
5137 }
5138
5139 /* ARM V6 srs (argument parse). */
5140
5141 static void
5142 do_srs (str)
5143      char* str;
5144 {
5145   char *exclam;
5146   skip_whitespace (str);
5147   exclam = strchr (str, '!');
5148   if (exclam)
5149     *exclam = '\0';
5150   do_cps_mode (&str);
5151   if (exclam)
5152     *exclam = '!';
5153   if (*str == '!') 
5154     {
5155       inst.instruction |= WRITE_BACK;
5156       str++;
5157     }
5158   end_of_line (str);
5159 }
5160
5161 /* ARM V6 SMMUL (argument parse). */
5162
5163 static void
5164 do_smmul (str)
5165      char* str;
5166 {
5167   int rd, rm, rs;
5168   
5169   skip_whitespace (str);
5170   if ((rd = reg_required_here (&str, 16)) == FAIL
5171       || skip_past_comma (&str) == FAIL
5172       || (rm = reg_required_here (&str, 0)) == FAIL
5173       || skip_past_comma (&str) == FAIL
5174       || (rs = reg_required_here (&str, 8)) == FAIL)
5175     {
5176       inst.error = BAD_ARGS;
5177       return;
5178     }
5179
5180   if (rd == REG_PC 
5181       || rm == REG_PC
5182       || rs == REG_PC)
5183     {
5184       inst.error = BAD_PC;
5185       return;
5186     }
5187
5188   end_of_line (str);
5189   
5190 }
5191
5192 /* ARM V6 SMLALD (argument parse). */
5193
5194 static void
5195 do_smlald (str)
5196     char* str;
5197 {
5198   int rdlo, rdhi, rm, rs;
5199   skip_whitespace (str);
5200   if ((rdlo = reg_required_here (&str, 12)) == FAIL
5201       || skip_past_comma (&str) == FAIL
5202       || (rdhi = reg_required_here (&str, 16)) == FAIL
5203       || skip_past_comma (&str) == FAIL
5204       || (rm = reg_required_here (&str, 0)) == FAIL
5205       || skip_past_comma (&str) == FAIL
5206       || (rs = reg_required_here (&str, 8)) == FAIL)
5207     {
5208       inst.error = BAD_ARGS;
5209       return;
5210     }
5211
5212   if (rdlo == REG_PC 
5213       || rdhi == REG_PC 
5214       || rm == REG_PC
5215       || rs == REG_PC)
5216     {
5217       inst.error = BAD_PC;
5218       return;
5219     }
5220
5221   end_of_line (str);
5222 }
5223
5224 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
5225    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5226
5227 static void 
5228 do_smlad (str)
5229      char *str;
5230 {
5231   int rd, rm, rs, rn;
5232   
5233   skip_whitespace (str);
5234   if ((rd = reg_required_here (&str, 16)) == FAIL
5235       || skip_past_comma (&str) == FAIL
5236       || (rm = reg_required_here (&str, 0)) == FAIL
5237       || skip_past_comma (&str) == FAIL
5238       || (rs = reg_required_here (&str, 8)) == FAIL
5239       || skip_past_comma (&str) == FAIL
5240       || (rn = reg_required_here (&str, 12)) == FAIL)
5241     {
5242       inst.error = BAD_ARGS;
5243       return;
5244     }
5245   
5246   if (rd == REG_PC 
5247       || rn == REG_PC 
5248       || rs == REG_PC
5249       || rm == REG_PC)
5250     {
5251       inst.error = BAD_PC;
5252       return;
5253     }
5254
5255   end_of_line (str);
5256
5257
5258 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5259    preserving the other bits.
5260
5261    setend <endian_specifier>, where <endian_specifier> is either 
5262    BE or LE. */
5263
5264 static void 
5265 do_setend (str)
5266      char *str;
5267 {
5268   if (do_endian_specifier (str))
5269     inst.instruction |= 0x200;
5270 }
5271
5272 /* Returns true if the endian-specifier indicates big-endianness.  */
5273
5274 static int
5275 do_endian_specifier (str)
5276      char *str;
5277 {
5278   int big_endian = 0;
5279
5280   skip_whitespace (str);
5281   if (strlen (str) < 2)
5282     inst.error = _("missing endian specifier");
5283   else if (strncasecmp (str, "BE", 2) == 0)
5284     {
5285       str += 2;
5286       big_endian = 1;
5287     }
5288   else if (strncasecmp (str, "LE", 2) == 0)
5289     str += 2;
5290   else
5291     inst.error = _("valid endian specifiers are be or le");
5292
5293   end_of_line (str);
5294
5295   return big_endian;
5296 }
5297
5298 /* ARM V6 SXTH.
5299
5300    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5301    Condition defaults to COND_ALWAYS.
5302    Error if any register uses R15. */
5303
5304 static void 
5305 do_sxth (str)
5306      char *str;
5307 {
5308   int rd, rm;
5309   expressionS expr;
5310   int rotation_clear_mask = 0xfffff3ff;
5311   int rotation_eight_mask = 0x00000400;
5312   int rotation_sixteen_mask = 0x00000800;
5313   int rotation_twenty_four_mask = 0x00000c00;
5314   
5315   skip_whitespace (str);
5316   if ((rd = reg_required_here (&str, 12)) == FAIL
5317       || skip_past_comma (&str) == FAIL
5318       || (rm = reg_required_here (&str, 0)) == FAIL)
5319     {
5320       inst.error = BAD_ARGS;
5321       return;
5322     }
5323
5324   else if (rd == REG_PC || rm == REG_PC)
5325     {
5326       inst.error = BAD_PC;
5327       return;
5328     }
5329   
5330   /* Zero out the rotation field. */
5331   inst.instruction &= rotation_clear_mask;
5332   
5333   /* Check for lack of optional rotation field. */
5334   if (skip_past_comma (&str) == FAIL)
5335     {
5336       end_of_line (str);
5337       return;
5338     }
5339   
5340   /* Move past 'ROR'. */
5341   skip_whitespace (str);
5342   if (strncasecmp (str, "ROR", 3) == 0)
5343     str+=3;
5344   else
5345     {
5346       inst.error = _("missing rotation field after comma");
5347       return;
5348     }
5349   
5350   /* Get the immediate constant. */
5351   skip_whitespace (str);
5352   if (is_immediate_prefix (* str))
5353     str++;
5354   else
5355     {
5356       inst.error = _("immediate expression expected");
5357       return;
5358     }
5359   
5360   if (my_get_expression (&expr, &str))
5361     {
5362       inst.error = _("bad expression");
5363       return;
5364     }
5365
5366   if (expr.X_op != O_constant)
5367     {
5368       inst.error = _("constant expression expected");
5369       return;
5370     }
5371   
5372   switch (expr.X_add_number) 
5373     {
5374     case 0:
5375       /* Rotation field has already been zeroed. */
5376       break;
5377     case 8:
5378       inst.instruction |= rotation_eight_mask;
5379       break;
5380
5381     case 16:
5382       inst.instruction |= rotation_sixteen_mask;
5383       break;
5384       
5385     case 24:
5386       inst.instruction |= rotation_twenty_four_mask;
5387       break;
5388
5389     default:
5390       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5391       break;
5392     }
5393
5394   end_of_line (str);
5395   
5396 }
5397
5398 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5399    extends it to 32-bits, and adds the result to a value in another
5400    register.  You can specify a rotation by 0, 8, 16, or 24 bits
5401    before extracting the 16-bit value.
5402    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5403    Condition defaults to COND_ALWAYS.
5404    Error if any register uses R15. */
5405
5406 static void 
5407 do_sxtah (str)
5408      char *str;
5409 {
5410   int rd, rn, rm;
5411   expressionS expr;
5412   int rotation_clear_mask = 0xfffff3ff;
5413   int rotation_eight_mask = 0x00000400;
5414   int rotation_sixteen_mask = 0x00000800;
5415   int rotation_twenty_four_mask = 0x00000c00;
5416   
5417   skip_whitespace (str);
5418   if ((rd = reg_required_here (&str, 12)) == FAIL
5419       || skip_past_comma (&str) == FAIL
5420       || (rn = reg_required_here (&str, 16)) == FAIL
5421       || skip_past_comma (&str) == FAIL
5422       || (rm = reg_required_here (&str, 0)) == FAIL)
5423     {
5424       inst.error = BAD_ARGS;
5425       return;
5426     }
5427
5428   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5429     {
5430       inst.error = BAD_PC;
5431       return;
5432     }
5433   
5434   /* Zero out the rotation field. */
5435   inst.instruction &= rotation_clear_mask;
5436   
5437   /* Check for lack of optional rotation field. */
5438   if (skip_past_comma (&str) == FAIL)
5439     {
5440       end_of_line (str);
5441       return;
5442     }
5443   
5444   /* Move past 'ROR'. */
5445   skip_whitespace (str);
5446   if (strncasecmp (str, "ROR", 3) == 0)
5447     str+=3;
5448   else
5449     {
5450       inst.error = _("missing rotation field after comma");
5451       return;
5452     }
5453   
5454   /* Get the immediate constant. */
5455   skip_whitespace (str);
5456   if (is_immediate_prefix (* str))
5457     str++;
5458   else
5459     {
5460       inst.error = _("immediate expression expected");
5461       return;
5462     }
5463   
5464   if (my_get_expression (&expr, &str))
5465     {
5466       inst.error = _("bad expression");
5467       return;
5468     }
5469
5470   if (expr.X_op != O_constant)
5471     {
5472       inst.error = _("constant expression expected");
5473       return;
5474     }
5475   
5476   switch (expr.X_add_number) 
5477     {
5478     case 0:
5479       /* Rotation field has already been zeroed. */
5480       break;
5481
5482     case 8:
5483       inst.instruction |= rotation_eight_mask;
5484       break;
5485
5486     case 16:
5487       inst.instruction |= rotation_sixteen_mask;
5488       break;
5489       
5490     case 24:
5491       inst.instruction |= rotation_twenty_four_mask;
5492       break;
5493
5494     default:
5495       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5496       break;
5497     }
5498
5499   end_of_line (str);
5500   
5501 }
5502    
5503
5504 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5505    word at the specified address and the following word
5506    respectively. 
5507    Unconditionally executed.
5508    Error if Rn is R15.   
5509 */
5510
5511 static void
5512 do_rfe (str)
5513      char *str;
5514 {
5515   int rn;
5516
5517   skip_whitespace (str);
5518   
5519   if ((rn = reg_required_here (&str, 16)) == FAIL)
5520     return;
5521
5522   if (rn == REG_PC)
5523     {
5524       inst.error = BAD_PC;
5525       return;
5526     }
5527
5528   skip_whitespace (str);
5529   
5530   if (*str == '!')
5531     {
5532       inst.instruction |= WRITE_BACK;
5533       str++;
5534     }
5535   end_of_line (str);
5536 }
5537
5538 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5539    register (argument parse).
5540    REV{<cond>} Rd, Rm.
5541    Condition defaults to COND_ALWAYS.
5542    Error if Rd or Rm are R15. */ 
5543
5544 static void
5545 do_rev (str)
5546      char* str;
5547 {
5548   int rd, rm;
5549
5550   skip_whitespace (str);
5551
5552   if ((rd = reg_required_here (&str, 12)) == FAIL
5553       || skip_past_comma (&str) == FAIL
5554       || (rm = reg_required_here (&str, 0)) == FAIL)
5555     inst.error = BAD_ARGS;
5556
5557   else if (rd == REG_PC || rm == REG_PC)
5558     inst.error = BAD_PC;
5559
5560   else
5561     end_of_line (str);
5562 }
5563
5564 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5565    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
5566    Condition defaults to COND_ALWAYS.
5567    Error if Rd, Rn or Rm are R15.  */
5568
5569 static void
5570 do_qadd16 (str) 
5571      char* str;
5572 {
5573   int rd, rm, rn;
5574
5575   skip_whitespace (str);
5576
5577   if ((rd = reg_required_here (&str, 12)) == FAIL
5578       || skip_past_comma (&str) == FAIL
5579       || (rn = reg_required_here (&str, 16)) == FAIL
5580       || skip_past_comma (&str) == FAIL
5581       || (rm = reg_required_here (&str, 0)) == FAIL)
5582     inst.error = BAD_ARGS;
5583
5584   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5585     inst.error = BAD_PC;
5586
5587   else
5588     end_of_line (str);
5589 }
5590
5591 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5592    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
5593    Condition defaults to COND_ALWAYS.
5594    Error if Rd, Rn or Rm are R15.  */
5595
5596 static void 
5597 do_pkhbt (str)
5598      char* str;
5599 {
5600   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5601 }
5602
5603 /* ARM V6 PKHTB (Argument Parse). */
5604
5605 static void 
5606 do_pkhtb (str)
5607      char* str;
5608 {
5609   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5610 }
5611
5612 static void
5613 do_pkh_core (str, shift)
5614      char* str;
5615      int shift;
5616 {
5617   int rd, rn, rm;
5618
5619   skip_whitespace (str);
5620   if (((rd = reg_required_here (&str, 12)) == FAIL)
5621       || (skip_past_comma (&str) == FAIL)
5622       || ((rn = reg_required_here (&str, 16)) == FAIL)
5623       || (skip_past_comma (&str) == FAIL)
5624       || ((rm = reg_required_here (&str, 0)) == FAIL))
5625     {
5626       inst.error = BAD_ARGS;
5627       return;
5628     }
5629
5630   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5631     {
5632       inst.error = BAD_PC;
5633       return;
5634     }
5635
5636   /* Check for optional shift immediate constant. */
5637   if (skip_past_comma (&str) == FAIL) 
5638     {
5639       if (shift == SHIFT_ASR_IMMEDIATE)
5640         {
5641           /* If the shift specifier is ommited, turn the instruction
5642              into pkhbt rd, rm, rn.  First, switch the instruction
5643              code, and clear the rn and rm fields.  */
5644           inst.instruction &= 0xfff0f010;
5645           /* Now, re-encode the registers.  */
5646           inst.instruction |= (rm << 16) | rn;
5647         }
5648       return;
5649     }
5650
5651   decode_shift (&str, shift);
5652 }
5653
5654 /* ARM V6 Load Register Exclusive instruction (argument parse).
5655    LDREX{<cond>} <Rd, [<Rn>]
5656    Condition defaults to COND_ALWAYS.
5657    Error if Rd or Rn are R15. 
5658    See ARMARMv6 A4.1.27: LDREX. */
5659
5660
5661 static void
5662 do_ldrex (str)
5663      char * str;
5664 {
5665   int rd, rn;
5666
5667   skip_whitespace (str);
5668
5669   /* Parse Rd. */
5670   if (((rd = reg_required_here (&str, 12)) == FAIL)
5671       || (skip_past_comma (&str) == FAIL))
5672     {
5673       inst.error = BAD_ARGS;
5674       return;
5675     }
5676   else if (rd == REG_PC)
5677     {
5678       inst.error = BAD_PC;
5679       return;
5680     }
5681   skip_whitespace (str);  
5682
5683   /* Skip past '['. */
5684   if ((strlen (str) >= 1) 
5685       &&strncmp (str, "[", 1) == 0)
5686     str+=1;
5687   skip_whitespace (str);  
5688
5689   /* Parse Rn. */
5690   if ((rn = reg_required_here (&str, 16)) == FAIL)
5691     {
5692       inst.error = BAD_ARGS;
5693       return;
5694     }
5695   else if (rn == REG_PC)
5696     {
5697       inst.error = BAD_PC;
5698       return;
5699     }
5700   skip_whitespace (str);  
5701
5702   /* Skip past ']'. */
5703   if ((strlen (str) >= 1) 
5704       && strncmp (str, "]", 1) == 0)
5705     str+=1;
5706   
5707   end_of_line (str);
5708 }
5709
5710 /* ARM V6 change processor state instruction (argument parse)
5711       CPS, CPSIE, CSPID . */
5712
5713 static void
5714 do_cps (str)
5715      char * str;
5716 {
5717   do_cps_mode (&str);
5718   end_of_line (str);
5719 }
5720
5721 static void
5722 do_cpsi (str)
5723      char * str;
5724 {
5725   do_cps_flags (&str, /*thumb_p=*/0);
5726
5727   if (skip_past_comma (&str) == SUCCESS)
5728     {
5729       skip_whitespace (str);
5730       do_cps_mode (&str);
5731     }
5732   end_of_line (str);
5733 }
5734
5735 static void
5736 do_cps_mode (str)
5737      char **str;
5738 {
5739   expressionS expr;
5740
5741   skip_whitespace (*str);
5742
5743   if (! is_immediate_prefix (**str))
5744     {
5745       inst.error = _("immediate expression expected");
5746       return;
5747     }
5748
5749   (*str)++; /* Strip off the immediate signifier. */
5750   if (my_get_expression (&expr, str))
5751     {
5752       inst.error = _("bad expression");
5753       return;
5754     }
5755
5756   if (expr.X_op != O_constant)
5757     {
5758       inst.error = _("constant expression expected");
5759       return;
5760     }
5761   
5762   /* The mode is a 5 bit field.  Valid values are 0-31. */
5763   if (((unsigned) expr.X_add_number) > 31
5764       || (inst.reloc.exp.X_add_number) < 0)
5765     {
5766       inst.error = _("invalid constant");
5767       return;
5768     }
5769   
5770   inst.instruction |= expr.X_add_number;
5771 }
5772
5773 static void
5774 do_cps_flags (str, thumb_p)
5775      char **str;
5776      int    thumb_p;
5777 {
5778   struct cps_flag { 
5779     char character;
5780     unsigned long arm_value;
5781     unsigned long thumb_value;
5782   };
5783   static struct cps_flag flag_table[] = {
5784     {'a', 0x100, 0x4 },
5785     {'i', 0x080, 0x2 },
5786     {'f', 0x040, 0x1 }
5787   };
5788
5789   int saw_a_flag = 0;
5790
5791   skip_whitespace (*str);
5792
5793   /* Get the a, f and i flags. */
5794   while (**str && **str != ',')
5795     {
5796       struct cps_flag *p;
5797       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5798       for (p = flag_table; p < q; ++p)
5799         if (strncasecmp (*str, &p->character, 1) == 0)
5800           {
5801             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5802             saw_a_flag = 1;
5803             break;
5804           }
5805       if (p == q)
5806         {
5807           inst.error = _("unrecognized flag");
5808           return;
5809         }
5810       (*str)++;
5811     }
5812   if (!saw_a_flag) 
5813     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5814 }
5815
5816 /* THUMB V5 breakpoint instruction (argument parse)
5817         BKPT <immed_8>.  */
5818
5819 static void
5820 do_t_bkpt (str)
5821      char * str;
5822 {
5823   expressionS expr;
5824   unsigned long number;
5825
5826   skip_whitespace (str);
5827
5828   /* Allow optional leading '#'.  */
5829   if (is_immediate_prefix (*str))
5830     str ++;
5831
5832   memset (& expr, '\0', sizeof (expr));
5833   if (my_get_expression (& expr, & str)
5834       || (expr.X_op != O_constant
5835           /* As a convenience we allow 'bkpt' without an operand.  */
5836           && expr.X_op != O_absent))
5837     {
5838       inst.error = _("bad expression");
5839       return;
5840     }
5841
5842   number = expr.X_add_number;
5843
5844   /* Check it fits an 8 bit unsigned.  */
5845   if (number != (number & 0xff))
5846     {
5847       inst.error = _("immediate value out of range");
5848       return;
5849     }
5850
5851   inst.instruction |= number;
5852
5853   end_of_line (str);
5854 }
5855
5856 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5857    Expects inst.instruction is set for BLX(1).
5858    Note: this is cloned from do_branch, and the reloc changed to be a
5859         new one that can cope with setting one extra bit (the H bit).  */
5860
5861 static void
5862 do_branch25 (str)
5863      char *        str;
5864 {
5865   if (my_get_expression (& inst.reloc.exp, & str))
5866     return;
5867
5868 #ifdef OBJ_ELF
5869   {
5870     char * save_in;
5871
5872     /* ScottB: February 5, 1998 */
5873     /* Check to see of PLT32 reloc required for the instruction.  */
5874
5875     /* arm_parse_reloc() works on input_line_pointer.
5876        We actually want to parse the operands to the branch instruction
5877        passed in 'str'.  Save the input pointer and restore it later.  */
5878     save_in = input_line_pointer;
5879     input_line_pointer = str;
5880
5881     if (inst.reloc.exp.X_op == O_symbol
5882         && *str == '('
5883         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5884       {
5885         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5886         inst.reloc.pc_rel = 0;
5887         /* Modify str to point to after parsed operands, otherwise
5888            end_of_line() will complain about the (PLT) left in str.  */
5889         str = input_line_pointer;
5890       }
5891     else
5892       {
5893         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5894         inst.reloc.pc_rel = 1;
5895       }
5896
5897     input_line_pointer = save_in;
5898   }
5899 #else
5900   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5901   inst.reloc.pc_rel = 1;
5902 #endif /* OBJ_ELF */
5903
5904   end_of_line (str);
5905 }
5906
5907 /* ARM V5 branch-link-exchange instruction (argument parse)
5908      BLX <target_addr>          ie BLX(1)
5909      BLX{<condition>} <Rm>      ie BLX(2)
5910    Unfortunately, there are two different opcodes for this mnemonic.
5911    So, the insns[].value is not used, and the code here zaps values
5912         into inst.instruction.
5913    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5914
5915 static void
5916 do_blx (str)
5917      char *        str;
5918 {
5919   char * mystr = str;
5920   int rm;
5921
5922   skip_whitespace (mystr);
5923   rm = reg_required_here (& mystr, 0);
5924
5925   /* The above may set inst.error.  Ignore his opinion.  */
5926   inst.error = 0;
5927
5928   if (rm != FAIL)
5929     {
5930       /* Arg is a register.
5931          Use the condition code our caller put in inst.instruction.
5932          Pass ourselves off as a BX with a funny opcode.  */
5933       inst.instruction |= 0x012fff30;
5934       do_bx (str);
5935     }
5936   else
5937     {
5938       /* This must be is BLX <target address>, no condition allowed.  */
5939       if (inst.instruction != COND_ALWAYS)
5940         {
5941           inst.error = BAD_COND;
5942           return;
5943         }
5944
5945       inst.instruction = 0xfafffffe;
5946
5947       /* Process like a B/BL, but with a different reloc.
5948          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5949       do_branch25 (str);
5950     }
5951 }
5952
5953 /* ARM V5 Thumb BLX (argument parse)
5954         BLX <target_addr>       which is BLX(1)
5955         BLX <Rm>                which is BLX(2)
5956    Unfortunately, there are two different opcodes for this mnemonic.
5957    So, the tinsns[].value is not used, and the code here zaps values
5958         into inst.instruction.  */
5959
5960 static void
5961 do_t_blx (str)
5962      char * str;
5963 {
5964   char * mystr = str;
5965   int rm;
5966
5967   skip_whitespace (mystr);
5968   inst.instruction = 0x4780;
5969
5970   /* Note that this call is to the ARM register recognizer.  BLX(2)
5971      uses the ARM register space, not the Thumb one, so a call to
5972      thumb_reg() would be wrong.  */
5973   rm = reg_required_here (& mystr, 3);
5974   inst.error = 0;
5975
5976   if (rm != FAIL)
5977     {
5978       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5979       inst.size = 2;
5980     }
5981   else
5982     {
5983       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5984       inst.instruction = 0xf7ffeffe;
5985       inst.size = 4;
5986
5987       if (my_get_expression (& inst.reloc.exp, & mystr))
5988         return;
5989
5990       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5991       inst.reloc.pc_rel = 1;
5992     }
5993
5994   end_of_line (mystr);
5995 }
5996
5997 /* ARM V5 breakpoint instruction (argument parse)
5998      BKPT <16 bit unsigned immediate>
5999      Instruction is not conditional.
6000         The bit pattern given in insns[] has the COND_ALWAYS condition,
6001         and it is an error if the caller tried to override that.  */
6002
6003 static void
6004 do_bkpt (str)
6005      char *        str;
6006 {
6007   expressionS expr;
6008   unsigned long number;
6009
6010   skip_whitespace (str);
6011
6012   /* Allow optional leading '#'.  */
6013   if (is_immediate_prefix (* str))
6014     str++;
6015
6016   memset (& expr, '\0', sizeof (expr));
6017
6018   if (my_get_expression (& expr, & str)
6019       || (expr.X_op != O_constant
6020           /* As a convenience we allow 'bkpt' without an operand.  */
6021           && expr.X_op != O_absent))
6022     {
6023       inst.error = _("bad expression");
6024       return;
6025     }
6026
6027   number = expr.X_add_number;
6028
6029   /* Check it fits a 16 bit unsigned.  */
6030   if (number != (number & 0xffff))
6031     {
6032       inst.error = _("immediate value out of range");
6033       return;
6034     }
6035
6036   /* Top 12 of 16 bits to bits 19:8.  */
6037   inst.instruction |= (number & 0xfff0) << 4;
6038
6039   /* Bottom 4 of 16 bits to bits 3:0.  */
6040   inst.instruction |= number & 0xf;
6041
6042   end_of_line (str);
6043 }
6044
6045 /* THUMB CPS instruction (argument parse).  */
6046
6047 static void
6048 do_t_cps (str)
6049      char *str;
6050 {
6051   do_cps_flags (&str, /*thumb_p=*/1);
6052   end_of_line (str);
6053 }
6054
6055 /* THUMB CPY instruction (argument parse).  */
6056
6057 static void
6058 do_t_cpy (str)
6059      char *str;
6060 {
6061   thumb_mov_compare (str, THUMB_CPY);
6062 }
6063
6064 /* THUMB SETEND instruction (argument parse).  */
6065
6066 static void
6067 do_t_setend (str)
6068      char *str;
6069 {
6070   if (do_endian_specifier (str))
6071     inst.instruction |= 0x8;
6072 }
6073
6074 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6075
6076 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6077
6078 static unsigned long
6079 check_iwmmxt_insn (str, insn_type, immediate_size)
6080      char * str;
6081      enum iwmmxt_insn_type insn_type;
6082      int immediate_size;
6083 {
6084   int reg = 0;
6085   const char *  inst_error;
6086   expressionS expr;
6087   unsigned long number;
6088
6089   inst_error = inst.error;
6090   if (!inst.error)
6091     inst.error = BAD_ARGS;
6092   skip_whitespace (str);
6093
6094   switch (insn_type)
6095     {
6096     case check_rd:
6097       if ((reg = reg_required_here (&str, 12)) == FAIL)
6098         return FAIL;
6099       break;
6100       
6101     case check_wr:
6102        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6103          return FAIL;
6104        break;
6105        
6106     case check_wrwr:
6107       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6108            || skip_past_comma (&str) == FAIL
6109            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6110         return FAIL;
6111       break;
6112       
6113     case check_wrwrwr:
6114       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6115            || skip_past_comma (&str) == FAIL
6116            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6117            || skip_past_comma (&str) == FAIL
6118            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6119         return FAIL;
6120       break;
6121       
6122     case check_wrwrwcg:
6123       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6124            || skip_past_comma (&str) == FAIL
6125            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6126            || skip_past_comma (&str) == FAIL
6127            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6128         return FAIL;
6129       break;
6130       
6131     case check_tbcst:
6132       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6133            || skip_past_comma (&str) == FAIL
6134            || reg_required_here (&str, 12) == FAIL))
6135         return FAIL;
6136       break;
6137       
6138     case check_tmovmsk:
6139       if ((reg_required_here (&str, 12) == FAIL
6140            || skip_past_comma (&str) == FAIL
6141            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6142         return FAIL;
6143       break;
6144       
6145     case check_tmia:
6146       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6147            || skip_past_comma (&str) == FAIL
6148            || reg_required_here (&str, 0) == FAIL
6149            || skip_past_comma (&str) == FAIL
6150            || reg_required_here (&str, 12) == FAIL))
6151         return FAIL;
6152       break;
6153       
6154     case check_tmcrr:
6155       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6156            || skip_past_comma (&str) == FAIL
6157            || reg_required_here (&str, 12) == FAIL
6158            || skip_past_comma (&str) == FAIL
6159            || reg_required_here (&str, 16) == FAIL))
6160         return FAIL;
6161       break;
6162       
6163     case check_tmrrc:
6164       if ((reg_required_here (&str, 12) == FAIL
6165            || skip_past_comma (&str) == FAIL
6166            || reg_required_here (&str, 16) == FAIL
6167            || skip_past_comma (&str) == FAIL
6168            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6169         return FAIL;
6170       break;
6171       
6172     case check_tmcr:
6173       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6174            || skip_past_comma (&str) == FAIL
6175            || reg_required_here (&str, 12) == FAIL))
6176         return FAIL;
6177       break;
6178       
6179     case check_tmrc:
6180       if ((reg_required_here (&str, 12) == FAIL
6181            || skip_past_comma (&str) == FAIL
6182            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6183         return FAIL;
6184       break;
6185       
6186     case check_tinsr:
6187       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6188            || skip_past_comma (&str) == FAIL
6189            || reg_required_here (&str, 12) == FAIL
6190            || skip_past_comma (&str) == FAIL))
6191         return FAIL;
6192       break;
6193       
6194     case check_textrc:
6195       if ((reg_required_here (&str, 12) == FAIL
6196            || skip_past_comma (&str) == FAIL))
6197         return FAIL;
6198       break;
6199       
6200     case check_waligni:
6201       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6202            || skip_past_comma (&str) == FAIL
6203            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6204            || skip_past_comma (&str) == FAIL
6205            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6206            || skip_past_comma (&str) == FAIL))
6207         return FAIL;
6208       break;
6209       
6210     case check_textrm:
6211       if ((reg_required_here (&str, 12) == FAIL
6212            || skip_past_comma (&str) == FAIL
6213            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6214            || skip_past_comma (&str) == FAIL))
6215         return FAIL;
6216       break;
6217       
6218     case check_wshufh:
6219       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6220            || skip_past_comma (&str) == FAIL
6221            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6222            || skip_past_comma (&str) == FAIL))
6223         return FAIL;
6224       break;
6225     }
6226   
6227   if (immediate_size == 0)
6228     {
6229       end_of_line (str);
6230       inst.error = inst_error;
6231       return reg;
6232     }
6233   else
6234     {
6235       skip_whitespace (str);      
6236   
6237       /* Allow optional leading '#'. */
6238       if (is_immediate_prefix (* str))
6239         str++;
6240
6241       memset (& expr, '\0', sizeof (expr));
6242   
6243       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6244         {
6245           inst.error = _("bad or missing expression");
6246           return FAIL;
6247         }
6248   
6249       number = expr.X_add_number;
6250   
6251       if (number != (number & immediate_size))
6252         {
6253           inst.error = _("immediate value out of range");
6254           return FAIL;
6255         }
6256       end_of_line (str);
6257       inst.error = inst_error;
6258       return number;
6259     }
6260 }
6261
6262 static void
6263 do_iwmmxt_byte_addr (str)
6264      char * str;
6265 {
6266   int op = (inst.instruction & 0x300) >> 8;
6267   int reg;
6268
6269   inst.instruction &= ~0x300;
6270   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6271
6272   skip_whitespace (str);
6273
6274   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6275       || skip_past_comma (& str) == FAIL
6276       || cp_byte_address_required_here (&str) == FAIL)
6277     {
6278       if (! inst.error)
6279         inst.error = BAD_ARGS;
6280     }
6281   else
6282     end_of_line (str);
6283
6284   if (wc_register (reg))
6285     {
6286       as_bad (_("non-word size not supported with control register"));
6287       inst.instruction |=  0xf0000100;
6288       inst.instruction &= ~0x00400000;
6289     }
6290 }
6291
6292 static void
6293 do_iwmmxt_tandc (str)
6294      char * str;
6295 {
6296   int reg;
6297
6298   reg = check_iwmmxt_insn (str, check_rd, 0);
6299
6300   if (reg != REG_PC && !inst.error)
6301     inst.error = _("only r15 allowed here");
6302 }
6303
6304 static void
6305 do_iwmmxt_tbcst (str)
6306      char * str;
6307 {
6308   check_iwmmxt_insn (str, check_tbcst, 0);
6309 }
6310
6311 static void
6312 do_iwmmxt_textrc (str)
6313      char * str;
6314 {
6315   unsigned long number;
6316
6317   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6318     return;
6319
6320   inst.instruction |= number & 0x7;
6321 }
6322
6323 static void
6324 do_iwmmxt_textrm (str)
6325      char * str;
6326 {
6327   unsigned long number;
6328
6329   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6330     return;
6331
6332   inst.instruction |= number & 0x7;
6333 }
6334
6335 static void
6336 do_iwmmxt_tinsr (str)
6337      char * str;
6338 {
6339   unsigned long number;
6340
6341   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6342     return;
6343
6344   inst.instruction |= number & 0x7;
6345 }
6346
6347 static void
6348 do_iwmmxt_tmcr (str)
6349      char * str;
6350 {
6351   check_iwmmxt_insn (str, check_tmcr, 0);
6352 }
6353
6354 static void
6355 do_iwmmxt_tmcrr (str)
6356      char * str;
6357 {
6358   check_iwmmxt_insn (str, check_tmcrr, 0);
6359 }
6360
6361 static void
6362 do_iwmmxt_tmia (str)
6363      char * str;
6364 {
6365   check_iwmmxt_insn (str, check_tmia, 0);
6366 }
6367
6368 static void
6369 do_iwmmxt_tmovmsk (str)
6370      char * str;
6371 {
6372   check_iwmmxt_insn (str, check_tmovmsk, 0);
6373 }
6374
6375 static void
6376 do_iwmmxt_tmrc (str)
6377      char * str;
6378 {
6379   check_iwmmxt_insn (str, check_tmrc, 0);
6380 }
6381
6382 static void
6383 do_iwmmxt_tmrrc (str)
6384      char * str;
6385 {
6386   check_iwmmxt_insn (str, check_tmrrc, 0);
6387 }
6388
6389 static void
6390 do_iwmmxt_torc (str)
6391      char * str;
6392 {
6393   check_iwmmxt_insn (str, check_rd, 0);
6394 }
6395
6396 static void
6397 do_iwmmxt_waligni (str)
6398      char * str;
6399 {
6400   unsigned long number;
6401
6402   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6403     return;
6404
6405   inst.instruction |= ((number & 0x7) << 20);
6406 }
6407
6408 static void
6409 do_iwmmxt_wmov (str)
6410      char * str;
6411 {
6412   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6413     return;
6414   
6415   inst.instruction |= ((inst.instruction >> 16) & 0xf);
6416 }
6417
6418 static void
6419 do_iwmmxt_word_addr (str)
6420      char * str;
6421 {
6422   int op = (inst.instruction & 0x300) >> 8;
6423   int reg;
6424
6425   inst.instruction &= ~0x300;
6426   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6427
6428   skip_whitespace (str);
6429
6430   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6431       || skip_past_comma (& str) == FAIL
6432       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6433     {
6434       if (! inst.error)
6435         inst.error = BAD_ARGS;
6436     }
6437   else
6438     end_of_line (str);
6439
6440   if (wc_register (reg))
6441     {
6442       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6443         as_bad (_("conditional execution not supported with control register"));
6444       if (op != 2)
6445         as_bad (_("non-word size not supported with control register"));
6446       inst.instruction |=  0xf0000100;
6447       inst.instruction &= ~0x00400000;
6448     }
6449 }
6450
6451 static void
6452 do_iwmmxt_wrwr (str)
6453      char * str;
6454 {
6455   check_iwmmxt_insn (str, check_wrwr, 0);
6456 }
6457
6458 static void
6459 do_iwmmxt_wrwrwcg (str)
6460      char * str;
6461 {
6462   check_iwmmxt_insn (str, check_wrwrwcg, 0);
6463 }
6464
6465 static void
6466 do_iwmmxt_wrwrwr (str)
6467      char * str;
6468 {
6469   check_iwmmxt_insn (str, check_wrwrwr, 0);
6470 }
6471
6472 static void
6473 do_iwmmxt_wshufh (str)
6474      char * str;
6475 {
6476   unsigned long number;
6477
6478   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6479     return;
6480
6481   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6482 }
6483
6484 static void
6485 do_iwmmxt_wzero (str)
6486      char * str;
6487 {
6488   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6489     return;
6490
6491   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6492 }
6493
6494 /* Xscale multiply-accumulate (argument parse)
6495      MIAcc   acc0,Rm,Rs
6496      MIAPHcc acc0,Rm,Rs
6497      MIAxycc acc0,Rm,Rs.  */
6498
6499 static void
6500 do_xsc_mia (str)
6501      char * str;
6502 {
6503   int rs;
6504   int rm;
6505
6506   if (accum0_required_here (& str) == FAIL)
6507     inst.error = ERR_NO_ACCUM;
6508
6509   else if (skip_past_comma (& str) == FAIL
6510            || (rm = reg_required_here (& str, 0)) == FAIL)
6511     inst.error = BAD_ARGS;
6512
6513   else if (skip_past_comma (& str) == FAIL
6514            || (rs = reg_required_here (& str, 12)) == FAIL)
6515     inst.error = BAD_ARGS;
6516
6517   /* inst.instruction has now been zapped with both rm and rs.  */
6518   else if (rm == REG_PC || rs == REG_PC)
6519     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
6520
6521   else
6522     end_of_line (str);
6523 }
6524
6525 /* Xscale move-accumulator-register (argument parse)
6526
6527      MARcc   acc0,RdLo,RdHi.  */
6528
6529 static void
6530 do_xsc_mar (str)
6531      char * str;
6532 {
6533   int rdlo, rdhi;
6534
6535   if (accum0_required_here (& str) == FAIL)
6536     inst.error = ERR_NO_ACCUM;
6537
6538   else if (skip_past_comma (& str) == FAIL
6539            || (rdlo = reg_required_here (& str, 12)) == FAIL)
6540     inst.error = BAD_ARGS;
6541
6542   else if (skip_past_comma (& str) == FAIL
6543            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6544     inst.error = BAD_ARGS;
6545
6546   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6547   else if (rdlo == REG_PC || rdhi == REG_PC)
6548     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6549
6550   else
6551     end_of_line (str);
6552 }
6553
6554 /* Xscale move-register-accumulator (argument parse)
6555
6556      MRAcc   RdLo,RdHi,acc0.  */
6557
6558 static void
6559 do_xsc_mra (str)
6560      char * str;
6561 {
6562   int rdlo;
6563   int rdhi;
6564
6565   skip_whitespace (str);
6566
6567   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6568     inst.error = BAD_ARGS;
6569
6570   else if (skip_past_comma (& str) == FAIL
6571            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6572     inst.error = BAD_ARGS;
6573
6574   else if  (skip_past_comma (& str) == FAIL
6575             || accum0_required_here (& str) == FAIL)
6576     inst.error = ERR_NO_ACCUM;
6577
6578   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6579   else if (rdlo == rdhi)
6580     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
6581
6582   else if (rdlo == REG_PC || rdhi == REG_PC)
6583     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6584   else
6585     end_of_line (str);
6586 }
6587
6588 /* ARMv5TE: Preload-Cache
6589
6590     PLD <addr_mode>
6591
6592   Syntactically, like LDR with B=1, W=0, L=1.  */
6593
6594 static void
6595 do_pld (str)
6596      char * str;
6597 {
6598   int rd;
6599
6600   skip_whitespace (str);
6601
6602   if (* str != '[')
6603     {
6604       inst.error = _("'[' expected after PLD mnemonic");
6605       return;
6606     }
6607
6608   ++str;
6609   skip_whitespace (str);
6610
6611   if ((rd = reg_required_here (& str, 16)) == FAIL)
6612     return;
6613
6614   skip_whitespace (str);
6615
6616   if (*str == ']')
6617     {
6618       /* [Rn], ... ?  */
6619       ++str;
6620       skip_whitespace (str);
6621
6622       /* Post-indexed addressing is not allowed with PLD.  */
6623       if (skip_past_comma (&str) == SUCCESS)
6624         {
6625           inst.error
6626             = _("post-indexed expression used in preload instruction");
6627           return;
6628         }
6629       else if (*str == '!') /* [Rn]! */
6630         {
6631           inst.error = _("writeback used in preload instruction");
6632           ++str;
6633         }
6634       else /* [Rn] */
6635         inst.instruction |= INDEX_UP | PRE_INDEX;
6636     }
6637   else /* [Rn, ...] */
6638     {
6639       if (skip_past_comma (& str) == FAIL)
6640         {
6641           inst.error = _("pre-indexed expression expected");
6642           return;
6643         }
6644
6645       if (ldst_extend (&str) == FAIL)
6646         return;
6647
6648       skip_whitespace (str);
6649
6650       if (* str != ']')
6651         {
6652           inst.error = _("missing ]");
6653           return;
6654         }
6655
6656       ++ str;
6657       skip_whitespace (str);
6658
6659       if (* str == '!') /* [Rn]! */
6660         {
6661           inst.error = _("writeback used in preload instruction");
6662           ++ str;
6663         }
6664
6665       inst.instruction |= PRE_INDEX;
6666     }
6667
6668   end_of_line (str);
6669 }
6670
6671 /* ARMv5TE load-consecutive (argument parse)
6672    Mode is like LDRH.
6673
6674      LDRccD R, mode
6675      STRccD R, mode.  */
6676
6677 static void
6678 do_ldrd (str)
6679      char * str;
6680 {
6681   int rd;
6682   int rn;
6683
6684   skip_whitespace (str);
6685
6686   if ((rd = reg_required_here (& str, 12)) == FAIL)
6687     {
6688       inst.error = BAD_ARGS;
6689       return;
6690     }
6691
6692   if (skip_past_comma (& str) == FAIL
6693       || (rn = ld_mode_required_here (& str)) == FAIL)
6694     {
6695       if (!inst.error)
6696         inst.error = BAD_ARGS;
6697       return;
6698     }
6699
6700   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6701   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
6702     {
6703       inst.error = _("destination register must be even");
6704       return;
6705     }
6706
6707   if (rd == REG_LR)
6708     {
6709       inst.error = _("r14 not allowed here");
6710       return;
6711     }
6712
6713   if (((rd == rn) || (rd + 1 == rn))
6714       && ((inst.instruction & WRITE_BACK)
6715           || (!(inst.instruction & PRE_INDEX))))
6716     as_warn (_("pre/post-indexing used when modified address register is destination"));
6717
6718   /* For an index-register load, the index register must not overlap the
6719      destination (even if not write-back).  */
6720   if ((inst.instruction & V4_STR_BIT) == 0
6721       && (inst.instruction & HWOFFSET_IMM) == 0)
6722     {
6723       int rm = inst.instruction & 0x0000000f;
6724
6725       if (rm == rd || (rm == rd + 1))
6726         as_warn (_("ldrd destination registers must not overlap index register"));
6727     }
6728
6729   end_of_line (str);
6730 }
6731
6732 /* Returns the index into fp_values of a floating point number,
6733    or -1 if not in the table.  */
6734
6735 static int
6736 my_get_float_expression (str)
6737      char ** str;
6738 {
6739   LITTLENUM_TYPE words[MAX_LITTLENUMS];
6740   char *         save_in;
6741   expressionS    exp;
6742   int            i;
6743   int            j;
6744
6745   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6746
6747   /* Look for a raw floating point number.  */
6748   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6749       && is_end_of_line[(unsigned char) *save_in])
6750     {
6751       for (i = 0; i < NUM_FLOAT_VALS; i++)
6752         {
6753           for (j = 0; j < MAX_LITTLENUMS; j++)
6754             {
6755               if (words[j] != fp_values[i][j])
6756                 break;
6757             }
6758
6759           if (j == MAX_LITTLENUMS)
6760             {
6761               *str = save_in;
6762               return i;
6763             }
6764         }
6765     }
6766
6767   /* Try and parse a more complex expression, this will probably fail
6768      unless the code uses a floating point prefix (eg "0f").  */
6769   save_in = input_line_pointer;
6770   input_line_pointer = *str;
6771   if (expression (&exp) == absolute_section
6772       && exp.X_op == O_big
6773       && exp.X_add_number < 0)
6774     {
6775       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6776          Ditto for 15.  */
6777       if (gen_to_words (words, 5, (long) 15) == 0)
6778         {
6779           for (i = 0; i < NUM_FLOAT_VALS; i++)
6780             {
6781               for (j = 0; j < MAX_LITTLENUMS; j++)
6782                 {
6783                   if (words[j] != fp_values[i][j])
6784                     break;
6785                 }
6786
6787               if (j == MAX_LITTLENUMS)
6788                 {
6789                   *str = input_line_pointer;
6790                   input_line_pointer = save_in;
6791                   return i;
6792                 }
6793             }
6794         }
6795     }
6796
6797   *str = input_line_pointer;
6798   input_line_pointer = save_in;
6799   return -1;
6800 }
6801
6802 /* Return TRUE if anything in the expression is a bignum.  */
6803
6804 static int
6805 walk_no_bignums (sp)
6806      symbolS * sp;
6807 {
6808   if (symbol_get_value_expression (sp)->X_op == O_big)
6809     return 1;
6810
6811   if (symbol_get_value_expression (sp)->X_add_symbol)
6812     {
6813       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6814               || (symbol_get_value_expression (sp)->X_op_symbol
6815                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6816     }
6817
6818   return 0;
6819 }
6820
6821 static int in_my_get_expression = 0;
6822
6823 static int
6824 my_get_expression (ep, str)
6825      expressionS * ep;
6826      char ** str;
6827 {
6828   char * save_in;
6829   segT   seg;
6830
6831   save_in = input_line_pointer;
6832   input_line_pointer = *str;
6833   in_my_get_expression = 1;
6834   seg = expression (ep);
6835   in_my_get_expression = 0;
6836
6837   if (ep->X_op == O_illegal)
6838     {
6839       /* We found a bad expression in md_operand().  */
6840       *str = input_line_pointer;
6841       input_line_pointer = save_in;
6842       return 1;
6843     }
6844
6845 #ifdef OBJ_AOUT
6846   if (seg != absolute_section
6847       && seg != text_section
6848       && seg != data_section
6849       && seg != bss_section
6850       && seg != undefined_section)
6851     {
6852       inst.error = _("bad_segment");
6853       *str = input_line_pointer;
6854       input_line_pointer = save_in;
6855       return 1;
6856     }
6857 #endif
6858
6859   /* Get rid of any bignums now, so that we don't generate an error for which
6860      we can't establish a line number later on.  Big numbers are never valid
6861      in instructions, which is where this routine is always called.  */
6862   if (ep->X_op == O_big
6863       || (ep->X_add_symbol
6864           && (walk_no_bignums (ep->X_add_symbol)
6865               || (ep->X_op_symbol
6866                   && walk_no_bignums (ep->X_op_symbol)))))
6867     {
6868       inst.error = _("invalid constant");
6869       *str = input_line_pointer;
6870       input_line_pointer = save_in;
6871       return 1;
6872     }
6873
6874   *str = input_line_pointer;
6875   input_line_pointer = save_in;
6876   return 0;
6877 }
6878
6879 /* We handle all bad expressions here, so that we can report the faulty
6880    instruction in the error message.  */
6881 void
6882 md_operand (expr)
6883      expressionS *expr;
6884 {
6885   if (in_my_get_expression)
6886     {
6887       expr->X_op = O_illegal;
6888       if (inst.error == NULL)
6889         inst.error = _("bad expression");
6890     }
6891 }
6892
6893 /* KIND indicates what kind of shifts are accepted.  */
6894
6895 static int
6896 decode_shift (str, kind)
6897      char ** str;
6898      int     kind;
6899 {
6900   const struct asm_shift_name * shift;
6901   char * p;
6902   char   c;
6903
6904   skip_whitespace (* str);
6905
6906   for (p = * str; ISALPHA (* p); p ++)
6907     ;
6908
6909   if (p == * str)
6910     {
6911       inst.error = _("shift expression expected");
6912       return FAIL;
6913     }
6914
6915   c = * p;
6916   * p = '\0';
6917   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6918   * p = c;
6919
6920   if (shift == NULL)
6921     {
6922       inst.error = _("shift expression expected");
6923       return FAIL;
6924     }
6925
6926   assert (shift->properties->index == shift_properties[shift->properties->index].index);
6927
6928   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6929       && shift->properties->index != SHIFT_LSL
6930       && shift->properties->index != SHIFT_ASR)
6931     {
6932       inst.error = _("'LSL' or 'ASR' required");
6933       return FAIL;
6934     }
6935   else if (kind == SHIFT_LSL_IMMEDIATE
6936            && shift->properties->index != SHIFT_LSL)
6937     {
6938       inst.error = _("'LSL' required");
6939       return FAIL;
6940     }
6941   else if (kind == SHIFT_ASR_IMMEDIATE
6942            && shift->properties->index != SHIFT_ASR)
6943     {
6944       inst.error = _("'ASR' required");
6945       return FAIL;
6946     }
6947     
6948   if (shift->properties->index == SHIFT_RRX)
6949     {
6950       * str = p;
6951       inst.instruction |= shift->properties->bit_field;
6952       return SUCCESS;
6953     }
6954
6955   skip_whitespace (p);
6956
6957   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6958     {
6959       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6960       * str = p;
6961       return SUCCESS;
6962     }
6963   else if (! is_immediate_prefix (* p))
6964     {
6965       inst.error = (NO_SHIFT_RESTRICT
6966                     ? _("shift requires register or #expression")
6967                     : _("shift requires #expression"));
6968       * str = p;
6969       return FAIL;
6970     }
6971
6972   inst.error = NULL;
6973   p ++;
6974
6975   if (my_get_expression (& inst.reloc.exp, & p))
6976     return FAIL;
6977
6978   /* Validate some simple #expressions.  */
6979   if (inst.reloc.exp.X_op == O_constant)
6980     {
6981       unsigned num = inst.reloc.exp.X_add_number;
6982
6983       /* Reject operations greater than 32.  */
6984       if (num > 32
6985           /* Reject a shift of 0 unless the mode allows it.  */
6986           || (num == 0 && shift->properties->allows_0 == 0)
6987           /* Reject a shift of 32 unless the mode allows it.  */
6988           || (num == 32 && shift->properties->allows_32 == 0)
6989           )
6990         {
6991           /* As a special case we allow a shift of zero for
6992              modes that do not support it to be recoded as an
6993              logical shift left of zero (ie nothing).  We warn
6994              about this though.  */
6995           if (num == 0)
6996             {
6997               as_warn (_("shift of 0 ignored."));
6998               shift = & shift_names[0];
6999               assert (shift->properties->index == SHIFT_LSL);
7000             }
7001           else
7002             {
7003               inst.error = _("invalid immediate shift");
7004               return FAIL;
7005             }
7006         }
7007
7008       /* Shifts of 32 are encoded as 0, for those shifts that
7009          support it.  */
7010       if (num == 32)
7011         num = 0;
7012
7013       inst.instruction |= (num << 7) | shift->properties->bit_field;
7014     }
7015   else
7016     {
7017       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
7018       inst.reloc.pc_rel = 0;
7019       inst.instruction |= shift->properties->bit_field;
7020     }
7021
7022   * str = p;
7023   return SUCCESS;
7024 }
7025
7026 /* Do those data_ops which can take a negative immediate constant
7027    by altering the instruction.  A bit of a hack really.
7028         MOV <-> MVN
7029         AND <-> BIC
7030         ADC <-> SBC
7031         by inverting the second operand, and
7032         ADD <-> SUB
7033         CMP <-> CMN
7034         by negating the second operand.  */
7035
7036 static int
7037 negate_data_op (instruction, value)
7038      unsigned long * instruction;
7039      unsigned long   value;
7040 {
7041   int op, new_inst;
7042   unsigned long negated, inverted;
7043
7044   negated = validate_immediate (-value);
7045   inverted = validate_immediate (~value);
7046
7047   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7048   switch (op)
7049     {
7050       /* First negates.  */
7051     case OPCODE_SUB:             /* ADD <-> SUB  */
7052       new_inst = OPCODE_ADD;
7053       value = negated;
7054       break;
7055
7056     case OPCODE_ADD:
7057       new_inst = OPCODE_SUB;
7058       value = negated;
7059       break;
7060
7061     case OPCODE_CMP:             /* CMP <-> CMN  */
7062       new_inst = OPCODE_CMN;
7063       value = negated;
7064       break;
7065
7066     case OPCODE_CMN:
7067       new_inst = OPCODE_CMP;
7068       value = negated;
7069       break;
7070
7071       /* Now Inverted ops.  */
7072     case OPCODE_MOV:             /* MOV <-> MVN  */
7073       new_inst = OPCODE_MVN;
7074       value = inverted;
7075       break;
7076
7077     case OPCODE_MVN:
7078       new_inst = OPCODE_MOV;
7079       value = inverted;
7080       break;
7081
7082     case OPCODE_AND:             /* AND <-> BIC  */
7083       new_inst = OPCODE_BIC;
7084       value = inverted;
7085       break;
7086
7087     case OPCODE_BIC:
7088       new_inst = OPCODE_AND;
7089       value = inverted;
7090       break;
7091
7092     case OPCODE_ADC:              /* ADC <-> SBC  */
7093       new_inst = OPCODE_SBC;
7094       value = inverted;
7095       break;
7096
7097     case OPCODE_SBC:
7098       new_inst = OPCODE_ADC;
7099       value = inverted;
7100       break;
7101
7102       /* We cannot do anything.  */
7103     default:
7104       return FAIL;
7105     }
7106
7107   if (value == (unsigned) FAIL)
7108     return FAIL;
7109
7110   *instruction &= OPCODE_MASK;
7111   *instruction |= new_inst << DATA_OP_SHIFT;
7112   return value;
7113 }
7114
7115 static int
7116 data_op2 (str)
7117      char ** str;
7118 {
7119   int value;
7120   expressionS expr;
7121
7122   skip_whitespace (* str);
7123
7124   if (reg_required_here (str, 0) != FAIL)
7125     {
7126       if (skip_past_comma (str) == SUCCESS)
7127         /* Shift operation on register.  */
7128         return decode_shift (str, NO_SHIFT_RESTRICT);
7129
7130       return SUCCESS;
7131     }
7132   else
7133     {
7134       /* Immediate expression.  */
7135       if (is_immediate_prefix (**str))
7136         {
7137           (*str)++;
7138           inst.error = NULL;
7139
7140           if (my_get_expression (&inst.reloc.exp, str))
7141             return FAIL;
7142
7143           if (inst.reloc.exp.X_add_symbol)
7144             {
7145               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7146               inst.reloc.pc_rel = 0;
7147             }
7148           else
7149             {
7150               if (skip_past_comma (str) == SUCCESS)
7151                 {
7152                   /* #x, y -- ie explicit rotation by Y.  */
7153                   if (my_get_expression (&expr, str))
7154                     return FAIL;
7155
7156                   if (expr.X_op != O_constant)
7157                     {
7158                       inst.error = _("constant expression expected");
7159                       return FAIL;
7160                     }
7161
7162                   /* Rotate must be a multiple of 2.  */
7163                   if (((unsigned) expr.X_add_number) > 30
7164                       || (expr.X_add_number & 1) != 0
7165                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7166                     {
7167                       inst.error = _("invalid constant");
7168                       return FAIL;
7169                     }
7170                   inst.instruction |= INST_IMMEDIATE;
7171                   inst.instruction |= inst.reloc.exp.X_add_number;
7172                   inst.instruction |= expr.X_add_number << 7;
7173                   return SUCCESS;
7174                 }
7175
7176               /* Implicit rotation, select a suitable one.  */
7177               value = validate_immediate (inst.reloc.exp.X_add_number);
7178
7179               if (value == FAIL)
7180                 {
7181                   /* Can't be done.  Perhaps the code reads something like
7182                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7183                   if ((value = negate_data_op (&inst.instruction,
7184                                                inst.reloc.exp.X_add_number))
7185                       == FAIL)
7186                     {
7187                       inst.error = _("invalid constant");
7188                       return FAIL;
7189                     }
7190                 }
7191
7192               inst.instruction |= value;
7193             }
7194
7195           inst.instruction |= INST_IMMEDIATE;
7196           return SUCCESS;
7197         }
7198
7199       (*str)++;
7200       inst.error = _("register or shift expression expected");
7201       return FAIL;
7202     }
7203 }
7204
7205 static int
7206 fp_op2 (str)
7207      char ** str;
7208 {
7209   skip_whitespace (* str);
7210
7211   if (fp_reg_required_here (str, 0) != FAIL)
7212     return SUCCESS;
7213   else
7214     {
7215       /* Immediate expression.  */
7216       if (*((*str)++) == '#')
7217         {
7218           int i;
7219
7220           inst.error = NULL;
7221
7222           skip_whitespace (* str);
7223
7224           /* First try and match exact strings, this is to guarantee
7225              that some formats will work even for cross assembly.  */
7226
7227           for (i = 0; fp_const[i]; i++)
7228             {
7229               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7230                 {
7231                   char *start = *str;
7232
7233                   *str += strlen (fp_const[i]);
7234                   if (is_end_of_line[(unsigned char) **str])
7235                     {
7236                       inst.instruction |= i + 8;
7237                       return SUCCESS;
7238                     }
7239                   *str = start;
7240                 }
7241             }
7242
7243           /* Just because we didn't get a match doesn't mean that the
7244              constant isn't valid, just that it is in a format that we
7245              don't automatically recognize.  Try parsing it with
7246              the standard expression routines.  */
7247           if ((i = my_get_float_expression (str)) >= 0)
7248             {
7249               inst.instruction |= i + 8;
7250               return SUCCESS;
7251             }
7252
7253           inst.error = _("invalid floating point immediate expression");
7254           return FAIL;
7255         }
7256       inst.error =
7257         _("floating point register or immediate expression expected");
7258       return FAIL;
7259     }
7260 }
7261
7262 static void
7263 do_arit (str)
7264      char * str;
7265 {
7266   skip_whitespace (str);
7267
7268   if (reg_required_here (&str, 12) == FAIL
7269       || skip_past_comma (&str) == FAIL
7270       || reg_required_here (&str, 16) == FAIL
7271       || skip_past_comma (&str) == FAIL
7272       || data_op2 (&str) == FAIL)
7273     {
7274       if (!inst.error)
7275         inst.error = BAD_ARGS;
7276       return;
7277     }
7278
7279   end_of_line (str);
7280 }
7281
7282 static void
7283 do_adr (str)
7284      char * str;
7285 {
7286   /* This is a pseudo-op of the form "adr rd, label" to be converted
7287      into a relative address of the form "add rd, pc, #label-.-8".  */
7288   skip_whitespace (str);
7289
7290   if (reg_required_here (&str, 12) == FAIL
7291       || skip_past_comma (&str) == FAIL
7292       || my_get_expression (&inst.reloc.exp, &str))
7293     {
7294       if (!inst.error)
7295         inst.error = BAD_ARGS;
7296       return;
7297     }
7298
7299   /* Frag hacking will turn this into a sub instruction if the offset turns
7300      out to be negative.  */
7301   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7302 #ifndef TE_WINCE
7303   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7304 #endif
7305   inst.reloc.pc_rel = 1;
7306
7307   end_of_line (str);
7308 }
7309
7310 static void
7311 do_adrl (str)
7312      char * str;
7313 {
7314   /* This is a pseudo-op of the form "adrl rd, label" to be converted
7315      into a relative address of the form:
7316      add rd, pc, #low(label-.-8)"
7317      add rd, rd, #high(label-.-8)"  */
7318
7319   skip_whitespace (str);
7320
7321   if (reg_required_here (&str, 12) == FAIL
7322       || skip_past_comma (&str) == FAIL
7323       || my_get_expression (&inst.reloc.exp, &str))
7324     {
7325       if (!inst.error)
7326         inst.error = BAD_ARGS;
7327
7328       return;
7329     }
7330
7331   end_of_line (str);
7332   /* Frag hacking will turn this into a sub instruction if the offset turns
7333      out to be negative.  */
7334   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7335 #ifndef TE_WINCE  
7336   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7337 #endif
7338   inst.reloc.pc_rel            = 1;
7339   inst.size                    = INSN_SIZE * 2;
7340 }
7341
7342 static void
7343 do_cmp (str)
7344      char * str;
7345 {
7346   skip_whitespace (str);
7347
7348   if (reg_required_here (&str, 16) == FAIL)
7349     {
7350       if (!inst.error)
7351         inst.error = BAD_ARGS;
7352       return;
7353     }
7354
7355   if (skip_past_comma (&str) == FAIL
7356       || data_op2 (&str) == FAIL)
7357     {
7358       if (!inst.error)
7359         inst.error = BAD_ARGS;
7360       return;
7361     }
7362
7363   end_of_line (str);
7364 }
7365
7366 static void
7367 do_mov (str)
7368      char * str;
7369 {
7370   skip_whitespace (str);
7371
7372   if (reg_required_here (&str, 12) == FAIL)
7373     {
7374       if (!inst.error)
7375         inst.error = BAD_ARGS;
7376       return;
7377     }
7378
7379   if (skip_past_comma (&str) == FAIL
7380       || data_op2 (&str) == FAIL)
7381     {
7382       if (!inst.error)
7383         inst.error = BAD_ARGS;
7384       return;
7385     }
7386
7387   end_of_line (str);
7388 }
7389
7390 static int
7391 ldst_extend (str)
7392      char ** str;
7393 {
7394   int add = INDEX_UP;
7395
7396   switch (**str)
7397     {
7398     case '#':
7399     case '$':
7400       (*str)++;
7401       if (my_get_expression (& inst.reloc.exp, str))
7402         return FAIL;
7403
7404       if (inst.reloc.exp.X_op == O_constant)
7405         {
7406           int value = inst.reloc.exp.X_add_number;
7407
7408           if (value < -4095 || value > 4095)
7409             {
7410               inst.error = _("address offset too large");
7411               return FAIL;
7412             }
7413
7414           if (value < 0)
7415             {
7416               value = -value;
7417               add = 0;
7418             }
7419
7420           inst.instruction |= add | value;
7421         }
7422       else
7423         {
7424           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7425           inst.reloc.pc_rel = 0;
7426         }
7427       return SUCCESS;
7428
7429     case '-':
7430       add = 0;
7431       /* Fall through.  */
7432
7433     case '+':
7434       (*str)++;
7435       /* Fall through.  */
7436
7437     default:
7438       if (reg_required_here (str, 0) == FAIL)
7439         return FAIL;
7440
7441       inst.instruction |= add | OFFSET_REG;
7442       if (skip_past_comma (str) == SUCCESS)
7443         return decode_shift (str, SHIFT_IMMEDIATE);
7444
7445       return SUCCESS;
7446     }
7447 }
7448
7449 static void
7450 do_ldst (str)
7451      char *        str;
7452 {
7453   int pre_inc = 0;
7454   int conflict_reg;
7455   int value;
7456
7457   skip_whitespace (str);
7458
7459   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7460     {
7461       if (!inst.error)
7462         inst.error = BAD_ARGS;
7463       return;
7464     }
7465
7466   if (skip_past_comma (&str) == FAIL)
7467     {
7468       inst.error = _("address expected");
7469       return;
7470     }
7471
7472   if (*str == '[')
7473     {
7474       int reg;
7475
7476       str++;
7477
7478       skip_whitespace (str);
7479
7480       if ((reg = reg_required_here (&str, 16)) == FAIL)
7481         return;
7482
7483       /* Conflicts can occur on stores as well as loads.  */
7484       conflict_reg = (conflict_reg == reg);
7485
7486       skip_whitespace (str);
7487
7488       if (*str == ']')
7489         {
7490           str ++;
7491
7492           if (skip_past_comma (&str) == SUCCESS)
7493             {
7494               /* [Rn],... (post inc)  */
7495               if (ldst_extend (&str) == FAIL)
7496                 return;
7497               if (conflict_reg)
7498                 as_warn (_("%s register same as write-back base"),
7499                          ((inst.instruction & LOAD_BIT)
7500                           ? _("destination") : _("source")));
7501             }
7502           else
7503             {
7504               /* [Rn]  */
7505               skip_whitespace (str);
7506
7507               if (*str == '!')
7508                 {
7509                   if (conflict_reg)
7510                     as_warn (_("%s register same as write-back base"),
7511                              ((inst.instruction & LOAD_BIT)
7512                               ? _("destination") : _("source")));
7513                   str++;
7514                   inst.instruction |= WRITE_BACK;
7515                 }
7516
7517               inst.instruction |= INDEX_UP;
7518               pre_inc = 1;
7519             }
7520         }
7521       else
7522         {
7523           /* [Rn,...]  */
7524           if (skip_past_comma (&str) == FAIL)
7525             {
7526               inst.error = _("pre-indexed expression expected");
7527               return;
7528             }
7529
7530           pre_inc = 1;
7531           if (ldst_extend (&str) == FAIL)
7532             return;
7533
7534           skip_whitespace (str);
7535
7536           if (*str++ != ']')
7537             {
7538               inst.error = _("missing ]");
7539               return;
7540             }
7541
7542           skip_whitespace (str);
7543
7544           if (*str == '!')
7545             {
7546               if (conflict_reg)
7547                 as_warn (_("%s register same as write-back base"),
7548                          ((inst.instruction & LOAD_BIT)
7549                           ? _("destination") : _("source")));
7550               str++;
7551               inst.instruction |= WRITE_BACK;
7552             }
7553         }
7554     }
7555   else if (*str == '=')
7556     {
7557       if ((inst.instruction & LOAD_BIT) == 0)
7558         {
7559           inst.error = _("invalid pseudo operation");
7560           return;
7561         }
7562
7563       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7564       str++;
7565
7566       skip_whitespace (str);
7567
7568       if (my_get_expression (&inst.reloc.exp, &str))
7569         return;
7570
7571       if (inst.reloc.exp.X_op != O_constant
7572           && inst.reloc.exp.X_op != O_symbol)
7573         {
7574           inst.error = _("constant expression expected");
7575           return;
7576         }
7577
7578       if (inst.reloc.exp.X_op == O_constant)
7579         {
7580           value = validate_immediate (inst.reloc.exp.X_add_number);
7581
7582           if (value != FAIL)
7583             {
7584               /* This can be done with a mov instruction.  */
7585               inst.instruction &= LITERAL_MASK;
7586               inst.instruction |= (INST_IMMEDIATE
7587                                    | (OPCODE_MOV << DATA_OP_SHIFT));
7588               inst.instruction |= value & 0xfff;
7589               end_of_line (str);
7590               return;
7591             }
7592
7593           value = validate_immediate (~inst.reloc.exp.X_add_number);
7594
7595           if (value != FAIL)
7596             {
7597               /* This can be done with a mvn instruction.  */
7598               inst.instruction &= LITERAL_MASK;
7599               inst.instruction |= (INST_IMMEDIATE
7600                                    | (OPCODE_MVN << DATA_OP_SHIFT));
7601               inst.instruction |= value & 0xfff;
7602               end_of_line (str);
7603               return;
7604             }
7605         }
7606
7607       /* Insert into literal pool.  */
7608       if (add_to_lit_pool () == FAIL)
7609         {
7610           if (!inst.error)
7611             inst.error = _("literal pool insertion failed");
7612           return;
7613         }
7614
7615       /* Change the instruction exp to point to the pool.  */
7616       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7617       inst.reloc.pc_rel = 1;
7618       inst.instruction |= (REG_PC << 16);
7619       pre_inc = 1;
7620     }
7621   else
7622     {
7623       if (my_get_expression (&inst.reloc.exp, &str))
7624         return;
7625
7626       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7627 #ifndef TE_WINCE
7628       /* PC rel adjust.  */
7629       inst.reloc.exp.X_add_number -= 8;
7630 #endif
7631       inst.reloc.pc_rel = 1;
7632       inst.instruction |= (REG_PC << 16);
7633       pre_inc = 1;
7634     }
7635
7636   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7637   end_of_line (str);
7638 }
7639
7640 static void
7641 do_ldstt (str)
7642      char *        str;
7643 {
7644   int conflict_reg;
7645
7646   skip_whitespace (str);
7647
7648   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7649     {
7650       if (!inst.error)
7651         inst.error = BAD_ARGS;
7652       return;
7653     }
7654
7655   if (skip_past_comma (& str) == FAIL)
7656     {
7657       inst.error = _("address expected");
7658       return;
7659     }
7660
7661   if (*str == '[')
7662     {
7663       int reg;
7664
7665       str++;
7666
7667       skip_whitespace (str);
7668
7669       if ((reg = reg_required_here (&str, 16)) == FAIL)
7670         return;
7671
7672       /* ldrt/strt always use post-indexed addressing, so if the base is
7673          the same as Rd, we warn.  */
7674       if (conflict_reg == reg)
7675         as_warn (_("%s register same as write-back base"),
7676                  ((inst.instruction & LOAD_BIT)
7677                   ? _("destination") : _("source")));
7678
7679       skip_whitespace (str);
7680
7681       if (*str == ']')
7682         {
7683           str ++;
7684
7685           if (skip_past_comma (&str) == SUCCESS)
7686             {
7687               /* [Rn],... (post inc)  */
7688               if (ldst_extend (&str) == FAIL)
7689                 return;
7690             }
7691           else
7692             {
7693               /* [Rn]  */
7694               skip_whitespace (str);
7695
7696               /* Skip a write-back '!'.  */
7697               if (*str == '!')
7698                 str++;
7699
7700               inst.instruction |= INDEX_UP;
7701             }
7702         }
7703       else
7704         {
7705           inst.error = _("post-indexed expression expected");
7706           return;
7707         }
7708     }
7709   else
7710     {
7711       inst.error = _("post-indexed expression expected");
7712       return;
7713     }
7714
7715   end_of_line (str);
7716 }
7717
7718 static int
7719 ldst_extend_v4 (str)
7720      char ** str;
7721 {
7722   int add = INDEX_UP;
7723
7724   switch (**str)
7725     {
7726     case '#':
7727     case '$':
7728       (*str)++;
7729       if (my_get_expression (& inst.reloc.exp, str))
7730         return FAIL;
7731
7732       if (inst.reloc.exp.X_op == O_constant)
7733         {
7734           int value = inst.reloc.exp.X_add_number;
7735
7736           if (value < -255 || value > 255)
7737             {
7738               inst.error = _("address offset too large");
7739               return FAIL;
7740             }
7741
7742           if (value < 0)
7743             {
7744               value = -value;
7745               add = 0;
7746             }
7747
7748           /* Halfword and signextension instructions have the
7749              immediate value split across bits 11..8 and bits 3..0.  */
7750           inst.instruction |= (add | HWOFFSET_IMM
7751                                | ((value >> 4) << 8) | (value & 0xF));
7752         }
7753       else
7754         {
7755           inst.instruction |= HWOFFSET_IMM;
7756           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7757           inst.reloc.pc_rel = 0;
7758         }
7759       return SUCCESS;
7760
7761     case '-':
7762       add = 0;
7763       /* Fall through.  */
7764
7765     case '+':
7766       (*str)++;
7767       /* Fall through.  */
7768
7769     default:
7770       if (reg_required_here (str, 0) == FAIL)
7771         return FAIL;
7772
7773       inst.instruction |= add;
7774       return SUCCESS;
7775     }
7776 }
7777
7778 /* Halfword and signed-byte load/store operations.  */
7779 static void
7780 do_ldstv4 (str)
7781      char *        str;
7782 {
7783   int pre_inc = 0;
7784   int conflict_reg;
7785   int value;
7786
7787   skip_whitespace (str);
7788
7789   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7790     {
7791       if (!inst.error)
7792         inst.error = BAD_ARGS;
7793       return;
7794     }
7795
7796   if (skip_past_comma (& str) == FAIL)
7797     {
7798       inst.error = _("address expected");
7799       return;
7800     }
7801
7802   if (*str == '[')
7803     {
7804       int reg;
7805
7806       str++;
7807
7808       skip_whitespace (str);
7809
7810       if ((reg = reg_required_here (&str, 16)) == FAIL)
7811         return;
7812
7813       /* Conflicts can occur on stores as well as loads.  */
7814       conflict_reg = (conflict_reg == reg);
7815
7816       skip_whitespace (str);
7817
7818       if (*str == ']')
7819         {
7820           str ++;
7821
7822           if (skip_past_comma (&str) == SUCCESS)
7823             {
7824               /* [Rn],... (post inc)  */
7825               if (ldst_extend_v4 (&str) == FAIL)
7826                 return;
7827               if (conflict_reg)
7828                 as_warn (_("%s register same as write-back base"),
7829                          ((inst.instruction & LOAD_BIT)
7830                           ? _("destination") : _("source")));
7831             }
7832           else
7833             {
7834               /* [Rn]  */
7835               inst.instruction |= HWOFFSET_IMM;
7836
7837               skip_whitespace (str);
7838
7839               if (*str == '!')
7840                 {
7841                   if (conflict_reg)
7842                     as_warn (_("%s register same as write-back base"),
7843                              ((inst.instruction & LOAD_BIT)
7844                               ? _("destination") : _("source")));
7845                   str++;
7846                   inst.instruction |= WRITE_BACK;
7847                 }
7848
7849               inst.instruction |= INDEX_UP;
7850               pre_inc = 1;
7851             }
7852         }
7853       else
7854         {
7855           /* [Rn,...]  */
7856           if (skip_past_comma (&str) == FAIL)
7857             {
7858               inst.error = _("pre-indexed expression expected");
7859               return;
7860             }
7861
7862           pre_inc = 1;
7863           if (ldst_extend_v4 (&str) == FAIL)
7864             return;
7865
7866           skip_whitespace (str);
7867
7868           if (*str++ != ']')
7869             {
7870               inst.error = _("missing ]");
7871               return;
7872             }
7873
7874           skip_whitespace (str);
7875
7876           if (*str == '!')
7877             {
7878               if (conflict_reg)
7879                 as_warn (_("%s register same as write-back base"),
7880                          ((inst.instruction & LOAD_BIT)
7881                           ? _("destination") : _("source")));
7882               str++;
7883               inst.instruction |= WRITE_BACK;
7884             }
7885         }
7886     }
7887   else if (*str == '=')
7888     {
7889       if ((inst.instruction & LOAD_BIT) == 0)
7890         {
7891           inst.error = _("invalid pseudo operation");
7892           return;
7893         }
7894
7895       /* XXX Does this work correctly for half-word/byte ops?  */
7896       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7897       str++;
7898
7899       skip_whitespace (str);
7900
7901       if (my_get_expression (&inst.reloc.exp, &str))
7902         return;
7903
7904       if (inst.reloc.exp.X_op != O_constant
7905           && inst.reloc.exp.X_op != O_symbol)
7906         {
7907           inst.error = _("constant expression expected");
7908           return;
7909         }
7910
7911       if (inst.reloc.exp.X_op == O_constant)
7912         {
7913           value = validate_immediate (inst.reloc.exp.X_add_number);
7914
7915           if (value != FAIL)
7916             {
7917               /* This can be done with a mov instruction.  */
7918               inst.instruction &= LITERAL_MASK;
7919               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7920               inst.instruction |= value & 0xfff;
7921               end_of_line (str);
7922               return;
7923             }
7924
7925           value = validate_immediate (~ inst.reloc.exp.X_add_number);
7926
7927           if (value != FAIL)
7928             {
7929               /* This can be done with a mvn instruction.  */
7930               inst.instruction &= LITERAL_MASK;
7931               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7932               inst.instruction |= value & 0xfff;
7933               end_of_line (str);
7934               return;
7935             }
7936         }
7937
7938       /* Insert into literal pool.  */
7939       if (add_to_lit_pool () == FAIL)
7940         {
7941           if (!inst.error)
7942             inst.error = _("literal pool insertion failed");
7943           return;
7944         }
7945
7946       /* Change the instruction exp to point to the pool.  */
7947       inst.instruction |= HWOFFSET_IMM;
7948       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7949       inst.reloc.pc_rel = 1;
7950       inst.instruction |= (REG_PC << 16);
7951       pre_inc = 1;
7952     }
7953   else
7954     {
7955       if (my_get_expression (&inst.reloc.exp, &str))
7956         return;
7957
7958       inst.instruction |= HWOFFSET_IMM;
7959       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7960 #ifndef TE_WINCE
7961       /* PC rel adjust.  */
7962       inst.reloc.exp.X_add_number -= 8;
7963 #endif
7964       inst.reloc.pc_rel = 1;
7965       inst.instruction |= (REG_PC << 16);
7966       pre_inc = 1;
7967     }
7968
7969   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7970   end_of_line (str);
7971 }
7972
7973 static long
7974 reg_list (strp)
7975      char ** strp;
7976 {
7977   char * str = * strp;
7978   long   range = 0;
7979   int    another_range;
7980
7981   /* We come back here if we get ranges concatenated by '+' or '|'.  */
7982   do
7983     {
7984       another_range = 0;
7985
7986       if (*str == '{')
7987         {
7988           int in_range = 0;
7989           int cur_reg = -1;
7990
7991           str++;
7992           do
7993             {
7994               int reg;
7995
7996               skip_whitespace (str);
7997
7998               if ((reg = reg_required_here (& str, -1)) == FAIL)
7999                 return FAIL;
8000
8001               if (in_range)
8002                 {
8003                   int i;
8004
8005                   if (reg <= cur_reg)
8006                     {
8007                       inst.error = _("bad range in register list");
8008                       return FAIL;
8009                     }
8010
8011                   for (i = cur_reg + 1; i < reg; i++)
8012                     {
8013                       if (range & (1 << i))
8014                         as_tsktsk
8015                           (_("Warning: duplicated register (r%d) in register list"),
8016                            i);
8017                       else
8018                         range |= 1 << i;
8019                     }
8020                   in_range = 0;
8021                 }
8022
8023               if (range & (1 << reg))
8024                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8025                            reg);
8026               else if (reg <= cur_reg)
8027                 as_tsktsk (_("Warning: register range not in ascending order"));
8028
8029               range |= 1 << reg;
8030               cur_reg = reg;
8031             }
8032           while (skip_past_comma (&str) != FAIL
8033                  || (in_range = 1, *str++ == '-'));
8034           str--;
8035           skip_whitespace (str);
8036
8037           if (*str++ != '}')
8038             {
8039               inst.error = _("missing `}'");
8040               return FAIL;
8041             }
8042         }
8043       else
8044         {
8045           expressionS expr;
8046
8047           if (my_get_expression (&expr, &str))
8048             return FAIL;
8049
8050           if (expr.X_op == O_constant)
8051             {
8052               if (expr.X_add_number
8053                   != (expr.X_add_number & 0x0000ffff))
8054                 {
8055                   inst.error = _("invalid register mask");
8056                   return FAIL;
8057                 }
8058
8059               if ((range & expr.X_add_number) != 0)
8060                 {
8061                   int regno = range & expr.X_add_number;
8062
8063                   regno &= -regno;
8064                   regno = (1 << regno) - 1;
8065                   as_tsktsk
8066                     (_("Warning: duplicated register (r%d) in register list"),
8067                      regno);
8068                 }
8069
8070               range |= expr.X_add_number;
8071             }
8072           else
8073             {
8074               if (inst.reloc.type != 0)
8075                 {
8076                   inst.error = _("expression too complex");
8077                   return FAIL;
8078                 }
8079
8080               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8081               inst.reloc.type = BFD_RELOC_ARM_MULTI;
8082               inst.reloc.pc_rel = 0;
8083             }
8084         }
8085
8086       skip_whitespace (str);
8087
8088       if (*str == '|' || *str == '+')
8089         {
8090           str++;
8091           another_range = 1;
8092         }
8093     }
8094   while (another_range);
8095
8096   *strp = str;
8097   return range;
8098 }
8099
8100 static void
8101 do_ldmstm (str)
8102      char * str;
8103 {
8104   int base_reg;
8105   long range;
8106
8107   skip_whitespace (str);
8108
8109   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8110     return;
8111
8112   if (base_reg == REG_PC)
8113     {
8114       inst.error = _("r15 not allowed as base register");
8115       return;
8116     }
8117
8118   skip_whitespace (str);
8119
8120   if (*str == '!')
8121     {
8122       inst.instruction |= WRITE_BACK;
8123       str++;
8124     }
8125
8126   if (skip_past_comma (&str) == FAIL
8127       || (range = reg_list (&str)) == FAIL)
8128     {
8129       if (! inst.error)
8130         inst.error = BAD_ARGS;
8131       return;
8132     }
8133
8134   if (*str == '^')
8135     {
8136       str++;
8137       inst.instruction |= LDM_TYPE_2_OR_3;
8138     }
8139
8140   if (inst.instruction & WRITE_BACK)
8141     {
8142       /* Check for unpredictable uses of writeback.  */
8143       if (inst.instruction & LOAD_BIT)
8144         {
8145           /* Not allowed in LDM type 2.  */
8146           if ((inst.instruction & LDM_TYPE_2_OR_3)
8147               && ((range & (1 << REG_PC)) == 0))
8148             as_warn (_("writeback of base register is UNPREDICTABLE"));
8149           /* Only allowed if base reg not in list for other types.  */
8150           else if (range & (1 << base_reg))
8151             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8152         }
8153       else /* STM.  */
8154         {
8155           /* Not allowed for type 2.  */
8156           if (inst.instruction & LDM_TYPE_2_OR_3)
8157             as_warn (_("writeback of base register is UNPREDICTABLE"));
8158           /* Only allowed if base reg not in list, or first in list.  */
8159           else if ((range & (1 << base_reg))
8160                    && (range & ((1 << base_reg) - 1)))
8161             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8162         }
8163     }
8164
8165   inst.instruction |= range;
8166   end_of_line (str);
8167 }
8168
8169 static void
8170 do_swi (str)
8171      char * str;
8172 {
8173   skip_whitespace (str);
8174
8175   /* Allow optional leading '#'.  */
8176   if (is_immediate_prefix (*str))
8177     str++;
8178
8179   if (my_get_expression (& inst.reloc.exp, & str))
8180     return;
8181
8182   inst.reloc.type = BFD_RELOC_ARM_SWI;
8183   inst.reloc.pc_rel = 0;
8184   end_of_line (str);
8185 }
8186
8187 static void
8188 do_swap (str)
8189      char * str;
8190 {
8191   int reg;
8192
8193   skip_whitespace (str);
8194
8195   if ((reg = reg_required_here (&str, 12)) == FAIL)
8196     return;
8197
8198   if (reg == REG_PC)
8199     {
8200       inst.error = _("r15 not allowed in swap");
8201       return;
8202     }
8203
8204   if (skip_past_comma (&str) == FAIL
8205       || (reg = reg_required_here (&str, 0)) == FAIL)
8206     {
8207       if (!inst.error)
8208         inst.error = BAD_ARGS;
8209       return;
8210     }
8211
8212   if (reg == REG_PC)
8213     {
8214       inst.error = _("r15 not allowed in swap");
8215       return;
8216     }
8217
8218   if (skip_past_comma (&str) == FAIL
8219       || *str++ != '[')
8220     {
8221       inst.error = BAD_ARGS;
8222       return;
8223     }
8224
8225   skip_whitespace (str);
8226
8227   if ((reg = reg_required_here (&str, 16)) == FAIL)
8228     return;
8229
8230   if (reg == REG_PC)
8231     {
8232       inst.error = BAD_PC;
8233       return;
8234     }
8235
8236   skip_whitespace (str);
8237
8238   if (*str++ != ']')
8239     {
8240       inst.error = _("missing ]");
8241       return;
8242     }
8243
8244   end_of_line (str);
8245 }
8246
8247 static void
8248 do_branch (str)
8249      char * str;
8250 {
8251   if (my_get_expression (&inst.reloc.exp, &str))
8252     return;
8253
8254 #ifdef OBJ_ELF
8255   {
8256     char * save_in;
8257
8258     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8259        required for the instruction.  */
8260
8261     /* arm_parse_reloc () works on input_line_pointer.
8262        We actually want to parse the operands to the branch instruction
8263        passed in 'str'.  Save the input pointer and restore it later.  */
8264     save_in = input_line_pointer;
8265     input_line_pointer = str;
8266     if (inst.reloc.exp.X_op == O_symbol
8267         && *str == '('
8268         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8269       {
8270         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8271         inst.reloc.pc_rel = 0;
8272         /* Modify str to point to after parsed operands, otherwise
8273            end_of_line() will complain about the (PLT) left in str.  */
8274         str = input_line_pointer;
8275       }
8276     else
8277       {
8278         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8279         inst.reloc.pc_rel = 1;
8280       }
8281     input_line_pointer = save_in;
8282   }
8283 #else
8284   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8285   inst.reloc.pc_rel = 1;
8286 #endif /* OBJ_ELF  */
8287
8288   end_of_line (str);
8289 }
8290
8291 static void
8292 do_bx (str)
8293      char * str;
8294 {
8295   int reg;
8296
8297   skip_whitespace (str);
8298
8299   if ((reg = reg_required_here (&str, 0)) == FAIL)
8300     {
8301       inst.error = BAD_ARGS;
8302       return;
8303     }
8304
8305   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8306   if (reg == REG_PC)
8307     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8308
8309   end_of_line (str);
8310 }
8311
8312 static void
8313 do_cdp (str)
8314      char * str;
8315 {
8316   /* Co-processor data operation.
8317      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8318   skip_whitespace (str);
8319
8320   if (co_proc_number (&str) == FAIL)
8321     {
8322       if (!inst.error)
8323         inst.error = BAD_ARGS;
8324       return;
8325     }
8326
8327   if (skip_past_comma (&str) == FAIL
8328       || cp_opc_expr (&str, 20,4) == FAIL)
8329     {
8330       if (!inst.error)
8331         inst.error = BAD_ARGS;
8332       return;
8333     }
8334
8335   if (skip_past_comma (&str) == FAIL
8336       || cp_reg_required_here (&str, 12) == FAIL)
8337     {
8338       if (!inst.error)
8339         inst.error = BAD_ARGS;
8340       return;
8341     }
8342
8343   if (skip_past_comma (&str) == FAIL
8344       || cp_reg_required_here (&str, 16) == FAIL)
8345     {
8346       if (!inst.error)
8347         inst.error = BAD_ARGS;
8348       return;
8349     }
8350
8351   if (skip_past_comma (&str) == FAIL
8352       || cp_reg_required_here (&str, 0) == FAIL)
8353     {
8354       if (!inst.error)
8355         inst.error = BAD_ARGS;
8356       return;
8357     }
8358
8359   if (skip_past_comma (&str) == SUCCESS)
8360     {
8361       if (cp_opc_expr (&str, 5, 3) == FAIL)
8362         {
8363           if (!inst.error)
8364             inst.error = BAD_ARGS;
8365           return;
8366         }
8367     }
8368
8369   end_of_line (str);
8370 }
8371
8372 static void
8373 do_lstc (str)
8374      char * str;
8375 {
8376   /* Co-processor register load/store.
8377      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8378
8379   skip_whitespace (str);
8380
8381   if (co_proc_number (&str) == FAIL)
8382     {
8383       if (!inst.error)
8384         inst.error = BAD_ARGS;
8385       return;
8386     }
8387
8388   if (skip_past_comma (&str) == FAIL
8389       || cp_reg_required_here (&str, 12) == FAIL)
8390     {
8391       if (!inst.error)
8392         inst.error = BAD_ARGS;
8393       return;
8394     }
8395
8396   if (skip_past_comma (&str) == FAIL
8397       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8398     {
8399       if (! inst.error)
8400         inst.error = BAD_ARGS;
8401       return;
8402     }
8403
8404   end_of_line (str);
8405 }
8406
8407 static void
8408 do_co_reg (str)
8409      char * str;
8410 {
8411   /* Co-processor register transfer.
8412      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8413
8414   skip_whitespace (str);
8415
8416   if (co_proc_number (&str) == FAIL)
8417     {
8418       if (!inst.error)
8419         inst.error = BAD_ARGS;
8420       return;
8421     }
8422
8423   if (skip_past_comma (&str) == FAIL
8424       || cp_opc_expr (&str, 21, 3) == FAIL)
8425     {
8426       if (!inst.error)
8427         inst.error = BAD_ARGS;
8428       return;
8429     }
8430
8431   if (skip_past_comma (&str) == FAIL
8432       || reg_required_here (&str, 12) == FAIL)
8433     {
8434       if (!inst.error)
8435         inst.error = BAD_ARGS;
8436       return;
8437     }
8438
8439   if (skip_past_comma (&str) == FAIL
8440       || cp_reg_required_here (&str, 16) == FAIL)
8441     {
8442       if (!inst.error)
8443         inst.error = BAD_ARGS;
8444       return;
8445     }
8446
8447   if (skip_past_comma (&str) == FAIL
8448       || cp_reg_required_here (&str, 0) == FAIL)
8449     {
8450       if (!inst.error)
8451         inst.error = BAD_ARGS;
8452       return;
8453     }
8454
8455   if (skip_past_comma (&str) == SUCCESS)
8456     {
8457       if (cp_opc_expr (&str, 5, 3) == FAIL)
8458         {
8459           if (!inst.error)
8460             inst.error = BAD_ARGS;
8461           return;
8462         }
8463     }
8464
8465   end_of_line (str);
8466 }
8467
8468 static void
8469 do_fpa_ctrl (str)
8470      char * str;
8471 {
8472   /* FP control registers.
8473      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8474
8475   skip_whitespace (str);
8476
8477   if (reg_required_here (&str, 12) == FAIL)
8478     {
8479       if (!inst.error)
8480         inst.error = BAD_ARGS;
8481       return;
8482     }
8483
8484   end_of_line (str);
8485 }
8486
8487 static void
8488 do_fpa_ldst (str)
8489      char * str;
8490 {
8491   skip_whitespace (str);
8492
8493   if (fp_reg_required_here (&str, 12) == FAIL)
8494     {
8495       if (!inst.error)
8496         inst.error = BAD_ARGS;
8497       return;
8498     }
8499
8500   if (skip_past_comma (&str) == FAIL
8501       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8502     {
8503       if (!inst.error)
8504         inst.error = BAD_ARGS;
8505       return;
8506     }
8507
8508   end_of_line (str);
8509 }
8510
8511 static void
8512 do_fpa_ldmstm (str)
8513      char * str;
8514 {
8515   int num_regs;
8516
8517   skip_whitespace (str);
8518
8519   if (fp_reg_required_here (&str, 12) == FAIL)
8520     {
8521       if (! inst.error)
8522         inst.error = BAD_ARGS;
8523       return;
8524     }
8525
8526   /* Get Number of registers to transfer.  */
8527   if (skip_past_comma (&str) == FAIL
8528       || my_get_expression (&inst.reloc.exp, &str))
8529     {
8530       if (! inst.error)
8531         inst.error = _("constant expression expected");
8532       return;
8533     }
8534
8535   if (inst.reloc.exp.X_op != O_constant)
8536     {
8537       inst.error = _("constant value required for number of registers");
8538       return;
8539     }
8540
8541   num_regs = inst.reloc.exp.X_add_number;
8542
8543   if (num_regs < 1 || num_regs > 4)
8544     {
8545       inst.error = _("number of registers must be in the range [1:4]");
8546       return;
8547     }
8548
8549   switch (num_regs)
8550     {
8551     case 1:
8552       inst.instruction |= CP_T_X;
8553       break;
8554     case 2:
8555       inst.instruction |= CP_T_Y;
8556       break;
8557     case 3:
8558       inst.instruction |= CP_T_Y | CP_T_X;
8559       break;
8560     case 4:
8561       break;
8562     default:
8563       abort ();
8564     }
8565
8566   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8567     {
8568       int reg;
8569       int write_back;
8570       int offset;
8571
8572       /* The instruction specified "ea" or "fd", so we can only accept
8573          [Rn]{!}.  The instruction does not really support stacking or
8574          unstacking, so we have to emulate these by setting appropriate
8575          bits and offsets.  */
8576       if (skip_past_comma (&str) == FAIL
8577           || *str != '[')
8578         {
8579           if (! inst.error)
8580             inst.error = BAD_ARGS;
8581           return;
8582         }
8583
8584       str++;
8585       skip_whitespace (str);
8586
8587       if ((reg = reg_required_here (&str, 16)) == FAIL)
8588         return;
8589
8590       skip_whitespace (str);
8591
8592       if (*str != ']')
8593         {
8594           inst.error = BAD_ARGS;
8595           return;
8596         }
8597
8598       str++;
8599       if (*str == '!')
8600         {
8601           write_back = 1;
8602           str++;
8603           if (reg == REG_PC)
8604             {
8605               inst.error =
8606                 _("r15 not allowed as base register with write-back");
8607               return;
8608             }
8609         }
8610       else
8611         write_back = 0;
8612
8613       if (inst.instruction & CP_T_Pre)
8614         {
8615           /* Pre-decrement.  */
8616           offset = 3 * num_regs;
8617           if (write_back)
8618             inst.instruction |= CP_T_WB;
8619         }
8620       else
8621         {
8622           /* Post-increment.  */
8623           if (write_back)
8624             {
8625               inst.instruction |= CP_T_WB;
8626               offset = 3 * num_regs;
8627             }
8628           else
8629             {
8630               /* No write-back, so convert this into a standard pre-increment
8631                  instruction -- aesthetically more pleasing.  */
8632               inst.instruction |= CP_T_Pre | CP_T_UD;
8633               offset = 0;
8634             }
8635         }
8636
8637       inst.instruction |= offset;
8638     }
8639   else if (skip_past_comma (&str) == FAIL
8640            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8641     {
8642       if (! inst.error)
8643         inst.error = BAD_ARGS;
8644       return;
8645     }
8646
8647   end_of_line (str);
8648 }
8649
8650 static void
8651 do_fpa_dyadic (str)
8652      char * str;
8653 {
8654   skip_whitespace (str);
8655
8656   if (fp_reg_required_here (&str, 12) == FAIL)
8657     {
8658       if (! inst.error)
8659         inst.error = BAD_ARGS;
8660       return;
8661     }
8662
8663   if (skip_past_comma (&str) == FAIL
8664       || fp_reg_required_here (&str, 16) == FAIL)
8665     {
8666       if (! inst.error)
8667         inst.error = BAD_ARGS;
8668       return;
8669     }
8670
8671   if (skip_past_comma (&str) == FAIL
8672       || fp_op2 (&str) == FAIL)
8673     {
8674       if (! inst.error)
8675         inst.error = BAD_ARGS;
8676       return;
8677     }
8678
8679   end_of_line (str);
8680 }
8681
8682 static void
8683 do_fpa_monadic (str)
8684      char * str;
8685 {
8686   skip_whitespace (str);
8687
8688   if (fp_reg_required_here (&str, 12) == FAIL)
8689     {
8690       if (! inst.error)
8691         inst.error = BAD_ARGS;
8692       return;
8693     }
8694
8695   if (skip_past_comma (&str) == FAIL
8696       || fp_op2 (&str) == FAIL)
8697     {
8698       if (! inst.error)
8699         inst.error = BAD_ARGS;
8700       return;
8701     }
8702
8703   end_of_line (str);
8704 }
8705
8706 static void
8707 do_fpa_cmp (str)
8708      char * str;
8709 {
8710   skip_whitespace (str);
8711
8712   if (fp_reg_required_here (&str, 16) == FAIL)
8713     {
8714       if (! inst.error)
8715         inst.error = BAD_ARGS;
8716       return;
8717     }
8718
8719   if (skip_past_comma (&str) == FAIL
8720       || fp_op2 (&str) == FAIL)
8721     {
8722       if (! inst.error)
8723         inst.error = BAD_ARGS;
8724       return;
8725     }
8726
8727   end_of_line (str);
8728 }
8729
8730 static void
8731 do_fpa_from_reg (str)
8732      char * str;
8733 {
8734   skip_whitespace (str);
8735
8736   if (fp_reg_required_here (&str, 16) == FAIL)
8737     {
8738       if (! inst.error)
8739         inst.error = BAD_ARGS;
8740       return;
8741     }
8742
8743   if (skip_past_comma (&str) == FAIL
8744       || reg_required_here (&str, 12) == FAIL)
8745     {
8746       if (! inst.error)
8747         inst.error = BAD_ARGS;
8748       return;
8749     }
8750
8751   end_of_line (str);
8752 }
8753
8754 static void
8755 do_fpa_to_reg (str)
8756      char * str;
8757 {
8758   skip_whitespace (str);
8759
8760   if (reg_required_here (&str, 12) == FAIL)
8761     return;
8762
8763   if (skip_past_comma (&str) == FAIL
8764       || fp_reg_required_here (&str, 0) == FAIL)
8765     {
8766       if (! inst.error)
8767         inst.error = BAD_ARGS;
8768       return;
8769     }
8770
8771   end_of_line (str);
8772 }
8773
8774 static int
8775 vfp_sp_reg_required_here (str, pos)
8776      char **str;
8777      enum vfp_sp_reg_pos pos;
8778 {
8779   int    reg;
8780   char *start = *str;
8781
8782   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8783     {
8784       switch (pos)
8785         {
8786         case VFP_REG_Sd:
8787           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8788           break;
8789
8790         case VFP_REG_Sn:
8791           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8792           break;
8793
8794         case VFP_REG_Sm:
8795           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8796           break;
8797
8798         default:
8799           abort ();
8800         }
8801       return reg;
8802     }
8803
8804   /* In the few cases where we might be able to accept something else
8805      this error can be overridden.  */
8806   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8807
8808   /* Restore the start point.  */
8809   *str = start;
8810   return FAIL;
8811 }
8812
8813 static int
8814 vfp_dp_reg_required_here (str, pos)
8815      char **str;
8816      enum vfp_dp_reg_pos pos;
8817 {
8818   int   reg;
8819   char *start = *str;
8820
8821   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8822     {
8823       switch (pos)
8824         {
8825         case VFP_REG_Dd:
8826           inst.instruction |= reg << 12;
8827           break;
8828
8829         case VFP_REG_Dn:
8830           inst.instruction |= reg << 16;
8831           break;
8832
8833         case VFP_REG_Dm:
8834           inst.instruction |= reg << 0;
8835           break;
8836
8837         default:
8838           abort ();
8839         }
8840       return reg;
8841     }
8842
8843   /* In the few cases where we might be able to accept something else
8844      this error can be overridden.  */
8845   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8846
8847   /* Restore the start point.  */
8848   *str = start;
8849   return FAIL;
8850 }
8851
8852 static void
8853 do_vfp_sp_monadic (str)
8854      char *str;
8855 {
8856   skip_whitespace (str);
8857
8858   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8859     return;
8860
8861   if (skip_past_comma (&str) == FAIL
8862       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8863     {
8864       if (! inst.error)
8865         inst.error = BAD_ARGS;
8866       return;
8867     }
8868
8869   end_of_line (str);
8870 }
8871
8872 static void
8873 do_vfp_dp_monadic (str)
8874      char *str;
8875 {
8876   skip_whitespace (str);
8877
8878   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8879     return;
8880
8881   if (skip_past_comma (&str) == FAIL
8882       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8883     {
8884       if (! inst.error)
8885         inst.error = BAD_ARGS;
8886       return;
8887     }
8888
8889   end_of_line (str);
8890 }
8891
8892 static void
8893 do_vfp_sp_dyadic (str)
8894      char *str;
8895 {
8896   skip_whitespace (str);
8897
8898   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8899     return;
8900
8901   if (skip_past_comma (&str) == FAIL
8902       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8903       || skip_past_comma (&str) == FAIL
8904       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8905     {
8906       if (! inst.error)
8907         inst.error = BAD_ARGS;
8908       return;
8909     }
8910
8911   end_of_line (str);
8912 }
8913
8914 static void
8915 do_vfp_dp_dyadic (str)
8916      char *str;
8917 {
8918   skip_whitespace (str);
8919
8920   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8921     return;
8922
8923   if (skip_past_comma (&str) == FAIL
8924       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8925       || skip_past_comma (&str) == FAIL
8926       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8927     {
8928       if (! inst.error)
8929         inst.error = BAD_ARGS;
8930       return;
8931     }
8932
8933   end_of_line (str);
8934 }
8935
8936 static void
8937 do_vfp_reg_from_sp (str)
8938      char *str;
8939 {
8940   skip_whitespace (str);
8941
8942   if (reg_required_here (&str, 12) == FAIL)
8943     return;
8944
8945   if (skip_past_comma (&str) == FAIL
8946       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8947     {
8948       if (! inst.error)
8949         inst.error = BAD_ARGS;
8950       return;
8951     }
8952
8953   end_of_line (str);
8954 }
8955
8956 static void
8957 do_vfp_reg2_from_sp2 (str)
8958      char *str;
8959 {
8960   skip_whitespace (str);
8961
8962   if (reg_required_here (&str, 12) == FAIL
8963       || skip_past_comma (&str) == FAIL
8964       || reg_required_here (&str, 16) == FAIL
8965       || skip_past_comma (&str) == FAIL)
8966     {
8967       if (! inst.error)
8968         inst.error = BAD_ARGS;
8969       return;
8970     }
8971
8972   /* We require exactly two consecutive SP registers.  */
8973   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8974     {
8975       if (! inst.error)
8976         inst.error = _("only two consecutive VFP SP registers allowed here");
8977     }
8978
8979   end_of_line (str);
8980 }
8981
8982 static void
8983 do_vfp_sp_from_reg (str)
8984      char *str;
8985 {
8986   skip_whitespace (str);
8987
8988   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8989     return;
8990
8991   if (skip_past_comma (&str) == FAIL
8992       || reg_required_here (&str, 12) == FAIL)
8993     {
8994       if (! inst.error)
8995         inst.error = BAD_ARGS;
8996       return;
8997     }
8998
8999   end_of_line (str);
9000 }
9001
9002 static void
9003 do_vfp_sp2_from_reg2 (str)
9004      char *str;
9005 {
9006   skip_whitespace (str);
9007
9008   /* We require exactly two consecutive SP registers.  */
9009   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
9010     {
9011       if (! inst.error)
9012         inst.error = _("only two consecutive VFP SP registers allowed here");
9013     }
9014
9015   if (skip_past_comma (&str) == FAIL
9016       || reg_required_here (&str, 12) == FAIL
9017       || skip_past_comma (&str) == FAIL
9018       || reg_required_here (&str, 16) == FAIL)
9019     {
9020       if (! inst.error)
9021         inst.error = BAD_ARGS;
9022       return;
9023     }
9024
9025   end_of_line (str);
9026 }
9027
9028 static void
9029 do_vfp_reg_from_dp (str)
9030      char *str;
9031 {
9032   skip_whitespace (str);
9033
9034   if (reg_required_here (&str, 12) == FAIL)
9035     return;
9036
9037   if (skip_past_comma (&str) == FAIL
9038       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9039     {
9040       if (! inst.error)
9041         inst.error = BAD_ARGS;
9042       return;
9043     }
9044
9045   end_of_line (str);
9046 }
9047
9048 static void
9049 do_vfp_reg2_from_dp (str)
9050      char *str;
9051 {
9052   skip_whitespace (str);
9053
9054   if (reg_required_here (&str, 12) == FAIL)
9055     return;
9056
9057   if (skip_past_comma (&str) == FAIL
9058       || reg_required_here (&str, 16) == FAIL
9059       || skip_past_comma (&str) == FAIL
9060       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9061     {
9062       if (! inst.error)
9063         inst.error = BAD_ARGS;
9064       return;
9065     }
9066
9067   end_of_line (str);
9068 }
9069
9070 static void
9071 do_vfp_dp_from_reg (str)
9072      char *str;
9073 {
9074   skip_whitespace (str);
9075
9076   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9077     return;
9078
9079   if (skip_past_comma (&str) == FAIL
9080       || reg_required_here (&str, 12) == FAIL)
9081     {
9082       if (! inst.error)
9083         inst.error = BAD_ARGS;
9084       return;
9085     }
9086
9087   end_of_line (str);
9088 }
9089
9090 static void
9091 do_vfp_dp_from_reg2 (str)
9092      char *str;
9093 {
9094   skip_whitespace (str);
9095
9096   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9097     return;
9098
9099   if (skip_past_comma (&str) == FAIL
9100       || reg_required_here (&str, 12) == FAIL
9101       || skip_past_comma (&str) == FAIL
9102       || reg_required_here (&str, 16) == FAIL)
9103     {
9104       if (! inst.error)
9105         inst.error = BAD_ARGS;
9106       return;
9107     }
9108
9109   end_of_line (str);
9110 }
9111
9112 static const struct vfp_reg *
9113 vfp_psr_parse (str)
9114      char **str;
9115 {
9116   char *start = *str;
9117   char  c;
9118   char *p;
9119   const struct vfp_reg *vreg;
9120
9121   p = start;
9122
9123   /* Find the end of the current token.  */
9124   do
9125     {
9126       c = *p++;
9127     }
9128   while (ISALPHA (c));
9129
9130   /* Mark it.  */
9131   *--p = 0;
9132
9133   for (vreg = vfp_regs + 0;
9134        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9135        vreg++)
9136     {
9137       if (strcmp (start, vreg->name) == 0)
9138         {
9139           *p = c;
9140           *str = p;
9141           return vreg;
9142         }
9143     }
9144
9145   *p = c;
9146   return NULL;
9147 }
9148
9149 static int
9150 vfp_psr_required_here (str)
9151      char **str;
9152 {
9153   char *start = *str;
9154   const struct vfp_reg *vreg;
9155
9156   vreg = vfp_psr_parse (str);
9157
9158   if (vreg)
9159     {
9160       inst.instruction |= vreg->regno;
9161       return SUCCESS;
9162     }
9163
9164   inst.error = _("VFP system register expected");
9165
9166   *str = start;
9167   return FAIL;
9168 }
9169
9170 static void
9171 do_vfp_reg_from_ctrl (str)
9172      char *str;
9173 {
9174   skip_whitespace (str);
9175
9176   if (reg_required_here (&str, 12) == FAIL)
9177     return;
9178
9179   if (skip_past_comma (&str) == FAIL
9180       || vfp_psr_required_here (&str) == FAIL)
9181     {
9182       if (! inst.error)
9183         inst.error = BAD_ARGS;
9184       return;
9185     }
9186
9187   end_of_line (str);
9188 }
9189
9190 static void
9191 do_vfp_ctrl_from_reg (str)
9192      char *str;
9193 {
9194   skip_whitespace (str);
9195
9196   if (vfp_psr_required_here (&str) == FAIL)
9197     return;
9198
9199   if (skip_past_comma (&str) == FAIL
9200       || reg_required_here (&str, 12) == FAIL)
9201     {
9202       if (! inst.error)
9203         inst.error = BAD_ARGS;
9204       return;
9205     }
9206
9207   end_of_line (str);
9208 }
9209
9210 static void
9211 do_vfp_sp_ldst (str)
9212      char *str;
9213 {
9214   skip_whitespace (str);
9215
9216   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9217     {
9218       if (!inst.error)
9219         inst.error = BAD_ARGS;
9220       return;
9221     }
9222
9223   if (skip_past_comma (&str) == FAIL
9224       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9225     {
9226       if (!inst.error)
9227         inst.error = BAD_ARGS;
9228       return;
9229     }
9230
9231   end_of_line (str);
9232 }
9233
9234 static void
9235 do_vfp_dp_ldst (str)
9236      char *str;
9237 {
9238   skip_whitespace (str);
9239
9240   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9241     {
9242       if (!inst.error)
9243         inst.error = BAD_ARGS;
9244       return;
9245     }
9246
9247   if (skip_past_comma (&str) == FAIL
9248       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9249     {
9250       if (!inst.error)
9251         inst.error = BAD_ARGS;
9252       return;
9253     }
9254
9255   end_of_line (str);
9256 }
9257
9258 /* Parse and encode a VFP SP register list, storing the initial
9259    register in position POS and returning the range as the result.  If
9260    the string is invalid return FAIL (an invalid range).  */
9261 static long
9262 vfp_sp_reg_list (str, pos)
9263      char **str;
9264      enum vfp_sp_reg_pos pos;
9265 {
9266   long range = 0;
9267   int base_reg = 0;
9268   int new_base;
9269   long base_bits = 0;
9270   int count = 0;
9271   long tempinst;
9272   unsigned long mask = 0;
9273   int warned = 0;
9274
9275   if (**str != '{')
9276     return FAIL;
9277
9278   (*str)++;
9279   skip_whitespace (*str);
9280
9281   tempinst = inst.instruction;
9282
9283   do
9284     {
9285       inst.instruction = 0;
9286
9287       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9288         return FAIL;
9289
9290       if (count == 0 || base_reg > new_base)
9291         {
9292           base_reg = new_base;
9293           base_bits = inst.instruction;
9294         }
9295
9296       if (mask & (1 << new_base))
9297         {
9298           inst.error = _("invalid register list");
9299           return FAIL;
9300         }
9301
9302       if ((mask >> new_base) != 0 && ! warned)
9303         {
9304           as_tsktsk (_("register list not in ascending order"));
9305           warned = 1;
9306         }
9307
9308       mask |= 1 << new_base;
9309       count++;
9310
9311       skip_whitespace (*str);
9312
9313       if (**str == '-') /* We have the start of a range expression */
9314         {
9315           int high_range;
9316
9317           (*str)++;
9318
9319           if ((high_range
9320                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9321               == FAIL)
9322             {
9323               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9324               return FAIL;
9325             }
9326
9327           if (high_range <= new_base)
9328             {
9329               inst.error = _("register range not in ascending order");
9330               return FAIL;
9331             }
9332
9333           for (new_base++; new_base <= high_range; new_base++)
9334             {
9335               if (mask & (1 << new_base))
9336                 {
9337                   inst.error = _("invalid register list");
9338                   return FAIL;
9339                 }
9340
9341               mask |= 1 << new_base;
9342               count++;
9343             }
9344         }
9345     }
9346   while (skip_past_comma (str) != FAIL);
9347
9348   if (**str != '}')
9349     {
9350       inst.error = _("invalid register list");
9351       return FAIL;
9352     }
9353
9354   (*str)++;
9355
9356   range = count;
9357
9358   /* Sanity check -- should have raised a parse error above.  */
9359   if (count == 0 || count > 32)
9360     abort ();
9361
9362   /* Final test -- the registers must be consecutive.  */
9363   while (count--)
9364     {
9365       if ((mask & (1 << base_reg++)) == 0)
9366         {
9367           inst.error = _("non-contiguous register range");
9368           return FAIL;
9369         }
9370     }
9371
9372   inst.instruction = tempinst | base_bits;
9373   return range;
9374 }
9375
9376 static long
9377 vfp_dp_reg_list (str)
9378      char **str;
9379 {
9380   long range = 0;
9381   int base_reg = 0;
9382   int new_base;
9383   int count = 0;
9384   long tempinst;
9385   unsigned long mask = 0;
9386   int warned = 0;
9387
9388   if (**str != '{')
9389     return FAIL;
9390
9391   (*str)++;
9392   skip_whitespace (*str);
9393
9394   tempinst = inst.instruction;
9395
9396   do
9397     {
9398       inst.instruction = 0;
9399
9400       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9401         return FAIL;
9402
9403       if (count == 0 || base_reg > new_base)
9404         {
9405           base_reg = new_base;
9406           range = inst.instruction;
9407         }
9408
9409       if (mask & (1 << new_base))
9410         {
9411           inst.error = _("invalid register list");
9412           return FAIL;
9413         }
9414
9415       if ((mask >> new_base) != 0 && ! warned)
9416         {
9417           as_tsktsk (_("register list not in ascending order"));
9418           warned = 1;
9419         }
9420
9421       mask |= 1 << new_base;
9422       count++;
9423
9424       skip_whitespace (*str);
9425
9426       if (**str == '-') /* We have the start of a range expression */
9427         {
9428           int high_range;
9429
9430           (*str)++;
9431
9432           if ((high_range
9433                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9434               == FAIL)
9435             {
9436               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9437               return FAIL;
9438             }
9439
9440           if (high_range <= new_base)
9441             {
9442               inst.error = _("register range not in ascending order");
9443               return FAIL;
9444             }
9445
9446           for (new_base++; new_base <= high_range; new_base++)
9447             {
9448               if (mask & (1 << new_base))
9449                 {
9450                   inst.error = _("invalid register list");
9451                   return FAIL;
9452                 }
9453
9454               mask |= 1 << new_base;
9455               count++;
9456             }
9457         }
9458     }
9459   while (skip_past_comma (str) != FAIL);
9460
9461   if (**str != '}')
9462     {
9463       inst.error = _("invalid register list");
9464       return FAIL;
9465     }
9466
9467   (*str)++;
9468
9469   range |= 2 * count;
9470
9471   /* Sanity check -- should have raised a parse error above.  */
9472   if (count == 0 || count > 16)
9473     abort ();
9474
9475   /* Final test -- the registers must be consecutive.  */
9476   while (count--)
9477     {
9478       if ((mask & (1 << base_reg++)) == 0)
9479         {
9480           inst.error = _("non-contiguous register range");
9481           return FAIL;
9482         }
9483     }
9484
9485   inst.instruction = tempinst;
9486   return range;
9487 }
9488
9489 static void
9490 vfp_sp_ldstm (str, ldstm_type)
9491      char *str;
9492      enum vfp_ldstm_type ldstm_type;
9493 {
9494   long range;
9495
9496   skip_whitespace (str);
9497
9498   if (reg_required_here (&str, 16) == FAIL)
9499     return;
9500
9501   skip_whitespace (str);
9502
9503   if (*str == '!')
9504     {
9505       inst.instruction |= WRITE_BACK;
9506       str++;
9507     }
9508   else if (ldstm_type != VFP_LDSTMIA)
9509     {
9510       inst.error = _("this addressing mode requires base-register writeback");
9511       return;
9512     }
9513
9514   if (skip_past_comma (&str) == FAIL
9515       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9516     {
9517       if (!inst.error)
9518         inst.error = BAD_ARGS;
9519       return;
9520     }
9521
9522   inst.instruction |= range;
9523   end_of_line (str);
9524 }
9525
9526 static void
9527 vfp_dp_ldstm (str, ldstm_type)
9528      char *str;
9529      enum vfp_ldstm_type ldstm_type;
9530 {
9531   long range;
9532
9533   skip_whitespace (str);
9534
9535   if (reg_required_here (&str, 16) == FAIL)
9536     return;
9537
9538   skip_whitespace (str);
9539
9540   if (*str == '!')
9541     {
9542       inst.instruction |= WRITE_BACK;
9543       str++;
9544     }
9545   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9546     {
9547       inst.error = _("this addressing mode requires base-register writeback");
9548       return;
9549     }
9550
9551   if (skip_past_comma (&str) == FAIL
9552       || (range = vfp_dp_reg_list (&str)) == FAIL)
9553     {
9554       if (!inst.error)
9555         inst.error = BAD_ARGS;
9556       return;
9557     }
9558
9559   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9560     range += 1;
9561
9562   inst.instruction |= range;
9563   end_of_line (str);
9564 }
9565
9566 static void
9567 do_vfp_sp_ldstmia (str)
9568      char *str;
9569 {
9570   vfp_sp_ldstm (str, VFP_LDSTMIA);
9571 }
9572
9573 static void
9574 do_vfp_sp_ldstmdb (str)
9575      char *str;
9576 {
9577   vfp_sp_ldstm (str, VFP_LDSTMDB);
9578 }
9579
9580 static void
9581 do_vfp_dp_ldstmia (str)
9582      char *str;
9583 {
9584   vfp_dp_ldstm (str, VFP_LDSTMIA);
9585 }
9586
9587 static void
9588 do_vfp_dp_ldstmdb (str)
9589      char *str;
9590 {
9591   vfp_dp_ldstm (str, VFP_LDSTMDB);
9592 }
9593
9594 static void
9595 do_vfp_xp_ldstmia (str)
9596      char *str;
9597 {
9598   vfp_dp_ldstm (str, VFP_LDSTMIAX);
9599 }
9600
9601 static void
9602 do_vfp_xp_ldstmdb (str)
9603      char *str;
9604 {
9605   vfp_dp_ldstm (str, VFP_LDSTMDBX);
9606 }
9607
9608 static void
9609 do_vfp_sp_compare_z (str)
9610      char *str;
9611 {
9612   skip_whitespace (str);
9613
9614   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9615     {
9616       if (!inst.error)
9617         inst.error = BAD_ARGS;
9618       return;
9619     }
9620
9621   end_of_line (str);
9622 }
9623
9624 static void
9625 do_vfp_dp_compare_z (str)
9626      char *str;
9627 {
9628   skip_whitespace (str);
9629
9630   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9631     {
9632       if (!inst.error)
9633         inst.error = BAD_ARGS;
9634       return;
9635     }
9636
9637   end_of_line (str);
9638 }
9639
9640 static void
9641 do_vfp_dp_sp_cvt (str)
9642      char *str;
9643 {
9644   skip_whitespace (str);
9645
9646   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9647     return;
9648
9649   if (skip_past_comma (&str) == FAIL
9650       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9651     {
9652       if (! inst.error)
9653         inst.error = BAD_ARGS;
9654       return;
9655     }
9656
9657   end_of_line (str);
9658 }
9659
9660 static void
9661 do_vfp_sp_dp_cvt (str)
9662      char *str;
9663 {
9664   skip_whitespace (str);
9665
9666   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9667     return;
9668
9669   if (skip_past_comma (&str) == FAIL
9670       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9671     {
9672       if (! inst.error)
9673         inst.error = BAD_ARGS;
9674       return;
9675     }
9676
9677   end_of_line (str);
9678 }
9679
9680 /* Thumb specific routines.  */
9681
9682 /* Parse and validate that a register is of the right form, this saves
9683    repeated checking of this information in many similar cases.
9684    Unlike the 32-bit case we do not insert the register into the opcode
9685    here, since the position is often unknown until the full instruction
9686    has been parsed.  */
9687
9688 static int
9689 thumb_reg (strp, hi_lo)
9690      char ** strp;
9691      int     hi_lo;
9692 {
9693   int reg;
9694
9695   if ((reg = reg_required_here (strp, -1)) == FAIL)
9696     return FAIL;
9697
9698   switch (hi_lo)
9699     {
9700     case THUMB_REG_LO:
9701       if (reg > 7)
9702         {
9703           inst.error = _("lo register required");
9704           return FAIL;
9705         }
9706       break;
9707
9708     case THUMB_REG_HI:
9709       if (reg < 8)
9710         {
9711           inst.error = _("hi register required");
9712           return FAIL;
9713         }
9714       break;
9715
9716     default:
9717       break;
9718     }
9719
9720   return reg;
9721 }
9722
9723 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9724    was SUB.  */
9725
9726 static void
9727 thumb_add_sub (str, subtract)
9728      char * str;
9729      int    subtract;
9730 {
9731   int Rd, Rs, Rn = FAIL;
9732
9733   skip_whitespace (str);
9734
9735   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9736       || skip_past_comma (&str) == FAIL)
9737     {
9738       if (! inst.error)
9739         inst.error = BAD_ARGS;
9740       return;
9741     }
9742
9743   if (is_immediate_prefix (*str))
9744     {
9745       Rs = Rd;
9746       str++;
9747       if (my_get_expression (&inst.reloc.exp, &str))
9748         return;
9749     }
9750   else
9751     {
9752       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9753         return;
9754
9755       if (skip_past_comma (&str) == FAIL)
9756         {
9757           /* Two operand format, shuffle the registers
9758              and pretend there are 3.  */
9759           Rn = Rs;
9760           Rs = Rd;
9761         }
9762       else if (is_immediate_prefix (*str))
9763         {
9764           str++;
9765           if (my_get_expression (&inst.reloc.exp, &str))
9766             return;
9767         }
9768       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9769         return;
9770     }
9771
9772   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9773      for the latter case, EXPR contains the immediate that was found.  */
9774   if (Rn != FAIL)
9775     {
9776       /* All register format.  */
9777       if (Rd > 7 || Rs > 7 || Rn > 7)
9778         {
9779           if (Rs != Rd)
9780             {
9781               inst.error = _("dest and source1 must be the same register");
9782               return;
9783             }
9784
9785           /* Can't do this for SUB.  */
9786           if (subtract)
9787             {
9788               inst.error = _("subtract valid only on lo regs");
9789               return;
9790             }
9791
9792           inst.instruction = (T_OPCODE_ADD_HI
9793                               | (Rd > 7 ? THUMB_H1 : 0)
9794                               | (Rn > 7 ? THUMB_H2 : 0));
9795           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9796         }
9797       else
9798         {
9799           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9800           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9801         }
9802     }
9803   else
9804     {
9805       /* Immediate expression, now things start to get nasty.  */
9806
9807       /* First deal with HI regs, only very restricted cases allowed:
9808          Adjusting SP, and using PC or SP to get an address.  */
9809       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9810           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9811         {
9812           inst.error = _("invalid Hi register with immediate");
9813           return;
9814         }
9815
9816       if (inst.reloc.exp.X_op != O_constant)
9817         {
9818           /* Value isn't known yet, all we can do is store all the fragments
9819              we know about in the instruction and let the reloc hacking
9820              work it all out.  */
9821           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9822           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9823         }
9824       else
9825         {
9826           int offset = inst.reloc.exp.X_add_number;
9827
9828           if (subtract)
9829             offset = - offset;
9830
9831           if (offset < 0)
9832             {
9833               offset = - offset;
9834               subtract = 1;
9835
9836               /* Quick check, in case offset is MIN_INT.  */
9837               if (offset < 0)
9838                 {
9839                   inst.error = _("immediate value out of range");
9840                   return;
9841                 }
9842             }
9843           /* Note - you cannot convert a subtract of 0 into an
9844              add of 0 because the carry flag is set differently.  */
9845           else if (offset > 0)
9846             subtract = 0;
9847
9848           if (Rd == REG_SP)
9849             {
9850               if (offset & ~0x1fc)
9851                 {
9852                   inst.error = _("invalid immediate value for stack adjust");
9853                   return;
9854                 }
9855               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9856               inst.instruction |= offset >> 2;
9857             }
9858           else if (Rs == REG_PC || Rs == REG_SP)
9859             {
9860               if (subtract
9861                   || (offset & ~0x3fc))
9862                 {
9863                   inst.error = _("invalid immediate for address calculation");
9864                   return;
9865                 }
9866               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9867                                   : T_OPCODE_ADD_SP);
9868               inst.instruction |= (Rd << 8) | (offset >> 2);
9869             }
9870           else if (Rs == Rd)
9871             {
9872               if (offset & ~0xff)
9873                 {
9874                   inst.error = _("immediate value out of range");
9875                   return;
9876                 }
9877               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9878               inst.instruction |= (Rd << 8) | offset;
9879             }
9880           else
9881             {
9882               if (offset & ~0x7)
9883                 {
9884                   inst.error = _("immediate value out of range");
9885                   return;
9886                 }
9887               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9888               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9889             }
9890         }
9891     }
9892
9893   end_of_line (str);
9894 }
9895
9896 static void
9897 thumb_shift (str, shift)
9898      char * str;
9899      int    shift;
9900 {
9901   int Rd, Rs, Rn = FAIL;
9902
9903   skip_whitespace (str);
9904
9905   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9906       || skip_past_comma (&str) == FAIL)
9907     {
9908       if (! inst.error)
9909         inst.error = BAD_ARGS;
9910       return;
9911     }
9912
9913   if (is_immediate_prefix (*str))
9914     {
9915       /* Two operand immediate format, set Rs to Rd.  */
9916       Rs = Rd;
9917       str ++;
9918       if (my_get_expression (&inst.reloc.exp, &str))
9919         return;
9920     }
9921   else
9922     {
9923       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9924         return;
9925
9926       if (skip_past_comma (&str) == FAIL)
9927         {
9928           /* Two operand format, shuffle the registers
9929              and pretend there are 3.  */
9930           Rn = Rs;
9931           Rs = Rd;
9932         }
9933       else if (is_immediate_prefix (*str))
9934         {
9935           str++;
9936           if (my_get_expression (&inst.reloc.exp, &str))
9937             return;
9938         }
9939       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9940         return;
9941     }
9942
9943   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9944      for the latter case, EXPR contains the immediate that was found.  */
9945
9946   if (Rn != FAIL)
9947     {
9948       if (Rs != Rd)
9949         {
9950           inst.error = _("source1 and dest must be same register");
9951           return;
9952         }
9953
9954       switch (shift)
9955         {
9956         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9957         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9958         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9959         }
9960
9961       inst.instruction |= Rd | (Rn << 3);
9962     }
9963   else
9964     {
9965       switch (shift)
9966         {
9967         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9968         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9969         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9970         }
9971
9972       if (inst.reloc.exp.X_op != O_constant)
9973         {
9974           /* Value isn't known yet, create a dummy reloc and let reloc
9975              hacking fix it up.  */
9976           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9977         }
9978       else
9979         {
9980           unsigned shift_value = inst.reloc.exp.X_add_number;
9981
9982           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9983             {
9984               inst.error = _("invalid immediate for shift");
9985               return;
9986             }
9987
9988           /* Shifts of zero are handled by converting to LSL.  */
9989           if (shift_value == 0)
9990             inst.instruction = T_OPCODE_LSL_I;
9991
9992           /* Shifts of 32 are encoded as a shift of zero.  */
9993           if (shift_value == 32)
9994             shift_value = 0;
9995
9996           inst.instruction |= shift_value << 6;
9997         }
9998
9999       inst.instruction |= Rd | (Rs << 3);
10000     }
10001
10002   end_of_line (str);
10003 }
10004
10005 static void
10006 thumb_mov_compare (str, move)
10007      char * str;
10008      int    move;
10009 {
10010   int Rd, Rs = FAIL;
10011
10012   skip_whitespace (str);
10013
10014   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
10015       || skip_past_comma (&str) == FAIL)
10016     {
10017       if (! inst.error)
10018         inst.error = BAD_ARGS;
10019       return;
10020     }
10021
10022   if (move != THUMB_CPY && is_immediate_prefix (*str))
10023     {
10024       str++;
10025       if (my_get_expression (&inst.reloc.exp, &str))
10026         return;
10027     }
10028   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10029     return;
10030
10031   if (Rs != FAIL)
10032     {
10033       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10034         {
10035           if (move == THUMB_MOVE)
10036             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10037                since a MOV instruction produces unpredictable results.  */
10038             inst.instruction = T_OPCODE_ADD_I3;
10039           else
10040             inst.instruction = T_OPCODE_CMP_LR;
10041           inst.instruction |= Rd | (Rs << 3);
10042         }
10043       else
10044         {
10045           if (move == THUMB_MOVE)
10046             inst.instruction = T_OPCODE_MOV_HR;
10047           else if (move != THUMB_CPY)
10048             inst.instruction = T_OPCODE_CMP_HR;
10049
10050           if (Rd > 7)
10051             inst.instruction |= THUMB_H1;
10052
10053           if (Rs > 7)
10054             inst.instruction |= THUMB_H2;
10055
10056           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10057         }
10058     }
10059   else
10060     {
10061       if (Rd > 7)
10062         {
10063           inst.error = _("only lo regs allowed with immediate");
10064           return;
10065         }
10066
10067       if (move == THUMB_MOVE)
10068         inst.instruction = T_OPCODE_MOV_I8;
10069       else
10070         inst.instruction = T_OPCODE_CMP_I8;
10071
10072       inst.instruction |= Rd << 8;
10073
10074       if (inst.reloc.exp.X_op != O_constant)
10075         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10076       else
10077         {
10078           unsigned value = inst.reloc.exp.X_add_number;
10079
10080           if (value > 255)
10081             {
10082               inst.error = _("invalid immediate");
10083               return;
10084             }
10085
10086           inst.instruction |= value;
10087         }
10088     }
10089
10090   end_of_line (str);
10091 }
10092
10093 static void
10094 thumb_load_store (str, load_store, size)
10095      char * str;
10096      int    load_store;
10097      int    size;
10098 {
10099   int Rd, Rb, Ro = FAIL;
10100
10101   skip_whitespace (str);
10102
10103   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10104       || skip_past_comma (&str) == FAIL)
10105     {
10106       if (! inst.error)
10107         inst.error = BAD_ARGS;
10108       return;
10109     }
10110
10111   if (*str == '[')
10112     {
10113       str++;
10114       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10115         return;
10116
10117       if (skip_past_comma (&str) != FAIL)
10118         {
10119           if (is_immediate_prefix (*str))
10120             {
10121               str++;
10122               if (my_get_expression (&inst.reloc.exp, &str))
10123                 return;
10124             }
10125           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10126             return;
10127         }
10128       else
10129         {
10130           inst.reloc.exp.X_op = O_constant;
10131           inst.reloc.exp.X_add_number = 0;
10132         }
10133
10134       if (*str != ']')
10135         {
10136           inst.error = _("expected ']'");
10137           return;
10138         }
10139       str++;
10140     }
10141   else if (*str == '=')
10142     {
10143       if (load_store != THUMB_LOAD)
10144         {
10145           inst.error = _("invalid pseudo operation");
10146           return;
10147         }
10148
10149       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10150       str++;
10151
10152       skip_whitespace (str);
10153
10154       if (my_get_expression (& inst.reloc.exp, & str))
10155         return;
10156
10157       end_of_line (str);
10158
10159       if (   inst.reloc.exp.X_op != O_constant
10160           && inst.reloc.exp.X_op != O_symbol)
10161         {
10162           inst.error = "Constant expression expected";
10163           return;
10164         }
10165
10166       if (inst.reloc.exp.X_op == O_constant
10167           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10168         {
10169           /* This can be done with a mov instruction.  */
10170
10171           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10172           inst.instruction |= inst.reloc.exp.X_add_number;
10173           return;
10174         }
10175
10176       /* Insert into literal pool.  */
10177       if (add_to_lit_pool () == FAIL)
10178         {
10179           if (!inst.error)
10180             inst.error = "literal pool insertion failed";
10181           return;
10182         }
10183
10184       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10185       inst.reloc.pc_rel = 1;
10186       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10187       /* Adjust ARM pipeline offset to Thumb.  */
10188       inst.reloc.exp.X_add_number += 4;
10189
10190       return;
10191     }
10192   else
10193     {
10194       if (my_get_expression (&inst.reloc.exp, &str))
10195         return;
10196
10197       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10198       inst.reloc.pc_rel = 1;
10199       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10200       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10201       end_of_line (str);
10202       return;
10203     }
10204
10205   if (Rb == REG_PC || Rb == REG_SP)
10206     {
10207       if (size != THUMB_WORD)
10208         {
10209           inst.error = _("byte or halfword not valid for base register");
10210           return;
10211         }
10212       else if (Rb == REG_PC && load_store != THUMB_LOAD)
10213         {
10214           inst.error = _("r15 based store not allowed");
10215           return;
10216         }
10217       else if (Ro != FAIL)
10218         {
10219           inst.error = _("invalid base register for register offset");
10220           return;
10221         }
10222
10223       if (Rb == REG_PC)
10224         inst.instruction = T_OPCODE_LDR_PC;
10225       else if (load_store == THUMB_LOAD)
10226         inst.instruction = T_OPCODE_LDR_SP;
10227       else
10228         inst.instruction = T_OPCODE_STR_SP;
10229
10230       inst.instruction |= Rd << 8;
10231       if (inst.reloc.exp.X_op == O_constant)
10232         {
10233           unsigned offset = inst.reloc.exp.X_add_number;
10234
10235           if (offset & ~0x3fc)
10236             {
10237               inst.error = _("invalid offset");
10238               return;
10239             }
10240
10241           inst.instruction |= offset >> 2;
10242         }
10243       else
10244         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10245     }
10246   else if (Rb > 7)
10247     {
10248       inst.error = _("invalid base register in load/store");
10249       return;
10250     }
10251   else if (Ro == FAIL)
10252     {
10253       /* Immediate offset.  */
10254       if (size == THUMB_WORD)
10255         inst.instruction = (load_store == THUMB_LOAD
10256                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10257       else if (size == THUMB_HALFWORD)
10258         inst.instruction = (load_store == THUMB_LOAD
10259                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10260       else
10261         inst.instruction = (load_store == THUMB_LOAD
10262                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10263
10264       inst.instruction |= Rd | (Rb << 3);
10265
10266       if (inst.reloc.exp.X_op == O_constant)
10267         {
10268           unsigned offset = inst.reloc.exp.X_add_number;
10269
10270           if (offset & ~(0x1f << size))
10271             {
10272               inst.error = _("invalid offset");
10273               return;
10274             }
10275           inst.instruction |= (offset >> size) << 6;
10276         }
10277       else
10278         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10279     }
10280   else
10281     {
10282       /* Register offset.  */
10283       if (size == THUMB_WORD)
10284         inst.instruction = (load_store == THUMB_LOAD
10285                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10286       else if (size == THUMB_HALFWORD)
10287         inst.instruction = (load_store == THUMB_LOAD
10288                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10289       else
10290         inst.instruction = (load_store == THUMB_LOAD
10291                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10292
10293       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10294     }
10295
10296   end_of_line (str);
10297 }
10298
10299 /* A register must be given at this point.
10300
10301    Shift is the place to put it in inst.instruction.
10302
10303    Restores input start point on err.
10304    Returns the reg#, or FAIL.  */
10305
10306 static int
10307 mav_reg_required_here (str, shift, regtype)
10308      char ** str;
10309      int shift;
10310      enum arm_reg_type regtype;
10311 {
10312   int   reg;
10313   char *start = *str;
10314
10315   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10316     {
10317       if (shift >= 0)
10318         inst.instruction |= reg << shift;
10319
10320       return reg;
10321     }
10322
10323   /* Restore the start point.  */
10324   *str = start;
10325
10326   /* In the few cases where we might be able to accept something else
10327      this error can be overridden.  */
10328   inst.error = _(all_reg_maps[regtype].expected);
10329
10330   return FAIL;
10331 }
10332
10333 /* Cirrus Maverick Instructions.  */
10334
10335 /* Wrapper functions.  */
10336
10337 static void
10338 do_mav_binops_1a (str)
10339      char * str;
10340 {
10341   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10342 }
10343
10344 static void
10345 do_mav_binops_1b (str)
10346      char * str;
10347 {
10348   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10349 }
10350
10351 static void
10352 do_mav_binops_1c (str)
10353      char * str;
10354 {
10355   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10356 }
10357
10358 static void
10359 do_mav_binops_1d (str)
10360      char * str;
10361 {
10362   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10363 }
10364
10365 static void
10366 do_mav_binops_1e (str)
10367      char * str;
10368 {
10369   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10370 }
10371
10372 static void
10373 do_mav_binops_1f (str)
10374      char * str;
10375 {
10376   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10377 }
10378
10379 static void
10380 do_mav_binops_1g (str)
10381      char * str;
10382 {
10383   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10384 }
10385
10386 static void
10387 do_mav_binops_1h (str)
10388      char * str;
10389 {
10390   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10391 }
10392
10393 static void
10394 do_mav_binops_1i (str)
10395      char * str;
10396 {
10397   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10398 }
10399
10400 static void
10401 do_mav_binops_1j (str)
10402      char * str;
10403 {
10404   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10405 }
10406
10407 static void
10408 do_mav_binops_1k (str)
10409      char * str;
10410 {
10411   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10412 }
10413
10414 static void
10415 do_mav_binops_1l (str)
10416      char * str;
10417 {
10418   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10419 }
10420
10421 static void
10422 do_mav_binops_1m (str)
10423      char * str;
10424 {
10425   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10426 }
10427
10428 static void
10429 do_mav_binops_1n (str)
10430      char * str;
10431 {
10432   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10433 }
10434
10435 static void
10436 do_mav_binops_1o (str)
10437      char * str;
10438 {
10439   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10440 }
10441
10442 static void
10443 do_mav_binops_2a (str)
10444      char * str;
10445 {
10446   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10447 }
10448
10449 static void
10450 do_mav_binops_2b (str)
10451      char * str;
10452 {
10453   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10454 }
10455
10456 static void
10457 do_mav_binops_2c (str)
10458      char * str;
10459 {
10460   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10461 }
10462
10463 static void
10464 do_mav_binops_3a (str)
10465      char * str;
10466 {
10467   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10468 }
10469
10470 static void
10471 do_mav_binops_3b (str)
10472      char * str;
10473 {
10474   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10475 }
10476
10477 static void
10478 do_mav_binops_3c (str)
10479      char * str;
10480 {
10481   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10482 }
10483
10484 static void
10485 do_mav_binops_3d (str)
10486      char * str;
10487 {
10488   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10489 }
10490
10491 static void
10492 do_mav_triple_4a (str)
10493      char * str;
10494 {
10495   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10496 }
10497
10498 static void
10499 do_mav_triple_4b (str)
10500      char * str;
10501 {
10502   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10503 }
10504
10505 static void
10506 do_mav_triple_5a (str)
10507      char * str;
10508 {
10509   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10510 }
10511
10512 static void
10513 do_mav_triple_5b (str)
10514      char * str;
10515 {
10516   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10517 }
10518
10519 static void
10520 do_mav_triple_5c (str)
10521      char * str;
10522 {
10523   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10524 }
10525
10526 static void
10527 do_mav_triple_5d (str)
10528      char * str;
10529 {
10530   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10531 }
10532
10533 static void
10534 do_mav_triple_5e (str)
10535      char * str;
10536 {
10537   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10538 }
10539
10540 static void
10541 do_mav_triple_5f (str)
10542      char * str;
10543 {
10544   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10545 }
10546
10547 static void
10548 do_mav_triple_5g (str)
10549      char * str;
10550 {
10551   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10552 }
10553
10554 static void
10555 do_mav_triple_5h (str)
10556      char * str;
10557 {
10558   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10559 }
10560
10561 static void
10562 do_mav_quad_6a (str)
10563      char * str;
10564 {
10565   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10566              REG_TYPE_MVFX);
10567 }
10568
10569 static void
10570 do_mav_quad_6b (str)
10571      char * str;
10572 {
10573   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10574              REG_TYPE_MVFX);
10575 }
10576
10577 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
10578 static void
10579 do_mav_dspsc_1 (str)
10580      char * str;
10581 {
10582   skip_whitespace (str);
10583
10584   /* cfmvsc32.  */
10585   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10586       || skip_past_comma (&str) == FAIL
10587       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10588     {
10589       if (!inst.error)
10590         inst.error = BAD_ARGS;
10591
10592       return;
10593     }
10594
10595   end_of_line (str);
10596 }
10597
10598 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
10599 static void
10600 do_mav_dspsc_2 (str)
10601      char * str;
10602 {
10603   skip_whitespace (str);
10604
10605   /* cfmv32sc.  */
10606   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10607       || skip_past_comma (&str) == FAIL
10608       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10609     {
10610       if (!inst.error)
10611         inst.error = BAD_ARGS;
10612
10613       return;
10614     }
10615
10616   end_of_line (str);
10617 }
10618
10619 static void
10620 do_mav_shift_1 (str)
10621      char * str;
10622 {
10623   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10624 }
10625
10626 static void
10627 do_mav_shift_2 (str)
10628      char * str;
10629 {
10630   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10631 }
10632
10633 static void
10634 do_mav_ldst_1 (str)
10635      char * str;
10636 {
10637   do_mav_ldst (str, REG_TYPE_MVF);
10638 }
10639
10640 static void
10641 do_mav_ldst_2 (str)
10642      char * str;
10643 {
10644   do_mav_ldst (str, REG_TYPE_MVD);
10645 }
10646
10647 static void
10648 do_mav_ldst_3 (str)
10649      char * str;
10650 {
10651   do_mav_ldst (str, REG_TYPE_MVFX);
10652 }
10653
10654 static void
10655 do_mav_ldst_4 (str)
10656      char * str;
10657 {
10658   do_mav_ldst (str, REG_TYPE_MVDX);
10659 }
10660
10661 /* Isnsn like "foo X,Y".  */
10662
10663 static void
10664 do_mav_binops (str, mode, reg0, reg1)
10665      char * str;
10666      int mode;
10667      enum arm_reg_type reg0;
10668      enum arm_reg_type reg1;
10669 {
10670   int shift0, shift1;
10671
10672   shift0 = mode & 0xff;
10673   shift1 = (mode >> 8) & 0xff;
10674
10675   skip_whitespace (str);
10676
10677   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10678       || skip_past_comma (&str) == FAIL
10679       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10680     {
10681       if (!inst.error)
10682         inst.error = BAD_ARGS;
10683     }
10684   else
10685     end_of_line (str);
10686 }
10687
10688 /* Isnsn like "foo X,Y,Z".  */
10689
10690 static void
10691 do_mav_triple (str, mode, reg0, reg1, reg2)
10692      char * str;
10693      int mode;
10694      enum arm_reg_type reg0;
10695      enum arm_reg_type reg1;
10696      enum arm_reg_type reg2;
10697 {
10698   int shift0, shift1, shift2;
10699
10700   shift0 = mode & 0xff;
10701   shift1 = (mode >> 8) & 0xff;
10702   shift2 = (mode >> 16) & 0xff;
10703
10704   skip_whitespace (str);
10705
10706   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10707       || skip_past_comma (&str) == FAIL
10708       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10709       || skip_past_comma (&str) == FAIL
10710       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10711     {
10712       if (!inst.error)
10713         inst.error = BAD_ARGS;
10714     }
10715   else
10716     end_of_line (str);
10717 }
10718
10719 /* Isnsn like "foo W,X,Y,Z".
10720     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10721
10722 static void
10723 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10724      char * str;
10725      int mode;
10726      enum arm_reg_type reg0;
10727      enum arm_reg_type reg1;
10728      enum arm_reg_type reg2;
10729      enum arm_reg_type reg3;
10730 {
10731   int shift0, shift1, shift2, shift3;
10732
10733   shift0= mode & 0xff;
10734   shift1 = (mode >> 8) & 0xff;
10735   shift2 = (mode >> 16) & 0xff;
10736   shift3 = (mode >> 24) & 0xff;
10737
10738   skip_whitespace (str);
10739
10740   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10741       || skip_past_comma (&str) == FAIL
10742       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10743       || skip_past_comma (&str) == FAIL
10744       || mav_reg_required_here (&str, shift2, reg2) == FAIL
10745       || skip_past_comma (&str) == FAIL
10746       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10747     {
10748       if (!inst.error)
10749         inst.error = BAD_ARGS;
10750     }
10751   else
10752     end_of_line (str);
10753 }
10754
10755 /* Maverick shift immediate instructions.
10756    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10757    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10758
10759 static void
10760 do_mav_shift (str, reg0, reg1)
10761      char * str;
10762      enum arm_reg_type reg0;
10763      enum arm_reg_type reg1;
10764 {
10765   int error;
10766   int imm, neg = 0;
10767
10768   skip_whitespace (str);
10769
10770   error = 0;
10771
10772   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10773       || skip_past_comma (&str) == FAIL
10774       || mav_reg_required_here (&str, 16, reg1) == FAIL
10775       || skip_past_comma  (&str) == FAIL)
10776     {
10777       if (!inst.error)
10778         inst.error = BAD_ARGS;
10779       return;
10780     }
10781
10782   /* Calculate the immediate operand.
10783      The operand is a 7bit signed number.  */
10784   skip_whitespace (str);
10785
10786   if (*str == '#')
10787     ++str;
10788
10789   if (!ISDIGIT (*str) && *str != '-')
10790     {
10791       inst.error = _("expecting immediate, 7bit operand");
10792       return;
10793     }
10794
10795   if (*str == '-')
10796     {
10797       neg = 1;
10798       ++str;
10799     }
10800
10801   for (imm = 0; *str && ISDIGIT (*str); ++str)
10802     imm = imm * 10 + *str - '0';
10803
10804   if (imm > 64)
10805     {
10806       inst.error = _("immediate out of range");
10807       return;
10808     }
10809
10810   /* Make negative imm's into 7bit signed numbers.  */
10811   if (neg)
10812     {
10813       imm = -imm;
10814       imm &= 0x0000007f;
10815     }
10816
10817   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10818      Bits 5-7 of the insn should have bits 4-6 of the immediate.
10819      Bit 4 should be 0.  */
10820   imm = (imm & 0xf) | ((imm & 0x70) << 1);
10821
10822   inst.instruction |= imm;
10823   end_of_line (str);
10824 }
10825
10826 static int
10827 mav_parse_offset (str, negative)
10828      char ** str;
10829      int *negative;
10830 {
10831   char * p = *str;
10832   int offset;
10833
10834   *negative = 0;
10835
10836   skip_whitespace (p);
10837
10838   if (*p == '#')
10839     ++p;
10840
10841   if (*p == '-')
10842     {
10843       *negative = 1;
10844       ++p;
10845     }
10846
10847   if (!ISDIGIT (*p))
10848     {
10849       inst.error = _("offset expected");
10850       return 0;
10851     }
10852
10853   for (offset = 0; *p && ISDIGIT (*p); ++p)
10854     offset = offset * 10 + *p - '0';
10855
10856   if (offset > 0x3fc)
10857     {
10858       inst.error = _("offset out of range");
10859       return 0;
10860     }
10861   if (offset & 0x3)
10862     {
10863       inst.error = _("offset not a multiple of 4");
10864       return 0;
10865     }
10866
10867   *str = p;
10868
10869   return *negative ? -offset : offset;
10870 }
10871
10872 /* Maverick load/store instructions.
10873   <insn><cond> CRd,[Rn,<offset>]{!}.
10874   <insn><cond> CRd,[Rn],<offset>.  */
10875
10876 static void
10877 do_mav_ldst (str, reg0)
10878      char * str;
10879      enum arm_reg_type reg0;
10880 {
10881   int offset, negative;
10882
10883   skip_whitespace (str);
10884
10885   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10886       || skip_past_comma (&str) == FAIL
10887       || *str++ != '['
10888       || reg_required_here (&str, 16) == FAIL)
10889     goto fail_ldst;
10890
10891   if (skip_past_comma (&str) == SUCCESS)
10892     {
10893       /* You are here: "<offset>]{!}".  */
10894       inst.instruction |= PRE_INDEX;
10895
10896       offset = mav_parse_offset (&str, &negative);
10897
10898       if (inst.error)
10899         return;
10900
10901       if (*str++ != ']')
10902         {
10903           inst.error = _("missing ]");
10904           return;
10905         }
10906
10907       if (*str == '!')
10908         {
10909           inst.instruction |= WRITE_BACK;
10910           ++str;
10911         }
10912     }
10913   else
10914     {
10915       /* You are here: "], <offset>".  */
10916       if (*str++ != ']')
10917         {
10918           inst.error = _("missing ]");
10919           return;
10920         }
10921
10922       if (skip_past_comma (&str) == FAIL
10923           || (offset = mav_parse_offset (&str, &negative), inst.error))
10924         goto fail_ldst;
10925
10926       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10927     }
10928
10929   if (negative)
10930     offset = -offset;
10931   else
10932     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10933
10934   inst.instruction |= offset >> 2;
10935   end_of_line (str);
10936   return;
10937
10938 fail_ldst:
10939   if (!inst.error)
10940      inst.error = BAD_ARGS;
10941 }
10942
10943 static void
10944 do_t_nop (str)
10945      char * str;
10946 {
10947   /* Do nothing.  */
10948   end_of_line (str);
10949 }
10950
10951 /* Handle the Format 4 instructions that do not have equivalents in other
10952    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10953    BIC and MVN.  */
10954
10955 static void
10956 do_t_arit (str)
10957      char * str;
10958 {
10959   int Rd, Rs, Rn;
10960
10961   skip_whitespace (str);
10962
10963   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10964       || skip_past_comma (&str) == FAIL
10965       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10966     {
10967       inst.error = BAD_ARGS;
10968       return;
10969     }
10970
10971   if (skip_past_comma (&str) != FAIL)
10972     {
10973       /* Three operand format not allowed for TST, CMN, NEG and MVN.
10974          (It isn't allowed for CMP either, but that isn't handled by this
10975          function.)  */
10976       if (inst.instruction == T_OPCODE_TST
10977           || inst.instruction == T_OPCODE_CMN
10978           || inst.instruction == T_OPCODE_NEG
10979           || inst.instruction == T_OPCODE_MVN)
10980         {
10981           inst.error = BAD_ARGS;
10982           return;
10983         }
10984
10985       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10986         return;
10987
10988       if (Rs != Rd)
10989         {
10990           inst.error = _("dest and source1 must be the same register");
10991           return;
10992         }
10993       Rs = Rn;
10994     }
10995
10996   if (inst.instruction == T_OPCODE_MUL
10997       && Rs == Rd)
10998     as_tsktsk (_("Rs and Rd must be different in MUL"));
10999
11000   inst.instruction |= Rd | (Rs << 3);
11001   end_of_line (str);
11002 }
11003
11004 static void
11005 do_t_add (str)
11006      char * str;
11007 {
11008   thumb_add_sub (str, 0);
11009 }
11010
11011 static void
11012 do_t_asr (str)
11013      char * str;
11014 {
11015   thumb_shift (str, THUMB_ASR);
11016 }
11017
11018 static void
11019 do_t_branch9 (str)
11020      char * str;
11021 {
11022   if (my_get_expression (&inst.reloc.exp, &str))
11023     return;
11024   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
11025   inst.reloc.pc_rel = 1;
11026   end_of_line (str);
11027 }
11028
11029 static void
11030 do_t_branch12 (str)
11031      char * str;
11032 {
11033   if (my_get_expression (&inst.reloc.exp, &str))
11034     return;
11035   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11036   inst.reloc.pc_rel = 1;
11037   end_of_line (str);
11038 }
11039
11040 /* Find the real, Thumb encoded start of a Thumb function.  */
11041
11042 static symbolS *
11043 find_real_start (symbolP)
11044      symbolS * symbolP;
11045 {
11046   char *       real_start;
11047   const char * name = S_GET_NAME (symbolP);
11048   symbolS *    new_target;
11049
11050   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11051 #define STUB_NAME ".real_start_of"
11052
11053   if (name == NULL)
11054     abort ();
11055
11056   /* Names that start with '.' are local labels, not function entry points.
11057      The compiler may generate BL instructions to these labels because it
11058      needs to perform a branch to a far away location.  */
11059   if (name[0] == '.')
11060     return symbolP;
11061
11062   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11063   sprintf (real_start, "%s%s", STUB_NAME, name);
11064
11065   new_target = symbol_find (real_start);
11066
11067   if (new_target == NULL)
11068     {
11069       as_warn ("Failed to find real start of function: %s\n", name);
11070       new_target = symbolP;
11071     }
11072
11073   free (real_start);
11074
11075   return new_target;
11076 }
11077
11078 static void
11079 do_t_branch23 (str)
11080      char * str;
11081 {
11082   if (my_get_expression (& inst.reloc.exp, & str))
11083     return;
11084
11085   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11086   inst.reloc.pc_rel = 1;
11087   end_of_line (str);
11088
11089   /* If the destination of the branch is a defined symbol which does not have
11090      the THUMB_FUNC attribute, then we must be calling a function which has
11091      the (interfacearm) attribute.  We look for the Thumb entry point to that
11092      function and change the branch to refer to that function instead.  */
11093   if (   inst.reloc.exp.X_op == O_symbol
11094       && inst.reloc.exp.X_add_symbol != NULL
11095       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11096       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11097     inst.reloc.exp.X_add_symbol =
11098       find_real_start (inst.reloc.exp.X_add_symbol);
11099 }
11100
11101 static void
11102 do_t_bx (str)
11103      char * str;
11104 {
11105   int reg;
11106
11107   skip_whitespace (str);
11108
11109   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11110     return;
11111
11112   /* This sets THUMB_H2 from the top bit of reg.  */
11113   inst.instruction |= reg << 3;
11114
11115   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11116      should cause the alignment to be checked once it is known.  This is
11117      because BX PC only works if the instruction is word aligned.  */
11118
11119   end_of_line (str);
11120 }
11121
11122 static void
11123 do_t_compare (str)
11124      char * str;
11125 {
11126   thumb_mov_compare (str, THUMB_COMPARE);
11127 }
11128
11129 static void
11130 do_t_ldmstm (str)
11131      char * str;
11132 {
11133   int Rb;
11134   long range;
11135
11136   skip_whitespace (str);
11137
11138   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11139     return;
11140
11141   if (*str != '!')
11142     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11143   else
11144     str++;
11145
11146   if (skip_past_comma (&str) == FAIL
11147       || (range = reg_list (&str)) == FAIL)
11148     {
11149       if (! inst.error)
11150         inst.error = BAD_ARGS;
11151       return;
11152     }
11153
11154   if (inst.reloc.type != BFD_RELOC_NONE)
11155     {
11156       /* This really doesn't seem worth it.  */
11157       inst.reloc.type = BFD_RELOC_NONE;
11158       inst.error = _("expression too complex");
11159       return;
11160     }
11161
11162   if (range & ~0xff)
11163     {
11164       inst.error = _("only lo-regs valid in load/store multiple");
11165       return;
11166     }
11167
11168   inst.instruction |= (Rb << 8) | range;
11169   end_of_line (str);
11170 }
11171
11172 static void
11173 do_t_ldr (str)
11174      char * str;
11175 {
11176   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11177 }
11178
11179 static void
11180 do_t_ldrb (str)
11181      char * str;
11182 {
11183   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11184 }
11185
11186 static void
11187 do_t_ldrh (str)
11188      char * str;
11189 {
11190   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11191 }
11192
11193 static void
11194 do_t_lds (str)
11195      char * str;
11196 {
11197   int Rd, Rb, Ro;
11198
11199   skip_whitespace (str);
11200
11201   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11202       || skip_past_comma (&str) == FAIL
11203       || *str++ != '['
11204       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11205       || skip_past_comma (&str) == FAIL
11206       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11207       || *str++ != ']')
11208     {
11209       if (! inst.error)
11210         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11211       return;
11212     }
11213
11214   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11215   end_of_line (str);
11216 }
11217
11218 static void
11219 do_t_lsl (str)
11220      char * str;
11221 {
11222   thumb_shift (str, THUMB_LSL);
11223 }
11224
11225 static void
11226 do_t_lsr (str)
11227      char * str;
11228 {
11229   thumb_shift (str, THUMB_LSR);
11230 }
11231
11232 static void
11233 do_t_mov (str)
11234      char * str;
11235 {
11236   thumb_mov_compare (str, THUMB_MOVE);
11237 }
11238
11239 static void
11240 do_t_push_pop (str)
11241      char * str;
11242 {
11243   long range;
11244
11245   skip_whitespace (str);
11246
11247   if ((range = reg_list (&str)) == FAIL)
11248     {
11249       if (! inst.error)
11250         inst.error = BAD_ARGS;
11251       return;
11252     }
11253
11254   if (inst.reloc.type != BFD_RELOC_NONE)
11255     {
11256       /* This really doesn't seem worth it.  */
11257       inst.reloc.type = BFD_RELOC_NONE;
11258       inst.error = _("expression too complex");
11259       return;
11260     }
11261
11262   if (range & ~0xff)
11263     {
11264       if ((inst.instruction == T_OPCODE_PUSH
11265            && (range & ~0xff) == 1 << REG_LR)
11266           || (inst.instruction == T_OPCODE_POP
11267               && (range & ~0xff) == 1 << REG_PC))
11268         {
11269           inst.instruction |= THUMB_PP_PC_LR;
11270           range &= 0xff;
11271         }
11272       else
11273         {
11274           inst.error = _("invalid register list to push/pop instruction");
11275           return;
11276         }
11277     }
11278
11279   inst.instruction |= range;
11280   end_of_line (str);
11281 }
11282
11283 static void
11284 do_t_str (str)
11285      char * str;
11286 {
11287   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11288 }
11289
11290 static void
11291 do_t_strb (str)
11292      char * str;
11293 {
11294   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11295 }
11296
11297 static void
11298 do_t_strh (str)
11299      char * str;
11300 {
11301   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11302 }
11303
11304 static void
11305 do_t_sub (str)
11306      char * str;
11307 {
11308   thumb_add_sub (str, 1);
11309 }
11310
11311 static void
11312 do_t_swi (str)
11313      char * str;
11314 {
11315   skip_whitespace (str);
11316
11317   if (my_get_expression (&inst.reloc.exp, &str))
11318     return;
11319
11320   inst.reloc.type = BFD_RELOC_ARM_SWI;
11321   end_of_line (str);
11322 }
11323
11324 static void
11325 do_t_adr (str)
11326      char * str;
11327 {
11328   int reg;
11329
11330   /* This is a pseudo-op of the form "adr rd, label" to be converted
11331      into a relative address of the form "add rd, pc, #label-.-4".  */
11332   skip_whitespace (str);
11333
11334   /* Store Rd in temporary location inside instruction.  */
11335   if ((reg = reg_required_here (&str, 4)) == FAIL
11336       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11337       || skip_past_comma (&str) == FAIL
11338       || my_get_expression (&inst.reloc.exp, &str))
11339     {
11340       if (!inst.error)
11341         inst.error = BAD_ARGS;
11342       return;
11343     }
11344
11345   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11346   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11347   inst.reloc.pc_rel = 1;
11348   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11349
11350   end_of_line (str);
11351 }
11352
11353 static void
11354 insert_reg (r, htab)
11355      const struct reg_entry *r;
11356      struct hash_control *htab;
11357 {
11358   int    len  = strlen (r->name) + 2;
11359   char * buf  = (char *) xmalloc (len);
11360   char * buf2 = (char *) xmalloc (len);
11361   int    i    = 0;
11362
11363 #ifdef REGISTER_PREFIX
11364   buf[i++] = REGISTER_PREFIX;
11365 #endif
11366
11367   strcpy (buf + i, r->name);
11368
11369   for (i = 0; buf[i]; i++)
11370     buf2[i] = TOUPPER (buf[i]);
11371
11372   buf2[i] = '\0';
11373
11374   hash_insert (htab, buf,  (PTR) r);
11375   hash_insert (htab, buf2, (PTR) r);
11376 }
11377
11378 static void
11379 build_reg_hsh (map)
11380      struct reg_map *map;
11381 {
11382   const struct reg_entry *r;
11383
11384   if ((map->htab = hash_new ()) == NULL)
11385     as_fatal (_("virtual memory exhausted"));
11386
11387   for (r = map->names; r->name != NULL; r++)
11388     insert_reg (r, map->htab);
11389 }
11390
11391 static void
11392 insert_reg_alias (str, regnum, htab)
11393      char *str;
11394      int regnum;
11395      struct hash_control *htab;
11396 {
11397   const char *error;
11398   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11399   const char *name = xmalloc (strlen (str) + 1);
11400   
11401   strcpy ((char *) name, str);
11402   
11403   new->name = name;
11404   new->number = regnum;
11405   new->builtin = FALSE;
11406
11407   error = hash_insert (htab, name, (PTR) new);
11408   if (error)
11409     {
11410       as_bad (_("failed to create an alias for %s, reason: %s"),
11411             str, error);
11412       free ((char *) name);
11413       free (new);
11414     }
11415 }
11416
11417 /* Look for the .req directive.  This is of the form:
11418
11419         new_register_name .req existing_register_name
11420
11421    If we find one, or if it looks sufficiently like one that we want to
11422    handle any error here, return non-zero.  Otherwise return zero.  */
11423 static int
11424 create_register_alias (newname, p)
11425      char *newname;
11426      char *p;
11427 {
11428   char *q;
11429   char c;
11430
11431   q = p;
11432   skip_whitespace (q);
11433
11434   c = *p;
11435   *p = '\0';
11436
11437   if (*q && !strncmp (q, ".req ", 5))
11438     {
11439       char *copy_of_str;
11440       char *r;
11441
11442 #ifndef IGNORE_OPCODE_CASE
11443       newname = original_case_string;
11444 #endif
11445       copy_of_str = newname;
11446
11447       q += 4;
11448       skip_whitespace (q);
11449
11450       for (r = q; *r != '\0'; r++)
11451         if (*r == ' ')
11452           break;
11453
11454       if (r != q)
11455         {
11456           enum arm_reg_type new_type, old_type;
11457           int old_regno;
11458           char d = *r;
11459
11460           *r = '\0';
11461           old_type = arm_reg_parse_any (q);
11462           *r = d;
11463
11464           new_type = arm_reg_parse_any (newname);
11465
11466           if (new_type == REG_TYPE_MAX)
11467             {
11468               if (old_type != REG_TYPE_MAX)
11469                 {
11470                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11471                   insert_reg_alias (newname, old_regno,
11472                                     all_reg_maps[old_type].htab);
11473                 }
11474               else
11475                 as_warn (_("register '%s' does not exist\n"), q);
11476             }
11477           else if (old_type == REG_TYPE_MAX)
11478             {
11479               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11480                        copy_of_str, q);
11481             }
11482           else
11483             {
11484               /* Do not warn about redefinitions to the same alias.  */
11485               if (new_type != old_type
11486                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11487                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11488                 as_warn (_("ignoring redefinition of register alias '%s'"),
11489                          copy_of_str);
11490
11491             }
11492         }
11493       else
11494         as_warn (_("ignoring incomplete .req pseuso op"));
11495
11496       *p = c;
11497       return 1;
11498     }
11499   
11500   *p = c;
11501   return 0;
11502 }
11503
11504 static void
11505 set_constant_flonums ()
11506 {
11507   int i;
11508
11509   for (i = 0; i < NUM_FLOAT_VALS; i++)
11510     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11511       abort ();
11512 }
11513
11514 /* Iterate over the base tables to create the instruction patterns.  */
11515 static void
11516 build_arm_ops_hsh ()
11517 {
11518   unsigned int i;
11519   unsigned int j;
11520   static struct obstack insn_obstack;
11521
11522   obstack_begin (&insn_obstack, 4000);
11523
11524   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11525     {
11526       const struct asm_opcode *insn = insns + i;
11527
11528       if (insn->cond_offset != 0)
11529         {
11530           /* Insn supports conditional execution.  Build the varaints
11531              and insert them in the hash table.  */
11532           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11533             {
11534               unsigned len = strlen (insn->template);
11535               struct asm_opcode *new;
11536               char *template;
11537
11538               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11539               /* All condition codes are two characters.  */
11540               template = obstack_alloc (&insn_obstack, len + 3);
11541
11542               strncpy (template, insn->template, insn->cond_offset);
11543               strcpy (template + insn->cond_offset, conds[j].template);
11544               if (len > insn->cond_offset)
11545                 strcpy (template + insn->cond_offset + 2,
11546                         insn->template + insn->cond_offset);
11547               new->template = template;
11548               new->cond_offset = 0;
11549               new->variant = insn->variant;
11550               new->parms = insn->parms;
11551               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11552
11553               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11554             }
11555         }
11556       /* Finally, insert the unconditional insn in the table directly;
11557          no need to build a copy.  */
11558       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11559     }
11560 }
11561
11562 #if 0 /* Suppressed - for now.  */
11563 #if defined OBJ_ELF || defined OBJ_COFF
11564
11565 #ifdef OBJ_ELF
11566 #define arm_Note Elf_External_Note
11567 #else
11568 typedef struct
11569 {
11570   unsigned char namesz[4];      /* Size of entry's owner string.  */
11571   unsigned char descsz[4];      /* Size of the note descriptor.  */
11572   unsigned char type[4];        /* Interpretation of the descriptor.  */
11573   char          name[1];        /* Start of the name+desc data.  */
11574 } arm_Note;
11575 #endif
11576
11577 /* The description is kept to a fix sized in order to make updating
11578    it and merging it easier.  */
11579 #define ARM_NOTE_DESCRIPTION_LENGTH     8
11580
11581 static void
11582 arm_add_note (name, description, type)
11583      const char * name;
11584      const char * description;
11585      unsigned int type;
11586 {
11587   arm_Note     note ATTRIBUTE_UNUSED;
11588   char *       p;
11589   unsigned int name_len;
11590
11591   name_len = (strlen (name) + 1 + 3) & ~3;
11592   
11593   p = frag_more (sizeof (note.namesz));
11594   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11595
11596   p = frag_more (sizeof (note.descsz));
11597   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11598
11599   p = frag_more (sizeof (note.type));
11600   md_number_to_chars (p, (valueT) type, sizeof (note.type));
11601
11602   p = frag_more (name_len);
11603   strcpy (p, name);
11604
11605   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11606   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11607   frag_align (2, 0, 0);
11608 }
11609 #endif
11610 #endif
11611
11612 void
11613 md_begin ()
11614 {
11615   unsigned mach;
11616   unsigned int i;
11617
11618   if (   (arm_ops_hsh = hash_new ()) == NULL
11619       || (arm_tops_hsh = hash_new ()) == NULL
11620       || (arm_cond_hsh = hash_new ()) == NULL
11621       || (arm_shift_hsh = hash_new ()) == NULL
11622       || (arm_psr_hsh = hash_new ()) == NULL)
11623     as_fatal (_("virtual memory exhausted"));
11624
11625   build_arm_ops_hsh ();
11626   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11627     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11628   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11629     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11630   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11631     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11632   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11633     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11634
11635   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11636     build_reg_hsh (all_reg_maps + i);
11637
11638   set_constant_flonums ();
11639
11640   /* Set the cpu variant based on the command-line options.  We prefer
11641      -mcpu= over -march= if both are set (as for GCC); and we prefer
11642      -mfpu= over any other way of setting the floating point unit.
11643      Use of legacy options with new options are faulted.  */
11644   if (legacy_cpu != -1)
11645     {
11646       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11647         as_bad (_("use of old and new-style options to set CPU type"));
11648
11649       mcpu_cpu_opt = legacy_cpu;
11650     }
11651   else if (mcpu_cpu_opt == -1)
11652     mcpu_cpu_opt = march_cpu_opt;
11653
11654   if (legacy_fpu != -1)
11655     {
11656       if (mfpu_opt != -1)
11657         as_bad (_("use of old and new-style options to set FPU type"));
11658
11659       mfpu_opt = legacy_fpu;
11660     }
11661   else if (mfpu_opt == -1)
11662     {
11663 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11664       /* Some environments specify a default FPU.  If they don't, infer it
11665          from the processor.  */
11666       if (mcpu_fpu_opt != -1)
11667         mfpu_opt = mcpu_fpu_opt;
11668       else
11669         mfpu_opt = march_fpu_opt;
11670 #else
11671       mfpu_opt = FPU_DEFAULT;
11672 #endif
11673     }
11674
11675   if (mfpu_opt == -1)
11676     {
11677       if (mcpu_cpu_opt == -1)
11678         mfpu_opt = FPU_DEFAULT;
11679       else if (mcpu_cpu_opt & ARM_EXT_V5)
11680         mfpu_opt = FPU_ARCH_VFP_V2;
11681       else
11682         mfpu_opt = FPU_ARCH_FPA;
11683     }
11684
11685   if (mcpu_cpu_opt == -1)
11686     mcpu_cpu_opt = CPU_DEFAULT;
11687
11688   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11689
11690   {
11691     unsigned int flags = 0;
11692
11693 #if defined OBJ_ELF
11694     flags = meabi_flags;
11695
11696     switch (meabi_flags)
11697       {
11698       case EF_ARM_EABI_UNKNOWN:
11699 #endif
11700 #if defined OBJ_COFF || defined OBJ_ELF
11701         /* Set the flags in the private structure.  */
11702         if (uses_apcs_26)      flags |= F_APCS26;
11703         if (support_interwork) flags |= F_INTERWORK;
11704         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11705         if (pic_code)          flags |= F_PIC;
11706         if ((cpu_variant & FPU_ANY) == FPU_NONE
11707              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11708           flags |= F_SOFT_FLOAT;
11709
11710         switch (mfloat_abi_opt)
11711           {
11712           case ARM_FLOAT_ABI_SOFT:
11713           case ARM_FLOAT_ABI_SOFTFP:
11714             flags |= F_SOFT_FLOAT;
11715             break;
11716
11717           case ARM_FLOAT_ABI_HARD:
11718             if (flags & F_SOFT_FLOAT)
11719               as_bad (_("hard-float conflicts with specified fpu"));
11720             break;
11721           }
11722
11723         /* Using VFP conventions (even if soft-float).  */
11724         if (cpu_variant & FPU_VFP_EXT_NONE)
11725           flags |= F_VFP_FLOAT;
11726 #endif
11727 #if defined OBJ_ELF
11728         if (cpu_variant & FPU_ARCH_MAVERICK)
11729             flags |= EF_ARM_MAVERICK_FLOAT;
11730         break;
11731
11732       case EF_ARM_EABI_VER3:
11733         /* No additional flags to set.  */
11734         break;
11735
11736       default:
11737         abort ();
11738       }
11739 #endif
11740 #if defined OBJ_COFF || defined OBJ_ELF
11741     bfd_set_private_flags (stdoutput, flags);
11742
11743     /* We have run out flags in the COFF header to encode the
11744        status of ATPCS support, so instead we create a dummy,
11745        empty, debug section called .arm.atpcs.  */
11746     if (atpcs)
11747       {
11748         asection * sec;
11749
11750         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11751
11752         if (sec != NULL)
11753           {
11754             bfd_set_section_flags
11755               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11756             bfd_set_section_size (stdoutput, sec, 0);
11757             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11758           }
11759       }
11760 #endif
11761   }
11762
11763   /* Record the CPU type as well.  */
11764   switch (cpu_variant & ARM_CPU_MASK)
11765     {
11766     case ARM_2:
11767       mach = bfd_mach_arm_2;
11768       break;
11769
11770     case ARM_3:                 /* Also ARM_250.  */
11771       mach = bfd_mach_arm_2a;
11772       break;
11773
11774     case ARM_6:                 /* Also ARM_7.  */
11775       mach = bfd_mach_arm_3;
11776       break;
11777
11778     default:
11779       mach = bfd_mach_arm_unknown;
11780       break;
11781     }
11782
11783   /* Catch special cases.  */
11784   if (cpu_variant & ARM_CEXT_IWMMXT)
11785     mach = bfd_mach_arm_iWMMXt;
11786   else if (cpu_variant & ARM_CEXT_XSCALE)
11787     mach = bfd_mach_arm_XScale;
11788   else if (cpu_variant & ARM_CEXT_MAVERICK)
11789     mach = bfd_mach_arm_ep9312;
11790   else if (cpu_variant & ARM_EXT_V5E)
11791     mach = bfd_mach_arm_5TE;
11792   else if (cpu_variant & ARM_EXT_V5)
11793     {
11794       if (cpu_variant & ARM_EXT_V4T)
11795         mach = bfd_mach_arm_5T;
11796       else
11797         mach = bfd_mach_arm_5;
11798     }
11799   else if (cpu_variant & ARM_EXT_V4)
11800     {
11801       if (cpu_variant & ARM_EXT_V4T)
11802         mach = bfd_mach_arm_4T;
11803       else
11804         mach = bfd_mach_arm_4;
11805     }
11806   else if (cpu_variant & ARM_EXT_V3M)
11807     mach = bfd_mach_arm_3M;
11808
11809 #if 0 /* Suppressed - for now.  */
11810 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11811
11812   /* Create a .note section to fully identify this arm binary.  */
11813
11814 #define NOTE_ARCH_STRING        "arch: "
11815
11816 #if defined OBJ_COFF && ! defined NT_VERSION
11817 #define NT_VERSION  1
11818 #define NT_ARCH     2
11819 #endif
11820   
11821   {
11822     segT current_seg = now_seg;
11823     subsegT current_subseg = now_subseg;
11824     asection * arm_arch;
11825     const char * arch_string;
11826
11827     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11828
11829 #ifdef OBJ_COFF
11830     bfd_set_section_flags (stdoutput, arm_arch,
11831                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11832                            | SEC_HAS_CONTENTS);
11833 #else
11834     bfd_set_section_flags (stdoutput, arm_arch,
11835                            SEC_READONLY | SEC_HAS_CONTENTS);
11836 #endif
11837     arm_arch->output_section = arm_arch;
11838     subseg_set (arm_arch, 0);
11839
11840     switch (mach)
11841       {
11842       default:
11843       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11844       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11845       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11846       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11847       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11848       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11849       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11850       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11851       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11852       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11853       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11854       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11855       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break; 
11856       }
11857
11858     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11859
11860     subseg_set (current_seg, current_subseg);
11861   }
11862 #endif
11863 #endif /* Suppressed code.  */
11864   
11865   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11866 }
11867
11868 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11869    for use in the a.out file, and stores them in the array pointed to by buf.
11870    This knows about the endian-ness of the target machine and does
11871    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11872    2 (short) and 4 (long)  Floating numbers are put out as a series of
11873    LITTLENUMS (shorts, here at least).  */
11874
11875 void
11876 md_number_to_chars (buf, val, n)
11877      char * buf;
11878      valueT val;
11879      int    n;
11880 {
11881   if (target_big_endian)
11882     number_to_chars_bigendian (buf, val, n);
11883   else
11884     number_to_chars_littleendian (buf, val, n);
11885 }
11886
11887 static valueT
11888 md_chars_to_number (buf, n)
11889      char * buf;
11890      int    n;
11891 {
11892   valueT result = 0;
11893   unsigned char * where = (unsigned char *) buf;
11894
11895   if (target_big_endian)
11896     {
11897       while (n--)
11898         {
11899           result <<= 8;
11900           result |= (*where++ & 255);
11901         }
11902     }
11903   else
11904     {
11905       while (n--)
11906         {
11907           result <<= 8;
11908           result |= (where[n] & 255);
11909         }
11910     }
11911
11912   return result;
11913 }
11914
11915 /* Turn a string in input_line_pointer into a floating point constant
11916    of type TYPE, and store the appropriate bytes in *LITP.  The number
11917    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11918    returned, or NULL on OK.
11919
11920    Note that fp constants aren't represent in the normal way on the ARM.
11921    In big endian mode, things are as expected.  However, in little endian
11922    mode fp constants are big-endian word-wise, and little-endian byte-wise
11923    within the words.  For example, (double) 1.1 in big endian mode is
11924    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11925    the byte sequence 99 99 f1 3f 9a 99 99 99.
11926
11927    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11928
11929 char *
11930 md_atof (type, litP, sizeP)
11931      char   type;
11932      char * litP;
11933      int *  sizeP;
11934 {
11935   int prec;
11936   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11937   char *t;
11938   int i;
11939
11940   switch (type)
11941     {
11942     case 'f':
11943     case 'F':
11944     case 's':
11945     case 'S':
11946       prec = 2;
11947       break;
11948
11949     case 'd':
11950     case 'D':
11951     case 'r':
11952     case 'R':
11953       prec = 4;
11954       break;
11955
11956     case 'x':
11957     case 'X':
11958       prec = 6;
11959       break;
11960
11961     case 'p':
11962     case 'P':
11963       prec = 6;
11964       break;
11965
11966     default:
11967       *sizeP = 0;
11968       return _("bad call to MD_ATOF()");
11969     }
11970
11971   t = atof_ieee (input_line_pointer, type, words);
11972   if (t)
11973     input_line_pointer = t;
11974   *sizeP = prec * 2;
11975
11976   if (target_big_endian)
11977     {
11978       for (i = 0; i < prec; i++)
11979         {
11980           md_number_to_chars (litP, (valueT) words[i], 2);
11981           litP += 2;
11982         }
11983     }
11984   else
11985     {
11986       if (cpu_variant & FPU_ARCH_VFP)
11987         for (i = prec - 1; i >= 0; i--)
11988           {
11989             md_number_to_chars (litP, (valueT) words[i], 2);
11990             litP += 2;
11991           }
11992       else
11993         /* For a 4 byte float the order of elements in `words' is 1 0.
11994            For an 8 byte float the order is 1 0 3 2.  */
11995         for (i = 0; i < prec; i += 2)
11996           {
11997             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11998             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11999             litP += 4;
12000           }
12001     }
12002
12003   return 0;
12004 }
12005
12006 /* The knowledge of the PC's pipeline offset is built into the insns
12007    themselves.  */
12008
12009 long
12010 md_pcrel_from (fixP)
12011      fixS * fixP;
12012 {
12013   if (fixP->fx_addsy
12014       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
12015       && fixP->fx_subsy == NULL)
12016     return 0;
12017
12018   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
12019     {
12020       /* PC relative addressing on the Thumb is slightly odd
12021          as the bottom two bits of the PC are forced to zero
12022          for the calculation.  */
12023       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
12024     }
12025
12026 #ifdef TE_WINCE
12027   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12028      so we un-adjust here to compensate for the accommodation.  */
12029   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
12030 #else
12031   return fixP->fx_where + fixP->fx_frag->fr_address;
12032 #endif
12033 }
12034
12035 /* Round up a section size to the appropriate boundary.  */
12036
12037 valueT
12038 md_section_align (segment, size)
12039      segT   segment ATTRIBUTE_UNUSED;
12040      valueT size;
12041 {
12042 #ifdef OBJ_ELF
12043   return size;
12044 #else
12045   /* Round all sects to multiple of 4.  */
12046   return (size + 3) & ~3;
12047 #endif
12048 }
12049
12050 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12051    Otherwise we have no need to default values of symbols.  */
12052
12053 symbolS *
12054 md_undefined_symbol (name)
12055      char * name ATTRIBUTE_UNUSED;
12056 {
12057 #ifdef OBJ_ELF
12058   if (name[0] == '_' && name[1] == 'G'
12059       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12060     {
12061       if (!GOT_symbol)
12062         {
12063           if (symbol_find (name))
12064             as_bad ("GOT already in the symbol table");
12065
12066           GOT_symbol = symbol_new (name, undefined_section,
12067                                    (valueT) 0, & zero_address_frag);
12068         }
12069
12070       return GOT_symbol;
12071     }
12072 #endif
12073
12074   return 0;
12075 }
12076
12077 /* arm_reg_parse () := if it looks like a register, return its token and
12078    advance the pointer.  */
12079
12080 static int
12081 arm_reg_parse (ccp, htab)
12082      register char ** ccp;
12083      struct hash_control *htab;
12084 {
12085   char * start = * ccp;
12086   char   c;
12087   char * p;
12088   struct reg_entry * reg;
12089
12090 #ifdef REGISTER_PREFIX
12091   if (*start != REGISTER_PREFIX)
12092     return FAIL;
12093   p = start + 1;
12094 #else
12095   p = start;
12096 #ifdef OPTIONAL_REGISTER_PREFIX
12097   if (*p == OPTIONAL_REGISTER_PREFIX)
12098     p++, start++;
12099 #endif
12100 #endif
12101   if (!ISALPHA (*p) || !is_name_beginner (*p))
12102     return FAIL;
12103
12104   c = *p++;
12105   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12106     c = *p++;
12107
12108   *--p = 0;
12109   reg = (struct reg_entry *) hash_find (htab, start);
12110   *p = c;
12111
12112   if (reg)
12113     {
12114       *ccp = p;
12115       return reg->number;
12116     }
12117
12118   return FAIL;
12119 }
12120
12121 /* Search for the following register name in each of the possible reg name
12122    tables.  Return the classification if found, or REG_TYPE_MAX if not
12123    present.  */
12124 static enum arm_reg_type
12125 arm_reg_parse_any (cp)
12126      char *cp;
12127 {
12128   int i;
12129
12130   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12131     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12132       return (enum arm_reg_type) i;
12133
12134   return REG_TYPE_MAX;
12135 }
12136
12137 void
12138 md_apply_fix3 (fixP, valP, seg)
12139      fixS *   fixP;
12140      valueT * valP;
12141      segT     seg;
12142 {
12143   offsetT        value = * valP;
12144   offsetT        newval;
12145   unsigned int   newimm;
12146   unsigned long  temp;
12147   int            sign;
12148   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12149   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12150
12151   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12152
12153   /* Note whether this will delete the relocation.  */
12154 #if 0
12155   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12156      doesn't work fully.)  */
12157   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12158       && !fixP->fx_pcrel)
12159 #else
12160   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12161 #endif
12162     fixP->fx_done = 1;
12163
12164   /* If this symbol is in a different section then we need to leave it for
12165      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12166      so we have to undo it's effects here.  */
12167   if (fixP->fx_pcrel)
12168     {
12169       if (fixP->fx_addsy != NULL
12170           && S_IS_DEFINED (fixP->fx_addsy)
12171           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12172         {
12173           if (target_oabi
12174               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12175                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12176                   ))
12177             value = 0;
12178           else
12179             value += md_pcrel_from (fixP);
12180         }
12181     }
12182
12183   /* Remember value for emit_reloc.  */
12184   fixP->fx_addnumber = value;
12185
12186   switch (fixP->fx_r_type)
12187     {
12188     case BFD_RELOC_ARM_IMMEDIATE:
12189       newimm = validate_immediate (value);
12190       temp = md_chars_to_number (buf, INSN_SIZE);
12191
12192       /* If the instruction will fail, see if we can fix things up by
12193          changing the opcode.  */
12194       if (newimm == (unsigned int) FAIL
12195           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12196         {
12197           as_bad_where (fixP->fx_file, fixP->fx_line,
12198                         _("invalid constant (%lx) after fixup"),
12199                         (unsigned long) value);
12200           break;
12201         }
12202
12203       newimm |= (temp & 0xfffff000);
12204       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12205       fixP->fx_done = 1;
12206       break;
12207
12208     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12209       {
12210         unsigned int highpart = 0;
12211         unsigned int newinsn  = 0xe1a00000; /* nop.  */
12212
12213         newimm = validate_immediate (value);
12214         temp = md_chars_to_number (buf, INSN_SIZE);
12215
12216         /* If the instruction will fail, see if we can fix things up by
12217            changing the opcode.  */
12218         if (newimm == (unsigned int) FAIL
12219             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12220           {
12221             /* No ?  OK - try using two ADD instructions to generate
12222                the value.  */
12223             newimm = validate_immediate_twopart (value, & highpart);
12224
12225             /* Yes - then make sure that the second instruction is
12226                also an add.  */
12227             if (newimm != (unsigned int) FAIL)
12228               newinsn = temp;
12229             /* Still No ?  Try using a negated value.  */
12230             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12231               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12232             /* Otherwise - give up.  */
12233             else
12234               {
12235                 as_bad_where (fixP->fx_file, fixP->fx_line,
12236                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12237                               (long) value);
12238                 break;
12239               }
12240
12241             /* Replace the first operand in the 2nd instruction (which
12242                is the PC) with the destination register.  We have
12243                already added in the PC in the first instruction and we
12244                do not want to do it again.  */
12245             newinsn &= ~ 0xf0000;
12246             newinsn |= ((newinsn & 0x0f000) << 4);
12247           }
12248
12249         newimm |= (temp & 0xfffff000);
12250         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12251
12252         highpart |= (newinsn & 0xfffff000);
12253         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12254       }
12255       break;
12256
12257     case BFD_RELOC_ARM_OFFSET_IMM:
12258       sign = value >= 0;
12259
12260       if (value < 0)
12261         value = - value;
12262
12263       if (validate_offset_imm (value, 0) == FAIL)
12264         {
12265           as_bad_where (fixP->fx_file, fixP->fx_line,
12266                         _("bad immediate value for offset (%ld)"),
12267                         (long) value);
12268           break;
12269         }
12270
12271       newval = md_chars_to_number (buf, INSN_SIZE);
12272       newval &= 0xff7ff000;
12273       newval |= value | (sign ? INDEX_UP : 0);
12274       md_number_to_chars (buf, newval, INSN_SIZE);
12275       break;
12276
12277     case BFD_RELOC_ARM_OFFSET_IMM8:
12278     case BFD_RELOC_ARM_HWLITERAL:
12279       sign = value >= 0;
12280
12281       if (value < 0)
12282         value = - value;
12283
12284       if (validate_offset_imm (value, 1) == FAIL)
12285         {
12286           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12287             as_bad_where (fixP->fx_file, fixP->fx_line,
12288                           _("invalid literal constant: pool needs to be closer"));
12289           else
12290             as_bad (_("bad immediate value for half-word offset (%ld)"),
12291                     (long) value);
12292           break;
12293         }
12294
12295       newval = md_chars_to_number (buf, INSN_SIZE);
12296       newval &= 0xff7ff0f0;
12297       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12298       md_number_to_chars (buf, newval, INSN_SIZE);
12299       break;
12300
12301     case BFD_RELOC_ARM_LITERAL:
12302       sign = value >= 0;
12303
12304       if (value < 0)
12305         value = - value;
12306
12307       if (validate_offset_imm (value, 0) == FAIL)
12308         {
12309           as_bad_where (fixP->fx_file, fixP->fx_line,
12310                         _("invalid literal constant: pool needs to be closer"));
12311           break;
12312         }
12313
12314       newval = md_chars_to_number (buf, INSN_SIZE);
12315       newval &= 0xff7ff000;
12316       newval |= value | (sign ? INDEX_UP : 0);
12317       md_number_to_chars (buf, newval, INSN_SIZE);
12318       break;
12319
12320     case BFD_RELOC_ARM_SHIFT_IMM:
12321       newval = md_chars_to_number (buf, INSN_SIZE);
12322       if (((unsigned long) value) > 32
12323           || (value == 32
12324               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12325         {
12326           as_bad_where (fixP->fx_file, fixP->fx_line,
12327                         _("shift expression is too large"));
12328           break;
12329         }
12330
12331       if (value == 0)
12332         /* Shifts of zero must be done as lsl.  */
12333         newval &= ~0x60;
12334       else if (value == 32)
12335         value = 0;
12336       newval &= 0xfffff07f;
12337       newval |= (value & 0x1f) << 7;
12338       md_number_to_chars (buf, newval, INSN_SIZE);
12339       break;
12340
12341     case BFD_RELOC_ARM_SWI:
12342       if (arm_data->thumb_mode)
12343         {
12344           if (((unsigned long) value) > 0xff)
12345             as_bad_where (fixP->fx_file, fixP->fx_line,
12346                           _("invalid swi expression"));
12347           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12348           newval |= value;
12349           md_number_to_chars (buf, newval, THUMB_SIZE);
12350         }
12351       else
12352         {
12353           if (((unsigned long) value) > 0x00ffffff)
12354             as_bad_where (fixP->fx_file, fixP->fx_line,
12355                           _("invalid swi expression"));
12356           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12357           newval |= value;
12358           md_number_to_chars (buf, newval, INSN_SIZE);
12359         }
12360       break;
12361
12362     case BFD_RELOC_ARM_MULTI:
12363       if (((unsigned long) value) > 0xffff)
12364         as_bad_where (fixP->fx_file, fixP->fx_line,
12365                       _("invalid expression in load/store multiple"));
12366       newval = value | md_chars_to_number (buf, INSN_SIZE);
12367       md_number_to_chars (buf, newval, INSN_SIZE);
12368       break;
12369
12370     case BFD_RELOC_ARM_PCREL_BRANCH:
12371       newval = md_chars_to_number (buf, INSN_SIZE);
12372
12373       /* Sign-extend a 24-bit number.  */
12374 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12375
12376 #ifdef OBJ_ELF
12377       if (! target_oabi)
12378         value = fixP->fx_offset;
12379 #endif
12380
12381       /* We are going to store value (shifted right by two) in the
12382          instruction, in a 24 bit, signed field.  Thus we need to check
12383          that none of the top 8 bits of the shifted value (top 7 bits of
12384          the unshifted, unsigned value) are set, or that they are all set.  */
12385       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12386           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12387         {
12388 #ifdef OBJ_ELF
12389           /* Normally we would be stuck at this point, since we cannot store
12390              the absolute address that is the destination of the branch in the
12391              24 bits of the branch instruction.  If however, we happen to know
12392              that the destination of the branch is in the same section as the
12393              branch instruction itself, then we can compute the relocation for
12394              ourselves and not have to bother the linker with it.
12395
12396              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12397              because I have not worked out how to do this for OBJ_COFF or
12398              target_oabi.  */
12399           if (! target_oabi
12400               && fixP->fx_addsy != NULL
12401               && S_IS_DEFINED (fixP->fx_addsy)
12402               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12403             {
12404               /* Get pc relative value to go into the branch.  */
12405               value = * valP;
12406
12407               /* Permit a backward branch provided that enough bits
12408                  are set.  Allow a forwards branch, provided that
12409                  enough bits are clear.  */
12410               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12411                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12412                 fixP->fx_done = 1;
12413             }
12414
12415           if (! fixP->fx_done)
12416 #endif
12417             as_bad_where (fixP->fx_file, fixP->fx_line,
12418                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12419         }
12420
12421       value >>= 2;
12422       value += SEXT24 (newval);
12423
12424       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12425           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12426         as_bad_where (fixP->fx_file, fixP->fx_line,
12427                       _("out of range branch"));
12428
12429       newval = (value & 0x00ffffff) | (newval & 0xff000000);
12430       md_number_to_chars (buf, newval, INSN_SIZE);
12431       break;
12432
12433     case BFD_RELOC_ARM_PCREL_BLX:
12434       {
12435         offsetT hbit;
12436         newval = md_chars_to_number (buf, INSN_SIZE);
12437
12438 #ifdef OBJ_ELF
12439         if (! target_oabi)
12440           value = fixP->fx_offset;
12441 #endif
12442         hbit   = (value >> 1) & 1;
12443         value  = (value >> 2) & 0x00ffffff;
12444         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12445         newval = value | (newval & 0xfe000000) | (hbit << 24);
12446         md_number_to_chars (buf, newval, INSN_SIZE);
12447       }
12448       break;
12449
12450     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12451       newval = md_chars_to_number (buf, THUMB_SIZE);
12452       {
12453         addressT diff = (newval & 0xff) << 1;
12454         if (diff & 0x100)
12455           diff |= ~0xff;
12456
12457         value += diff;
12458         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12459           as_bad_where (fixP->fx_file, fixP->fx_line,
12460                         _("branch out of range"));
12461         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12462       }
12463       md_number_to_chars (buf, newval, THUMB_SIZE);
12464       break;
12465
12466     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12467       newval = md_chars_to_number (buf, THUMB_SIZE);
12468       {
12469         addressT diff = (newval & 0x7ff) << 1;
12470         if (diff & 0x800)
12471           diff |= ~0x7ff;
12472
12473         value += diff;
12474         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12475           as_bad_where (fixP->fx_file, fixP->fx_line,
12476                         _("branch out of range"));
12477         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12478       }
12479       md_number_to_chars (buf, newval, THUMB_SIZE);
12480       break;
12481
12482     case BFD_RELOC_THUMB_PCREL_BLX:
12483     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12484       {
12485         offsetT newval2;
12486         addressT diff;
12487
12488         newval  = md_chars_to_number (buf, THUMB_SIZE);
12489         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12490         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12491         if (diff & 0x400000)
12492           diff |= ~0x3fffff;
12493 #ifdef OBJ_ELF
12494         value = fixP->fx_offset;
12495 #endif
12496         value += diff;
12497
12498         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12499           as_bad_where (fixP->fx_file, fixP->fx_line,
12500                         _("branch with link out of range"));
12501
12502         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12503         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12504         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12505           /* For a BLX instruction, make sure that the relocation is rounded up
12506              to a word boundary.  This follows the semantics of the instruction
12507              which specifies that bit 1 of the target address will come from bit
12508              1 of the base address.  */
12509           newval2 = (newval2 + 1) & ~ 1;
12510         md_number_to_chars (buf, newval, THUMB_SIZE);
12511         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12512       }
12513       break;
12514
12515     case BFD_RELOC_8:
12516       if (fixP->fx_done || fixP->fx_pcrel)
12517         md_number_to_chars (buf, value, 1);
12518 #ifdef OBJ_ELF
12519       else if (!target_oabi)
12520         {
12521           value = fixP->fx_offset;
12522           md_number_to_chars (buf, value, 1);
12523         }
12524 #endif
12525       break;
12526
12527     case BFD_RELOC_16:
12528       if (fixP->fx_done || fixP->fx_pcrel)
12529         md_number_to_chars (buf, value, 2);
12530 #ifdef OBJ_ELF
12531       else if (!target_oabi)
12532         {
12533           value = fixP->fx_offset;
12534           md_number_to_chars (buf, value, 2);
12535         }
12536 #endif
12537       break;
12538
12539 #ifdef OBJ_ELF
12540     case BFD_RELOC_ARM_GOT32:
12541     case BFD_RELOC_ARM_GOTOFF:
12542       md_number_to_chars (buf, 0, 4);
12543       break;
12544 #endif
12545
12546     case BFD_RELOC_RVA:
12547     case BFD_RELOC_32:
12548       if (fixP->fx_done || fixP->fx_pcrel)
12549         md_number_to_chars (buf, value, 4);
12550 #ifdef OBJ_ELF
12551       else if (!target_oabi)
12552         {
12553           value = fixP->fx_offset;
12554           md_number_to_chars (buf, value, 4);
12555         }
12556 #endif
12557       break;
12558
12559 #ifdef OBJ_ELF
12560     case BFD_RELOC_ARM_PLT32:
12561       /* It appears the instruction is fully prepared at this point.  */
12562       break;
12563 #endif
12564
12565     case BFD_RELOC_ARM_CP_OFF_IMM:
12566       sign = value >= 0;
12567       if (value < -1023 || value > 1023 || (value & 3))
12568         as_bad_where (fixP->fx_file, fixP->fx_line,
12569                       _("illegal value for co-processor offset"));
12570       if (value < 0)
12571         value = -value;
12572       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12573       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12574       md_number_to_chars (buf, newval, INSN_SIZE);
12575       break;
12576
12577     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12578       sign = value >= 0;
12579       if (value < -255 || value > 255)
12580         as_bad_where (fixP->fx_file, fixP->fx_line,
12581                       _("Illegal value for co-processor offset"));
12582       if (value < 0)
12583         value = -value;
12584       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12585       newval |= value | (sign ?  INDEX_UP : 0);
12586       md_number_to_chars (buf, newval , INSN_SIZE);
12587       break;
12588
12589     case BFD_RELOC_ARM_THUMB_OFFSET:
12590       newval = md_chars_to_number (buf, THUMB_SIZE);
12591       /* Exactly what ranges, and where the offset is inserted depends
12592          on the type of instruction, we can establish this from the
12593          top 4 bits.  */
12594       switch (newval >> 12)
12595         {
12596         case 4: /* PC load.  */
12597           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12598              forced to zero for these loads, so we will need to round
12599              up the offset if the instruction address is not word
12600              aligned (since the final address produced must be, and
12601              we can only describe word-aligned immediate offsets).  */
12602
12603           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12604             as_bad_where (fixP->fx_file, fixP->fx_line,
12605                           _("invalid offset, target not word aligned (0x%08X)"),
12606                           (unsigned int) (fixP->fx_frag->fr_address
12607                                           + fixP->fx_where + value));
12608
12609           if ((value + 2) & ~0x3fe)
12610             as_bad_where (fixP->fx_file, fixP->fx_line,
12611                           _("invalid offset, value too big (0x%08lX)"),
12612                           (long) value);
12613
12614           /* Round up, since pc will be rounded down.  */
12615           newval |= (value + 2) >> 2;
12616           break;
12617
12618         case 9: /* SP load/store.  */
12619           if (value & ~0x3fc)
12620             as_bad_where (fixP->fx_file, fixP->fx_line,
12621                           _("invalid offset, value too big (0x%08lX)"),
12622                           (long) value);
12623           newval |= value >> 2;
12624           break;
12625
12626         case 6: /* Word load/store.  */
12627           if (value & ~0x7c)
12628             as_bad_where (fixP->fx_file, fixP->fx_line,
12629                           _("invalid offset, value too big (0x%08lX)"),
12630                           (long) value);
12631           newval |= value << 4; /* 6 - 2.  */
12632           break;
12633
12634         case 7: /* Byte load/store.  */
12635           if (value & ~0x1f)
12636             as_bad_where (fixP->fx_file, fixP->fx_line,
12637                           _("invalid offset, value too big (0x%08lX)"),
12638                           (long) value);
12639           newval |= value << 6;
12640           break;
12641
12642         case 8: /* Halfword load/store.  */
12643           if (value & ~0x3e)
12644             as_bad_where (fixP->fx_file, fixP->fx_line,
12645                           _("invalid offset, value too big (0x%08lX)"),
12646                           (long) value);
12647           newval |= value << 5; /* 6 - 1.  */
12648           break;
12649
12650         default:
12651           as_bad_where (fixP->fx_file, fixP->fx_line,
12652                         "Unable to process relocation for thumb opcode: %lx",
12653                         (unsigned long) newval);
12654           break;
12655         }
12656       md_number_to_chars (buf, newval, THUMB_SIZE);
12657       break;
12658
12659     case BFD_RELOC_ARM_THUMB_ADD:
12660       /* This is a complicated relocation, since we use it for all of
12661          the following immediate relocations:
12662
12663             3bit ADD/SUB
12664             8bit ADD/SUB
12665             9bit ADD/SUB SP word-aligned
12666            10bit ADD PC/SP word-aligned
12667
12668          The type of instruction being processed is encoded in the
12669          instruction field:
12670
12671            0x8000  SUB
12672            0x00F0  Rd
12673            0x000F  Rs
12674       */
12675       newval = md_chars_to_number (buf, THUMB_SIZE);
12676       {
12677         int rd = (newval >> 4) & 0xf;
12678         int rs = newval & 0xf;
12679         int subtract = newval & 0x8000;
12680
12681         if (rd == REG_SP)
12682           {
12683             if (value & ~0x1fc)
12684               as_bad_where (fixP->fx_file, fixP->fx_line,
12685                             _("invalid immediate for stack address calculation"));
12686             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12687             newval |= value >> 2;
12688           }
12689         else if (rs == REG_PC || rs == REG_SP)
12690           {
12691             if (subtract ||
12692                 value & ~0x3fc)
12693               as_bad_where (fixP->fx_file, fixP->fx_line,
12694                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12695                             (unsigned long) value);
12696             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12697             newval |= rd << 8;
12698             newval |= value >> 2;
12699           }
12700         else if (rs == rd)
12701           {
12702             if (value & ~0xff)
12703               as_bad_where (fixP->fx_file, fixP->fx_line,
12704                             _("invalid 8bit immediate"));
12705             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12706             newval |= (rd << 8) | value;
12707           }
12708         else
12709           {
12710             if (value & ~0x7)
12711               as_bad_where (fixP->fx_file, fixP->fx_line,
12712                             _("invalid 3bit immediate"));
12713             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12714             newval |= rd | (rs << 3) | (value << 6);
12715           }
12716       }
12717       md_number_to_chars (buf, newval, THUMB_SIZE);
12718       break;
12719
12720     case BFD_RELOC_ARM_THUMB_IMM:
12721       newval = md_chars_to_number (buf, THUMB_SIZE);
12722       switch (newval >> 11)
12723         {
12724         case 0x04: /* 8bit immediate MOV.  */
12725         case 0x05: /* 8bit immediate CMP.  */
12726           if (value < 0 || value > 255)
12727             as_bad_where (fixP->fx_file, fixP->fx_line,
12728                           _("invalid immediate: %ld is too large"),
12729                           (long) value);
12730           newval |= value;
12731           break;
12732
12733         default:
12734           abort ();
12735         }
12736       md_number_to_chars (buf, newval, THUMB_SIZE);
12737       break;
12738
12739     case BFD_RELOC_ARM_THUMB_SHIFT:
12740       /* 5bit shift value (0..31).  */
12741       if (value < 0 || value > 31)
12742         as_bad_where (fixP->fx_file, fixP->fx_line,
12743                       _("illegal Thumb shift value: %ld"), (long) value);
12744       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12745       newval |= value << 6;
12746       md_number_to_chars (buf, newval, THUMB_SIZE);
12747       break;
12748
12749     case BFD_RELOC_VTABLE_INHERIT:
12750     case BFD_RELOC_VTABLE_ENTRY:
12751       fixP->fx_done = 0;
12752       return;
12753
12754     case BFD_RELOC_NONE:
12755     default:
12756       as_bad_where (fixP->fx_file, fixP->fx_line,
12757                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12758     }
12759 }
12760
12761 /* Translate internal representation of relocation info to BFD target
12762    format.  */
12763
12764 arelent *
12765 tc_gen_reloc (section, fixp)
12766      asection * section ATTRIBUTE_UNUSED;
12767      fixS * fixp;
12768 {
12769   arelent * reloc;
12770   bfd_reloc_code_real_type code;
12771
12772   reloc = (arelent *) xmalloc (sizeof (arelent));
12773
12774   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12775   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12776   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12777
12778   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12779 #ifndef OBJ_ELF
12780   if (fixp->fx_pcrel == 0)
12781     reloc->addend = fixp->fx_offset;
12782   else
12783     reloc->addend = fixp->fx_offset = reloc->address;
12784 #else  /* OBJ_ELF */
12785   reloc->addend = fixp->fx_offset;
12786 #endif
12787
12788   switch (fixp->fx_r_type)
12789     {
12790     case BFD_RELOC_8:
12791       if (fixp->fx_pcrel)
12792         {
12793           code = BFD_RELOC_8_PCREL;
12794           break;
12795         }
12796
12797     case BFD_RELOC_16:
12798       if (fixp->fx_pcrel)
12799         {
12800           code = BFD_RELOC_16_PCREL;
12801           break;
12802         }
12803
12804     case BFD_RELOC_32:
12805       if (fixp->fx_pcrel)
12806         {
12807           code = BFD_RELOC_32_PCREL;
12808           break;
12809         }
12810
12811     case BFD_RELOC_ARM_PCREL_BRANCH:
12812     case BFD_RELOC_ARM_PCREL_BLX:
12813     case BFD_RELOC_RVA:
12814     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12815     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12816     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12817     case BFD_RELOC_THUMB_PCREL_BLX:
12818     case BFD_RELOC_VTABLE_ENTRY:
12819     case BFD_RELOC_VTABLE_INHERIT:
12820       code = fixp->fx_r_type;
12821       break;
12822
12823     case BFD_RELOC_ARM_LITERAL:
12824     case BFD_RELOC_ARM_HWLITERAL:
12825       /* If this is called then the a literal has
12826          been referenced across a section boundary.  */
12827       as_bad_where (fixp->fx_file, fixp->fx_line,
12828                     _("literal referenced across section boundary"));
12829       return NULL;
12830
12831 #ifdef OBJ_ELF
12832     case BFD_RELOC_ARM_GOT32:
12833     case BFD_RELOC_ARM_GOTOFF:
12834     case BFD_RELOC_ARM_PLT32:
12835       code = fixp->fx_r_type;
12836       break;
12837 #endif
12838
12839     case BFD_RELOC_ARM_IMMEDIATE:
12840       as_bad_where (fixp->fx_file, fixp->fx_line,
12841                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12842       return NULL;
12843
12844     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12845       as_bad_where (fixp->fx_file, fixp->fx_line,
12846                     _("ADRL used for a symbol not defined in the same file"));
12847       return NULL;
12848
12849     case BFD_RELOC_ARM_OFFSET_IMM:
12850       if (fixp->fx_addsy != NULL
12851           && !S_IS_DEFINED (fixp->fx_addsy)
12852           && S_IS_LOCAL (fixp->fx_addsy))
12853         {
12854           as_bad_where (fixp->fx_file, fixp->fx_line,
12855                         _("undefined local label `%s'"),
12856                         S_GET_NAME (fixp->fx_addsy));
12857           return NULL;
12858         }
12859
12860       as_bad_where (fixp->fx_file, fixp->fx_line,
12861                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12862       return NULL;
12863
12864     default:
12865       {
12866         char * type;
12867
12868         switch (fixp->fx_r_type)
12869           {
12870           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12871           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12872           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12873           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12874           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12875           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12876           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12877           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12878           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12879           default:                         type = _("<unknown>"); break;
12880           }
12881         as_bad_where (fixp->fx_file, fixp->fx_line,
12882                       _("cannot represent %s relocation in this object file format"),
12883                       type);
12884         return NULL;
12885       }
12886     }
12887
12888 #ifdef OBJ_ELF
12889   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12890       && GOT_symbol
12891       && fixp->fx_addsy == GOT_symbol)
12892     {
12893       code = BFD_RELOC_ARM_GOTPC;
12894       reloc->addend = fixp->fx_offset = reloc->address;
12895     }
12896 #endif
12897
12898   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12899
12900   if (reloc->howto == NULL)
12901     {
12902       as_bad_where (fixp->fx_file, fixp->fx_line,
12903                     _("cannot represent %s relocation in this object file format"),
12904                     bfd_get_reloc_code_name (code));
12905       return NULL;
12906     }
12907
12908   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12909      vtable entry to be used in the relocation's section offset.  */
12910   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12911     reloc->address = fixp->fx_offset;
12912
12913   return reloc;
12914 }
12915
12916 int
12917 md_estimate_size_before_relax (fragP, segtype)
12918      fragS * fragP ATTRIBUTE_UNUSED;
12919      segT    segtype ATTRIBUTE_UNUSED;
12920 {
12921   as_fatal (_("md_estimate_size_before_relax\n"));
12922   return 1;
12923 }
12924
12925 static void
12926 output_inst (str)
12927      const char *str;
12928 {
12929   char * to = NULL;
12930
12931   if (inst.error)
12932     {
12933       as_bad ("%s -- `%s'", inst.error, str);
12934       return;
12935     }
12936
12937   to = frag_more (inst.size);
12938
12939   if (thumb_mode && (inst.size > THUMB_SIZE))
12940     {
12941       assert (inst.size == (2 * THUMB_SIZE));
12942       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12943       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12944     }
12945   else if (inst.size > INSN_SIZE)
12946     {
12947       assert (inst.size == (2 * INSN_SIZE));
12948       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12949       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12950     }
12951   else
12952     md_number_to_chars (to, inst.instruction, inst.size);
12953
12954   if (inst.reloc.type != BFD_RELOC_NONE)
12955     fix_new_arm (frag_now, to - frag_now->fr_literal,
12956                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12957                  inst.reloc.type);
12958
12959 #ifdef OBJ_ELF
12960   dwarf2_emit_insn (inst.size);
12961 #endif
12962 }
12963
12964 void
12965 md_assemble (str)
12966      char * str;
12967 {
12968   char  c;
12969   char *p;
12970   char *start;
12971
12972   /* Align the instruction.
12973      This may not be the right thing to do but ...  */
12974 #if 0
12975   arm_align (2, 0);
12976 #endif
12977
12978   /* Align the previous label if needed.  */
12979   if (last_label_seen != NULL)
12980     {
12981       symbol_set_frag (last_label_seen, frag_now);
12982       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12983       S_SET_SEGMENT (last_label_seen, now_seg);
12984     }
12985
12986   memset (&inst, '\0', sizeof (inst));
12987   inst.reloc.type = BFD_RELOC_NONE;
12988
12989   skip_whitespace (str);
12990
12991   /* Scan up to the end of the op-code, which must end in white space or
12992      end of string.  */
12993   for (start = p = str; *p != '\0'; p++)
12994     if (*p == ' ')
12995       break;
12996
12997   if (p == str)
12998     {
12999       as_bad (_("no operator -- statement `%s'\n"), str);
13000       return;
13001     }
13002
13003   if (thumb_mode)
13004     {
13005       const struct thumb_opcode * opcode;
13006
13007       c = *p;
13008       *p = '\0';
13009       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
13010       *p = c;
13011
13012       if (opcode)
13013         {
13014           /* Check that this instruction is supported for this CPU.  */
13015           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
13016             {
13017               as_bad (_("selected processor does not support `%s'"), str);
13018               return;
13019             }
13020
13021           mapping_state (MAP_THUMB);
13022           inst.instruction = opcode->value;
13023           inst.size = opcode->size;
13024           (*opcode->parms) (p);
13025           output_inst (str);
13026           return;
13027         }
13028     }
13029   else
13030     {
13031       const struct asm_opcode * opcode;
13032
13033       c = *p;
13034       *p = '\0';
13035       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13036       *p = c;
13037
13038       if (opcode)
13039         {
13040           /* Check that this instruction is supported for this CPU.  */
13041           if ((opcode->variant & cpu_variant) == 0)
13042             {
13043               as_bad (_("selected processor does not support `%s'"), str);
13044               return;
13045             }
13046
13047           mapping_state (MAP_ARM);
13048           inst.instruction = opcode->value;
13049           inst.size = INSN_SIZE;
13050           (*opcode->parms) (p);
13051           output_inst (str);
13052           return;
13053         }
13054     }
13055
13056   /* It wasn't an instruction, but it might be a register alias of the form
13057      alias .req reg.  */
13058   if (create_register_alias (str, p))
13059     return;
13060
13061   as_bad (_("bad instruction `%s'"), start);
13062 }
13063
13064 /* md_parse_option
13065       Invocation line includes a switch not recognized by the base assembler.
13066       See if it's a processor-specific option.
13067
13068       This routine is somewhat complicated by the need for backwards
13069       compatibility (since older releases of gcc can't be changed).
13070       The new options try to make the interface as compatible as
13071       possible with GCC.
13072
13073       New options (supported) are:
13074
13075               -mcpu=<cpu name>           Assemble for selected processor
13076               -march=<architecture name> Assemble for selected architecture
13077               -mfpu=<fpu architecture>   Assemble for selected FPU.
13078               -EB/-mbig-endian           Big-endian
13079               -EL/-mlittle-endian        Little-endian
13080               -k                         Generate PIC code
13081               -mthumb                    Start in Thumb mode
13082               -mthumb-interwork          Code supports ARM/Thumb interworking
13083
13084       For now we will also provide support for:
13085
13086               -mapcs-32                  32-bit Program counter
13087               -mapcs-26                  26-bit Program counter
13088               -macps-float               Floats passed in FP registers
13089               -mapcs-reentrant           Reentrant code
13090               -matpcs
13091       (sometime these will probably be replaced with -mapcs=<list of options>
13092       and -matpcs=<list of options>)
13093
13094       The remaining options are only supported for back-wards compatibility.
13095       Cpu variants, the arm part is optional:
13096               -m[arm]1                Currently not supported.
13097               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13098               -m[arm]3                Arm 3 processor
13099               -m[arm]6[xx],           Arm 6 processors
13100               -m[arm]7[xx][t][[d]m]   Arm 7 processors
13101               -m[arm]8[10]            Arm 8 processors
13102               -m[arm]9[20][tdmi]      Arm 9 processors
13103               -mstrongarm[110[0]]     StrongARM processors
13104               -mxscale                XScale processors
13105               -m[arm]v[2345[t[e]]]    Arm architectures
13106               -mall                   All (except the ARM1)
13107       FP variants:
13108               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13109               -mfpe-old               (No float load/store multiples)
13110               -mvfpxd                 VFP Single precision
13111               -mvfp                   All VFP
13112               -mno-fpu                Disable all floating point instructions
13113
13114       The following CPU names are recognized:
13115               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13116               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13117               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13118               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13119               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13120               arm10t arm10e, arm1020t, arm1020e, arm10200e,
13121               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13122
13123       */
13124
13125 const char * md_shortopts = "m:k";
13126
13127 #ifdef ARM_BI_ENDIAN
13128 #define OPTION_EB (OPTION_MD_BASE + 0)
13129 #define OPTION_EL (OPTION_MD_BASE + 1)
13130 #else
13131 #if TARGET_BYTES_BIG_ENDIAN
13132 #define OPTION_EB (OPTION_MD_BASE + 0)
13133 #else
13134 #define OPTION_EL (OPTION_MD_BASE + 1)
13135 #endif
13136 #endif
13137
13138 struct option md_longopts[] =
13139 {
13140 #ifdef OPTION_EB
13141   {"EB", no_argument, NULL, OPTION_EB},
13142 #endif
13143 #ifdef OPTION_EL
13144   {"EL", no_argument, NULL, OPTION_EL},
13145 #endif
13146   {NULL, no_argument, NULL, 0}
13147 };
13148
13149 size_t md_longopts_size = sizeof (md_longopts);
13150
13151 struct arm_option_table
13152 {
13153   char *option;         /* Option name to match.  */
13154   char *help;           /* Help information.  */
13155   int  *var;            /* Variable to change.  */
13156   int   value;          /* What to change it to.  */
13157   char *deprecated;     /* If non-null, print this message.  */
13158 };
13159
13160 struct arm_option_table arm_opts[] =
13161 {
13162   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13163   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13164   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13165    &support_interwork, 1, NULL},
13166   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13167   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13168   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13169   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13170    1, NULL},
13171   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13172   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13173   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13174   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13175    NULL},
13176
13177   /* These are recognized by the assembler, but have no affect on code.  */
13178   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13179   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13180
13181   /* DON'T add any new processors to this list -- we want the whole list
13182      to go away...  Add them to the processors table instead.  */
13183   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13184   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13185   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13186   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13187   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13188   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13189   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13190   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13191   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13192   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13193   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13194   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13195   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13196   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13197   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13198   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13199   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13200   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13201   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13202   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13203   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13204   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13205   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13206   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13207   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13208   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13209   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13210   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13211   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13212   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13213   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13214   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13215   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13216   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13217   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13218   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13219   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13220   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13221   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13222   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13223   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13224   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13225   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13226   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13227   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13228   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13229   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13230   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13231   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13232   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13233   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13234   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13235   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13236   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13237   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13238   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13239   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13240   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13241   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13242   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13243   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13244   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13245   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13246   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13247   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13248   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13249   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13250   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13251   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13252   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13253    N_("use -mcpu=strongarm110")},
13254   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13255    N_("use -mcpu=strongarm1100")},
13256   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13257    N_("use -mcpu=strongarm1110")},
13258   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13259   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13260   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13261
13262   /* Architecture variants -- don't add any more to this list either.  */
13263   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13264   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13265   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13266   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13267   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13268   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13269   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13270   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13271   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13272   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13273   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13274   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13275   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13276   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13277   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13278   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13279   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13280   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13281
13282   /* Floating point variants -- don't add any more to this list either.  */
13283   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13284   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13285   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13286   {"mno-fpu",  NULL, &legacy_fpu, 0,
13287    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13288
13289   {NULL, NULL, NULL, 0, NULL}
13290 };
13291
13292 struct arm_cpu_option_table
13293 {
13294   char *name;
13295   int   value;
13296   /* For some CPUs we assume an FPU unless the user explicitly sets
13297      -mfpu=...  */
13298   int   default_fpu;
13299 };
13300
13301 /* This list should, at a minimum, contain all the cpu names
13302    recognized by GCC.  */
13303 static struct arm_cpu_option_table arm_cpus[] =
13304 {
13305   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13306   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13307   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13308   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13309   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13310   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13311   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13312   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13313   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13314   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13315   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13316   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13317   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13318   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13319   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13320   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13321   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13322   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13323   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13324   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13325   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13326   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13327   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13328   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13329   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13330   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13331   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13332   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13333   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13334   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13335   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13336   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13337   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13338   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13339   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13340   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13341   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13342   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13343   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13344   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13345   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13346   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13347   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13348   /* For V5 or later processors we default to using VFP; but the user
13349      should really set the FPU type explicitly.  */
13350   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13351   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13352   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13353   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13354   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13355   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13356   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13357   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13358   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13359   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13360   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13361   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13362   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13363   {"arm1026ejs",        ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13364   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13365   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13366   /* ??? XSCALE is really an architecture.  */
13367   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13368   /* ??? iwmmxt is not a processor.  */
13369   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13370   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13371   /* Maverick */
13372   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13373   {NULL, 0, 0}
13374 };
13375
13376 struct arm_arch_option_table
13377 {
13378   char *name;
13379   int   value;
13380   int   default_fpu;
13381 };
13382
13383 /* This list should, at a minimum, contain all the architecture names
13384    recognized by GCC.  */
13385 static struct arm_arch_option_table arm_archs[] =
13386 {
13387   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13388   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13389   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13390   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13391   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13392   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13393   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13394   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13395   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13396   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13397   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13398   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13399   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13400   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13401   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13402   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13403   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13404   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13405   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13406   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13407   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13408   {NULL, 0, 0}
13409 };
13410
13411 /* ISA extensions in the co-processor space.  */
13412 struct arm_arch_extension_table
13413 {
13414   char *name;
13415   int value;
13416 };
13417
13418 static struct arm_arch_extension_table arm_extensions[] =
13419 {
13420   {"maverick",          ARM_CEXT_MAVERICK},
13421   {"xscale",            ARM_CEXT_XSCALE},
13422   {"iwmmxt",            ARM_CEXT_IWMMXT},
13423   {NULL,                0}
13424 };
13425
13426 struct arm_fpu_option_table
13427 {
13428   char *name;
13429   int   value;
13430 };
13431
13432 /* This list should, at a minimum, contain all the fpu names
13433    recognized by GCC.  */
13434 static struct arm_fpu_option_table arm_fpus[] =
13435 {
13436   {"softfpa",           FPU_NONE},
13437   {"fpe",               FPU_ARCH_FPE},
13438   {"fpe2",              FPU_ARCH_FPE},
13439   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13440   {"fpa",               FPU_ARCH_FPA},
13441   {"fpa10",             FPU_ARCH_FPA},
13442   {"fpa11",             FPU_ARCH_FPA},
13443   {"arm7500fe",         FPU_ARCH_FPA},
13444   {"softvfp",           FPU_ARCH_VFP},
13445   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13446   {"vfp",               FPU_ARCH_VFP_V2},
13447   {"vfp9",              FPU_ARCH_VFP_V2},
13448   {"vfp10",             FPU_ARCH_VFP_V2},
13449   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13450   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13451   {"arm1020t",          FPU_ARCH_VFP_V1},
13452   {"arm1020e",          FPU_ARCH_VFP_V2},
13453   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13454   {"maverick",          FPU_ARCH_MAVERICK},
13455   {NULL, 0}
13456 };
13457
13458 struct arm_float_abi_option_table
13459 {
13460   char *name;
13461   int value;
13462 };
13463
13464 static struct arm_float_abi_option_table arm_float_abis[] =
13465 {
13466   {"hard",      ARM_FLOAT_ABI_HARD},
13467   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13468   {"soft",      ARM_FLOAT_ABI_SOFT},
13469   {NULL, 0}
13470 };
13471
13472 struct arm_eabi_option_table
13473 {
13474   char *name;
13475   unsigned int value;
13476 };
13477
13478 #ifdef OBJ_ELF
13479 /* We only know hot to output GNU and ver 3 (AAELF) formats.  */
13480 static struct arm_eabi_option_table arm_eabis[] =
13481 {
13482   {"gnu",       EF_ARM_EABI_UNKNOWN},
13483   {"3",         EF_ARM_EABI_VER3},
13484   {NULL, 0}
13485 };
13486 #endif
13487
13488 struct arm_long_option_table
13489 {
13490   char *option;         /* Substring to match.  */
13491   char *help;           /* Help information.  */
13492   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
13493   char *deprecated;     /* If non-null, print this message.  */
13494 };
13495
13496 static int
13497 arm_parse_extension (str, opt_p)
13498      char *str;
13499      int *opt_p;
13500 {
13501   while (str != NULL && *str != 0)
13502     {
13503       struct arm_arch_extension_table *opt;
13504       char *ext;
13505       int optlen;
13506
13507       if (*str != '+')
13508         {
13509           as_bad (_("invalid architectural extension"));
13510           return 0;
13511         }
13512
13513       str++;
13514       ext = strchr (str, '+');
13515
13516       if (ext != NULL)
13517         optlen = ext - str;
13518       else
13519         optlen = strlen (str);
13520
13521       if (optlen == 0)
13522         {
13523           as_bad (_("missing architectural extension"));
13524           return 0;
13525         }
13526
13527       for (opt = arm_extensions; opt->name != NULL; opt++)
13528         if (strncmp (opt->name, str, optlen) == 0)
13529           {
13530             *opt_p |= opt->value;
13531             break;
13532           }
13533
13534       if (opt->name == NULL)
13535         {
13536           as_bad (_("unknown architectural extnsion `%s'"), str);
13537           return 0;
13538         }
13539
13540       str = ext;
13541     };
13542
13543   return 1;
13544 }
13545
13546 static int
13547 arm_parse_cpu (str)
13548      char *str;
13549 {
13550   struct arm_cpu_option_table *opt;
13551   char *ext = strchr (str, '+');
13552   int optlen;
13553
13554   if (ext != NULL)
13555     optlen = ext - str;
13556   else
13557     optlen = strlen (str);
13558
13559   if (optlen == 0)
13560     {
13561       as_bad (_("missing cpu name `%s'"), str);
13562       return 0;
13563     }
13564
13565   for (opt = arm_cpus; opt->name != NULL; opt++)
13566     if (strncmp (opt->name, str, optlen) == 0)
13567       {
13568         mcpu_cpu_opt = opt->value;
13569         mcpu_fpu_opt = opt->default_fpu;
13570
13571         if (ext != NULL)
13572           return arm_parse_extension (ext, &mcpu_cpu_opt);
13573
13574         return 1;
13575       }
13576
13577   as_bad (_("unknown cpu `%s'"), str);
13578   return 0;
13579 }
13580
13581 static int
13582 arm_parse_arch (str)
13583      char *str;
13584 {
13585   struct arm_arch_option_table *opt;
13586   char *ext = strchr (str, '+');
13587   int optlen;
13588
13589   if (ext != NULL)
13590     optlen = ext - str;
13591   else
13592     optlen = strlen (str);
13593
13594   if (optlen == 0)
13595     {
13596       as_bad (_("missing architecture name `%s'"), str);
13597       return 0;
13598     }
13599
13600
13601   for (opt = arm_archs; opt->name != NULL; opt++)
13602     if (strcmp (opt->name, str) == 0)
13603       {
13604         march_cpu_opt = opt->value;
13605         march_fpu_opt = opt->default_fpu;
13606
13607         if (ext != NULL)
13608           return arm_parse_extension (ext, &march_cpu_opt);
13609
13610         return 1;
13611       }
13612
13613   as_bad (_("unknown architecture `%s'\n"), str);
13614   return 0;
13615 }
13616
13617 static int
13618 arm_parse_fpu (str)
13619      char *str;
13620 {
13621   struct arm_fpu_option_table *opt;
13622
13623   for (opt = arm_fpus; opt->name != NULL; opt++)
13624     if (strcmp (opt->name, str) == 0)
13625       {
13626         mfpu_opt = opt->value;
13627         return 1;
13628       }
13629
13630   as_bad (_("unknown floating point format `%s'\n"), str);
13631   return 0;
13632 }
13633
13634 static int
13635 arm_parse_float_abi (str)
13636      char * str;
13637 {
13638   struct arm_float_abi_option_table *opt;
13639
13640   for (opt = arm_float_abis; opt->name != NULL; opt++)
13641     if (strcmp (opt->name, str) == 0)
13642       {
13643         mfloat_abi_opt = opt->value;
13644         return 1;
13645       }
13646
13647   as_bad (_("unknown floating point abi `%s'\n"), str);
13648   return 0;
13649 }
13650
13651 #ifdef OBJ_ELF
13652 static int
13653 arm_parse_eabi (str)
13654      char * str;
13655 {
13656   struct arm_eabi_option_table *opt;
13657
13658   for (opt = arm_eabis; opt->name != NULL; opt++)
13659     if (strcmp (opt->name, str) == 0)
13660       {
13661         meabi_flags = opt->value;
13662         return 1;
13663       }
13664   as_bad (_("unknown EABI `%s'\n"), str);
13665   return 0;
13666 }
13667 #endif
13668
13669 struct arm_long_option_table arm_long_opts[] =
13670 {
13671   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13672    arm_parse_cpu, NULL},
13673   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13674    arm_parse_arch, NULL},
13675   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13676    arm_parse_fpu, NULL},
13677   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13678    arm_parse_float_abi, NULL},
13679 #ifdef OBJ_ELF
13680   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13681    arm_parse_eabi, NULL},
13682 #endif
13683   {NULL, NULL, 0, NULL}
13684 };
13685
13686 int
13687 md_parse_option (c, arg)
13688      int    c;
13689      char * arg;
13690 {
13691   struct arm_option_table *opt;
13692   struct arm_long_option_table *lopt;
13693
13694   switch (c)
13695     {
13696 #ifdef OPTION_EB
13697     case OPTION_EB:
13698       target_big_endian = 1;
13699       break;
13700 #endif
13701
13702 #ifdef OPTION_EL
13703     case OPTION_EL:
13704       target_big_endian = 0;
13705       break;
13706 #endif
13707
13708     case 'a':
13709       /* Listing option.  Just ignore these, we don't support additional
13710          ones.  */
13711       return 0;
13712
13713     default:
13714       for (opt = arm_opts; opt->option != NULL; opt++)
13715         {
13716           if (c == opt->option[0]
13717               && ((arg == NULL && opt->option[1] == 0)
13718                   || strcmp (arg, opt->option + 1) == 0))
13719             {
13720 #if WARN_DEPRECATED
13721               /* If the option is deprecated, tell the user.  */
13722               if (opt->deprecated != NULL)
13723                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13724                            arg ? arg : "", _(opt->deprecated));
13725 #endif
13726
13727               if (opt->var != NULL)
13728                 *opt->var = opt->value;
13729
13730               return 1;
13731             }
13732         }
13733
13734       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13735         {
13736           /* These options are expected to have an argument.  */
13737           if (c == lopt->option[0]
13738               && arg != NULL
13739               && strncmp (arg, lopt->option + 1,
13740                           strlen (lopt->option + 1)) == 0)
13741             {
13742 #if WARN_DEPRECATED
13743               /* If the option is deprecated, tell the user.  */
13744               if (lopt->deprecated != NULL)
13745                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13746                            _(lopt->deprecated));
13747 #endif
13748
13749               /* Call the sup-option parser.  */
13750               return (*lopt->func)(arg + strlen (lopt->option) - 1);
13751             }
13752         }
13753
13754       as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13755       return 0;
13756     }
13757
13758   return 1;
13759 }
13760
13761 void
13762 md_show_usage (fp)
13763      FILE * fp;
13764 {
13765   struct arm_option_table *opt;
13766   struct arm_long_option_table *lopt;
13767
13768   fprintf (fp, _(" ARM-specific assembler options:\n"));
13769
13770   for (opt = arm_opts; opt->option != NULL; opt++)
13771     if (opt->help != NULL)
13772       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13773
13774   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13775     if (lopt->help != NULL)
13776       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13777
13778 #ifdef OPTION_EB
13779   fprintf (fp, _("\
13780   -EB                     assemble code for a big-endian cpu\n"));
13781 #endif
13782
13783 #ifdef OPTION_EL
13784   fprintf (fp, _("\
13785   -EL                     assemble code for a little-endian cpu\n"));
13786 #endif
13787 }
13788
13789 /* We need to be able to fix up arbitrary expressions in some statements.
13790    This is so that we can handle symbols that are an arbitrary distance from
13791    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13792    which returns part of an address in a form which will be valid for
13793    a data instruction.  We do this by pushing the expression into a symbol
13794    in the expr_section, and creating a fix for that.  */
13795
13796 static void
13797 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13798      fragS *       frag;
13799      int           where;
13800      short int     size;
13801      expressionS * exp;
13802      int           pc_rel;
13803      int           reloc;
13804 {
13805   fixS *           new_fix;
13806   arm_fix_data *   arm_data;
13807
13808   switch (exp->X_op)
13809     {
13810     case O_constant:
13811     case O_symbol:
13812     case O_add:
13813     case O_subtract:
13814       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13815       break;
13816
13817     default:
13818       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13819                          pc_rel, reloc);
13820       break;
13821     }
13822
13823   /* Mark whether the fix is to a THUMB instruction, or an ARM
13824      instruction.  */
13825   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13826   new_fix->tc_fix_data = (PTR) arm_data;
13827   arm_data->thumb_mode = thumb_mode;
13828 }
13829
13830 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13831
13832 void
13833 cons_fix_new_arm (frag, where, size, exp)
13834      fragS *       frag;
13835      int           where;
13836      int           size;
13837      expressionS * exp;
13838 {
13839   bfd_reloc_code_real_type type;
13840   int pcrel = 0;
13841
13842   /* Pick a reloc.
13843      FIXME: @@ Should look at CPU word size.  */
13844   switch (size)
13845     {
13846     case 1:
13847       type = BFD_RELOC_8;
13848       break;
13849     case 2:
13850       type = BFD_RELOC_16;
13851       break;
13852     case 4:
13853     default:
13854       type = BFD_RELOC_32;
13855       break;
13856     case 8:
13857       type = BFD_RELOC_64;
13858       break;
13859     }
13860
13861   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13862 }
13863
13864 /* A good place to do this, although this was probably not intended
13865    for this kind of use.  We need to dump the literal pool before
13866    references are made to a null symbol pointer.  */
13867
13868 void
13869 arm_cleanup ()
13870 {
13871   literal_pool * pool;
13872
13873   for (pool = list_of_pools; pool; pool = pool->next)
13874     {
13875       /* Put it at the end of the relevent section.  */
13876       subseg_set (pool->section, pool->sub_section);
13877 #ifdef OBJ_ELF
13878       arm_elf_change_section ();
13879 #endif
13880       s_ltorg (0);
13881     }
13882 }
13883
13884 void
13885 arm_start_line_hook ()
13886 {
13887   last_label_seen = NULL;
13888 }
13889
13890 void
13891 arm_frob_label (sym)
13892      symbolS * sym;
13893 {
13894   last_label_seen = sym;
13895
13896   ARM_SET_THUMB (sym, thumb_mode);
13897
13898 #if defined OBJ_COFF || defined OBJ_ELF
13899   ARM_SET_INTERWORK (sym, support_interwork);
13900 #endif
13901
13902   /* Note - do not allow local symbols (.Lxxx) to be labeled
13903      as Thumb functions.  This is because these labels, whilst
13904      they exist inside Thumb code, are not the entry points for
13905      possible ARM->Thumb calls.  Also, these labels can be used
13906      as part of a computed goto or switch statement.  eg gcc
13907      can generate code that looks like this:
13908
13909                 ldr  r2, [pc, .Laaa]
13910                 lsl  r3, r3, #2
13911                 ldr  r2, [r3, r2]
13912                 mov  pc, r2
13913
13914        .Lbbb:  .word .Lxxx
13915        .Lccc:  .word .Lyyy
13916        ..etc...
13917        .Laaa:   .word Lbbb
13918
13919      The first instruction loads the address of the jump table.
13920      The second instruction converts a table index into a byte offset.
13921      The third instruction gets the jump address out of the table.
13922      The fourth instruction performs the jump.
13923
13924      If the address stored at .Laaa is that of a symbol which has the
13925      Thumb_Func bit set, then the linker will arrange for this address
13926      to have the bottom bit set, which in turn would mean that the
13927      address computation performed by the third instruction would end
13928      up with the bottom bit set.  Since the ARM is capable of unaligned
13929      word loads, the instruction would then load the incorrect address
13930      out of the jump table, and chaos would ensue.  */
13931   if (label_is_thumb_function_name
13932       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13933       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13934     {
13935       /* When the address of a Thumb function is taken the bottom
13936          bit of that address should be set.  This will allow
13937          interworking between Arm and Thumb functions to work
13938          correctly.  */
13939
13940       THUMB_SET_FUNC (sym, 1);
13941
13942       label_is_thumb_function_name = FALSE;
13943     }
13944 }
13945
13946 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13947    ARM ones.  */
13948
13949 void
13950 arm_adjust_symtab ()
13951 {
13952 #ifdef OBJ_COFF
13953   symbolS * sym;
13954
13955   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13956     {
13957       if (ARM_IS_THUMB (sym))
13958         {
13959           if (THUMB_IS_FUNC (sym))
13960             {
13961               /* Mark the symbol as a Thumb function.  */
13962               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13963                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13964                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13965
13966               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13967                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13968               else
13969                 as_bad (_("%s: unexpected function type: %d"),
13970                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13971             }
13972           else switch (S_GET_STORAGE_CLASS (sym))
13973             {
13974             case C_EXT:
13975               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13976               break;
13977             case C_STAT:
13978               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13979               break;
13980             case C_LABEL:
13981               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13982               break;
13983             default:
13984               /* Do nothing.  */
13985               break;
13986             }
13987         }
13988
13989       if (ARM_IS_INTERWORK (sym))
13990         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13991     }
13992 #endif
13993 #ifdef OBJ_ELF
13994   symbolS * sym;
13995   char      bind;
13996
13997   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13998     {
13999       if (ARM_IS_THUMB (sym))
14000         {
14001           elf_symbol_type * elf_sym;
14002
14003           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
14004           bind = ELF_ST_BIND (elf_sym);
14005
14006           /* If it's a .thumb_func, declare it as so,
14007              otherwise tag label as .code 16.  */
14008           if (THUMB_IS_FUNC (sym))
14009             elf_sym->internal_elf_sym.st_info =
14010               ELF_ST_INFO (bind, STT_ARM_TFUNC);
14011           else
14012             elf_sym->internal_elf_sym.st_info =
14013               ELF_ST_INFO (bind, STT_ARM_16BIT);
14014         }
14015     }
14016 #endif
14017 }
14018
14019 int
14020 arm_data_in_code ()
14021 {
14022   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
14023     {
14024       *input_line_pointer = '/';
14025       input_line_pointer += 5;
14026       *input_line_pointer = 0;
14027       return 1;
14028     }
14029
14030   return 0;
14031 }
14032
14033 char *
14034 arm_canonicalize_symbol_name (name)
14035      char * name;
14036 {
14037   int len;
14038
14039   if (thumb_mode && (len = strlen (name)) > 5
14040       && streq (name + len - 5, "/data"))
14041     *(name + len - 5) = 0;
14042
14043   return name;
14044 }
14045
14046 #if defined OBJ_COFF || defined OBJ_ELF
14047 void
14048 arm_validate_fix (fixP)
14049      fixS * fixP;
14050 {
14051   /* If the destination of the branch is a defined symbol which does not have
14052      the THUMB_FUNC attribute, then we must be calling a function which has
14053      the (interfacearm) attribute.  We look for the Thumb entry point to that
14054      function and change the branch to refer to that function instead.  */
14055   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
14056       && fixP->fx_addsy != NULL
14057       && S_IS_DEFINED (fixP->fx_addsy)
14058       && ! THUMB_IS_FUNC (fixP->fx_addsy))
14059     {
14060       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
14061     }
14062 }
14063 #endif
14064
14065 int
14066 arm_force_relocation (fixp)
14067      struct fix * fixp;
14068 {
14069 #if defined (OBJ_COFF) && defined (TE_PE)
14070   if (fixp->fx_r_type == BFD_RELOC_RVA)
14071     return 1;
14072 #endif
14073 #ifdef OBJ_ELF
14074   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14075       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14076       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14077       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14078     return 1;
14079 #endif
14080
14081   /* Resolve these relocations even if the symbol is extern or weak.  */
14082   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14083       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14084       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14085     return 0;
14086
14087   return generic_force_reloc (fixp);
14088 }
14089
14090 #ifdef OBJ_COFF
14091 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
14092    local labels from being added to the output symbol table when they
14093    are used with the ADRL pseudo op.  The ADRL relocation should always
14094    be resolved before the binbary is emitted, so it is safe to say that
14095    it is adjustable.  */
14096
14097 bfd_boolean
14098 arm_fix_adjustable (fixP)
14099    fixS * fixP;
14100 {
14101   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14102     return 1;
14103   return 0;
14104 }
14105 #endif
14106
14107 #ifdef OBJ_ELF
14108 /* Relocations against Thumb function names must be left unadjusted,
14109    so that the linker can use this information to correctly set the
14110    bottom bit of their addresses.  The MIPS version of this function
14111    also prevents relocations that are mips-16 specific, but I do not
14112    know why it does this.
14113
14114    FIXME:
14115    There is one other problem that ought to be addressed here, but
14116    which currently is not:  Taking the address of a label (rather
14117    than a function) and then later jumping to that address.  Such
14118    addresses also ought to have their bottom bit set (assuming that
14119    they reside in Thumb code), but at the moment they will not.  */
14120
14121 bfd_boolean
14122 arm_fix_adjustable (fixP)
14123    fixS * fixP;
14124 {
14125   if (fixP->fx_addsy == NULL)
14126     return 1;
14127
14128   if (THUMB_IS_FUNC (fixP->fx_addsy)
14129       && fixP->fx_subsy == NULL)
14130     return 0;
14131
14132   /* We need the symbol name for the VTABLE entries.  */
14133   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14134       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14135     return 0;
14136
14137   /* Don't allow symbols to be discarded on GOT related relocs.  */
14138   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14139       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14140       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14141     return 0;
14142
14143   return 1;
14144 }
14145
14146 const char *
14147 elf32_arm_target_format ()
14148 {
14149   if (target_big_endian)
14150     {
14151       if (target_oabi)
14152         return "elf32-bigarm-oabi";
14153       else
14154         return "elf32-bigarm";
14155     }
14156   else
14157     {
14158       if (target_oabi)
14159         return "elf32-littlearm-oabi";
14160       else
14161         return "elf32-littlearm";
14162     }
14163 }
14164
14165 void
14166 armelf_frob_symbol (symp, puntp)
14167      symbolS * symp;
14168      int *     puntp;
14169 {
14170   elf_frob_symbol (symp, puntp);
14171 }
14172
14173 static bfd_reloc_code_real_type
14174 arm_parse_reloc ()
14175 {
14176   char         id [16];
14177   char *       ip;
14178   unsigned int i;
14179   static struct
14180   {
14181     char * str;
14182     int    len;
14183     bfd_reloc_code_real_type reloc;
14184   }
14185   reloc_map[] =
14186   {
14187 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14188     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14189     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14190     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14191        branch instructions generated by GCC for PLT relocs.  */
14192     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14193     { NULL, 0,         BFD_RELOC_UNUSED }
14194 #undef MAP
14195   };
14196
14197   for (i = 0, ip = input_line_pointer;
14198        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14199        i++, ip++)
14200     id[i] = TOLOWER (*ip);
14201
14202   for (i = 0; reloc_map[i].str; i++)
14203     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14204       break;
14205
14206   input_line_pointer += reloc_map[i].len;
14207
14208   return reloc_map[i].reloc;
14209 }
14210
14211 static void
14212 s_arm_elf_cons (nbytes)
14213      int nbytes;
14214 {
14215   expressionS exp;
14216
14217 #ifdef md_flush_pending_output
14218   md_flush_pending_output ();
14219 #endif
14220
14221   if (is_it_end_of_statement ())
14222     {
14223       demand_empty_rest_of_line ();
14224       return;
14225     }
14226
14227 #ifdef md_cons_align
14228   md_cons_align (nbytes);
14229 #endif
14230
14231   mapping_state (MAP_DATA);
14232   do
14233     {
14234       bfd_reloc_code_real_type reloc;
14235
14236       expression (& exp);
14237
14238       if (exp.X_op == O_symbol
14239           && * input_line_pointer == '('
14240           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14241         {
14242           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14243           int size = bfd_get_reloc_size (howto);
14244
14245           if (size > nbytes)
14246             as_bad ("%s relocations do not fit in %d bytes",
14247                     howto->name, nbytes);
14248           else
14249             {
14250               register char *p = frag_more ((int) nbytes);
14251               int offset = nbytes - size;
14252
14253               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14254                            &exp, 0, reloc);
14255             }
14256         }
14257       else
14258         emit_expr (&exp, (unsigned int) nbytes);
14259     }
14260   while (*input_line_pointer++ == ',');
14261
14262   /* Put terminator back into stream.  */
14263   input_line_pointer --;
14264   demand_empty_rest_of_line ();
14265 }
14266
14267 #endif /* OBJ_ELF */
14268
14269 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14270    of an rs_align_code fragment.  */
14271
14272 void
14273 arm_handle_align (fragP)
14274      fragS *fragP;
14275 {
14276   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14277   static char const thumb_noop[2] = { 0xc0, 0x46 };
14278   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14279   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14280
14281   int bytes, fix, noop_size;
14282   char * p;
14283   const char * noop;
14284
14285   if (fragP->fr_type != rs_align_code)
14286     return;
14287
14288   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14289   p = fragP->fr_literal + fragP->fr_fix;
14290   fix = 0;
14291
14292   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14293     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14294
14295   if (fragP->tc_frag_data)
14296     {
14297       if (target_big_endian)
14298         noop = thumb_bigend_noop;
14299       else
14300         noop = thumb_noop;
14301       noop_size = sizeof (thumb_noop);
14302     }
14303   else
14304     {
14305       if (target_big_endian)
14306         noop = arm_bigend_noop;
14307       else
14308         noop = arm_noop;
14309       noop_size = sizeof (arm_noop);
14310     }
14311
14312   if (bytes & (noop_size - 1))
14313     {
14314       fix = bytes & (noop_size - 1);
14315       memset (p, 0, fix);
14316       p += fix;
14317       bytes -= fix;
14318     }
14319
14320   while (bytes >= noop_size)
14321     {
14322       memcpy (p, noop, noop_size);
14323       p += noop_size;
14324       bytes -= noop_size;
14325       fix += noop_size;
14326     }
14327
14328   fragP->fr_fix += fix;
14329   fragP->fr_var = noop_size;
14330 }
14331
14332 /* Called from md_do_align.  Used to create an alignment
14333    frag in a code section.  */
14334
14335 void
14336 arm_frag_align_code (n, max)
14337      int n;
14338      int max;
14339 {
14340   char * p;
14341
14342   /* We assume that there will never be a requirement
14343      to support alignments greater than 32 bytes.  */
14344   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14345     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14346
14347   p = frag_var (rs_align_code,
14348                 MAX_MEM_FOR_RS_ALIGN_CODE,
14349                 1,
14350                 (relax_substateT) max,
14351                 (symbolS *) NULL,
14352                 (offsetT) n,
14353                 (char *) NULL);
14354   *p = 0;
14355
14356 }
14357
14358 /* Perform target specific initialisation of a frag.  */
14359
14360 void
14361 arm_init_frag (fragP)
14362      fragS *fragP;
14363 {
14364   /* Record whether this frag is in an ARM or a THUMB area.  */
14365   fragP->tc_frag_data = thumb_mode;
14366 }