Apply fixes for Maverick Crunch
[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
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5         Modified by David Taylor (dtaylor@armltd.co.uk)
6         Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7         Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8         Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
9
10    This file is part of GAS, the GNU Assembler.
11
12    GAS is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2, or (at your option)
15    any later version.
16
17    GAS is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with GAS; see the file COPYING.  If not, write to the Free
24    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25    02111-1307, USA.  */
26
27 #include <string.h>
28 #define  NO_RELOC 0
29 #include "as.h"
30 #include "safe-ctype.h"
31
32 /* Need TARGET_CPU.  */
33 #include "config.h"
34 #include "subsegs.h"
35 #include "obstack.h"
36 #include "symbols.h"
37 #include "listing.h"
38
39 #ifdef OBJ_ELF
40 #include "elf/arm.h"
41 #include "dwarf2dbg.h"
42 #endif
43
44 /* XXX Set this to 1 after the next binutils release */
45 #define WARN_DEPRECATED 0
46
47 /* The following bitmasks control CPU extensions:  */
48 #define ARM_EXT_V1       0x00000001     /* All processors (core set).  */
49 #define ARM_EXT_V2       0x00000002     /* Multiply instructions.  */
50 #define ARM_EXT_V2S      0x00000004     /* SWP instructions.       */
51 #define ARM_EXT_V3       0x00000008     /* MSR MRS.                */
52 #define ARM_EXT_V3M      0x00000010     /* Allow long multiplies.  */
53 #define ARM_EXT_V4       0x00000020     /* Allow half word loads.  */
54 #define ARM_EXT_V4T      0x00000040     /* Thumb v1.               */
55 #define ARM_EXT_V5       0x00000080     /* Allow CLZ, etc.         */
56 #define ARM_EXT_V5T      0x00000100     /* Thumb v2.               */
57 #define ARM_EXT_V5ExP    0x00000200     /* DSP core set.           */
58 #define ARM_EXT_V5E      0x00000400     /* DSP Double transfers.   */
59 #define ARM_EXT_V5J      0x00000800     /* Jazelle extension.      */
60 #define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
61
62 /* Co-processor space extensions.  */
63 #define ARM_CEXT_XSCALE   0x00800000    /* Allow MIA etc.          */
64 #define ARM_CEXT_MAVERICK 0x00400000    /* Use Cirrus/DSP coprocessor.  */
65 #define ARM_CEXT_IWMMXT   0x00200000    /* Intel Wireless MMX technology coprocessor.   */
66
67 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
68    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
69    ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
70    three more to cover cores prior to ARM6.  Finally, there are cores which
71    implement further extensions in the co-processor space.  */
72 #define ARM_ARCH_V1                       ARM_EXT_V1
73 #define ARM_ARCH_V2     (ARM_ARCH_V1    | ARM_EXT_V2)
74 #define ARM_ARCH_V2S    (ARM_ARCH_V2    | ARM_EXT_V2S)
75 #define ARM_ARCH_V3     (ARM_ARCH_V2S   | ARM_EXT_V3)
76 #define ARM_ARCH_V3M    (ARM_ARCH_V3    | ARM_EXT_V3M)
77 #define ARM_ARCH_V4xM   (ARM_ARCH_V3    | ARM_EXT_V4)
78 #define ARM_ARCH_V4     (ARM_ARCH_V3M   | ARM_EXT_V4)
79 #define ARM_ARCH_V4TxM  (ARM_ARCH_V4xM  | ARM_EXT_V4T)
80 #define ARM_ARCH_V4T    (ARM_ARCH_V4    | ARM_EXT_V4T)
81 #define ARM_ARCH_V5xM   (ARM_ARCH_V4xM  | ARM_EXT_V5)
82 #define ARM_ARCH_V5     (ARM_ARCH_V4    | ARM_EXT_V5)
83 #define ARM_ARCH_V5TxM  (ARM_ARCH_V5xM  | ARM_EXT_V4T | ARM_EXT_V5T)
84 #define ARM_ARCH_V5T    (ARM_ARCH_V5    | ARM_EXT_V4T | ARM_EXT_V5T)
85 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T   | ARM_EXT_V5ExP)
86 #define ARM_ARCH_V5TE   (ARM_ARCH_V5TExP | ARM_EXT_V5E)
87 #define ARM_ARCH_V5TEJ  (ARM_ARCH_V5TE  | ARM_EXT_V5J)
88 #define ARM_ARCH_V6     (ARM_ARCH_V5TEJ | ARM_EXT_V6)
89
90 /* Processors with specific extensions in the co-processor space.  */
91 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE  | ARM_CEXT_XSCALE)
92 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
93
94 /* Some useful combinations:  */
95 #define ARM_ANY         0x0000ffff      /* Any basic core.  */
96 #define ARM_ALL         0x00ffffff      /* Any core + co-processor */
97 #define CPROC_ANY       0x00ff0000      /* Any co-processor */
98 #define FPU_ANY         0xff000000      /* Note this is ~ARM_ALL.  */
99
100
101 #define FPU_FPA_EXT_V1   0x80000000     /* Base FPA instruction set.  */
102 #define FPU_FPA_EXT_V2   0x40000000     /* LFM/SFM.                   */
103 #define FPU_VFP_EXT_NONE 0x20000000     /* Use VFP word-ordering.     */
104 #define FPU_VFP_EXT_V1xD 0x10000000     /* Base VFP instruction set.  */
105 #define FPU_VFP_EXT_V1   0x08000000     /* Double-precision insns.    */
106 #define FPU_VFP_EXT_V2   0x04000000     /* ARM10E VFPr1.              */
107 #define FPU_MAVERICK     0x02000000     /* Cirrus Maverick.           */
108 #define FPU_NONE         0
109
110 #define FPU_ARCH_FPE     FPU_FPA_EXT_V1
111 #define FPU_ARCH_FPA    (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
112
113 #define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
114 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
115 #define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
116 #define FPU_ARCH_VFP_V2   (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
117
118 #define FPU_ARCH_MAVERICK  FPU_MAVERICK
119
120 enum arm_float_abi
121 {
122   ARM_FLOAT_ABI_HARD,
123   ARM_FLOAT_ABI_SOFTFP,
124   ARM_FLOAT_ABI_SOFT
125 };
126
127 /* Types of processor to assemble for.  */
128 #define ARM_1           ARM_ARCH_V1
129 #define ARM_2           ARM_ARCH_V2
130 #define ARM_3           ARM_ARCH_V2S
131 #define ARM_250         ARM_ARCH_V2S
132 #define ARM_6           ARM_ARCH_V3
133 #define ARM_7           ARM_ARCH_V3
134 #define ARM_8           ARM_ARCH_V4
135 #define ARM_9           ARM_ARCH_V4T
136 #define ARM_STRONG      ARM_ARCH_V4
137 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
138
139 #ifndef CPU_DEFAULT
140 #if defined __XSCALE__
141 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
142 #else
143 #if defined __thumb__
144 #define CPU_DEFAULT     (ARM_ARCH_V5T)
145 #else
146 #define CPU_DEFAULT     ARM_ANY
147 #endif
148 #endif
149 #endif
150
151 #ifdef TE_LINUX
152 #define FPU_DEFAULT FPU_ARCH_FPA
153 #endif
154
155 #ifdef TE_NetBSD
156 #ifdef OBJ_ELF
157 #define FPU_DEFAULT FPU_ARCH_VFP        /* Soft-float, but VFP order.  */
158 #else
159 /* Legacy a.out format.  */
160 #define FPU_DEFAULT FPU_ARCH_FPA        /* Soft-float, but FPA order.  */
161 #endif
162 #endif
163
164 /* For backwards compatibility we default to the FPA.  */
165 #ifndef FPU_DEFAULT
166 #define FPU_DEFAULT FPU_ARCH_FPA
167 #endif
168
169 #define streq(a, b)           (strcmp (a, b) == 0)
170 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
171
172 static unsigned long cpu_variant;
173 static int target_oabi = 0;
174
175 /* Flags stored in private area of BFD structure.  */
176 static int uses_apcs_26      = FALSE;
177 static int atpcs             = FALSE;
178 static int support_interwork = FALSE;
179 static int uses_apcs_float   = FALSE;
180 static int pic_code          = FALSE;
181
182 /* Variables that we set while parsing command-line options.  Once all
183    options have been read we re-process these values to set the real
184    assembly flags.  */
185 static int legacy_cpu = -1;
186 static int legacy_fpu = -1;
187
188 static int mcpu_cpu_opt = -1;
189 static int mcpu_fpu_opt = -1;
190 static int march_cpu_opt = -1;
191 static int march_fpu_opt = -1;
192 static int mfpu_opt = -1;
193 static int mfloat_abi_opt = -1;
194
195 /* This array holds the chars that always start a comment.  If the
196    pre-processor is disabled, these aren't very useful.  */
197 const char comment_chars[] = "@";
198
199 /* This array holds the chars that only start a comment at the beginning of
200    a line.  If the line seems to have the form '# 123 filename'
201    .line and .file directives will appear in the pre-processed output.  */
202 /* Note that input_file.c hand checks for '#' at the beginning of the
203    first line of the input file.  This is because the compiler outputs
204    #NO_APP at the beginning of its output.  */
205 /* Also note that comments like this one will always work.  */
206 const char line_comment_chars[] = "#";
207
208 const char line_separator_chars[] = ";";
209
210 /* Chars that can be used to separate mant
211    from exp in floating point numbers.  */
212 const char EXP_CHARS[] = "eE";
213
214 /* Chars that mean this number is a floating point constant.  */
215 /* As in 0f12.456  */
216 /* or    0d1.2345e12  */
217
218 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
219
220 /* Prefix characters that indicate the start of an immediate
221    value.  */
222 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
223
224 #ifdef OBJ_ELF
225 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
226 symbolS * GOT_symbol;
227 #endif
228
229 /* Size of relocation record.  */
230 const int md_reloc_size = 8;
231
232 /* 0: assemble for ARM,
233    1: assemble for Thumb,
234    2: assemble for Thumb even though target CPU does not support thumb
235       instructions.  */
236 static int thumb_mode = 0;
237
238 typedef struct arm_fix
239 {
240   int thumb_mode;
241 } arm_fix_data;
242
243 struct arm_it
244 {
245   const char *  error;
246   unsigned long instruction;
247   int           size;
248   struct
249   {
250     bfd_reloc_code_real_type type;
251     expressionS              exp;
252     int                      pc_rel;
253   } reloc;
254 };
255
256 struct arm_it inst;
257
258 enum asm_shift_index
259 {
260   SHIFT_LSL = 0,
261   SHIFT_LSR,
262   SHIFT_ASR,
263   SHIFT_ROR,
264   SHIFT_RRX
265 };
266
267 struct asm_shift_properties
268 {
269   enum asm_shift_index index;
270   unsigned long        bit_field;
271   unsigned int         allows_0  : 1;
272   unsigned int         allows_32 : 1;
273 };
274
275 static const struct asm_shift_properties shift_properties [] =
276 {
277   { SHIFT_LSL, 0,    1, 0},
278   { SHIFT_LSR, 0x20, 0, 1},
279   { SHIFT_ASR, 0x40, 0, 1},
280   { SHIFT_ROR, 0x60, 0, 0},
281   { SHIFT_RRX, 0x60, 0, 0}
282 };
283
284 struct asm_shift_name
285 {
286   const char *                        name;
287   const struct asm_shift_properties * properties;
288 };
289
290 static const struct asm_shift_name shift_names [] =
291 {
292   { "asl", shift_properties + SHIFT_LSL },
293   { "lsl", shift_properties + SHIFT_LSL },
294   { "lsr", shift_properties + SHIFT_LSR },
295   { "asr", shift_properties + SHIFT_ASR },
296   { "ror", shift_properties + SHIFT_ROR },
297   { "rrx", shift_properties + SHIFT_RRX },
298   { "ASL", shift_properties + SHIFT_LSL },
299   { "LSL", shift_properties + SHIFT_LSL },
300   { "LSR", shift_properties + SHIFT_LSR },
301   { "ASR", shift_properties + SHIFT_ASR },
302   { "ROR", shift_properties + SHIFT_ROR },
303   { "RRX", shift_properties + SHIFT_RRX }
304 };
305
306 /* Any kind of shift is accepted.  */
307 #define NO_SHIFT_RESTRICT 1
308 /* The shift operand must be an immediate value, not a register.  */
309 #define SHIFT_IMMEDIATE   0
310 /* The shift must be LSL or ASR and the operand must be an immediate.  */
311 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
312 /* The shift must be ASR and the operand must be an immediate.  */
313 #define SHIFT_ASR_IMMEDIATE 3
314 /* The shift must be LSL and the operand must be an immediate.  */
315 #define SHIFT_LSL_IMMEDIATE 4
316
317 #define NUM_FLOAT_VALS 8
318
319 const char * fp_const[] =
320 {
321   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
322 };
323
324 /* Number of littlenums required to hold an extended precision number.  */
325 #define MAX_LITTLENUMS 6
326
327 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
328
329 #define FAIL    (-1)
330 #define SUCCESS (0)
331
332 /* Whether a Co-processor load/store operation accepts write-back forms.  */
333 #define CP_WB_OK 1
334 #define CP_NO_WB 0
335
336 #define SUFF_S 1
337 #define SUFF_D 2
338 #define SUFF_E 3
339 #define SUFF_P 4
340
341 #define CP_T_X   0x00008000
342 #define CP_T_Y   0x00400000
343 #define CP_T_Pre 0x01000000
344 #define CP_T_UD  0x00800000
345 #define CP_T_WB  0x00200000
346
347 #define CONDS_BIT        0x00100000
348 #define LOAD_BIT         0x00100000
349
350 #define DOUBLE_LOAD_FLAG 0x00000001
351
352 struct asm_cond
353 {
354   const char *  template;
355   unsigned long value;
356 };
357
358 #define COND_ALWAYS 0xe0000000
359 #define COND_MASK   0xf0000000
360
361 static const struct asm_cond conds[] =
362 {
363   {"eq", 0x00000000},
364   {"ne", 0x10000000},
365   {"cs", 0x20000000}, {"hs", 0x20000000},
366   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
367   {"mi", 0x40000000},
368   {"pl", 0x50000000},
369   {"vs", 0x60000000},
370   {"vc", 0x70000000},
371   {"hi", 0x80000000},
372   {"ls", 0x90000000},
373   {"ge", 0xa0000000},
374   {"lt", 0xb0000000},
375   {"gt", 0xc0000000},
376   {"le", 0xd0000000},
377   {"al", 0xe0000000},
378   {"nv", 0xf0000000}
379 };
380
381 struct asm_psr
382 {
383   const char *template;
384   bfd_boolean cpsr;
385   unsigned long field;
386 };
387
388 /* The bit that distinguishes CPSR and SPSR.  */
389 #define SPSR_BIT   (1 << 22)
390
391 /* How many bits to shift the PSR_xxx bits up by.  */
392 #define PSR_SHIFT  16
393
394 #define PSR_c   (1 << 0)
395 #define PSR_x   (1 << 1)
396 #define PSR_s   (1 << 2)
397 #define PSR_f   (1 << 3)
398
399 static const struct asm_psr psrs[] =
400 {
401   {"CPSR",      TRUE,  PSR_c | PSR_f},
402   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
403   {"SPSR",      FALSE, PSR_c | PSR_f},
404   {"SPSR_all",  FALSE, PSR_c | PSR_f},
405   {"CPSR_flg",  TRUE,  PSR_f},
406   {"CPSR_f",    TRUE,  PSR_f},
407   {"SPSR_flg",  FALSE, PSR_f},
408   {"SPSR_f",    FALSE, PSR_f},
409   {"CPSR_c",    TRUE,  PSR_c},
410   {"CPSR_ctl",  TRUE,  PSR_c},
411   {"SPSR_c",    FALSE, PSR_c},
412   {"SPSR_ctl",  FALSE, PSR_c},
413   {"CPSR_x",    TRUE,  PSR_x},
414   {"CPSR_s",    TRUE,  PSR_s},
415   {"SPSR_x",    FALSE, PSR_x},
416   {"SPSR_s",    FALSE, PSR_s},
417   /* Combinations of flags.  */
418   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
419   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
420   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
421   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
422   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
423   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
424   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
425   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
426   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
427   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
428   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
429   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
430   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
431   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
432   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
433   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
434   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
435   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
436   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
437   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
438   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
439   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
440   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
441   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
442   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
443   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
444   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
445   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
446   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
447   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
448   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
449   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
450   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
451   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
452   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
453   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
454   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
455   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
456   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
457   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
458   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
459   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
460   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
461   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
462   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
463   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
464   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
465   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
466   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
467   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
468   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
469   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
470   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
471   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
472   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
473   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
474   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
475   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
476   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
477   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
478   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
479   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
480   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
481   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
482   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
483   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
484   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
485   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
486   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
487   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
488   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
489   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
490   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
491   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
492   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
493   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
494   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
495   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
496   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
497   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
498   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
499   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
500   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
501   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
502   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
503   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
504   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
505   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
506   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
507   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
508   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
509   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
510   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
511   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
512   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
513   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
514   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
515   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
516   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
517   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
518   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
519   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
520   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
521   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
522   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
523   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
524   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
525   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
526   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
527   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
528   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
529   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
530   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
531   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
532   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
533   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
534   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
535   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
536   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
537   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
538 };
539
540 enum wreg_type
541   {
542     IWMMXT_REG_WR = 0,
543     IWMMXT_REG_WC = 1,
544     IWMMXT_REG_WR_OR_WC = 2,
545     IWMMXT_REG_WCG
546   };
547
548 enum iwmmxt_insn_type
549 {
550   check_rd,
551   check_wr,
552   check_wrwr,
553   check_wrwrwr,
554   check_wrwrwcg,
555   check_tbcst,
556   check_tmovmsk,
557   check_tmia,
558   check_tmcrr,
559   check_tmrrc,
560   check_tmcr,
561   check_tmrc,
562   check_tinsr,
563   check_textrc,
564   check_waligni,
565   check_textrm,
566   check_wshufh
567 };
568
569 enum vfp_dp_reg_pos
570 {
571   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
572 };
573
574 enum vfp_sp_reg_pos
575 {
576   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
577 };
578
579 enum vfp_ldstm_type
580 {
581   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
582 };
583
584 /* VFP system registers.  */
585 struct vfp_reg
586 {
587   const char *name;
588   unsigned long regno;
589 };
590
591 static const struct vfp_reg vfp_regs[] =
592 {
593   {"fpsid", 0x00000000},
594   {"FPSID", 0x00000000},
595   {"fpscr", 0x00010000},
596   {"FPSCR", 0x00010000},
597   {"fpexc", 0x00080000},
598   {"FPEXC", 0x00080000}
599 };
600
601 /* Structure for a hash table entry for a register.  */
602 struct reg_entry
603 {
604   const char * name;
605   int          number;
606   bfd_boolean  builtin;
607 };
608
609 /* Some well known registers that we refer to directly elsewhere.  */
610 #define REG_SP  13
611 #define REG_LR  14
612 #define REG_PC  15
613
614 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
615 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
616 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
617
618 /* These are the standard names.  Users can add aliases with .req.
619    and delete them with .unreq.  */
620
621 /* Integer Register Numbers.  */
622 static const struct reg_entry rn_table[] =
623 {
624   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
625   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
626   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
627   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
628   /* ATPCS Synonyms.  */
629   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
630   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
631   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
632   /* Well-known aliases.  */
633   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
634   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
635   {NULL, 0, TRUE}
636 };
637
638 #define WR_PREFIX 0x200
639 #define WC_PREFIX 0x400
640
641 static const struct reg_entry iwmmxt_table[] =
642 {
643   /* Intel Wireless MMX technology register names.  */
644   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
645   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
646   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
647   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
648   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
649   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
650   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
651   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
652   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
653   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
654   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
655   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
656
657   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
658   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
659   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
660   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
661   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
662   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
663   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
664   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
665   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
666   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
667   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
668   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
669   {NULL, 0, TRUE}
670 };
671
672 /* Co-processor Numbers.  */
673 static const struct reg_entry cp_table[] =
674 {
675   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
676   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
677   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
678   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
679   {NULL, 0, TRUE}
680 };
681
682 /* Co-processor Register Numbers.  */
683 static const struct reg_entry cn_table[] =
684 {
685   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
686   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
687   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
688   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
689   /* Not really valid, but kept for back-wards compatibility.  */
690   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
691   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
692   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
693   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
694   {NULL, 0, TRUE}
695 };
696
697 /* FPA Registers.  */
698 static const struct reg_entry fn_table[] =
699 {
700   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
701   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
702   {NULL, 0, TRUE}
703 };
704
705 /* VFP SP Registers.  */
706 static const struct reg_entry sn_table[] =
707 {
708   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
709   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
710   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
711   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
712   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
713   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
714   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
715   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
716   {NULL, 0, TRUE}
717 };
718
719 /* VFP DP Registers.  */
720 static const struct reg_entry dn_table[] =
721 {
722   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
723   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
724   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
725   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
726   {NULL, 0, TRUE}
727 };
728
729 /* Maverick DSP coprocessor registers.  */
730 static const struct reg_entry mav_mvf_table[] =
731 {
732   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
733   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
734   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
735   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
736   {NULL, 0, TRUE}
737 };
738
739 static const struct reg_entry mav_mvd_table[] =
740 {
741   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
742   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
743   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
744   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
745   {NULL, 0, TRUE}
746 };
747
748 static const struct reg_entry mav_mvfx_table[] =
749 {
750   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
751   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
752   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
753   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
754   {NULL, 0, TRUE}
755 };
756
757 static const struct reg_entry mav_mvdx_table[] =
758 {
759   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
760   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
761   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
762   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
763   {NULL, 0, TRUE}
764 };
765
766 static const struct reg_entry mav_mvax_table[] =
767 {
768   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
769   {NULL, 0, TRUE}
770 };
771
772 static const struct reg_entry mav_dspsc_table[] =
773 {
774   {"dspsc", 0, TRUE},
775   {NULL, 0, TRUE}
776 };
777
778 struct reg_map
779 {
780   const struct reg_entry *names;
781   int max_regno;
782   struct hash_control *htab;
783   const char *expected;
784 };
785
786 struct reg_map all_reg_maps[] =
787 {
788   {rn_table,        15, NULL, N_("ARM register expected")},
789   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
790   {cn_table,        15, NULL, N_("co-processor register expected")},
791   {fn_table,         7, NULL, N_("FPA register expected")},
792   {sn_table,        31, NULL, N_("VFP single precision register expected")},
793   {dn_table,        15, NULL, N_("VFP double precision register expected")},
794   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
795   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
796   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
797   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
798   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
799   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
800   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
801 };
802
803 /* Enumeration matching entries in table above.  */
804 enum arm_reg_type
805 {
806   REG_TYPE_RN = 0,
807 #define REG_TYPE_FIRST REG_TYPE_RN
808   REG_TYPE_CP = 1,
809   REG_TYPE_CN = 2,
810   REG_TYPE_FN = 3,
811   REG_TYPE_SN = 4,
812   REG_TYPE_DN = 5,
813   REG_TYPE_MVF = 6,
814   REG_TYPE_MVD = 7,
815   REG_TYPE_MVFX = 8,
816   REG_TYPE_MVDX = 9,
817   REG_TYPE_MVAX = 10,
818   REG_TYPE_DSPSC = 11,
819   REG_TYPE_IWMMXT = 12,
820
821   REG_TYPE_MAX = 13
822 };
823
824 /* Functions called by parser.  */
825 /* ARM instructions.  */
826 static void do_arit             PARAMS ((char *));
827 static void do_cmp              PARAMS ((char *));
828 static void do_mov              PARAMS ((char *));
829 static void do_ldst             PARAMS ((char *));
830 static void do_ldstt            PARAMS ((char *));
831 static void do_ldmstm           PARAMS ((char *));
832 static void do_branch           PARAMS ((char *));
833 static void do_swi              PARAMS ((char *));
834
835 /* Pseudo Op codes.  */
836 static void do_adr              PARAMS ((char *));
837 static void do_adrl             PARAMS ((char *));
838 static void do_empty            PARAMS ((char *));
839
840 /* ARM v2.  */
841 static void do_mul              PARAMS ((char *));
842 static void do_mla              PARAMS ((char *));
843
844 /* ARM v2S.  */
845 static void do_swap             PARAMS ((char *));
846
847 /* ARM v3.  */
848 static void do_msr              PARAMS ((char *));
849 static void do_mrs              PARAMS ((char *));
850
851 /* ARM v3M.  */
852 static void do_mull             PARAMS ((char *));
853
854 /* ARM v4.  */
855 static void do_ldstv4           PARAMS ((char *));
856
857 /* ARM v4T.  */
858 static void do_bx               PARAMS ((char *));
859
860 /* ARM v5T.  */
861 static void do_blx              PARAMS ((char *));
862 static void do_bkpt             PARAMS ((char *));
863 static void do_clz              PARAMS ((char *));
864 static void do_lstc2            PARAMS ((char *));
865 static void do_cdp2             PARAMS ((char *));
866 static void do_co_reg2          PARAMS ((char *));
867
868 /* ARM v5TExP.  */
869 static void do_smla             PARAMS ((char *));
870 static void do_smlal            PARAMS ((char *));
871 static void do_smul             PARAMS ((char *));
872 static void do_qadd             PARAMS ((char *));
873
874 /* ARM v5TE.  */
875 static void do_pld              PARAMS ((char *));
876 static void do_ldrd             PARAMS ((char *));
877 static void do_co_reg2c         PARAMS ((char *));
878
879 /* ARM v5TEJ.  */
880 static void do_bxj              PARAMS ((char *));
881
882 /* ARM V6. */
883 static void do_cps              PARAMS ((char *));
884 static void do_cpsi             PARAMS ((char *));
885 static void do_ldrex            PARAMS ((char *));
886 static void do_pkhbt            PARAMS ((char *));
887 static void do_pkhtb            PARAMS ((char *));
888 static void do_qadd16           PARAMS ((char *));
889 static void do_rev              PARAMS ((char *));
890 static void do_rfe              PARAMS ((char *));
891 static void do_sxtah            PARAMS ((char *));
892 static void do_sxth             PARAMS ((char *));
893 static void do_setend           PARAMS ((char *));
894 static void do_smlad            PARAMS ((char *));
895 static void do_smlald           PARAMS ((char *));
896 static void do_smmul            PARAMS ((char *));
897 static void do_ssat             PARAMS ((char *));
898 static void do_usat             PARAMS ((char *));
899 static void do_srs              PARAMS ((char *));
900 static void do_ssat16           PARAMS ((char *));
901 static void do_usat16           PARAMS ((char *));
902 static void do_strex            PARAMS ((char *));
903 static void do_umaal            PARAMS ((char *));
904
905 static void do_cps_mode         PARAMS ((char **));
906 static void do_cps_flags        PARAMS ((char **, int));
907 static int do_endian_specifier  PARAMS ((char *));
908 static void do_pkh_core         PARAMS ((char *, int));
909 static void do_sat              PARAMS ((char **, int));
910 static void do_sat16            PARAMS ((char **, int));
911
912 /* Coprocessor Instructions.  */
913 static void do_cdp              PARAMS ((char *));
914 static void do_lstc             PARAMS ((char *));
915 static void do_co_reg           PARAMS ((char *));
916
917 /* FPA instructions.  */
918 static void do_fpa_ctrl         PARAMS ((char *));
919 static void do_fpa_ldst         PARAMS ((char *));
920 static void do_fpa_ldmstm       PARAMS ((char *));
921 static void do_fpa_dyadic       PARAMS ((char *));
922 static void do_fpa_monadic      PARAMS ((char *));
923 static void do_fpa_cmp          PARAMS ((char *));
924 static void do_fpa_from_reg     PARAMS ((char *));
925 static void do_fpa_to_reg       PARAMS ((char *));
926
927 /* VFP instructions.  */
928 static void do_vfp_sp_monadic   PARAMS ((char *));
929 static void do_vfp_dp_monadic   PARAMS ((char *));
930 static void do_vfp_sp_dyadic    PARAMS ((char *));
931 static void do_vfp_dp_dyadic    PARAMS ((char *));
932 static void do_vfp_reg_from_sp  PARAMS ((char *));
933 static void do_vfp_sp_from_reg  PARAMS ((char *));
934 static void do_vfp_reg2_from_sp2 PARAMS ((char *));
935 static void do_vfp_sp2_from_reg2 PARAMS ((char *));
936 static void do_vfp_reg_from_dp  PARAMS ((char *));
937 static void do_vfp_reg2_from_dp PARAMS ((char *));
938 static void do_vfp_dp_from_reg  PARAMS ((char *));
939 static void do_vfp_dp_from_reg2 PARAMS ((char *));
940 static void do_vfp_reg_from_ctrl PARAMS ((char *));
941 static void do_vfp_ctrl_from_reg PARAMS ((char *));
942 static void do_vfp_sp_ldst      PARAMS ((char *));
943 static void do_vfp_dp_ldst      PARAMS ((char *));
944 static void do_vfp_sp_ldstmia   PARAMS ((char *));
945 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
946 static void do_vfp_dp_ldstmia   PARAMS ((char *));
947 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
948 static void do_vfp_xp_ldstmia   PARAMS ((char *));
949 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
950 static void do_vfp_sp_compare_z PARAMS ((char *));
951 static void do_vfp_dp_compare_z PARAMS ((char *));
952 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
953 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
954
955 /* XScale.  */
956 static void do_xsc_mia          PARAMS ((char *));
957 static void do_xsc_mar          PARAMS ((char *));
958 static void do_xsc_mra          PARAMS ((char *));
959
960 /* Maverick.  */
961 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
962                                          enum arm_reg_type));
963 static void do_mav_binops_1a    PARAMS ((char *));
964 static void do_mav_binops_1b    PARAMS ((char *));
965 static void do_mav_binops_1c    PARAMS ((char *));
966 static void do_mav_binops_1d    PARAMS ((char *));
967 static void do_mav_binops_1e    PARAMS ((char *));
968 static void do_mav_binops_1f    PARAMS ((char *));
969 static void do_mav_binops_1g    PARAMS ((char *));
970 static void do_mav_binops_1h    PARAMS ((char *));
971 static void do_mav_binops_1i    PARAMS ((char *));
972 static void do_mav_binops_1j    PARAMS ((char *));
973 static void do_mav_binops_1k    PARAMS ((char *));
974 static void do_mav_binops_1l    PARAMS ((char *));
975 static void do_mav_binops_1m    PARAMS ((char *));
976 static void do_mav_binops_1n    PARAMS ((char *));
977 static void do_mav_binops_1o    PARAMS ((char *));
978 static void do_mav_binops_2a    PARAMS ((char *));
979 static void do_mav_binops_2b    PARAMS ((char *));
980 static void do_mav_binops_2c    PARAMS ((char *));
981 static void do_mav_binops_3a    PARAMS ((char *));
982 static void do_mav_binops_3b    PARAMS ((char *));
983 static void do_mav_binops_3c    PARAMS ((char *));
984 static void do_mav_binops_3d    PARAMS ((char *));
985 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
986                                          enum arm_reg_type,
987                                          enum arm_reg_type));
988 static void do_mav_triple_4a    PARAMS ((char *));
989 static void do_mav_triple_4b    PARAMS ((char *));
990 static void do_mav_triple_5a    PARAMS ((char *));
991 static void do_mav_triple_5b    PARAMS ((char *));
992 static void do_mav_triple_5c    PARAMS ((char *));
993 static void do_mav_triple_5d    PARAMS ((char *));
994 static void do_mav_triple_5e    PARAMS ((char *));
995 static void do_mav_triple_5f    PARAMS ((char *));
996 static void do_mav_triple_5g    PARAMS ((char *));
997 static void do_mav_triple_5h    PARAMS ((char *));
998 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
999                                          enum arm_reg_type,
1000                                          enum arm_reg_type,
1001                                          enum arm_reg_type));
1002 static void do_mav_quad_6a      PARAMS ((char *));
1003 static void do_mav_quad_6b      PARAMS ((char *));
1004 static void do_mav_dspsc_1      PARAMS ((char *));
1005 static void do_mav_dspsc_2      PARAMS ((char *));
1006 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
1007                                          enum arm_reg_type));
1008 static void do_mav_shift_1      PARAMS ((char *));
1009 static void do_mav_shift_2      PARAMS ((char *));
1010 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
1011 static void do_mav_ldst_1       PARAMS ((char *));
1012 static void do_mav_ldst_2       PARAMS ((char *));
1013 static void do_mav_ldst_3       PARAMS ((char *));
1014 static void do_mav_ldst_4       PARAMS ((char *));
1015
1016 static int mav_reg_required_here        PARAMS ((char **, int,
1017                                                  enum arm_reg_type));
1018 static int mav_parse_offset     PARAMS ((char **, int *));
1019
1020 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
1021                                          int, int));
1022 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
1023 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1024 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1025 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
1026                                          fragS *));
1027 static int add_to_lit_pool      PARAMS ((void));
1028 static unsigned validate_immediate PARAMS ((unsigned));
1029 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1030                                                     unsigned int *));
1031 static int validate_offset_imm  PARAMS ((unsigned int, int));
1032 static void opcode_select       PARAMS ((int));
1033 static void end_of_line         PARAMS ((char *));
1034 static int reg_required_here    PARAMS ((char **, int));
1035 static int psr_required_here    PARAMS ((char **));
1036 static int co_proc_number       PARAMS ((char **));
1037 static int cp_opc_expr          PARAMS ((char **, int, int));
1038 static int cp_reg_required_here PARAMS ((char **, int));
1039 static int fp_reg_required_here PARAMS ((char **, int));
1040 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1041 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1042 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1043 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1044 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
1045 static long vfp_dp_reg_list     PARAMS ((char **));
1046 static int vfp_psr_required_here PARAMS ((char **str));
1047 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1048 static int cp_address_offset    PARAMS ((char **));
1049 static int cp_address_required_here     PARAMS ((char **, int));
1050 static int my_get_float_expression      PARAMS ((char **));
1051 static int skip_past_comma      PARAMS ((char **));
1052 static int walk_no_bignums      PARAMS ((symbolS *));
1053 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
1054 static int data_op2             PARAMS ((char **));
1055 static int fp_op2               PARAMS ((char **));
1056 static long reg_list            PARAMS ((char **));
1057 static void thumb_load_store    PARAMS ((char *, int, int));
1058 static int decode_shift         PARAMS ((char **, int));
1059 static int ldst_extend          PARAMS ((char **));
1060 static int ldst_extend_v4               PARAMS ((char **));
1061 static void thumb_add_sub       PARAMS ((char *, int));
1062 static void insert_reg          PARAMS ((const struct reg_entry *,
1063                                          struct hash_control *));
1064 static void thumb_shift         PARAMS ((char *, int));
1065 static void thumb_mov_compare   PARAMS ((char *, int));
1066 static void build_arm_ops_hsh   PARAMS ((void));
1067 static void set_constant_flonums        PARAMS ((void));
1068 static valueT md_chars_to_number        PARAMS ((char *, int));
1069 static void build_reg_hsh       PARAMS ((struct reg_map *));
1070 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
1071 static int create_register_alias        PARAMS ((char *, char *));
1072 static void output_inst         PARAMS ((const char *));
1073 static int accum0_required_here PARAMS ((char **));
1074 static int ld_mode_required_here PARAMS ((char **));
1075 static void do_branch25         PARAMS ((char *));
1076 static symbolS * find_real_start PARAMS ((symbolS *));
1077 #ifdef OBJ_ELF
1078 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1079 #endif
1080
1081 static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1082 static void do_iwmmxt_byte_addr PARAMS ((char *));
1083 static void do_iwmmxt_tandc     PARAMS ((char *));
1084 static void do_iwmmxt_tbcst     PARAMS ((char *));
1085 static void do_iwmmxt_textrc    PARAMS ((char *));
1086 static void do_iwmmxt_textrm    PARAMS ((char *));
1087 static void do_iwmmxt_tinsr     PARAMS ((char *));
1088 static void do_iwmmxt_tmcr      PARAMS ((char *));
1089 static void do_iwmmxt_tmcrr     PARAMS ((char *));
1090 static void do_iwmmxt_tmia      PARAMS ((char *));
1091 static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1092 static void do_iwmmxt_tmrc      PARAMS ((char *));
1093 static void do_iwmmxt_tmrrc     PARAMS ((char *));
1094 static void do_iwmmxt_torc      PARAMS ((char *));
1095 static void do_iwmmxt_waligni   PARAMS ((char *));
1096 static void do_iwmmxt_wmov      PARAMS ((char *));
1097 static void do_iwmmxt_word_addr PARAMS ((char *));
1098 static void do_iwmmxt_wrwr      PARAMS ((char *));
1099 static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1100 static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1101 static void do_iwmmxt_wshufh    PARAMS ((char *));
1102 static void do_iwmmxt_wzero     PARAMS ((char *));
1103 static int cp_byte_address_offset         PARAMS ((char **));
1104 static int cp_byte_address_required_here  PARAMS ((char **));
1105
1106 /* ARM instructions take 4bytes in the object file, Thumb instructions
1107    take 2:  */
1108 #define INSN_SIZE       4
1109
1110 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1111 #define MAV_MODE1       0x100c
1112
1113 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1114 #define MAV_MODE2       0x0c10
1115
1116 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1117 #define MAV_MODE3       0x100c
1118
1119 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1120 #define MAV_MODE4       0x0c0010
1121
1122 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1123 #define MAV_MODE5       0x00100c
1124
1125 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1126 #define MAV_MODE6       0x00100c05
1127
1128 struct asm_opcode
1129 {
1130   /* Basic string to match.  */
1131   const char * template;
1132
1133   /* Basic instruction code.  */
1134   unsigned long value;
1135
1136   /* Offset into the template where the condition code (if any) will be.
1137      If zero, then the instruction is never conditional.  */
1138   unsigned cond_offset;
1139
1140   /* Which architecture variant provides this instruction.  */
1141   unsigned long variant;
1142
1143   /* Function to call to parse args.  */
1144   void (* parms) PARAMS ((char *));
1145 };
1146
1147 static const struct asm_opcode insns[] =
1148 {
1149   /* Core ARM Instructions.  */
1150   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1151   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1152   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1153   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1154   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1155   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1156   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1157   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1158   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1159   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1160   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1161   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1162   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1163   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1164   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1165   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1166   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1167   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1168   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1169   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1170
1171   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1172   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1173   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1174   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1175   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1176   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1177   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1178   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1179   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1180   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1181   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1182   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1183
1184   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1185   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1186   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1187   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1188
1189   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1190   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1191   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1192   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1193   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1194   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1195   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1196   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1197
1198   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1199   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1200   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1201   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1202   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1203   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1204   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1205   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1206
1207   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1208   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1209   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1210   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1211   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1212   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1213   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1214   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1215
1216   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1217 #ifdef TE_WINCE
1218   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1219   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1220   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1221 #else
1222   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1223   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1224 #endif
1225
1226   /* Pseudo ops.  */
1227   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1228   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1229   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1230
1231   /* ARM 2 multiplies.  */
1232   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1233   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1234   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1235   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1236
1237   /* Generic coprocessor instructions.  */
1238   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1239   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1240   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1241   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1242   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1243   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1244   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1245
1246   /* ARM 3 - swp instructions.  */
1247   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1248   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1249
1250   /* ARM 6 Status register instructions.  */
1251   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1252   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1253   /* ScottB: our code uses     0xe128f000 for msr.
1254      NickC:  but this is wrong because the bits 16 through 19 are
1255              handled by the PSR_xxx defines above.  */
1256
1257   /* ARM 7M long multiplies.  */
1258   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1259   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1260   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1261   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1262   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1263   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1264   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1265   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1266
1267   /* ARM Architecture 4.  */
1268   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1269   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1270   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1271   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1272
1273   /* ARM Architecture 4T.  */
1274   /* Note: bx (and blx) are required on V5, even if the processor does
1275      not support Thumb.  */
1276   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1277
1278   /*  ARM Architecture 5T.  */
1279   /* Note: blx has 2 variants, so the .value is set dynamically.
1280      Only one of the variants has conditional execution.  */
1281   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1282   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1283   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1284   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1285   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1286   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1287   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1288   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1289   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1290   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1291
1292   /*  ARM Architecture 5TExP.  */
1293   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1294   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1295   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1296   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1297
1298   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1299   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1300
1301   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1302   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1303   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1304   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1305
1306   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1307   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1308   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1309   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1310
1311   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1312   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1313
1314   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1315   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1316   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1317   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1318
1319   /*  ARM Architecture 5TE.  */
1320   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1321   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1322   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1323
1324   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1325   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1326
1327   /*  ARM Architecture 5TEJ.  */
1328   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1329
1330   /*  ARM V6.  */
1331   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1332   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1333   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1334   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1335   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1336   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1337   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1338   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1339   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1340   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1341   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1342   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1343   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1344   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1345   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1346   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1347   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1348   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1349   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1350   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1351   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1352   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1353   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1354   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1355   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1356   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1357   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1358   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1359   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1360   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1361   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1362   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1363   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1364   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1365   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1366   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1367   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1368   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1369   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1370   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1371   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1372   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1373   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1374   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1375   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1376   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1377   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1378   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1379   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1380   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1381   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1382   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1383   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1384   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1385   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1386   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1387   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1388   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1389   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1390   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1391   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1392   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1393   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1394   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1395   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1396   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1397   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1398   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1399   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1400   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1401   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1402   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1403   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1404   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1405   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1406   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1407   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1408   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1409   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1410   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1411   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1412   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1413   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1414   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1415   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1416   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1417   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1418   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1419   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1420   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1421   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1422   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1423   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1424   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1425   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1426   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1427   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1428   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1429   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1430
1431   /* Core FPA instruction set (V1).  */
1432   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1433   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1434   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1435   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1436
1437   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1438   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1439   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1440   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1441
1442   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1443   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1444   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1445   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1446
1447   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1448   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1449   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1450   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1457   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459
1460   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1463   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1470   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472
1473   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1476   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1483   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485
1486   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1489   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1496   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498
1499   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1502   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1509   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511
1512   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1515   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1522   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524
1525   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1528   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1535   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537
1538   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1541   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1548   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550
1551   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1554   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1561   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563
1564   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1567   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1574   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576
1577   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1580   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1587   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1588   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1589
1590   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1591   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1592   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1593   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1594   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1595   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1596   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1597   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1598   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1599   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1600   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1601   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1602
1603   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1604   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1605   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1606   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1607   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1608   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1609   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1610   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1611   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1612   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1613   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1614   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1615
1616   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1617   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1618   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1619   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1620   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1621   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1622   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1623   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1624   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1625   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1626   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1627   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1628
1629   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1630   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1631   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1632   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1633   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1634   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1635   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1636   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1637   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1638   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1639   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1640   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1641
1642   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1643   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1644   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1645   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1646   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1647   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1648   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1649   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1650   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1651   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1652   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1653   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1654
1655   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1656   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1657   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1658   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1665   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667
1668   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1671   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1678   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680
1681   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1684   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1691   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693
1694   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1697   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1704   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706
1707   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1710   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1717   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719
1720   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1723   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1730   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732
1733   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1736   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1743   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745
1746   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1749   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1756   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1757   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1758
1759   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1760   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1761   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1762   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1763   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1764   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1765   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1766   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1767   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1768   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1769   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1770   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1771
1772   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1773   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1774   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1775   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1776   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1777   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1778   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1779   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1780   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1781   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1782   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1783   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1784
1785   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1786   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1787   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1788   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1789   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1790   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1791   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1792   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1793   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1794   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1795   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1796   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1797
1798   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1799   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1800   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1801   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1802   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1803   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1804   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1805   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1806   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1807   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1808   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1809   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1810
1811   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1812   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1813   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1814   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1815   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1816   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1817   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1818   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1819   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1820   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1821   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1822   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1823
1824   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1825   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1826   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1827   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1828   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1829      not be an optional suffix, but part of the instruction.  To be
1830      compatible, we accept either.  */
1831   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1832   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1833
1834   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1835   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1836   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1837   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1838   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1839   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1840   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1841   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1842   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1843   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1844   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1845   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1846
1847   /* The implementation of the FIX instruction is broken on some
1848      assemblers, in that it accepts a precision specifier as well as a
1849      rounding specifier, despite the fact that this is meaningless.
1850      To be more compatible, we accept it as well, though of course it
1851      does not set any bits.  */
1852   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1853   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1854   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1855   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1856   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1857   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1858   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1859   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1860   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1861   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1862   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1863   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1864   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1865
1866   /* Instructions that were new with the real FPA, call them V2.  */
1867   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1868   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1869   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1870   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1871   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1872   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1873
1874   /* VFP V1xD (single precision).  */
1875   /* Moves and type conversions.  */
1876   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1877   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1878   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1879   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1880   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1881   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1882   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1883   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1884   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1885   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1886   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1887   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1888
1889   /* Memory operations.  */
1890   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1891   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1892   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1893   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1894   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1895   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1896   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1897   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1898   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1899   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1900   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1901   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1902   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1903   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1904   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1905   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1906   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1907   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1908
1909   /* Monadic operations.  */
1910   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1911   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1912   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1913
1914   /* Dyadic operations.  */
1915   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1916   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1917   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1918   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1922   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1923   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1924
1925   /* Comparisons.  */
1926   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1927   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1928   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1929   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1930
1931   /* VFP V1 (Double precision).  */
1932   /* Moves and type conversions.  */
1933   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1934   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1935   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1936   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1937   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1938   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1939   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1940   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1941   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1942   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1943   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1944   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1945   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1946
1947   /* Memory operations.  */
1948   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1949   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1950   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1951   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1952   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1953   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1954   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1955   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1956   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1957   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1958
1959   /* Monadic operations.  */
1960   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1961   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1962   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1963
1964   /* Dyadic operations.  */
1965   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1966   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1967   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1968   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1969   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1970   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1971   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1972   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1973   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1974
1975   /* Comparisons.  */
1976   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1977   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1978   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1979   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1980
1981   /* VFP V2.  */
1982   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
1983   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
1984   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1985   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1986
1987   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1988   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1989   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1990   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1991   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1992   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1993   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1994   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1995   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1996
1997   /* Intel Wireless MMX technology instructions.  */
1998   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1999   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2000   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2001   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2002   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2003   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2004   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2005   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2006   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2007   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2008   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2009   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2010   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2011   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2012   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2013   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2014   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2015   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2016   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2017   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2018   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2019   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2020   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2021   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2022   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2023   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2024   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2025   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2026   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2027   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2028   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2029   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2030   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2031   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2032   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2033   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2034   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2035   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2036   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2045   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2062   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2063   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2065   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2066   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2067   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2068   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2069   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2084   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2087   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2097   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2099   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2100   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2101   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2102   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2103   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2104   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2105   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2106   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2107   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2108   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2109   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2110   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2111   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2112   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2113   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2114   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2115   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2116   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2117   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2118   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2119   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2120   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2121   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2122   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2123   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2124   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2125   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2126   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2127   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2128   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2129   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2130   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2131   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2132   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2133   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2134   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2138   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2139   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2140   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2141   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2142   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2143   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2144   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2145   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2146   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2147   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2148   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2149   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2150   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2151   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2152   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2153   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2154   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2155   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2156   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2157   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2158   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2159   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2160
2161   /* Cirrus Maverick instructions.  */
2162   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2163   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2164   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2165   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2166   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2167   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2168   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2169   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2170   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2171   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2172   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2173   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2174   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2175   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2176   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2177   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2178   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2179   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2180   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2181   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2182   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2183   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2184   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2185   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2186   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2187   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2188   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2189   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2190   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2191   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2192   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2193   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2194   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2195   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2196   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2197   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2198   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2199   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2200   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2201   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2202   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2203   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2204   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2205   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2206   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2207   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2208   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2209   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2210   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2211   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2212   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2213   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2214   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2215   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2216   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2217   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2218   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2219   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2220   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2221   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2222   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2223   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2224   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2225   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2226   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2227   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2228   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2229   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2230   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2231   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2232   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2233   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2234   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2235   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2236   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2237   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2238 };
2239
2240 /* Defines for various bits that we will want to toggle.  */
2241 #define INST_IMMEDIATE  0x02000000
2242 #define OFFSET_REG      0x02000000
2243 #define HWOFFSET_IMM    0x00400000
2244 #define SHIFT_BY_REG    0x00000010
2245 #define PRE_INDEX       0x01000000
2246 #define INDEX_UP        0x00800000
2247 #define WRITE_BACK      0x00200000
2248 #define LDM_TYPE_2_OR_3 0x00400000
2249
2250 #define LITERAL_MASK    0xf000f000
2251 #define OPCODE_MASK     0xfe1fffff
2252 #define V4_STR_BIT      0x00000020
2253
2254 #define DATA_OP_SHIFT   21
2255
2256 /* Codes to distinguish the arithmetic instructions.  */
2257 #define OPCODE_AND      0
2258 #define OPCODE_EOR      1
2259 #define OPCODE_SUB      2
2260 #define OPCODE_RSB      3
2261 #define OPCODE_ADD      4
2262 #define OPCODE_ADC      5
2263 #define OPCODE_SBC      6
2264 #define OPCODE_RSC      7
2265 #define OPCODE_TST      8
2266 #define OPCODE_TEQ      9
2267 #define OPCODE_CMP      10
2268 #define OPCODE_CMN      11
2269 #define OPCODE_ORR      12
2270 #define OPCODE_MOV      13
2271 #define OPCODE_BIC      14
2272 #define OPCODE_MVN      15
2273
2274 /* Thumb v1 (ARMv4T).  */
2275 static void do_t_nop            PARAMS ((char *));
2276 static void do_t_arit           PARAMS ((char *));
2277 static void do_t_add            PARAMS ((char *));
2278 static void do_t_asr            PARAMS ((char *));
2279 static void do_t_branch9        PARAMS ((char *));
2280 static void do_t_branch12       PARAMS ((char *));
2281 static void do_t_branch23       PARAMS ((char *));
2282 static void do_t_bx             PARAMS ((char *));
2283 static void do_t_compare        PARAMS ((char *));
2284 static void do_t_ldmstm         PARAMS ((char *));
2285 static void do_t_ldr            PARAMS ((char *));
2286 static void do_t_ldrb           PARAMS ((char *));
2287 static void do_t_ldrh           PARAMS ((char *));
2288 static void do_t_lds            PARAMS ((char *));
2289 static void do_t_lsl            PARAMS ((char *));
2290 static void do_t_lsr            PARAMS ((char *));
2291 static void do_t_mov            PARAMS ((char *));
2292 static void do_t_push_pop       PARAMS ((char *));
2293 static void do_t_str            PARAMS ((char *));
2294 static void do_t_strb           PARAMS ((char *));
2295 static void do_t_strh           PARAMS ((char *));
2296 static void do_t_sub            PARAMS ((char *));
2297 static void do_t_swi            PARAMS ((char *));
2298 static void do_t_adr            PARAMS ((char *));
2299
2300 /* Thumb v2 (ARMv5T).  */
2301 static void do_t_blx            PARAMS ((char *));
2302 static void do_t_bkpt           PARAMS ((char *));
2303
2304 /* ARM V6.  */
2305 static void do_t_cps            PARAMS ((char *));
2306 static void do_t_cpy            PARAMS ((char *));
2307 static void do_t_setend         PARAMS ((char *));;
2308
2309 #define T_OPCODE_MUL 0x4340
2310 #define T_OPCODE_TST 0x4200
2311 #define T_OPCODE_CMN 0x42c0
2312 #define T_OPCODE_NEG 0x4240
2313 #define T_OPCODE_MVN 0x43c0
2314
2315 #define T_OPCODE_ADD_R3 0x1800
2316 #define T_OPCODE_SUB_R3 0x1a00
2317 #define T_OPCODE_ADD_HI 0x4400
2318 #define T_OPCODE_ADD_ST 0xb000
2319 #define T_OPCODE_SUB_ST 0xb080
2320 #define T_OPCODE_ADD_SP 0xa800
2321 #define T_OPCODE_ADD_PC 0xa000
2322 #define T_OPCODE_ADD_I8 0x3000
2323 #define T_OPCODE_SUB_I8 0x3800
2324 #define T_OPCODE_ADD_I3 0x1c00
2325 #define T_OPCODE_SUB_I3 0x1e00
2326
2327 #define T_OPCODE_ASR_R  0x4100
2328 #define T_OPCODE_LSL_R  0x4080
2329 #define T_OPCODE_LSR_R  0x40c0
2330 #define T_OPCODE_ASR_I  0x1000
2331 #define T_OPCODE_LSL_I  0x0000
2332 #define T_OPCODE_LSR_I  0x0800
2333
2334 #define T_OPCODE_MOV_I8 0x2000
2335 #define T_OPCODE_CMP_I8 0x2800
2336 #define T_OPCODE_CMP_LR 0x4280
2337 #define T_OPCODE_MOV_HR 0x4600
2338 #define T_OPCODE_CMP_HR 0x4500
2339
2340 #define T_OPCODE_LDR_PC 0x4800
2341 #define T_OPCODE_LDR_SP 0x9800
2342 #define T_OPCODE_STR_SP 0x9000
2343 #define T_OPCODE_LDR_IW 0x6800
2344 #define T_OPCODE_STR_IW 0x6000
2345 #define T_OPCODE_LDR_IH 0x8800
2346 #define T_OPCODE_STR_IH 0x8000
2347 #define T_OPCODE_LDR_IB 0x7800
2348 #define T_OPCODE_STR_IB 0x7000
2349 #define T_OPCODE_LDR_RW 0x5800
2350 #define T_OPCODE_STR_RW 0x5000
2351 #define T_OPCODE_LDR_RH 0x5a00
2352 #define T_OPCODE_STR_RH 0x5200
2353 #define T_OPCODE_LDR_RB 0x5c00
2354 #define T_OPCODE_STR_RB 0x5400
2355
2356 #define T_OPCODE_PUSH   0xb400
2357 #define T_OPCODE_POP    0xbc00
2358
2359 #define T_OPCODE_BRANCH 0xe7fe
2360
2361 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
2362
2363 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
2364 #define THUMB_REG_LO    0x1
2365 #define THUMB_REG_HI    0x2
2366 #define THUMB_REG_ANY   0x3
2367
2368 #define THUMB_H1        0x0080
2369 #define THUMB_H2        0x0040
2370
2371 #define THUMB_ASR 0
2372 #define THUMB_LSL 1
2373 #define THUMB_LSR 2
2374
2375 #define THUMB_MOVE 0
2376 #define THUMB_COMPARE 1
2377 #define THUMB_CPY 2
2378
2379 #define THUMB_LOAD 0
2380 #define THUMB_STORE 1
2381
2382 #define THUMB_PP_PC_LR 0x0100
2383
2384 /* These three are used for immediate shifts, do not alter.  */
2385 #define THUMB_WORD 2
2386 #define THUMB_HALFWORD 1
2387 #define THUMB_BYTE 0
2388
2389 struct thumb_opcode
2390 {
2391   /* Basic string to match.  */
2392   const char * template;
2393
2394   /* Basic instruction code.  */
2395   unsigned long value;
2396
2397   int size;
2398
2399   /* Which CPU variants this exists for.  */
2400   unsigned long variant;
2401
2402   /* Function to call to parse args.  */
2403   void (* parms) PARAMS ((char *));
2404 };
2405
2406 static const struct thumb_opcode tinsns[] =
2407 {
2408   /* Thumb v1 (ARMv4T).  */
2409   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
2410   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
2411   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
2412   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
2413   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
2414   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
2415   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
2416   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2417   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2418   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2419   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2420   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2421   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
2422   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
2423   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
2424   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
2425   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
2426   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
2427   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
2428   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
2429   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
2430   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
2431   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
2432   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
2433   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
2434   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
2435   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2436   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2437   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2438   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2439   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2440   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2441   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2442   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2443   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2444   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2445   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2446   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2447   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2448   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2449   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2450   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2451   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2452   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2453   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2454   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2455   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2456   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2457   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2458   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2459   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2460   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2461   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2462   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2463   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2464   /* Pseudo ops:  */
2465   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2466   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2467   /* Thumb v2 (ARMv5T).  */
2468   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2469   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2470
2471   /* ARM V6.  */
2472   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
2473   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
2474   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
2475   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
2476   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
2477   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
2478   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
2479   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
2480   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
2481   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
2482   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
2483 };
2484
2485 #define BAD_ARGS        _("bad arguments to instruction")
2486 #define BAD_PC          _("r15 not allowed here")
2487 #define BAD_COND        _("instruction is not conditional")
2488 #define ERR_NO_ACCUM    _("acc0 expected")
2489
2490 static struct hash_control * arm_ops_hsh   = NULL;
2491 static struct hash_control * arm_tops_hsh  = NULL;
2492 static struct hash_control * arm_cond_hsh  = NULL;
2493 static struct hash_control * arm_shift_hsh = NULL;
2494 static struct hash_control * arm_psr_hsh   = NULL;
2495
2496 /* This table describes all the machine specific pseudo-ops the assembler
2497    has to support.  The fields are:
2498      pseudo-op name without dot
2499      function to call to execute this pseudo-op
2500      Integer arg to pass to the function.  */
2501
2502 static void s_req PARAMS ((int));
2503 static void s_unreq PARAMS ((int));
2504 static void s_align PARAMS ((int));
2505 static void s_bss PARAMS ((int));
2506 static void s_even PARAMS ((int));
2507 static void s_ltorg PARAMS ((int));
2508 static void s_arm PARAMS ((int));
2509 static void s_thumb PARAMS ((int));
2510 static void s_code PARAMS ((int));
2511 static void s_force_thumb PARAMS ((int));
2512 static void s_thumb_func PARAMS ((int));
2513 static void s_thumb_set PARAMS ((int));
2514 #ifdef OBJ_ELF
2515 static void s_arm_elf_cons PARAMS ((int));
2516 #endif
2517
2518 static int my_get_expression PARAMS ((expressionS *, char **));
2519
2520 const pseudo_typeS md_pseudo_table[] =
2521 {
2522   /* Never called because '.req' does not start a line.  */
2523   { "req",         s_req,         0 },
2524   { "unreq",       s_unreq,       0 },
2525   { "bss",         s_bss,         0 },
2526   { "align",       s_align,       0 },
2527   { "arm",         s_arm,         0 },
2528   { "thumb",       s_thumb,       0 },
2529   { "code",        s_code,        0 },
2530   { "force_thumb", s_force_thumb, 0 },
2531   { "thumb_func",  s_thumb_func,  0 },
2532   { "thumb_set",   s_thumb_set,   0 },
2533   { "even",        s_even,        0 },
2534   { "ltorg",       s_ltorg,       0 },
2535   { "pool",        s_ltorg,       0 },
2536 #ifdef OBJ_ELF
2537   { "word",        s_arm_elf_cons, 4 },
2538   { "long",        s_arm_elf_cons, 4 },
2539 #else
2540   { "word",        cons, 4},
2541 #endif
2542   { "extend",      float_cons, 'x' },
2543   { "ldouble",     float_cons, 'x' },
2544   { "packed",      float_cons, 'p' },
2545   { 0, 0, 0 }
2546 };
2547
2548 /* Other internal functions.  */
2549 static int arm_parse_extension PARAMS ((char *, int *));
2550 static int arm_parse_cpu PARAMS ((char *));
2551 static int arm_parse_arch PARAMS ((char *));
2552 static int arm_parse_fpu PARAMS ((char *));
2553 static int arm_parse_float_abi PARAMS ((char *));
2554 #if 0 /* Suppressed - for now.  */
2555 #if defined OBJ_COFF || defined OBJ_ELF
2556 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2557 #endif
2558 #endif
2559
2560 /* Stuff needed to resolve the label ambiguity
2561    As:
2562      ...
2563      label:   <insn>
2564    may differ from:
2565      ...
2566      label:
2567               <insn>
2568 */
2569
2570 symbolS *  last_label_seen;
2571 static int label_is_thumb_function_name = FALSE;
2572
2573 /* Literal Pool stuff.  */
2574
2575 #define MAX_LITERAL_POOL_SIZE 1024
2576
2577 /* Literal pool structure.  Held on a per-section
2578    and per-sub-section basis.  */
2579 typedef struct literal_pool
2580 {
2581   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2582   unsigned int   next_free_entry;
2583   unsigned int   id;
2584   symbolS *      symbol;
2585   segT           section;
2586   subsegT        sub_section;
2587   struct literal_pool * next;
2588 } literal_pool;
2589
2590 /* Pointer to a linked list of literal pools.  */
2591 literal_pool * list_of_pools = NULL;
2592
2593 static literal_pool * find_literal_pool PARAMS ((void));
2594 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2595
2596 static literal_pool *
2597 find_literal_pool ()
2598 {
2599   literal_pool * pool;
2600
2601   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2602     {
2603       if (pool->section == now_seg
2604           && pool->sub_section == now_subseg)
2605         break;
2606     }
2607
2608   return pool;
2609 }
2610
2611 static literal_pool *
2612 find_or_make_literal_pool ()
2613 {
2614   /* Next literal pool ID number.  */
2615   static unsigned int latest_pool_num = 1;
2616   literal_pool *      pool;
2617
2618   pool = find_literal_pool ();
2619
2620   if (pool == NULL)
2621     {
2622       /* Create a new pool.  */
2623       pool = (literal_pool *) xmalloc (sizeof (* pool));
2624       if (! pool)
2625         return NULL;
2626
2627       pool->next_free_entry = 0;
2628       pool->section         = now_seg;
2629       pool->sub_section     = now_subseg;
2630       pool->next            = list_of_pools;
2631       pool->symbol          = NULL;
2632
2633       /* Add it to the list.  */
2634       list_of_pools = pool;
2635     }
2636
2637   /* New pools, and emptied pools, will have a NULL symbol.  */
2638   if (pool->symbol == NULL)
2639     {
2640       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2641                                     (valueT) 0, &zero_address_frag);
2642       pool->id = latest_pool_num ++;
2643     }
2644
2645   /* Done.  */
2646   return pool;
2647 }
2648
2649 /* Add the literal in the global 'inst'
2650    structure to the relevent literal pool.  */
2651 static int
2652 add_to_lit_pool ()
2653 {
2654   literal_pool * pool;
2655   unsigned int entry;
2656
2657   pool = find_or_make_literal_pool ();
2658
2659   /* Check if this literal value is already in the pool.  */
2660   for (entry = 0; entry < pool->next_free_entry; entry ++)
2661     {
2662       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2663           && (inst.reloc.exp.X_op == O_constant)
2664           && (pool->literals[entry].X_add_number
2665               == inst.reloc.exp.X_add_number)
2666           && (pool->literals[entry].X_unsigned
2667               == inst.reloc.exp.X_unsigned))
2668         break;
2669
2670       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2671           && (inst.reloc.exp.X_op == O_symbol)
2672           && (pool->literals[entry].X_add_number
2673               == inst.reloc.exp.X_add_number)
2674           && (pool->literals[entry].X_add_symbol
2675               == inst.reloc.exp.X_add_symbol)
2676           && (pool->literals[entry].X_op_symbol
2677               == inst.reloc.exp.X_op_symbol))
2678         break;
2679     }
2680
2681   /* Do we need to create a new entry?  */
2682   if (entry == pool->next_free_entry)
2683     {
2684       if (entry >= MAX_LITERAL_POOL_SIZE)
2685         {
2686           inst.error = _("literal pool overflow");
2687           return FAIL;
2688         }
2689
2690       pool->literals[entry] = inst.reloc.exp;
2691       pool->next_free_entry += 1;
2692     }
2693
2694   inst.reloc.exp.X_op         = O_symbol;
2695   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2696   inst.reloc.exp.X_add_symbol = pool->symbol;
2697
2698   return SUCCESS;
2699 }
2700
2701 /* Can't use symbol_new here, so have to create a symbol and then at
2702    a later date assign it a value. Thats what these functions do.  */
2703
2704 static void
2705 symbol_locate (symbolP, name, segment, valu, frag)
2706      symbolS *    symbolP;
2707      const char * name;         /* It is copied, the caller can modify.  */
2708      segT         segment;      /* Segment identifier (SEG_<something>).  */
2709      valueT       valu;         /* Symbol value.  */
2710      fragS *      frag;         /* Associated fragment.  */
2711 {
2712   unsigned int name_length;
2713   char * preserved_copy_of_name;
2714
2715   name_length = strlen (name) + 1;   /* +1 for \0.  */
2716   obstack_grow (&notes, name, name_length);
2717   preserved_copy_of_name = obstack_finish (&notes);
2718 #ifdef STRIP_UNDERSCORE
2719   if (preserved_copy_of_name[0] == '_')
2720     preserved_copy_of_name++;
2721 #endif
2722
2723 #ifdef tc_canonicalize_symbol_name
2724   preserved_copy_of_name =
2725     tc_canonicalize_symbol_name (preserved_copy_of_name);
2726 #endif
2727
2728   S_SET_NAME (symbolP, preserved_copy_of_name);
2729
2730   S_SET_SEGMENT (symbolP, segment);
2731   S_SET_VALUE (symbolP, valu);
2732   symbol_clear_list_pointers (symbolP);
2733
2734   symbol_set_frag (symbolP, frag);
2735
2736   /* Link to end of symbol chain.  */
2737   {
2738     extern int symbol_table_frozen;
2739     if (symbol_table_frozen)
2740       abort ();
2741   }
2742
2743   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2744
2745   obj_symbol_new_hook (symbolP);
2746
2747 #ifdef tc_symbol_new_hook
2748   tc_symbol_new_hook (symbolP);
2749 #endif
2750
2751 #ifdef DEBUG_SYMS
2752   verify_symbol_chain (symbol_rootP, symbol_lastP);
2753 #endif /* DEBUG_SYMS  */
2754 }
2755
2756 /* Check that an immediate is valid.
2757    If so, convert it to the right format.  */
2758
2759 static unsigned int
2760 validate_immediate (val)
2761      unsigned int val;
2762 {
2763   unsigned int a;
2764   unsigned int i;
2765
2766 #define rotate_left(v, n) (v << n | v >> (32 - n))
2767
2768   for (i = 0; i < 32; i += 2)
2769     if ((a = rotate_left (val, i)) <= 0xff)
2770       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2771
2772   return FAIL;
2773 }
2774
2775 /* Check to see if an immediate can be computed as two separate immediate
2776    values, added together.  We already know that this value cannot be
2777    computed by just one ARM instruction.  */
2778
2779 static unsigned int
2780 validate_immediate_twopart (val, highpart)
2781      unsigned int   val;
2782      unsigned int * highpart;
2783 {
2784   unsigned int a;
2785   unsigned int i;
2786
2787   for (i = 0; i < 32; i += 2)
2788     if (((a = rotate_left (val, i)) & 0xff) != 0)
2789       {
2790         if (a & 0xff00)
2791           {
2792             if (a & ~ 0xffff)
2793               continue;
2794             * highpart = (a  >> 8) | ((i + 24) << 7);
2795           }
2796         else if (a & 0xff0000)
2797           {
2798             if (a & 0xff000000)
2799               continue;
2800             * highpart = (a >> 16) | ((i + 16) << 7);
2801           }
2802         else
2803           {
2804             assert (a & 0xff000000);
2805             * highpart = (a >> 24) | ((i + 8) << 7);
2806           }
2807
2808         return (a & 0xff) | (i << 7);
2809       }
2810
2811   return FAIL;
2812 }
2813
2814 static int
2815 validate_offset_imm (val, hwse)
2816      unsigned int val;
2817      int hwse;
2818 {
2819   if ((hwse && val > 255) || val > 4095)
2820     return FAIL;
2821   return val;
2822 }
2823
2824 \f
2825 #ifdef OBJ_ELF
2826 enum mstate
2827 {
2828   MAP_DATA,
2829   MAP_ARM,
2830   MAP_THUMB
2831 };
2832
2833 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2834    (This text is taken from version B-02 of the spec):
2835
2836       4.4.7 Mapping and tagging symbols
2837
2838       A section of an ARM ELF file can contain a mixture of ARM code,
2839       Thumb code, and data.  There are inline transitions between code
2840       and data at literal pool boundaries. There can also be inline
2841       transitions between ARM code and Thumb code, for example in
2842       ARM-Thumb inter-working veneers.  Linkers, machine-level
2843       debuggers, profiling tools, and disassembly tools need to map
2844       images accurately. For example, setting an ARM breakpoint on a
2845       Thumb location, or in a literal pool, can crash the program
2846       being debugged, ruining the debugging session.
2847
2848       ARM ELF entities are mapped (see section 4.4.7.1 below) and
2849       tagged (see section 4.4.7.2 below) using local symbols (with
2850       binding STB_LOCAL).  To assist consumers, mapping and tagging
2851       symbols should be collated first in the symbol table, before
2852       other symbols with binding STB_LOCAL.
2853
2854       To allow properly collated mapping and tagging symbols to be
2855       skipped by consumers that have no interest in them, the first
2856       such symbol should have the name $m and its st_value field equal
2857       to the total number of mapping and tagging symbols (including
2858       the $m) in the symbol table.
2859
2860       4.4.7.1 Mapping symbols
2861
2862       $a    Labels the first byte of a sequence of ARM instructions.
2863             Its type is STT_FUNC.
2864
2865       $d    Labels the first byte of a sequence of data items.
2866             Its type is STT_OBJECT.
2867
2868       $t    Labels the first byte of a sequence of Thumb instructions.
2869             Its type is STT_FUNC.
2870
2871       This list of mapping symbols may be extended in the future.
2872
2873       Section-relative mapping symbols
2874
2875       Mapping symbols defined in a section define a sequence of
2876       half-open address intervals that cover the address range of the
2877       section. Each interval starts at the address defined by a
2878       mapping symbol, and continues up to, but not including, the
2879       address defined by the next (in address order) mapping symbol or
2880       the end of the section. A corollary is that there must be a
2881       mapping symbol defined at the beginning of each section.
2882       Consumers can ignore the size of a section-relative mapping
2883       symbol. Producers can set it to 0.
2884
2885       Absolute mapping symbols
2886
2887       Because of the need to crystallize a Thumb address with the
2888       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2889       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2890       or $t.
2891
2892       The extent of a mapping symbol defined in SHN_ABS is [st_value,
2893       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2894       where [x, y) denotes the half-open address range from x,
2895       inclusive, to y, exclusive.
2896
2897       In the absence of a mapping symbol, a consumer can interpret a
2898       function symbol with an odd value as the Thumb code address
2899       obtained by clearing the least significant bit of the
2900       value. This interpretation is deprecated, and it may not work in
2901       the future.
2902
2903    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2904    the EABI (which is still under development), so they are not
2905    implemented here.  */
2906
2907 static void
2908 mapping_state (enum mstate state)
2909 {
2910   static enum mstate mapstate = MAP_DATA;
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     default:
2937       abort ();
2938     }
2939
2940   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2941   symbol_table_insert (symbolP);
2942   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2943   
2944   switch (state)
2945     {
2946     case MAP_ARM:
2947       THUMB_SET_FUNC (symbolP, 0);
2948       ARM_SET_THUMB (symbolP, 0);
2949       ARM_SET_INTERWORK (symbolP, support_interwork);
2950       break;
2951       
2952     case MAP_THUMB:
2953       THUMB_SET_FUNC (symbolP, 1);
2954       ARM_SET_THUMB (symbolP, 1);
2955       ARM_SET_INTERWORK (symbolP, support_interwork);
2956       break;
2957       
2958     case MAP_DATA:
2959     default:
2960       return;
2961     }
2962 }
2963
2964 /* When we change sections we need to issue a new mapping symbol.  */
2965
2966 void
2967 arm_elf_change_section (void)
2968 {
2969   flagword flags;
2970
2971   if (!SEG_NORMAL (now_seg))
2972     return;
2973
2974   flags = bfd_get_section_flags (stdoutput, now_seg);
2975
2976   /* We can ignore sections that only contain debug info.  */
2977   if ((flags & SEC_ALLOC) == 0)
2978     return;
2979
2980   if (flags & SEC_CODE)
2981     {
2982       if (thumb_mode)
2983         mapping_state (MAP_THUMB);
2984       else
2985         mapping_state (MAP_ARM);
2986     }
2987   else
2988     /* This section does not contain code.  Therefore it must contain data.  */
2989     mapping_state (MAP_DATA);    
2990 }
2991 #else
2992 #define mapping_state(a)
2993 #endif /* OBJ_ELF */
2994 \f
2995
2996 static void
2997 s_req (a)
2998      int a ATTRIBUTE_UNUSED;
2999 {
3000   as_bad (_("invalid syntax for .req directive"));
3001 }
3002
3003 /* The .unreq directive deletes an alias which was previously defined
3004    by .req.  For example:
3005
3006        my_alias .req r11
3007        .unreq my_alias    */
3008
3009 static void
3010 s_unreq (int a ATTRIBUTE_UNUSED)
3011 {
3012   char *name;
3013   char saved_char;
3014
3015   skip_whitespace (input_line_pointer);
3016   name = input_line_pointer;
3017
3018   while (*input_line_pointer != 0
3019          && *input_line_pointer != ' '
3020          && *input_line_pointer != '\n')
3021     ++input_line_pointer;
3022
3023   saved_char = *input_line_pointer;
3024   *input_line_pointer = 0;
3025
3026   if (*name)
3027     {
3028       enum arm_reg_type req_type = arm_reg_parse_any (name);
3029
3030       if (req_type != REG_TYPE_MAX)
3031         {
3032           char *temp_name = name;
3033           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3034
3035           if (req_no != FAIL)
3036             {
3037               struct reg_entry *req_entry;
3038
3039               /* Check to see if this alias is a builtin one.  */
3040               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3041
3042               if (!req_entry)
3043                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
3044               else if (req_entry->builtin)
3045                 /* FIXME: We are deleting a built in register alias which
3046                    points to a const data structure, so we only need to
3047                    free up the memory used by the key in the hash table.
3048                    Unfortunately we have not recorded this value, so this
3049                    is a memory leak.  */
3050                   /* FIXME: Should we issue a warning message ?  */
3051                 ;
3052               else
3053                 {
3054                   /* Deleting a user defined alias.  We need to free the
3055                      key and the value, but fortunately the key is the same
3056                      as the value->name field.  */
3057                   free ((char *) req_entry->name);
3058                   free (req_entry);
3059                 }
3060             }
3061           else
3062             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3063         }
3064       else
3065         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3066     }
3067   else
3068     as_bad (_("invalid syntax for .unreq directive"));
3069
3070   *input_line_pointer = saved_char;
3071   demand_empty_rest_of_line ();
3072 }
3073
3074 static void
3075 s_bss (ignore)
3076      int ignore ATTRIBUTE_UNUSED;
3077 {
3078   /* We don't support putting frags in the BSS segment, we fake it by
3079      marking in_bss, then looking at s_skip for clues.  */
3080   subseg_set (bss_section, 0);
3081   demand_empty_rest_of_line ();
3082   mapping_state (MAP_DATA);
3083 }
3084
3085 static void
3086 s_even (ignore)
3087      int ignore ATTRIBUTE_UNUSED;
3088 {
3089   /* Never make frag if expect extra pass.  */
3090   if (!need_pass_2)
3091     frag_align (1, 0, 0);
3092
3093   record_alignment (now_seg, 1);
3094
3095   demand_empty_rest_of_line ();
3096 }
3097
3098 static void
3099 s_ltorg (ignored)
3100      int ignored ATTRIBUTE_UNUSED;
3101 {
3102   unsigned int entry;
3103   literal_pool * pool;
3104   char sym_name[20];
3105
3106   pool = find_literal_pool ();
3107   if (pool == NULL
3108       || pool->symbol == NULL
3109       || pool->next_free_entry == 0)
3110     return;
3111
3112   /* Align pool as you have word accesses.
3113      Only make a frag if we have to.  */
3114   if (!need_pass_2)
3115     frag_align (2, 0, 0);
3116
3117   record_alignment (now_seg, 2);
3118
3119   sprintf (sym_name, "$$lit_\002%x", pool->id);
3120
3121   symbol_locate (pool->symbol, sym_name, now_seg,
3122                  (valueT) frag_now_fix (), frag_now);
3123   symbol_table_insert (pool->symbol);
3124
3125   ARM_SET_THUMB (pool->symbol, thumb_mode);
3126
3127 #if defined OBJ_COFF || defined OBJ_ELF
3128   ARM_SET_INTERWORK (pool->symbol, support_interwork);
3129 #endif
3130
3131   for (entry = 0; entry < pool->next_free_entry; entry ++)
3132     /* First output the expression in the instruction to the pool.  */
3133     emit_expr (&(pool->literals[entry]), 4); /* .word  */
3134
3135   /* Mark the pool as empty.  */
3136   pool->next_free_entry = 0;
3137   pool->symbol = NULL;
3138 }
3139
3140 /* Same as s_align_ptwo but align 0 => align 2.  */
3141
3142 static void
3143 s_align (unused)
3144      int unused ATTRIBUTE_UNUSED;
3145 {
3146   register int temp;
3147   register long temp_fill;
3148   long max_alignment = 15;
3149
3150   temp = get_absolute_expression ();
3151   if (temp > max_alignment)
3152     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3153   else if (temp < 0)
3154     {
3155       as_bad (_("alignment negative. 0 assumed."));
3156       temp = 0;
3157     }
3158
3159   if (*input_line_pointer == ',')
3160     {
3161       input_line_pointer++;
3162       temp_fill = get_absolute_expression ();
3163     }
3164   else
3165     temp_fill = 0;
3166
3167   if (!temp)
3168     temp = 2;
3169
3170   /* Only make a frag if we HAVE to.  */
3171   if (temp && !need_pass_2)
3172     frag_align (temp, (int) temp_fill, 0);
3173   demand_empty_rest_of_line ();
3174
3175   record_alignment (now_seg, temp);
3176 }
3177
3178 static void
3179 s_force_thumb (ignore)
3180      int ignore ATTRIBUTE_UNUSED;
3181 {
3182   /* If we are not already in thumb mode go into it, EVEN if
3183      the target processor does not support thumb instructions.
3184      This is used by gcc/config/arm/lib1funcs.asm for example
3185      to compile interworking support functions even if the
3186      target processor should not support interworking.  */
3187   if (! thumb_mode)
3188     {
3189       thumb_mode = 2;
3190
3191       record_alignment (now_seg, 1);
3192     }
3193
3194   demand_empty_rest_of_line ();
3195 }
3196
3197 static void
3198 s_thumb_func (ignore)
3199      int ignore ATTRIBUTE_UNUSED;
3200 {
3201   if (! thumb_mode)
3202     opcode_select (16);
3203
3204   /* The following label is the name/address of the start of a Thumb function.
3205      We need to know this for the interworking support.  */
3206   label_is_thumb_function_name = TRUE;
3207
3208   demand_empty_rest_of_line ();
3209 }
3210
3211 /* Perform a .set directive, but also mark the alias as
3212    being a thumb function.  */
3213
3214 static void
3215 s_thumb_set (equiv)
3216      int equiv;
3217 {
3218   /* XXX the following is a duplicate of the code for s_set() in read.c
3219      We cannot just call that code as we need to get at the symbol that
3220      is created.  */
3221   register char *    name;
3222   register char      delim;
3223   register char *    end_name;
3224   register symbolS * symbolP;
3225
3226   /* Especial apologies for the random logic:
3227      This just grew, and could be parsed much more simply!
3228      Dean - in haste.  */
3229   name      = input_line_pointer;
3230   delim     = get_symbol_end ();
3231   end_name  = input_line_pointer;
3232   *end_name = delim;
3233
3234   SKIP_WHITESPACE ();
3235
3236   if (*input_line_pointer != ',')
3237     {
3238       *end_name = 0;
3239       as_bad (_("expected comma after name \"%s\""), name);
3240       *end_name = delim;
3241       ignore_rest_of_line ();
3242       return;
3243     }
3244
3245   input_line_pointer++;
3246   *end_name = 0;
3247
3248   if (name[0] == '.' && name[1] == '\0')
3249     {
3250       /* XXX - this should not happen to .thumb_set.  */
3251       abort ();
3252     }
3253
3254   if ((symbolP = symbol_find (name)) == NULL
3255       && (symbolP = md_undefined_symbol (name)) == NULL)
3256     {
3257 #ifndef NO_LISTING
3258       /* When doing symbol listings, play games with dummy fragments living
3259          outside the normal fragment chain to record the file and line info
3260          for this symbol.  */
3261       if (listing & LISTING_SYMBOLS)
3262         {
3263           extern struct list_info_struct * listing_tail;
3264           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3265
3266           memset (dummy_frag, 0, sizeof (fragS));
3267           dummy_frag->fr_type = rs_fill;
3268           dummy_frag->line = listing_tail;
3269           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3270           dummy_frag->fr_symbol = symbolP;
3271         }
3272       else
3273 #endif
3274         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3275
3276 #ifdef OBJ_COFF
3277       /* "set" symbols are local unless otherwise specified.  */
3278       SF_SET_LOCAL (symbolP);
3279 #endif /* OBJ_COFF  */
3280     }                           /* Make a new symbol.  */
3281
3282   symbol_table_insert (symbolP);
3283
3284   * end_name = delim;
3285
3286   if (equiv
3287       && S_IS_DEFINED (symbolP)
3288       && S_GET_SEGMENT (symbolP) != reg_section)
3289     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3290
3291   pseudo_set (symbolP);
3292
3293   demand_empty_rest_of_line ();
3294
3295   /* XXX Now we come to the Thumb specific bit of code.  */
3296
3297   THUMB_SET_FUNC (symbolP, 1);
3298   ARM_SET_THUMB (symbolP, 1);
3299 #if defined OBJ_ELF || defined OBJ_COFF
3300   ARM_SET_INTERWORK (symbolP, support_interwork);
3301 #endif
3302 }
3303
3304 static void
3305 opcode_select (width)
3306      int width;
3307 {
3308   switch (width)
3309     {
3310     case 16:
3311       if (! thumb_mode)
3312         {
3313           if (! (cpu_variant & ARM_EXT_V4T))
3314             as_bad (_("selected processor does not support THUMB opcodes"));
3315
3316           thumb_mode = 1;
3317           /* No need to force the alignment, since we will have been
3318              coming from ARM mode, which is word-aligned.  */
3319           record_alignment (now_seg, 1);
3320         }
3321       mapping_state (MAP_THUMB);
3322       break;
3323
3324     case 32:
3325       if (thumb_mode)
3326         {
3327           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3328             as_bad (_("selected processor does not support ARM opcodes"));
3329
3330           thumb_mode = 0;
3331
3332           if (!need_pass_2)
3333             frag_align (2, 0, 0);
3334
3335           record_alignment (now_seg, 1);
3336         }
3337       mapping_state (MAP_ARM);
3338       break;
3339
3340     default:
3341       as_bad (_("invalid instruction size selected (%d)"), width);
3342     }
3343 }
3344
3345 static void
3346 s_arm (ignore)
3347      int ignore ATTRIBUTE_UNUSED;
3348 {
3349   opcode_select (32);
3350   demand_empty_rest_of_line ();
3351 }
3352
3353 static void
3354 s_thumb (ignore)
3355      int ignore ATTRIBUTE_UNUSED;
3356 {
3357   opcode_select (16);
3358   demand_empty_rest_of_line ();
3359 }
3360
3361 static void
3362 s_code (unused)
3363      int unused ATTRIBUTE_UNUSED;
3364 {
3365   register int temp;
3366
3367   temp = get_absolute_expression ();
3368   switch (temp)
3369     {
3370     case 16:
3371     case 32:
3372       opcode_select (temp);
3373       break;
3374
3375     default:
3376       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3377     }
3378 }
3379
3380 static void
3381 end_of_line (str)
3382      char *str;
3383 {
3384   skip_whitespace (str);
3385
3386   if (*str != '\0' && !inst.error)
3387     inst.error = _("garbage following instruction");
3388 }
3389
3390 static int
3391 skip_past_comma (str)
3392      char ** str;
3393 {
3394   char * p = * str, c;
3395   int comma = 0;
3396
3397   while ((c = *p) == ' ' || c == ',')
3398     {
3399       p++;
3400       if (c == ',' && comma++)
3401         return FAIL;
3402     }
3403
3404   if (c == '\0')
3405     return FAIL;
3406
3407   *str = p;
3408   return comma ? SUCCESS : FAIL;
3409 }
3410
3411 /* A standard register must be given at this point.
3412    SHIFT is the place to put it in inst.instruction.
3413    Restores input start point on error.
3414    Returns the reg#, or FAIL.  */
3415
3416 static int
3417 reg_required_here (str, shift)
3418      char ** str;
3419      int     shift;
3420 {
3421   static char buff [128]; /* XXX  */
3422   int         reg;
3423   char *      start = * str;
3424
3425   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3426     {
3427       if (shift >= 0)
3428         inst.instruction |= reg << shift;
3429       return reg;
3430     }
3431
3432   /* Restore the start point, we may have got a reg of the wrong class.  */
3433   *str = start;
3434
3435   /* In the few cases where we might be able to accept something else
3436      this error can be overridden.  */
3437   sprintf (buff, _("register expected, not '%.100s'"), start);
3438   inst.error = buff;
3439
3440   return FAIL;
3441 }
3442
3443 /* A Intel Wireless MMX technology register
3444    must be given at this point.
3445    Shift is the place to put it in inst.instruction.
3446    Restores input start point on err.
3447    Returns the reg#, or FAIL.  */
3448
3449 static int
3450 wreg_required_here (str, shift, reg_type)
3451      char ** str;
3452      int     shift;
3453      enum wreg_type reg_type;
3454 {
3455   static char buff [128];
3456   int    reg;
3457   char * start = *str;
3458
3459   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3460     {
3461       if (wr_register (reg)
3462           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3463         {
3464           if (shift >= 0)
3465             inst.instruction |= (reg ^ WR_PREFIX) << shift;
3466           return reg;
3467         }
3468       else if (wc_register (reg)
3469                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3470         {
3471           if (shift >= 0)
3472             inst.instruction |= (reg ^ WC_PREFIX) << shift;
3473           return reg;
3474         }
3475       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3476         {
3477           if (shift >= 0)
3478             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3479           return reg;
3480         }
3481     }
3482
3483   /* Restore the start point, we may have got a reg of the wrong class.  */
3484   *str = start;
3485
3486   /* In the few cases where we might be able to accept
3487      something else this error can be overridden.  */
3488   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3489   inst.error = buff;
3490
3491   return FAIL;
3492 }
3493
3494 static const struct asm_psr *
3495 arm_psr_parse (ccp)
3496      register char ** ccp;
3497 {
3498   char * start = * ccp;
3499   char   c;
3500   char * p;
3501   const struct asm_psr * psr;
3502
3503   p = start;
3504
3505   /* Skip to the end of the next word in the input stream.  */
3506   do
3507     {
3508       c = *p++;
3509     }
3510   while (ISALPHA (c) || c == '_');
3511
3512   /* Terminate the word.  */
3513   *--p = 0;
3514
3515   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3516      feature for ease of use and backwards compatibility.  */
3517   if (!strncmp (start, "cpsr", 4))
3518     strncpy (start, "CPSR", 4);
3519   else if (!strncmp (start, "spsr", 4))
3520     strncpy (start, "SPSR", 4);
3521
3522   /* Now locate the word in the psr hash table.  */
3523   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3524
3525   /* Restore the input stream.  */
3526   *p = c;
3527
3528   /* If we found a valid match, advance the
3529      stream pointer past the end of the word.  */
3530   *ccp = p;
3531
3532   return psr;
3533 }
3534
3535 /* Parse the input looking for a PSR flag.  */
3536
3537 static int
3538 psr_required_here (str)
3539      char ** str;
3540 {
3541   char * start = * str;
3542   const struct asm_psr * psr;
3543
3544   psr = arm_psr_parse (str);
3545
3546   if (psr)
3547     {
3548       /* If this is the SPSR that is being modified, set the R bit.  */
3549       if (! psr->cpsr)
3550         inst.instruction |= SPSR_BIT;
3551
3552       /* Set the psr flags in the MSR instruction.  */
3553       inst.instruction |= psr->field << PSR_SHIFT;
3554
3555       return SUCCESS;
3556     }
3557
3558   /* In the few cases where we might be able to accept
3559      something else this error can be overridden.  */
3560   inst.error = _("flag for {c}psr instruction expected");
3561
3562   /* Restore the start point.  */
3563   *str = start;
3564   return FAIL;
3565 }
3566
3567 static int
3568 co_proc_number (str)
3569      char **str;
3570 {
3571   int processor, pchar;
3572   char *start;
3573
3574   skip_whitespace (*str);
3575   start = *str;
3576
3577   /* The data sheet seems to imply that just a number on its own is valid
3578      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3579      accept either.  */
3580   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3581       == FAIL)
3582     {
3583       *str = start;
3584
3585       pchar = *(*str)++;
3586       if (pchar >= '0' && pchar <= '9')
3587         {
3588           processor = pchar - '0';
3589           if (**str >= '0' && **str <= '9')
3590             {
3591               processor = processor * 10 + *(*str)++ - '0';
3592               if (processor > 15)
3593                 {
3594                   inst.error = _("illegal co-processor number");
3595                   return FAIL;
3596                 }
3597             }
3598         }
3599       else
3600         {
3601           inst.error = _("bad or missing co-processor number");
3602           return FAIL;
3603         }
3604     }
3605
3606   inst.instruction |= processor << 8;
3607   return SUCCESS;
3608 }
3609
3610 static int
3611 cp_opc_expr (str, where, length)
3612      char ** str;
3613      int where;
3614      int length;
3615 {
3616   expressionS expr;
3617
3618   skip_whitespace (* str);
3619
3620   memset (&expr, '\0', sizeof (expr));
3621
3622   if (my_get_expression (&expr, str))
3623     return FAIL;
3624   if (expr.X_op != O_constant)
3625     {
3626       inst.error = _("bad or missing expression");
3627       return FAIL;
3628     }
3629
3630   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3631     {
3632       inst.error = _("immediate co-processor expression too large");
3633       return FAIL;
3634     }
3635
3636   inst.instruction |= expr.X_add_number << where;
3637   return SUCCESS;
3638 }
3639
3640 static int
3641 cp_reg_required_here (str, where)
3642      char ** str;
3643      int     where;
3644 {
3645   int    reg;
3646   char * start = *str;
3647
3648   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3649     {
3650       inst.instruction |= reg << where;
3651       return reg;
3652     }
3653
3654   /* In the few cases where we might be able to accept something else
3655      this error can be overridden.  */
3656   inst.error = _("co-processor register expected");
3657
3658   /* Restore the start point.  */
3659   *str = start;
3660   return FAIL;
3661 }
3662
3663 static int
3664 fp_reg_required_here (str, where)
3665      char ** str;
3666      int     where;
3667 {
3668   int    reg;
3669   char * start = * str;
3670
3671   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3672     {
3673       inst.instruction |= reg << where;
3674       return reg;
3675     }
3676
3677   /* In the few cases where we might be able to accept something else
3678      this error can be overridden.  */
3679   inst.error = _("floating point register expected");
3680
3681   /* Restore the start point.  */
3682   *str = start;
3683   return FAIL;
3684 }
3685
3686 static int
3687 cp_address_offset (str)
3688      char ** str;
3689 {
3690   int offset;
3691
3692   skip_whitespace (* str);
3693
3694   if (! is_immediate_prefix (**str))
3695     {
3696       inst.error = _("immediate expression expected");
3697       return FAIL;
3698     }
3699
3700   (*str)++;
3701
3702   if (my_get_expression (& inst.reloc.exp, str))
3703     return FAIL;
3704
3705   if (inst.reloc.exp.X_op == O_constant)
3706     {
3707       offset = inst.reloc.exp.X_add_number;
3708
3709       if (offset & 3)
3710         {
3711           inst.error = _("co-processor address must be word aligned");
3712           return FAIL;
3713         }
3714
3715       if (offset > 1023 || offset < -1023)
3716         {
3717           inst.error = _("offset too large");
3718           return FAIL;
3719         }
3720
3721       if (offset >= 0)
3722         inst.instruction |= INDEX_UP;
3723       else
3724         offset = -offset;
3725
3726       inst.instruction |= offset >> 2;
3727     }
3728   else
3729     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3730
3731   return SUCCESS;
3732 }
3733
3734 static int
3735 cp_address_required_here (str, wb_ok)
3736      char ** str;
3737      int wb_ok;
3738 {
3739   char * p = * str;
3740   int    pre_inc = 0;
3741   int    write_back = 0;
3742
3743   if (*p == '[')
3744     {
3745       int reg;
3746
3747       p++;
3748       skip_whitespace (p);
3749
3750       if ((reg = reg_required_here (& p, 16)) == FAIL)
3751         return FAIL;
3752
3753       skip_whitespace (p);
3754
3755       if (*p == ']')
3756         {
3757           p++;
3758
3759           skip_whitespace (p);
3760
3761           if (*p == '\0')
3762             {
3763               /* As an extension to the official ARM syntax we allow:
3764                  
3765                    [Rn]
3766                    
3767                  as a short hand for:
3768
3769                    [Rn,#0]  */
3770               inst.instruction |= PRE_INDEX | INDEX_UP;
3771               *str = p;
3772               return SUCCESS;
3773             }
3774           
3775           if (skip_past_comma (& p) == FAIL)
3776             {
3777               inst.error = _("comma expected after closing square bracket");
3778               return FAIL;
3779             }
3780
3781           skip_whitespace (p);
3782
3783           if (*p == '#')
3784             {
3785               if (wb_ok)
3786                 {
3787                   /* [Rn], #expr  */
3788                   write_back = WRITE_BACK;
3789
3790                   if (reg == REG_PC)
3791                     {
3792                       inst.error = _("pc may not be used in post-increment");
3793                       return FAIL;
3794                     }
3795
3796                   if (cp_address_offset (& p) == FAIL)
3797                     return FAIL;
3798                 }
3799               else
3800                 pre_inc = PRE_INDEX | INDEX_UP;
3801             }
3802           else if (*p == '{')
3803             {
3804               int option;
3805
3806               /* [Rn], {<expr>}  */
3807               p++;
3808
3809               skip_whitespace (p);
3810
3811               if (my_get_expression (& inst.reloc.exp, & p))
3812                 return FAIL;
3813
3814               if (inst.reloc.exp.X_op == O_constant)
3815                 {
3816                   option = inst.reloc.exp.X_add_number;
3817
3818                   if (option > 255 || option < 0)
3819                     {
3820                       inst.error = _("'option' field too large");
3821                       return FAIL;
3822                     }
3823
3824                   skip_whitespace (p);
3825
3826                   if (*p != '}')
3827                     {
3828                       inst.error = _("'}' expected at end of 'option' field");
3829                       return FAIL;
3830                     }
3831                   else
3832                     {
3833                       p++;
3834                       inst.instruction |= option;
3835                       inst.instruction |= INDEX_UP;
3836                     }
3837                 }
3838               else
3839                 {
3840                   inst.error = _("non-constant expressions for 'option' field not supported");
3841                   return FAIL;
3842                 }
3843             }
3844           else
3845             {
3846               inst.error = _("# or { expected after comma");
3847               return FAIL;            
3848             }
3849         }
3850       else
3851         {
3852           /* '['Rn, #expr']'[!]  */
3853
3854           if (skip_past_comma (& p) == FAIL)
3855             {
3856               inst.error = _("pre-indexed expression expected");
3857               return FAIL;
3858             }
3859
3860           pre_inc = PRE_INDEX;
3861
3862           if (cp_address_offset (& p) == FAIL)
3863             return FAIL;
3864
3865           skip_whitespace (p);
3866
3867           if (*p++ != ']')
3868             {
3869               inst.error = _("missing ]");
3870               return FAIL;
3871             }
3872
3873           skip_whitespace (p);
3874
3875           if (wb_ok && *p == '!')
3876             {
3877               if (reg == REG_PC)
3878                 {
3879                   inst.error = _("pc may not be used with write-back");
3880                   return FAIL;
3881                 }
3882
3883               p++;
3884               write_back = WRITE_BACK;
3885             }
3886         }
3887     }
3888   else
3889     {
3890       if (my_get_expression (&inst.reloc.exp, &p))
3891         return FAIL;
3892
3893       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3894       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3895       inst.reloc.pc_rel = 1;
3896       inst.instruction |= (REG_PC << 16);
3897       pre_inc = PRE_INDEX;
3898     }
3899
3900   inst.instruction |= write_back | pre_inc;
3901   *str = p;
3902   return SUCCESS;
3903 }
3904
3905 static int
3906 cp_byte_address_offset (str)
3907      char ** str;
3908 {
3909   int offset;
3910
3911   skip_whitespace (* str);
3912
3913   if (! is_immediate_prefix (**str))
3914     {
3915       inst.error = _("immediate expression expected");
3916       return FAIL;
3917     }
3918
3919   (*str)++;
3920   
3921   if (my_get_expression (& inst.reloc.exp, str))
3922     return FAIL;
3923   
3924   if (inst.reloc.exp.X_op == O_constant)
3925     {
3926       offset = inst.reloc.exp.X_add_number;
3927       
3928       if (offset > 255 || offset < -255)
3929         {
3930           inst.error = _("offset too large");
3931           return FAIL;
3932         }
3933
3934       if (offset >= 0)
3935         inst.instruction |= INDEX_UP;
3936       else
3937         offset = -offset;
3938
3939       inst.instruction |= offset;
3940     }
3941   else
3942     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3943
3944   return SUCCESS;
3945 }
3946
3947 static int
3948 cp_byte_address_required_here (str)
3949      char ** str;
3950 {
3951   char * p = * str;
3952   int    pre_inc = 0;
3953   int    write_back = 0;
3954
3955   if (*p == '[')
3956     {
3957       int reg;
3958
3959       p++;
3960       skip_whitespace (p);
3961
3962       if ((reg = reg_required_here (& p, 16)) == FAIL)
3963         return FAIL;
3964
3965       skip_whitespace (p);
3966
3967       if (*p == ']')
3968         {
3969           p++;
3970           
3971           if (skip_past_comma (& p) == SUCCESS)
3972             {
3973               /* [Rn], #expr */
3974               write_back = WRITE_BACK;
3975               
3976               if (reg == REG_PC)
3977                 {
3978                   inst.error = _("pc may not be used in post-increment");
3979                   return FAIL;
3980                 }
3981
3982               if (cp_byte_address_offset (& p) == FAIL)
3983                 return FAIL;
3984             }
3985           else
3986             pre_inc = PRE_INDEX | INDEX_UP;
3987         }
3988       else
3989         {
3990           /* '['Rn, #expr']'[!] */
3991
3992           if (skip_past_comma (& p) == FAIL)
3993             {
3994               inst.error = _("pre-indexed expression expected");
3995               return FAIL;
3996             }
3997
3998           pre_inc = PRE_INDEX;
3999           
4000           if (cp_byte_address_offset (& p) == FAIL)
4001             return FAIL;
4002
4003           skip_whitespace (p);
4004
4005           if (*p++ != ']')
4006             {
4007               inst.error = _("missing ]");
4008               return FAIL;
4009             }
4010
4011           skip_whitespace (p);
4012
4013           if (*p == '!')
4014             {
4015               if (reg == REG_PC)
4016                 {
4017                   inst.error = _("pc may not be used with write-back");
4018                   return FAIL;
4019                 }
4020
4021               p++;
4022               write_back = WRITE_BACK;
4023             }
4024         }
4025     }
4026   else
4027     {
4028       if (my_get_expression (&inst.reloc.exp, &p))
4029         return FAIL;
4030
4031       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4032       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
4033       inst.reloc.pc_rel = 1;
4034       inst.instruction |= (REG_PC << 16);
4035       pre_inc = PRE_INDEX;
4036     }
4037
4038   inst.instruction |= write_back | pre_inc;
4039   *str = p;
4040   return SUCCESS;
4041 }
4042
4043 static void
4044 do_empty (str)
4045      char * str;
4046 {
4047   /* Do nothing really.  */
4048   end_of_line (str);
4049 }
4050
4051 static void
4052 do_mrs (str)
4053      char *str;
4054 {
4055   int skip = 0;
4056
4057   /* Only one syntax.  */
4058   skip_whitespace (str);
4059
4060   if (reg_required_here (&str, 12) == FAIL)
4061     {
4062       inst.error = BAD_ARGS;
4063       return;
4064     }
4065
4066   if (skip_past_comma (&str) == FAIL)
4067     {
4068       inst.error = _("comma expected after register name");
4069       return;
4070     }
4071
4072   skip_whitespace (str);
4073
4074   if (   strcmp (str, "CPSR") == 0
4075       || strcmp (str, "SPSR") == 0
4076          /* Lower case versions for backwards compatibility.  */
4077       || strcmp (str, "cpsr") == 0
4078       || strcmp (str, "spsr") == 0)
4079     skip = 4;
4080
4081   /* This is for backwards compatibility with older toolchains.  */
4082   else if (   strcmp (str, "cpsr_all") == 0
4083            || strcmp (str, "spsr_all") == 0)
4084     skip = 8;
4085   else
4086     {
4087       inst.error = _("CPSR or SPSR expected");
4088       return;
4089     }
4090
4091   if (* str == 's' || * str == 'S')
4092     inst.instruction |= SPSR_BIT;
4093   str += skip;
4094
4095   end_of_line (str);
4096 }
4097
4098 /* Two possible forms:
4099       "{C|S}PSR_<field>, Rm",
4100       "{C|S}PSR_f, #expression".  */
4101
4102 static void
4103 do_msr (str)
4104      char * str;
4105 {
4106   skip_whitespace (str);
4107
4108   if (psr_required_here (& str) == FAIL)
4109     return;
4110
4111   if (skip_past_comma (& str) == FAIL)
4112     {
4113       inst.error = _("comma missing after psr flags");
4114       return;
4115     }
4116
4117   skip_whitespace (str);
4118
4119   if (reg_required_here (& str, 0) != FAIL)
4120     {
4121       inst.error = NULL;
4122       end_of_line (str);
4123       return;
4124     }
4125
4126   if (! is_immediate_prefix (* str))
4127     {
4128       inst.error =
4129         _("only a register or immediate value can follow a psr flag");
4130       return;
4131     }
4132
4133   str ++;
4134   inst.error = NULL;
4135
4136   if (my_get_expression (& inst.reloc.exp, & str))
4137     {
4138       inst.error =
4139         _("only a register or immediate value can follow a psr flag");
4140       return;
4141     }
4142
4143 #if 0  /* The first edition of the ARM architecture manual stated that
4144           writing anything other than the flags with an immediate operation
4145           had UNPREDICTABLE effects.  This constraint was removed in the
4146           second edition of the specification.  */
4147   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4148       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4149     {
4150       inst.error = _("immediate value cannot be used to set this field");
4151       return;
4152     }
4153 #endif
4154
4155   inst.instruction |= INST_IMMEDIATE;
4156
4157   if (inst.reloc.exp.X_add_symbol)
4158     {
4159       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4160       inst.reloc.pc_rel = 0;
4161     }
4162   else
4163     {
4164       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4165
4166       if (value == (unsigned) FAIL)
4167         {
4168           inst.error = _("invalid constant");
4169           return;
4170         }
4171
4172       inst.instruction |= value;
4173     }
4174
4175   inst.error = NULL;
4176   end_of_line (str);
4177 }
4178
4179 /* Long Multiply Parser
4180    UMULL RdLo, RdHi, Rm, Rs
4181    SMULL RdLo, RdHi, Rm, Rs
4182    UMLAL RdLo, RdHi, Rm, Rs
4183    SMLAL RdLo, RdHi, Rm, Rs.  */
4184
4185 static void
4186 do_mull (str)
4187      char * str;
4188 {
4189   int rdlo, rdhi, rm, rs;
4190
4191   /* Only one format "rdlo, rdhi, rm, rs".  */
4192   skip_whitespace (str);
4193
4194   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4195     {
4196       inst.error = BAD_ARGS;
4197       return;
4198     }
4199
4200   if (skip_past_comma (&str) == FAIL
4201       || (rdhi = reg_required_here (&str, 16)) == FAIL)
4202     {
4203       inst.error = BAD_ARGS;
4204       return;
4205     }
4206
4207   if (skip_past_comma (&str) == FAIL
4208       || (rm = reg_required_here (&str, 0)) == FAIL)
4209     {
4210       inst.error = BAD_ARGS;
4211       return;
4212     }
4213
4214   /* rdhi, rdlo and rm must all be different.  */
4215   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4216     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4217
4218   if (skip_past_comma (&str) == FAIL
4219       || (rs = reg_required_here (&str, 8)) == FAIL)
4220     {
4221       inst.error = BAD_ARGS;
4222       return;
4223     }
4224
4225   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4226     {
4227       inst.error = BAD_PC;
4228       return;
4229     }
4230
4231   end_of_line (str);
4232 }
4233
4234 static void
4235 do_mul (str)
4236      char * str;
4237 {
4238   int rd, rm;
4239
4240   /* Only one format "rd, rm, rs".  */
4241   skip_whitespace (str);
4242
4243   if ((rd = reg_required_here (&str, 16)) == FAIL)
4244     {
4245       inst.error = BAD_ARGS;
4246       return;
4247     }
4248
4249   if (rd == REG_PC)
4250     {
4251       inst.error = BAD_PC;
4252       return;
4253     }
4254
4255   if (skip_past_comma (&str) == FAIL
4256       || (rm = reg_required_here (&str, 0)) == FAIL)
4257     {
4258       inst.error = BAD_ARGS;
4259       return;
4260     }
4261
4262   if (rm == REG_PC)
4263     {
4264       inst.error = BAD_PC;
4265       return;
4266     }
4267
4268   if (rm == rd)
4269     as_tsktsk (_("rd and rm should be different in mul"));
4270
4271   if (skip_past_comma (&str) == FAIL
4272       || (rm = reg_required_here (&str, 8)) == FAIL)
4273     {
4274       inst.error = BAD_ARGS;
4275       return;
4276     }
4277
4278   if (rm == REG_PC)
4279     {
4280       inst.error = BAD_PC;
4281       return;
4282     }
4283
4284   end_of_line (str);
4285 }
4286
4287 static void
4288 do_mla (str)
4289      char * str;
4290 {
4291   int rd, rm;
4292
4293   /* Only one format "rd, rm, rs, rn".  */
4294   skip_whitespace (str);
4295
4296   if ((rd = reg_required_here (&str, 16)) == FAIL)
4297     {
4298       inst.error = BAD_ARGS;
4299       return;
4300     }
4301
4302   if (rd == REG_PC)
4303     {
4304       inst.error = BAD_PC;
4305       return;
4306     }
4307
4308   if (skip_past_comma (&str) == FAIL
4309       || (rm = reg_required_here (&str, 0)) == FAIL)
4310     {
4311       inst.error = BAD_ARGS;
4312       return;
4313     }
4314
4315   if (rm == REG_PC)
4316     {
4317       inst.error = BAD_PC;
4318       return;
4319     }
4320
4321   if (rm == rd)
4322     as_tsktsk (_("rd and rm should be different in mla"));
4323
4324   if (skip_past_comma (&str) == FAIL
4325       || (rd = reg_required_here (&str, 8)) == FAIL
4326       || skip_past_comma (&str) == FAIL
4327       || (rm = reg_required_here (&str, 12)) == FAIL)
4328     {
4329       inst.error = BAD_ARGS;
4330       return;
4331     }
4332
4333   if (rd == REG_PC || rm == REG_PC)
4334     {
4335       inst.error = BAD_PC;
4336       return;
4337     }
4338
4339   end_of_line (str);
4340 }
4341
4342 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4343    Advances *str to the next non-alphanumeric.
4344    Returns 0, or else FAIL (in which case sets inst.error).
4345
4346   (In a future XScale, there may be accumulators other than zero.
4347   At that time this routine and its callers can be upgraded to suit.)  */
4348
4349 static int
4350 accum0_required_here (str)
4351      char ** str;
4352 {
4353   static char buff [128];       /* Note the address is taken.  Hence, static.  */
4354   char * p = * str;
4355   char   c;
4356   int result = 0;               /* The accum number.  */
4357
4358   skip_whitespace (p);
4359
4360   *str = p;                     /* Advance caller's string pointer too.  */
4361   c = *p++;
4362   while (ISALNUM (c))
4363     c = *p++;
4364
4365   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
4366
4367   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4368     {
4369       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4370       inst.error = buff;
4371       result = FAIL;
4372     }
4373
4374   *p = c;                       /* Unzap.  */
4375   *str = p;                     /* Caller's string pointer to after match.  */
4376   return result;
4377 }
4378
4379 /* Expects **str -> after a comma. May be leading blanks.
4380    Advances *str, recognizing a load  mode, and setting inst.instruction.
4381    Returns rn, or else FAIL (in which case may set inst.error
4382    and not advance str)
4383
4384    Note: doesn't know Rd, so no err checks that require such knowledge.  */
4385
4386 static int
4387 ld_mode_required_here (string)
4388      char ** string;
4389 {
4390   char * str = * string;
4391   int    rn;
4392   int    pre_inc = 0;
4393
4394   skip_whitespace (str);
4395
4396   if (* str == '[')
4397     {
4398       str++;
4399
4400       skip_whitespace (str);
4401
4402       if ((rn = reg_required_here (& str, 16)) == FAIL)
4403         return FAIL;
4404
4405       skip_whitespace (str);
4406
4407       if (* str == ']')
4408         {
4409           str ++;
4410
4411           if (skip_past_comma (& str) == SUCCESS)
4412             {
4413               /* [Rn],... (post inc) */
4414               if (ldst_extend_v4 (&str) == FAIL)
4415                 return FAIL;
4416             }
4417           else        /* [Rn] */
4418             {
4419               skip_whitespace (str);
4420
4421               if (* str == '!')
4422                 {
4423                   str ++;
4424                   inst.instruction |= WRITE_BACK;
4425                 }
4426
4427               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4428               pre_inc = 1;
4429             }
4430         }
4431       else        /* [Rn,...] */
4432         {
4433           if (skip_past_comma (& str) == FAIL)
4434             {
4435               inst.error = _("pre-indexed expression expected");
4436               return FAIL;
4437             }
4438
4439           pre_inc = 1;
4440
4441           if (ldst_extend_v4 (&str) == FAIL)
4442             return FAIL;
4443
4444           skip_whitespace (str);
4445
4446           if (* str ++ != ']')
4447             {
4448               inst.error = _("missing ]");
4449               return FAIL;
4450             }
4451
4452           skip_whitespace (str);
4453
4454           if (* str == '!')
4455             {
4456               str ++;
4457               inst.instruction |= WRITE_BACK;
4458             }
4459         }
4460     }
4461   else if (* str == '=')        /* ldr's "r,=label" syntax */
4462     /* We should never reach here, because <text> = <expression> is
4463        caught gas/read.c read_a_source_file() as a .set operation.  */
4464     return FAIL;
4465   else                          /* PC +- 8 bit immediate offset.  */
4466     {
4467       if (my_get_expression (& inst.reloc.exp, & str))
4468         return FAIL;
4469
4470       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
4471       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4472       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
4473       inst.reloc.pc_rel            = 1;
4474       inst.instruction            |= (REG_PC << 16);
4475
4476       rn = REG_PC;
4477       pre_inc = 1;
4478     }
4479
4480   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4481   * string = str;
4482
4483   return rn;
4484 }
4485
4486 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4487    SMLAxy{cond} Rd,Rm,Rs,Rn
4488    SMLAWy{cond} Rd,Rm,Rs,Rn
4489    Error if any register is R15.  */
4490
4491 static void
4492 do_smla (str)
4493      char *        str;
4494 {
4495   int rd, rm, rs, rn;
4496
4497   skip_whitespace (str);
4498
4499   if ((rd = reg_required_here (& str, 16)) == FAIL
4500       || skip_past_comma (& str) == FAIL
4501       || (rm = reg_required_here (& str, 0)) == FAIL
4502       || skip_past_comma (& str) == FAIL
4503       || (rs = reg_required_here (& str, 8)) == FAIL
4504       || skip_past_comma (& str) == FAIL
4505       || (rn = reg_required_here (& str, 12)) == FAIL)
4506     inst.error = BAD_ARGS;
4507
4508   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4509     inst.error = BAD_PC;
4510
4511   else
4512     end_of_line (str);
4513 }
4514
4515 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4516    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4517    Error if any register is R15.
4518    Warning if Rdlo == Rdhi.  */
4519
4520 static void
4521 do_smlal (str)
4522      char *        str;
4523 {
4524   int rdlo, rdhi, rm, rs;
4525
4526   skip_whitespace (str);
4527
4528   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4529       || skip_past_comma (& str) == FAIL
4530       || (rdhi = reg_required_here (& str, 16)) == FAIL
4531       || skip_past_comma (& str) == FAIL
4532       || (rm = reg_required_here (& str, 0)) == FAIL
4533       || skip_past_comma (& str) == FAIL
4534       || (rs = reg_required_here (& str, 8)) == FAIL)
4535     {
4536       inst.error = BAD_ARGS;
4537       return;
4538     }
4539
4540   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4541     {
4542       inst.error = BAD_PC;
4543       return;
4544     }
4545
4546   if (rdlo == rdhi)
4547     as_tsktsk (_("rdhi and rdlo must be different"));
4548
4549   end_of_line (str);
4550 }
4551
4552 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4553    SMULxy{cond} Rd,Rm,Rs
4554    Error if any register is R15.  */
4555
4556 static void
4557 do_smul (str)
4558      char *        str;
4559 {
4560   int rd, rm, rs;
4561
4562   skip_whitespace (str);
4563
4564   if ((rd = reg_required_here (& str, 16)) == FAIL
4565       || skip_past_comma (& str) == FAIL
4566       || (rm = reg_required_here (& str, 0)) == FAIL
4567       || skip_past_comma (& str) == FAIL
4568       || (rs = reg_required_here (& str, 8)) == FAIL)
4569     inst.error = BAD_ARGS;
4570
4571   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4572     inst.error = BAD_PC;
4573
4574   else
4575     end_of_line (str);
4576 }
4577
4578 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4579    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4580    Error if any register is R15.  */
4581
4582 static void
4583 do_qadd (str)
4584      char *        str;
4585 {
4586   int rd, rm, rn;
4587
4588   skip_whitespace (str);
4589
4590   if ((rd = reg_required_here (& str, 12)) == FAIL
4591       || skip_past_comma (& str) == FAIL
4592       || (rm = reg_required_here (& str, 0)) == FAIL
4593       || skip_past_comma (& str) == FAIL
4594       || (rn = reg_required_here (& str, 16)) == FAIL)
4595     inst.error = BAD_ARGS;
4596
4597   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4598     inst.error = BAD_PC;
4599
4600   else
4601     end_of_line (str);
4602 }
4603
4604 /* ARM V5E (el Segundo)
4605    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4606    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4607
4608    These are equivalent to the XScale instructions MAR and MRA,
4609    respectively, when coproc == 0, opcode == 0, and CRm == 0.
4610
4611    Result unpredicatable if Rd or Rn is R15.  */
4612
4613 static void
4614 do_co_reg2c (str)
4615      char *        str;
4616 {
4617   int rd, rn;
4618
4619   skip_whitespace (str);
4620
4621   if (co_proc_number (& str) == FAIL)
4622     {
4623       if (!inst.error)
4624         inst.error = BAD_ARGS;
4625       return;
4626     }
4627
4628   if (skip_past_comma (& str) == FAIL
4629       || cp_opc_expr (& str, 4, 4) == FAIL)
4630     {
4631       if (!inst.error)
4632         inst.error = BAD_ARGS;
4633       return;
4634     }
4635
4636   if (skip_past_comma (& str) == FAIL
4637       || (rd = reg_required_here (& str, 12)) == FAIL)
4638     {
4639       if (!inst.error)
4640         inst.error = BAD_ARGS;
4641       return;
4642     }
4643
4644   if (skip_past_comma (& str) == FAIL
4645       || (rn = reg_required_here (& str, 16)) == FAIL)
4646     {
4647       if (!inst.error)
4648         inst.error = BAD_ARGS;
4649       return;
4650     }
4651
4652   /* Unpredictable result if rd or rn is R15.  */
4653   if (rd == REG_PC || rn == REG_PC)
4654     as_tsktsk
4655       (_("Warning: instruction unpredictable when using r15"));
4656
4657   if (skip_past_comma (& str) == FAIL
4658       || cp_reg_required_here (& str, 0) == FAIL)
4659     {
4660       if (!inst.error)
4661         inst.error = BAD_ARGS;
4662       return;
4663     }
4664
4665   end_of_line (str);
4666 }
4667
4668 /* ARM V5 count-leading-zeroes instruction (argument parse)
4669      CLZ{<cond>} <Rd>, <Rm>
4670      Condition defaults to COND_ALWAYS.
4671      Error if Rd or Rm are R15.  */
4672
4673 static void
4674 do_clz (str)
4675      char *        str;
4676 {
4677   int rd, rm;
4678
4679   skip_whitespace (str);
4680
4681   if (((rd = reg_required_here (& str, 12)) == FAIL)
4682       || (skip_past_comma (& str) == FAIL)
4683       || ((rm = reg_required_here (& str, 0)) == FAIL))
4684     inst.error = BAD_ARGS;
4685
4686   else if (rd == REG_PC || rm == REG_PC )
4687     inst.error = BAD_PC;
4688
4689   else
4690     end_of_line (str);
4691 }
4692
4693 /* ARM V5 (argument parse)
4694      LDC2{L} <coproc>, <CRd>, <addressing mode>
4695      STC2{L} <coproc>, <CRd>, <addressing mode>
4696      Instruction is not conditional, and has 0xf in the condition field.
4697      Otherwise, it's the same as LDC/STC.  */
4698
4699 static void
4700 do_lstc2 (str)
4701      char *        str;
4702 {
4703   skip_whitespace (str);
4704
4705   if (co_proc_number (& str) == FAIL)
4706     {
4707       if (!inst.error)
4708         inst.error = BAD_ARGS;
4709     }
4710   else if (skip_past_comma (& str) == FAIL
4711            || cp_reg_required_here (& str, 12) == FAIL)
4712     {
4713       if (!inst.error)
4714         inst.error = BAD_ARGS;
4715     }
4716   else if (skip_past_comma (& str) == FAIL
4717            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4718     {
4719       if (! inst.error)
4720         inst.error = BAD_ARGS;
4721     }
4722   else
4723     end_of_line (str);
4724 }
4725
4726 /* ARM V5 (argument parse)
4727      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4728      Instruction is not conditional, and has 0xf in the condition field.
4729      Otherwise, it's the same as CDP.  */
4730
4731 static void
4732 do_cdp2 (str)
4733      char *        str;
4734 {
4735   skip_whitespace (str);
4736
4737   if (co_proc_number (& str) == FAIL)
4738     {
4739       if (!inst.error)
4740         inst.error = BAD_ARGS;
4741       return;
4742     }
4743
4744   if (skip_past_comma (& str) == FAIL
4745       || cp_opc_expr (& str, 20,4) == FAIL)
4746     {
4747       if (!inst.error)
4748         inst.error = BAD_ARGS;
4749       return;
4750     }
4751
4752   if (skip_past_comma (& str) == FAIL
4753       || cp_reg_required_here (& str, 12) == FAIL)
4754     {
4755       if (!inst.error)
4756         inst.error = BAD_ARGS;
4757       return;
4758     }
4759
4760   if (skip_past_comma (& str) == FAIL
4761       || cp_reg_required_here (& str, 16) == FAIL)
4762     {
4763       if (!inst.error)
4764         inst.error = BAD_ARGS;
4765       return;
4766     }
4767
4768   if (skip_past_comma (& str) == FAIL
4769       || cp_reg_required_here (& str, 0) == FAIL)
4770     {
4771       if (!inst.error)
4772         inst.error = BAD_ARGS;
4773       return;
4774     }
4775
4776   if (skip_past_comma (& str) == SUCCESS)
4777     {
4778       if (cp_opc_expr (& str, 5, 3) == FAIL)
4779         {
4780           if (!inst.error)
4781             inst.error = BAD_ARGS;
4782           return;
4783         }
4784     }
4785
4786   end_of_line (str);
4787 }
4788
4789 /* ARM V5 (argument parse)
4790      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4791      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4792      Instruction is not conditional, and has 0xf in the condition field.
4793      Otherwise, it's the same as MCR/MRC.  */
4794
4795 static void
4796 do_co_reg2 (str)
4797      char *        str;
4798 {
4799   skip_whitespace (str);
4800
4801   if (co_proc_number (& str) == FAIL)
4802     {
4803       if (!inst.error)
4804         inst.error = BAD_ARGS;
4805       return;
4806     }
4807
4808   if (skip_past_comma (& str) == FAIL
4809       || cp_opc_expr (& str, 21, 3) == FAIL)
4810     {
4811       if (!inst.error)
4812         inst.error = BAD_ARGS;
4813       return;
4814     }
4815
4816   if (skip_past_comma (& str) == FAIL
4817       || reg_required_here (& str, 12) == FAIL)
4818     {
4819       if (!inst.error)
4820         inst.error = BAD_ARGS;
4821       return;
4822     }
4823
4824   if (skip_past_comma (& str) == FAIL
4825       || cp_reg_required_here (& str, 16) == FAIL)
4826     {
4827       if (!inst.error)
4828         inst.error = BAD_ARGS;
4829       return;
4830     }
4831
4832   if (skip_past_comma (& str) == FAIL
4833       || cp_reg_required_here (& str, 0) == FAIL)
4834     {
4835       if (!inst.error)
4836         inst.error = BAD_ARGS;
4837       return;
4838     }
4839
4840   if (skip_past_comma (& str) == SUCCESS)
4841     {
4842       if (cp_opc_expr (& str, 5, 3) == FAIL)
4843         {
4844           if (!inst.error)
4845             inst.error = BAD_ARGS;
4846           return;
4847         }
4848     }
4849
4850   end_of_line (str);
4851 }
4852
4853 /* ARM v5TEJ.  Jump to Jazelle code.  */
4854 static void
4855 do_bxj (str)
4856      char * str;
4857 {
4858   int reg;
4859
4860   skip_whitespace (str);
4861
4862   if ((reg = reg_required_here (&str, 0)) == FAIL)
4863     {
4864       inst.error = BAD_ARGS;
4865       return;
4866     }
4867
4868   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4869   if (reg == REG_PC)
4870     as_tsktsk (_("use of r15 in bxj is not really useful"));
4871
4872   end_of_line (str);
4873 }
4874
4875 /* ARM V6 umaal (argument parse). */
4876
4877 static void
4878 do_umaal (str)
4879      char *str;
4880 {
4881
4882   int rdlo, rdhi, rm, rs;
4883
4884   skip_whitespace (str);
4885   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4886       || skip_past_comma (& str) == FAIL
4887       || (rdhi = reg_required_here (& str, 16)) == FAIL
4888       || skip_past_comma (& str) == FAIL
4889       || (rm = reg_required_here (& str, 0)) == FAIL
4890       || skip_past_comma (& str) == FAIL
4891       || (rs = reg_required_here (& str, 8)) == FAIL)
4892     {
4893       inst.error = BAD_ARGS;
4894       return;      
4895     }
4896
4897   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4898     {
4899       inst.error = BAD_PC;
4900       return;
4901     }
4902
4903   end_of_line (str);
4904 }
4905
4906 /* ARM V6 strex (argument parse). */
4907
4908 static void 
4909 do_strex (str)
4910      char *str;
4911 {
4912   int rd, rm, rn;
4913
4914   /* Parse Rd, Rm,. */
4915   skip_whitespace (str);
4916   if ((rd = reg_required_here (& str, 12)) == FAIL
4917       || skip_past_comma (& str) == FAIL
4918       || (rm = reg_required_here (& str, 0)) == FAIL
4919       || skip_past_comma (& str) == FAIL)
4920     {
4921       inst.error = BAD_ARGS;
4922       return;
4923     }
4924   if (rd == REG_PC || rm == REG_PC)
4925     {
4926       inst.error = BAD_PC;
4927       return;
4928     }
4929   if (rd == rm)
4930     {
4931       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4932       return;
4933     }
4934
4935   /* Skip past '['. */
4936   if ((strlen (str) >= 1) 
4937       && strncmp (str, "[", 1) == 0)
4938     str+=1;
4939   skip_whitespace (str);  
4940
4941   /* Parse Rn. */
4942   if ((rn = reg_required_here (& str, 16)) == FAIL)
4943     {
4944       inst.error = BAD_ARGS;
4945       return;
4946     }
4947   else if (rn == REG_PC)
4948     {
4949       inst.error = BAD_PC;
4950       return;
4951     }
4952   if (rd == rn)
4953     {
4954       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4955       return;
4956     }
4957   skip_whitespace (str);  
4958
4959   /* Skip past ']'. */
4960   if ((strlen (str) >= 1) 
4961       && strncmp (str, "]", 1) == 0)
4962     str+=1;
4963   
4964   end_of_line (str);
4965 }
4966
4967 /* ARM V6 ssat (argument parse). */
4968
4969 static void
4970 do_ssat (str)
4971      char* str;
4972 {
4973   do_sat (&str, /*bias=*/-1);
4974   end_of_line (str);
4975 }
4976
4977 /* ARM V6 usat (argument parse). */
4978
4979 static void
4980 do_usat (str)
4981      char* str;
4982 {
4983   do_sat (&str, /*bias=*/0);
4984   end_of_line (str);
4985 }
4986
4987 static void
4988 do_sat (str, bias)
4989      char **str;
4990      int    bias;
4991 {
4992   int rd, rm;
4993   expressionS expr;
4994
4995   skip_whitespace (*str);
4996   
4997   /* Parse <Rd>, field. */
4998   if ((rd = reg_required_here (str, 12)) == FAIL
4999       || skip_past_comma (str) == FAIL)
5000     {
5001       inst.error = BAD_ARGS;
5002       return;
5003     }
5004   if (rd == REG_PC)
5005     {
5006       inst.error = BAD_PC;
5007       return;
5008     }
5009
5010   /* Parse #<immed>,  field. */
5011   if (is_immediate_prefix (**str))
5012     (*str)++;
5013   else
5014     {
5015       inst.error = _("immediate expression expected");
5016       return;
5017     }
5018   if (my_get_expression (&expr, str))
5019     {
5020       inst.error = _("bad expression");
5021       return;
5022     }
5023   if (expr.X_op != O_constant)
5024     {
5025       inst.error = _("constant expression expected");
5026       return;
5027     }
5028   if (expr.X_add_number + bias < 0
5029       || expr.X_add_number + bias > 31)
5030     {
5031       inst.error = _("immediate value out of range");
5032       return;
5033     }
5034   inst.instruction |= (expr.X_add_number + bias) << 16;
5035   if (skip_past_comma (str) == FAIL)
5036     {
5037       inst.error = BAD_ARGS;
5038       return;
5039     }
5040
5041   /* Parse <Rm> field. */
5042   if ((rm = reg_required_here (str, 0)) == FAIL)
5043     {
5044       inst.error = BAD_ARGS;
5045       return;
5046     }
5047   if (rm == REG_PC)
5048     {
5049       inst.error = BAD_PC;
5050       return;
5051     }
5052
5053   if (skip_past_comma (str) == SUCCESS)
5054     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5055 }
5056
5057 /* ARM V6 ssat16 (argument parse). */
5058
5059 static void
5060 do_ssat16 (str)
5061      char *str;
5062 {
5063   do_sat16 (&str, /*bias=*/-1);
5064   end_of_line (str);
5065 }
5066
5067 static void
5068 do_usat16 (str)
5069      char *str;
5070 {
5071   do_sat16 (&str, /*bias=*/0);
5072   end_of_line (str);
5073 }
5074
5075 static void
5076 do_sat16 (str, bias)
5077      char **str;
5078      int bias;
5079 {
5080   int rd, rm;
5081   expressionS expr;
5082
5083   skip_whitespace (*str);
5084
5085   /* Parse the <Rd> field. */
5086   if ((rd = reg_required_here (str, 12)) == FAIL
5087       || skip_past_comma (str) == FAIL)
5088     {
5089       inst.error = BAD_ARGS;
5090       return;
5091     }
5092   if (rd == REG_PC)
5093     {
5094       inst.error = BAD_PC;
5095       return;
5096     }
5097
5098   /* Parse #<immed>, field. */
5099   if (is_immediate_prefix (**str))
5100     (*str)++;
5101   else
5102     {
5103       inst.error = _("immediate expression expected");
5104       return;
5105     }
5106   if (my_get_expression (&expr, str))
5107     {
5108       inst.error = _("bad expression");
5109       return;
5110     }
5111   if (expr.X_op != O_constant)
5112     {
5113       inst.error = _("constant expression expected");
5114       return;
5115     }
5116   if (expr.X_add_number + bias < 0
5117       || expr.X_add_number + bias > 15)
5118     {
5119       inst.error = _("immediate value out of range");
5120       return;
5121     }
5122   inst.instruction |= (expr.X_add_number + bias) << 16;
5123   if (skip_past_comma (str) == FAIL)
5124     {
5125       inst.error = BAD_ARGS;
5126       return;
5127     }
5128
5129   /* Parse <Rm> field. */
5130   if ((rm = reg_required_here (str, 0)) == FAIL)
5131     {
5132       inst.error = BAD_ARGS;
5133       return;
5134     }
5135   if (rm == REG_PC)
5136     {
5137       inst.error = BAD_PC;
5138       return;
5139     }
5140 }
5141
5142 /* ARM V6 srs (argument parse). */
5143
5144 static void
5145 do_srs (str)
5146      char* str;
5147 {
5148   char *exclam;
5149   skip_whitespace (str);
5150   exclam = strchr (str, '!');
5151   if (exclam)
5152     *exclam = '\0';
5153   do_cps_mode (&str);
5154   if (exclam)
5155     *exclam = '!';
5156   if (*str == '!') 
5157     {
5158       inst.instruction |= WRITE_BACK;
5159       str++;
5160     }
5161   end_of_line (str);
5162 }
5163
5164 /* ARM V6 SMMUL (argument parse). */
5165
5166 static void
5167 do_smmul (str)
5168      char* str;
5169 {
5170   int rd, rm, rs;
5171   
5172   skip_whitespace (str);
5173   if ((rd = reg_required_here (&str, 16)) == FAIL
5174       || skip_past_comma (&str) == FAIL
5175       || (rm = reg_required_here (&str, 0)) == FAIL
5176       || skip_past_comma (&str) == FAIL
5177       || (rs = reg_required_here (&str, 8)) == FAIL)
5178     {
5179       inst.error = BAD_ARGS;
5180       return;
5181     }
5182
5183   if (rd == REG_PC 
5184       || rm == REG_PC
5185       || rs == REG_PC)
5186     {
5187       inst.error = BAD_PC;
5188       return;
5189     }
5190
5191   end_of_line (str);
5192   
5193 }
5194
5195 /* ARM V6 SMLALD (argument parse). */
5196
5197 static void
5198 do_smlald (str)
5199     char* str;
5200 {
5201   int rdlo, rdhi, rm, rs;
5202   skip_whitespace (str);
5203   if ((rdlo = reg_required_here (&str, 12)) == FAIL
5204       || skip_past_comma (&str) == FAIL
5205       || (rdhi = reg_required_here (&str, 16)) == FAIL
5206       || skip_past_comma (&str) == FAIL
5207       || (rm = reg_required_here (&str, 0)) == FAIL
5208       || skip_past_comma (&str) == FAIL
5209       || (rs = reg_required_here (&str, 8)) == FAIL)
5210     {
5211       inst.error = BAD_ARGS;
5212       return;
5213     }
5214
5215   if (rdlo == REG_PC 
5216       || rdhi == REG_PC 
5217       || rm == REG_PC
5218       || rs == REG_PC)
5219     {
5220       inst.error = BAD_PC;
5221       return;
5222     }
5223
5224   end_of_line (str);
5225 }
5226
5227 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
5228    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5229
5230 static void 
5231 do_smlad (str)
5232      char *str;
5233 {
5234   int rd, rm, rs, rn;
5235   
5236   skip_whitespace (str);
5237   if ((rd = reg_required_here (&str, 16)) == FAIL
5238       || skip_past_comma (&str) == FAIL
5239       || (rm = reg_required_here (&str, 0)) == FAIL
5240       || skip_past_comma (&str) == FAIL
5241       || (rs = reg_required_here (&str, 8)) == FAIL
5242       || skip_past_comma (&str) == FAIL
5243       || (rn = reg_required_here (&str, 12)) == FAIL)
5244     {
5245       inst.error = BAD_ARGS;
5246       return;
5247     }
5248   
5249   if (rd == REG_PC 
5250       || rn == REG_PC 
5251       || rs == REG_PC
5252       || rm == REG_PC)
5253     {
5254       inst.error = BAD_PC;
5255       return;
5256     }
5257
5258   end_of_line (str);
5259
5260
5261 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5262    preserving the other bits.
5263
5264    setend <endian_specifier>, where <endian_specifier> is either 
5265    BE or LE. */
5266
5267 static void 
5268 do_setend (str)
5269      char *str;
5270 {
5271   if (do_endian_specifier (str))
5272     inst.instruction |= 0x200;
5273 }
5274
5275 /* Returns true if the endian-specifier indicates big-endianness.  */
5276
5277 static int
5278 do_endian_specifier (str)
5279      char *str;
5280 {
5281   int big_endian = 0;
5282
5283   skip_whitespace (str);
5284   if (strlen (str) < 2)
5285     inst.error = _("missing endian specifier");
5286   else if (strncasecmp (str, "BE", 2) == 0)
5287     {
5288       str += 2;
5289       big_endian = 1;
5290     }
5291   else if (strncasecmp (str, "LE", 2) == 0)
5292     str += 2;
5293   else
5294     inst.error = _("valid endian specifiers are be or le");
5295
5296   end_of_line (str);
5297
5298   return big_endian;
5299 }
5300
5301 /* ARM V6 SXTH.
5302
5303    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5304    Condition defaults to COND_ALWAYS.
5305    Error if any register uses R15. */
5306
5307 static void 
5308 do_sxth (str)
5309      char *str;
5310 {
5311   int rd, rm;
5312   expressionS expr;
5313   int rotation_clear_mask = 0xfffff3ff;
5314   int rotation_eight_mask = 0x00000400;
5315   int rotation_sixteen_mask = 0x00000800;
5316   int rotation_twenty_four_mask = 0x00000c00;
5317   
5318   skip_whitespace (str);
5319   if ((rd = reg_required_here (&str, 12)) == FAIL
5320       || skip_past_comma (&str) == FAIL
5321       || (rm = reg_required_here (&str, 0)) == FAIL)
5322     {
5323       inst.error = BAD_ARGS;
5324       return;
5325     }
5326
5327   else if (rd == REG_PC || rm == REG_PC)
5328     {
5329       inst.error = BAD_PC;
5330       return;
5331     }
5332   
5333   /* Zero out the rotation field. */
5334   inst.instruction &= rotation_clear_mask;
5335   
5336   /* Check for lack of optional rotation field. */
5337   if (skip_past_comma (&str) == FAIL)
5338     {
5339       end_of_line (str);
5340       return;
5341     }
5342   
5343   /* Move past 'ROR'. */
5344   skip_whitespace (str);
5345   if (strncasecmp (str, "ROR", 3) == 0)
5346     str+=3;
5347   else
5348     {
5349       inst.error = _("missing rotation field after comma");
5350       return;
5351     }
5352   
5353   /* Get the immediate constant. */
5354   skip_whitespace (str);
5355   if (is_immediate_prefix (* str))
5356     str++;
5357   else
5358     {
5359       inst.error = _("immediate expression expected");
5360       return;
5361     }
5362   
5363   if (my_get_expression (&expr, &str))
5364     {
5365       inst.error = _("bad expression");
5366       return;
5367     }
5368
5369   if (expr.X_op != O_constant)
5370     {
5371       inst.error = _("constant expression expected");
5372       return;
5373     }
5374   
5375   switch (expr.X_add_number) 
5376     {
5377     case 0:
5378       /* Rotation field has already been zeroed. */
5379       break;
5380     case 8:
5381       inst.instruction |= rotation_eight_mask;
5382       break;
5383
5384     case 16:
5385       inst.instruction |= rotation_sixteen_mask;
5386       break;
5387       
5388     case 24:
5389       inst.instruction |= rotation_twenty_four_mask;
5390       break;
5391
5392     default:
5393       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5394       break;
5395     }
5396
5397   end_of_line (str);
5398   
5399 }
5400
5401 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5402    extends it to 32-bits, and adds the result to a value in another
5403    register.  You can specify a rotation by 0, 8, 16, or 24 bits
5404    before extracting the 16-bit value.
5405    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5406    Condition defaults to COND_ALWAYS.
5407    Error if any register uses R15. */
5408
5409 static void 
5410 do_sxtah (str)
5411      char *str;
5412 {
5413   int rd, rn, rm;
5414   expressionS expr;
5415   int rotation_clear_mask = 0xfffff3ff;
5416   int rotation_eight_mask = 0x00000400;
5417   int rotation_sixteen_mask = 0x00000800;
5418   int rotation_twenty_four_mask = 0x00000c00;
5419   
5420   skip_whitespace (str);
5421   if ((rd = reg_required_here (&str, 12)) == FAIL
5422       || skip_past_comma (&str) == FAIL
5423       || (rn = reg_required_here (&str, 16)) == FAIL
5424       || skip_past_comma (&str) == FAIL
5425       || (rm = reg_required_here (&str, 0)) == FAIL)
5426     {
5427       inst.error = BAD_ARGS;
5428       return;
5429     }
5430
5431   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5432     {
5433       inst.error = BAD_PC;
5434       return;
5435     }
5436   
5437   /* Zero out the rotation field. */
5438   inst.instruction &= rotation_clear_mask;
5439   
5440   /* Check for lack of optional rotation field. */
5441   if (skip_past_comma (&str) == FAIL)
5442     {
5443       end_of_line (str);
5444       return;
5445     }
5446   
5447   /* Move past 'ROR'. */
5448   skip_whitespace (str);
5449   if (strncasecmp (str, "ROR", 3) == 0)
5450     str+=3;
5451   else
5452     {
5453       inst.error = _("missing rotation field after comma");
5454       return;
5455     }
5456   
5457   /* Get the immediate constant. */
5458   skip_whitespace (str);
5459   if (is_immediate_prefix (* str))
5460     str++;
5461   else
5462     {
5463       inst.error = _("immediate expression expected");
5464       return;
5465     }
5466   
5467   if (my_get_expression (&expr, &str))
5468     {
5469       inst.error = _("bad expression");
5470       return;
5471     }
5472
5473   if (expr.X_op != O_constant)
5474     {
5475       inst.error = _("constant expression expected");
5476       return;
5477     }
5478   
5479   switch (expr.X_add_number) 
5480     {
5481     case 0:
5482       /* Rotation field has already been zeroed. */
5483       break;
5484
5485     case 8:
5486       inst.instruction |= rotation_eight_mask;
5487       break;
5488
5489     case 16:
5490       inst.instruction |= rotation_sixteen_mask;
5491       break;
5492       
5493     case 24:
5494       inst.instruction |= rotation_twenty_four_mask;
5495       break;
5496
5497     default:
5498       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5499       break;
5500     }
5501
5502   end_of_line (str);
5503   
5504 }
5505    
5506
5507 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5508    word at the specified address and the following word
5509    respectively. 
5510    Unconditionally executed.
5511    Error if Rn is R15.   
5512 */
5513
5514 static void
5515 do_rfe (str)
5516      char *str;
5517 {
5518   int rn;
5519
5520   skip_whitespace (str);
5521   
5522   if ((rn = reg_required_here (&str, 16)) == FAIL)
5523     return;
5524
5525   if (rn == REG_PC)
5526     {
5527       inst.error = BAD_PC;
5528       return;
5529     }
5530
5531   skip_whitespace (str);
5532   
5533   if (*str == '!')
5534     {
5535       inst.instruction |= WRITE_BACK;
5536       str++;
5537     }
5538   end_of_line (str);
5539 }
5540
5541 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5542    register (argument parse).
5543    REV{<cond>} Rd, Rm.
5544    Condition defaults to COND_ALWAYS.
5545    Error if Rd or Rm are R15. */ 
5546
5547 static void
5548 do_rev (str)
5549      char* str;
5550 {
5551   int rd, rm;
5552
5553   skip_whitespace (str);
5554
5555   if ((rd = reg_required_here (&str, 12)) == FAIL
5556       || skip_past_comma (&str) == FAIL
5557       || (rm = reg_required_here (&str, 0)) == FAIL)
5558     inst.error = BAD_ARGS;
5559
5560   else if (rd == REG_PC || rm == REG_PC)
5561     inst.error = BAD_PC;
5562
5563   else
5564     end_of_line (str);
5565 }
5566
5567 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5568    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
5569    Condition defaults to COND_ALWAYS.
5570    Error if Rd, Rn or Rm are R15.  */
5571
5572 static void
5573 do_qadd16 (str) 
5574      char* str;
5575 {
5576   int rd, rm, rn;
5577
5578   skip_whitespace (str);
5579
5580   if ((rd = reg_required_here (&str, 12)) == FAIL
5581       || skip_past_comma (&str) == FAIL
5582       || (rn = reg_required_here (&str, 16)) == FAIL
5583       || skip_past_comma (&str) == FAIL
5584       || (rm = reg_required_here (&str, 0)) == FAIL)
5585     inst.error = BAD_ARGS;
5586
5587   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5588     inst.error = BAD_PC;
5589
5590   else
5591     end_of_line (str);
5592 }
5593
5594 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5595    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
5596    Condition defaults to COND_ALWAYS.
5597    Error if Rd, Rn or Rm are R15.  */
5598
5599 static void 
5600 do_pkhbt (str)
5601      char* str;
5602 {
5603   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5604 }
5605
5606 /* ARM V6 PKHTB (Argument Parse). */
5607
5608 static void 
5609 do_pkhtb (str)
5610      char* str;
5611 {
5612   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5613 }
5614
5615 static void
5616 do_pkh_core (str, shift)
5617      char* str;
5618      int shift;
5619 {
5620   int rd, rn, rm;
5621
5622   skip_whitespace (str);
5623   if (((rd = reg_required_here (&str, 12)) == FAIL)
5624       || (skip_past_comma (&str) == FAIL)
5625       || ((rn = reg_required_here (&str, 16)) == FAIL)
5626       || (skip_past_comma (&str) == FAIL)
5627       || ((rm = reg_required_here (&str, 0)) == FAIL))
5628     {
5629       inst.error = BAD_ARGS;
5630       return;
5631     }
5632
5633   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5634     {
5635       inst.error = BAD_PC;
5636       return;
5637     }
5638
5639   /* Check for optional shift immediate constant. */
5640   if (skip_past_comma (&str) == FAIL) 
5641     {
5642       if (shift == SHIFT_ASR_IMMEDIATE)
5643         {
5644           /* If the shift specifier is ommited, turn the instruction
5645              into pkhbt rd, rm, rn.  First, switch the instruction
5646              code, and clear the rn and rm fields.  */
5647           inst.instruction &= 0xfff0f010;
5648           /* Now, re-encode the registers.  */
5649           inst.instruction |= (rm << 16) | rn;
5650         }
5651       return;
5652     }
5653
5654   decode_shift (&str, shift);
5655 }
5656
5657 /* ARM V6 Load Register Exclusive instruction (argument parse).
5658    LDREX{<cond>} <Rd, [<Rn>]
5659    Condition defaults to COND_ALWAYS.
5660    Error if Rd or Rn are R15. 
5661    See ARMARMv6 A4.1.27: LDREX. */
5662
5663
5664 static void
5665 do_ldrex (str)
5666      char * str;
5667 {
5668   int rd, rn;
5669
5670   skip_whitespace (str);
5671
5672   /* Parse Rd. */
5673   if (((rd = reg_required_here (&str, 12)) == FAIL)
5674       || (skip_past_comma (&str) == FAIL))
5675     {
5676       inst.error = BAD_ARGS;
5677       return;
5678     }
5679   else if (rd == REG_PC)
5680     {
5681       inst.error = BAD_PC;
5682       return;
5683     }
5684   skip_whitespace (str);  
5685
5686   /* Skip past '['. */
5687   if ((strlen (str) >= 1) 
5688       &&strncmp (str, "[", 1) == 0)
5689     str+=1;
5690   skip_whitespace (str);  
5691
5692   /* Parse Rn. */
5693   if ((rn = reg_required_here (&str, 16)) == FAIL)
5694     {
5695       inst.error = BAD_ARGS;
5696       return;
5697     }
5698   else if (rn == REG_PC)
5699     {
5700       inst.error = BAD_PC;
5701       return;
5702     }
5703   skip_whitespace (str);  
5704
5705   /* Skip past ']'. */
5706   if ((strlen (str) >= 1) 
5707       && strncmp (str, "]", 1) == 0)
5708     str+=1;
5709   
5710   end_of_line (str);
5711 }
5712
5713 /* ARM V6 change processor state instruction (argument parse)
5714       CPS, CPSIE, CSPID . */
5715
5716 static void
5717 do_cps (str)
5718      char * str;
5719 {
5720   do_cps_mode (&str);
5721   end_of_line (str);
5722 }
5723
5724 static void
5725 do_cpsi (str)
5726      char * str;
5727 {
5728   do_cps_flags (&str, /*thumb_p=*/0);
5729
5730   if (skip_past_comma (&str) == SUCCESS)
5731     {
5732       skip_whitespace (str);
5733       do_cps_mode (&str);
5734     }
5735   end_of_line (str);
5736 }
5737
5738 static void
5739 do_cps_mode (str)
5740      char **str;
5741 {
5742   expressionS expr;
5743
5744   skip_whitespace (*str);
5745
5746   if (! is_immediate_prefix (**str))
5747     {
5748       inst.error = _("immediate expression expected");
5749       return;
5750     }
5751
5752   (*str)++; /* Strip off the immediate signifier. */
5753   if (my_get_expression (&expr, str))
5754     {
5755       inst.error = _("bad expression");
5756       return;
5757     }
5758
5759   if (expr.X_op != O_constant)
5760     {
5761       inst.error = _("constant expression expected");
5762       return;
5763     }
5764   
5765   /* The mode is a 5 bit field.  Valid values are 0-31. */
5766   if (((unsigned) expr.X_add_number) > 31
5767       || (inst.reloc.exp.X_add_number) < 0)
5768     {
5769       inst.error = _("invalid constant");
5770       return;
5771     }
5772   
5773   inst.instruction |= expr.X_add_number;
5774 }
5775
5776 static void
5777 do_cps_flags (str, thumb_p)
5778      char **str;
5779      int    thumb_p;
5780 {
5781   struct cps_flag { 
5782     char character;
5783     unsigned long arm_value;
5784     unsigned long thumb_value;
5785   };
5786   static struct cps_flag flag_table[] = {
5787     {'a', 0x100, 0x4 },
5788     {'i', 0x080, 0x2 },
5789     {'f', 0x040, 0x1 }
5790   };
5791
5792   int saw_a_flag = 0;
5793
5794   skip_whitespace (*str);
5795
5796   /* Get the a, f and i flags. */
5797   while (**str && **str != ',')
5798     {
5799       struct cps_flag *p;
5800       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5801       for (p = flag_table; p < q; ++p)
5802         if (strncasecmp (*str, &p->character, 1) == 0)
5803           {
5804             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5805             saw_a_flag = 1;
5806             break;
5807           }
5808       if (p == q)
5809         {
5810           inst.error = _("unrecognized flag");
5811           return;
5812         }
5813       (*str)++;
5814     }
5815   if (!saw_a_flag) 
5816     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5817 }
5818
5819 /* THUMB V5 breakpoint instruction (argument parse)
5820         BKPT <immed_8>.  */
5821
5822 static void
5823 do_t_bkpt (str)
5824      char * str;
5825 {
5826   expressionS expr;
5827   unsigned long number;
5828
5829   skip_whitespace (str);
5830
5831   /* Allow optional leading '#'.  */
5832   if (is_immediate_prefix (*str))
5833     str ++;
5834
5835   memset (& expr, '\0', sizeof (expr));
5836   if (my_get_expression (& expr, & str)
5837       || (expr.X_op != O_constant
5838           /* As a convenience we allow 'bkpt' without an operand.  */
5839           && expr.X_op != O_absent))
5840     {
5841       inst.error = _("bad expression");
5842       return;
5843     }
5844
5845   number = expr.X_add_number;
5846
5847   /* Check it fits an 8 bit unsigned.  */
5848   if (number != (number & 0xff))
5849     {
5850       inst.error = _("immediate value out of range");
5851       return;
5852     }
5853
5854   inst.instruction |= number;
5855
5856   end_of_line (str);
5857 }
5858
5859 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5860    Expects inst.instruction is set for BLX(1).
5861    Note: this is cloned from do_branch, and the reloc changed to be a
5862         new one that can cope with setting one extra bit (the H bit).  */
5863
5864 static void
5865 do_branch25 (str)
5866      char *        str;
5867 {
5868   if (my_get_expression (& inst.reloc.exp, & str))
5869     return;
5870
5871 #ifdef OBJ_ELF
5872   {
5873     char * save_in;
5874
5875     /* ScottB: February 5, 1998 */
5876     /* Check to see of PLT32 reloc required for the instruction.  */
5877
5878     /* arm_parse_reloc() works on input_line_pointer.
5879        We actually want to parse the operands to the branch instruction
5880        passed in 'str'.  Save the input pointer and restore it later.  */
5881     save_in = input_line_pointer;
5882     input_line_pointer = str;
5883
5884     if (inst.reloc.exp.X_op == O_symbol
5885         && *str == '('
5886         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5887       {
5888         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5889         inst.reloc.pc_rel = 0;
5890         /* Modify str to point to after parsed operands, otherwise
5891            end_of_line() will complain about the (PLT) left in str.  */
5892         str = input_line_pointer;
5893       }
5894     else
5895       {
5896         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5897         inst.reloc.pc_rel = 1;
5898       }
5899
5900     input_line_pointer = save_in;
5901   }
5902 #else
5903   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5904   inst.reloc.pc_rel = 1;
5905 #endif /* OBJ_ELF */
5906
5907   end_of_line (str);
5908 }
5909
5910 /* ARM V5 branch-link-exchange instruction (argument parse)
5911      BLX <target_addr>          ie BLX(1)
5912      BLX{<condition>} <Rm>      ie BLX(2)
5913    Unfortunately, there are two different opcodes for this mnemonic.
5914    So, the insns[].value is not used, and the code here zaps values
5915         into inst.instruction.
5916    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5917
5918 static void
5919 do_blx (str)
5920      char *        str;
5921 {
5922   char * mystr = str;
5923   int rm;
5924
5925   skip_whitespace (mystr);
5926   rm = reg_required_here (& mystr, 0);
5927
5928   /* The above may set inst.error.  Ignore his opinion.  */
5929   inst.error = 0;
5930
5931   if (rm != FAIL)
5932     {
5933       /* Arg is a register.
5934          Use the condition code our caller put in inst.instruction.
5935          Pass ourselves off as a BX with a funny opcode.  */
5936       inst.instruction |= 0x012fff30;
5937       do_bx (str);
5938     }
5939   else
5940     {
5941       /* This must be is BLX <target address>, no condition allowed.  */
5942       if (inst.instruction != COND_ALWAYS)
5943         {
5944           inst.error = BAD_COND;
5945           return;
5946         }
5947
5948       inst.instruction = 0xfafffffe;
5949
5950       /* Process like a B/BL, but with a different reloc.
5951          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5952       do_branch25 (str);
5953     }
5954 }
5955
5956 /* ARM V5 Thumb BLX (argument parse)
5957         BLX <target_addr>       which is BLX(1)
5958         BLX <Rm>                which is BLX(2)
5959    Unfortunately, there are two different opcodes for this mnemonic.
5960    So, the tinsns[].value is not used, and the code here zaps values
5961         into inst.instruction.  */
5962
5963 static void
5964 do_t_blx (str)
5965      char * str;
5966 {
5967   char * mystr = str;
5968   int rm;
5969
5970   skip_whitespace (mystr);
5971   inst.instruction = 0x4780;
5972
5973   /* Note that this call is to the ARM register recognizer.  BLX(2)
5974      uses the ARM register space, not the Thumb one, so a call to
5975      thumb_reg() would be wrong.  */
5976   rm = reg_required_here (& mystr, 3);
5977   inst.error = 0;
5978
5979   if (rm != FAIL)
5980     {
5981       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5982       inst.size = 2;
5983     }
5984   else
5985     {
5986       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5987       inst.instruction = 0xf7ffeffe;
5988       inst.size = 4;
5989
5990       if (my_get_expression (& inst.reloc.exp, & mystr))
5991         return;
5992
5993       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5994       inst.reloc.pc_rel = 1;
5995     }
5996
5997   end_of_line (mystr);
5998 }
5999
6000 /* ARM V5 breakpoint instruction (argument parse)
6001      BKPT <16 bit unsigned immediate>
6002      Instruction is not conditional.
6003         The bit pattern given in insns[] has the COND_ALWAYS condition,
6004         and it is an error if the caller tried to override that.  */
6005
6006 static void
6007 do_bkpt (str)
6008      char *        str;
6009 {
6010   expressionS expr;
6011   unsigned long number;
6012
6013   skip_whitespace (str);
6014
6015   /* Allow optional leading '#'.  */
6016   if (is_immediate_prefix (* str))
6017     str++;
6018
6019   memset (& expr, '\0', sizeof (expr));
6020
6021   if (my_get_expression (& expr, & str)
6022       || (expr.X_op != O_constant
6023           /* As a convenience we allow 'bkpt' without an operand.  */
6024           && expr.X_op != O_absent))
6025     {
6026       inst.error = _("bad expression");
6027       return;
6028     }
6029
6030   number = expr.X_add_number;
6031
6032   /* Check it fits a 16 bit unsigned.  */
6033   if (number != (number & 0xffff))
6034     {
6035       inst.error = _("immediate value out of range");
6036       return;
6037     }
6038
6039   /* Top 12 of 16 bits to bits 19:8.  */
6040   inst.instruction |= (number & 0xfff0) << 4;
6041
6042   /* Bottom 4 of 16 bits to bits 3:0.  */
6043   inst.instruction |= number & 0xf;
6044
6045   end_of_line (str);
6046 }
6047
6048 /* THUMB CPS instruction (argument parse).  */
6049
6050 static void
6051 do_t_cps (str)
6052      char *str;
6053 {
6054   do_cps_flags (&str, /*thumb_p=*/1);
6055   end_of_line (str);
6056 }
6057
6058 /* THUMB CPY instruction (argument parse).  */
6059
6060 static void
6061 do_t_cpy (str)
6062      char *str;
6063 {
6064   thumb_mov_compare (str, THUMB_CPY);
6065 }
6066
6067 /* THUMB SETEND instruction (argument parse).  */
6068
6069 static void
6070 do_t_setend (str)
6071      char *str;
6072 {
6073   if (do_endian_specifier (str))
6074     inst.instruction |= 0x8;
6075 }
6076
6077 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6078
6079 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6080
6081 static unsigned long
6082 check_iwmmxt_insn (str, insn_type, immediate_size)
6083      char * str;
6084      enum iwmmxt_insn_type insn_type;
6085      int immediate_size;
6086 {
6087   int reg = 0;
6088   const char *  inst_error;
6089   expressionS expr;
6090   unsigned long number;
6091
6092   inst_error = inst.error;
6093   if (!inst.error)
6094     inst.error = BAD_ARGS;
6095   skip_whitespace (str);
6096
6097   switch (insn_type)
6098     {
6099     case check_rd:
6100       if ((reg = reg_required_here (&str, 12)) == FAIL)
6101         return FAIL;
6102       break;
6103       
6104     case check_wr:
6105        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6106          return FAIL;
6107        break;
6108        
6109     case check_wrwr:
6110       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6111            || skip_past_comma (&str) == FAIL
6112            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6113         return FAIL;
6114       break;
6115       
6116     case check_wrwrwr:
6117       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6118            || skip_past_comma (&str) == FAIL
6119            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6120            || skip_past_comma (&str) == FAIL
6121            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6122         return FAIL;
6123       break;
6124       
6125     case check_wrwrwcg:
6126       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6127            || skip_past_comma (&str) == FAIL
6128            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6129            || skip_past_comma (&str) == FAIL
6130            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6131         return FAIL;
6132       break;
6133       
6134     case check_tbcst:
6135       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6136            || skip_past_comma (&str) == FAIL
6137            || reg_required_here (&str, 12) == FAIL))
6138         return FAIL;
6139       break;
6140       
6141     case check_tmovmsk:
6142       if ((reg_required_here (&str, 12) == FAIL
6143            || skip_past_comma (&str) == FAIL
6144            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6145         return FAIL;
6146       break;
6147       
6148     case check_tmia:
6149       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6150            || skip_past_comma (&str) == FAIL
6151            || reg_required_here (&str, 0) == FAIL
6152            || skip_past_comma (&str) == FAIL
6153            || reg_required_here (&str, 12) == FAIL))
6154         return FAIL;
6155       break;
6156       
6157     case check_tmcrr:
6158       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6159            || skip_past_comma (&str) == FAIL
6160            || reg_required_here (&str, 12) == FAIL
6161            || skip_past_comma (&str) == FAIL
6162            || reg_required_here (&str, 16) == FAIL))
6163         return FAIL;
6164       break;
6165       
6166     case check_tmrrc:
6167       if ((reg_required_here (&str, 12) == FAIL
6168            || skip_past_comma (&str) == FAIL
6169            || reg_required_here (&str, 16) == FAIL
6170            || skip_past_comma (&str) == FAIL
6171            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6172         return FAIL;
6173       break;
6174       
6175     case check_tmcr:
6176       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6177            || skip_past_comma (&str) == FAIL
6178            || reg_required_here (&str, 12) == FAIL))
6179         return FAIL;
6180       break;
6181       
6182     case check_tmrc:
6183       if ((reg_required_here (&str, 12) == FAIL
6184            || skip_past_comma (&str) == FAIL
6185            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6186         return FAIL;
6187       break;
6188       
6189     case check_tinsr:
6190       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6191            || skip_past_comma (&str) == FAIL
6192            || reg_required_here (&str, 12) == FAIL
6193            || skip_past_comma (&str) == FAIL))
6194         return FAIL;
6195       break;
6196       
6197     case check_textrc:
6198       if ((reg_required_here (&str, 12) == FAIL
6199            || skip_past_comma (&str) == FAIL))
6200         return FAIL;
6201       break;
6202       
6203     case check_waligni:
6204       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6205            || skip_past_comma (&str) == FAIL
6206            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6207            || skip_past_comma (&str) == FAIL
6208            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6209            || skip_past_comma (&str) == FAIL))
6210         return FAIL;
6211       break;
6212       
6213     case check_textrm:
6214       if ((reg_required_here (&str, 12) == FAIL
6215            || skip_past_comma (&str) == FAIL
6216            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6217            || skip_past_comma (&str) == FAIL))
6218         return FAIL;
6219       break;
6220       
6221     case check_wshufh:
6222       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6223            || skip_past_comma (&str) == FAIL
6224            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6225            || skip_past_comma (&str) == FAIL))
6226         return FAIL;
6227       break;
6228     }
6229   
6230   if (immediate_size == 0)
6231     {
6232       end_of_line (str);
6233       inst.error = inst_error;
6234       return reg;
6235     }
6236   else
6237     {
6238       skip_whitespace (str);      
6239   
6240       /* Allow optional leading '#'. */
6241       if (is_immediate_prefix (* str))
6242         str++;
6243
6244       memset (& expr, '\0', sizeof (expr));
6245   
6246       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6247         {
6248           inst.error = _("bad or missing expression");
6249           return FAIL;
6250         }
6251   
6252       number = expr.X_add_number;
6253   
6254       if (number != (number & immediate_size))
6255         {
6256           inst.error = _("immediate value out of range");
6257           return FAIL;
6258         }
6259       end_of_line (str);
6260       inst.error = inst_error;
6261       return number;
6262     }
6263 }
6264
6265 static void
6266 do_iwmmxt_byte_addr (str)
6267      char * str;
6268 {
6269   int op = (inst.instruction & 0x300) >> 8;
6270   int reg;
6271
6272   inst.instruction &= ~0x300;
6273   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6274
6275   skip_whitespace (str);
6276
6277   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6278       || skip_past_comma (& str) == FAIL
6279       || cp_byte_address_required_here (&str) == FAIL)
6280     {
6281       if (! inst.error)
6282         inst.error = BAD_ARGS;
6283     }
6284   else
6285     end_of_line (str);
6286
6287   if (wc_register (reg))
6288     {
6289       as_bad (_("non-word size not supported with control register"));
6290       inst.instruction |=  0xf0000100;
6291       inst.instruction &= ~0x00400000;
6292     }
6293 }
6294
6295 static void
6296 do_iwmmxt_tandc (str)
6297      char * str;
6298 {
6299   int reg;
6300
6301   reg = check_iwmmxt_insn (str, check_rd, 0);
6302
6303   if (reg != REG_PC && !inst.error)
6304     inst.error = _("only r15 allowed here");
6305 }
6306
6307 static void
6308 do_iwmmxt_tbcst (str)
6309      char * str;
6310 {
6311   check_iwmmxt_insn (str, check_tbcst, 0);
6312 }
6313
6314 static void
6315 do_iwmmxt_textrc (str)
6316      char * str;
6317 {
6318   unsigned long number;
6319
6320   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6321     return;
6322
6323   inst.instruction |= number & 0x7;
6324 }
6325
6326 static void
6327 do_iwmmxt_textrm (str)
6328      char * str;
6329 {
6330   unsigned long number;
6331
6332   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6333     return;
6334
6335   inst.instruction |= number & 0x7;
6336 }
6337
6338 static void
6339 do_iwmmxt_tinsr (str)
6340      char * str;
6341 {
6342   unsigned long number;
6343
6344   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6345     return;
6346
6347   inst.instruction |= number & 0x7;
6348 }
6349
6350 static void
6351 do_iwmmxt_tmcr (str)
6352      char * str;
6353 {
6354   check_iwmmxt_insn (str, check_tmcr, 0);
6355 }
6356
6357 static void
6358 do_iwmmxt_tmcrr (str)
6359      char * str;
6360 {
6361   check_iwmmxt_insn (str, check_tmcrr, 0);
6362 }
6363
6364 static void
6365 do_iwmmxt_tmia (str)
6366      char * str;
6367 {
6368   check_iwmmxt_insn (str, check_tmia, 0);
6369 }
6370
6371 static void
6372 do_iwmmxt_tmovmsk (str)
6373      char * str;
6374 {
6375   check_iwmmxt_insn (str, check_tmovmsk, 0);
6376 }
6377
6378 static void
6379 do_iwmmxt_tmrc (str)
6380      char * str;
6381 {
6382   check_iwmmxt_insn (str, check_tmrc, 0);
6383 }
6384
6385 static void
6386 do_iwmmxt_tmrrc (str)
6387      char * str;
6388 {
6389   check_iwmmxt_insn (str, check_tmrrc, 0);
6390 }
6391
6392 static void
6393 do_iwmmxt_torc (str)
6394      char * str;
6395 {
6396   check_iwmmxt_insn (str, check_rd, 0);
6397 }
6398
6399 static void
6400 do_iwmmxt_waligni (str)
6401      char * str;
6402 {
6403   unsigned long number;
6404
6405   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6406     return;
6407
6408   inst.instruction |= ((number & 0x7) << 20);
6409 }
6410
6411 static void
6412 do_iwmmxt_wmov (str)
6413      char * str;
6414 {
6415   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6416     return;
6417   
6418   inst.instruction |= ((inst.instruction >> 16) & 0xf);
6419 }
6420
6421 static void
6422 do_iwmmxt_word_addr (str)
6423      char * str;
6424 {
6425   int op = (inst.instruction & 0x300) >> 8;
6426   int reg;
6427
6428   inst.instruction &= ~0x300;
6429   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6430
6431   skip_whitespace (str);
6432
6433   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6434       || skip_past_comma (& str) == FAIL
6435       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6436     {
6437       if (! inst.error)
6438         inst.error = BAD_ARGS;
6439     }
6440   else
6441     end_of_line (str);
6442
6443   if (wc_register (reg))
6444     {
6445       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6446         as_bad (_("conditional execution not supported with control register"));
6447       if (op != 2)
6448         as_bad (_("non-word size not supported with control register"));
6449       inst.instruction |=  0xf0000100;
6450       inst.instruction &= ~0x00400000;
6451     }
6452 }
6453
6454 static void
6455 do_iwmmxt_wrwr (str)
6456      char * str;
6457 {
6458   check_iwmmxt_insn (str, check_wrwr, 0);
6459 }
6460
6461 static void
6462 do_iwmmxt_wrwrwcg (str)
6463      char * str;
6464 {
6465   check_iwmmxt_insn (str, check_wrwrwcg, 0);
6466 }
6467
6468 static void
6469 do_iwmmxt_wrwrwr (str)
6470      char * str;
6471 {
6472   check_iwmmxt_insn (str, check_wrwrwr, 0);
6473 }
6474
6475 static void
6476 do_iwmmxt_wshufh (str)
6477      char * str;
6478 {
6479   unsigned long number;
6480
6481   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6482     return;
6483
6484   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6485 }
6486
6487 static void
6488 do_iwmmxt_wzero (str)
6489      char * str;
6490 {
6491   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6492     return;
6493
6494   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6495 }
6496
6497 /* Xscale multiply-accumulate (argument parse)
6498      MIAcc   acc0,Rm,Rs
6499      MIAPHcc acc0,Rm,Rs
6500      MIAxycc acc0,Rm,Rs.  */
6501
6502 static void
6503 do_xsc_mia (str)
6504      char * str;
6505 {
6506   int rs;
6507   int rm;
6508
6509   if (accum0_required_here (& str) == FAIL)
6510     inst.error = ERR_NO_ACCUM;
6511
6512   else if (skip_past_comma (& str) == FAIL
6513            || (rm = reg_required_here (& str, 0)) == FAIL)
6514     inst.error = BAD_ARGS;
6515
6516   else if (skip_past_comma (& str) == FAIL
6517            || (rs = reg_required_here (& str, 12)) == FAIL)
6518     inst.error = BAD_ARGS;
6519
6520   /* inst.instruction has now been zapped with both rm and rs.  */
6521   else if (rm == REG_PC || rs == REG_PC)
6522     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
6523
6524   else
6525     end_of_line (str);
6526 }
6527
6528 /* Xscale move-accumulator-register (argument parse)
6529
6530      MARcc   acc0,RdLo,RdHi.  */
6531
6532 static void
6533 do_xsc_mar (str)
6534      char * str;
6535 {
6536   int rdlo, rdhi;
6537
6538   if (accum0_required_here (& str) == FAIL)
6539     inst.error = ERR_NO_ACCUM;
6540
6541   else if (skip_past_comma (& str) == FAIL
6542            || (rdlo = reg_required_here (& str, 12)) == FAIL)
6543     inst.error = BAD_ARGS;
6544
6545   else if (skip_past_comma (& str) == FAIL
6546            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6547     inst.error = BAD_ARGS;
6548
6549   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6550   else if (rdlo == REG_PC || rdhi == REG_PC)
6551     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6552
6553   else
6554     end_of_line (str);
6555 }
6556
6557 /* Xscale move-register-accumulator (argument parse)
6558
6559      MRAcc   RdLo,RdHi,acc0.  */
6560
6561 static void
6562 do_xsc_mra (str)
6563      char * str;
6564 {
6565   int rdlo;
6566   int rdhi;
6567
6568   skip_whitespace (str);
6569
6570   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6571     inst.error = BAD_ARGS;
6572
6573   else if (skip_past_comma (& str) == FAIL
6574            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6575     inst.error = BAD_ARGS;
6576
6577   else if  (skip_past_comma (& str) == FAIL
6578             || accum0_required_here (& str) == FAIL)
6579     inst.error = ERR_NO_ACCUM;
6580
6581   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6582   else if (rdlo == rdhi)
6583     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
6584
6585   else if (rdlo == REG_PC || rdhi == REG_PC)
6586     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6587   else
6588     end_of_line (str);
6589 }
6590
6591 /* ARMv5TE: Preload-Cache
6592
6593     PLD <addr_mode>
6594
6595   Syntactically, like LDR with B=1, W=0, L=1.  */
6596
6597 static void
6598 do_pld (str)
6599      char * str;
6600 {
6601   int rd;
6602
6603   skip_whitespace (str);
6604
6605   if (* str != '[')
6606     {
6607       inst.error = _("'[' expected after PLD mnemonic");
6608       return;
6609     }
6610
6611   ++str;
6612   skip_whitespace (str);
6613
6614   if ((rd = reg_required_here (& str, 16)) == FAIL)
6615     return;
6616
6617   skip_whitespace (str);
6618
6619   if (*str == ']')
6620     {
6621       /* [Rn], ... ?  */
6622       ++str;
6623       skip_whitespace (str);
6624
6625       /* Post-indexed addressing is not allowed with PLD.  */
6626       if (skip_past_comma (&str) == SUCCESS)
6627         {
6628           inst.error
6629             = _("post-indexed expression used in preload instruction");
6630           return;
6631         }
6632       else if (*str == '!') /* [Rn]! */
6633         {
6634           inst.error = _("writeback used in preload instruction");
6635           ++str;
6636         }
6637       else /* [Rn] */
6638         inst.instruction |= INDEX_UP | PRE_INDEX;
6639     }
6640   else /* [Rn, ...] */
6641     {
6642       if (skip_past_comma (& str) == FAIL)
6643         {
6644           inst.error = _("pre-indexed expression expected");
6645           return;
6646         }
6647
6648       if (ldst_extend (&str) == FAIL)
6649         return;
6650
6651       skip_whitespace (str);
6652
6653       if (* str != ']')
6654         {
6655           inst.error = _("missing ]");
6656           return;
6657         }
6658
6659       ++ str;
6660       skip_whitespace (str);
6661
6662       if (* str == '!') /* [Rn]! */
6663         {
6664           inst.error = _("writeback used in preload instruction");
6665           ++ str;
6666         }
6667
6668       inst.instruction |= PRE_INDEX;
6669     }
6670
6671   end_of_line (str);
6672 }
6673
6674 /* ARMv5TE load-consecutive (argument parse)
6675    Mode is like LDRH.
6676
6677      LDRccD R, mode
6678      STRccD R, mode.  */
6679
6680 static void
6681 do_ldrd (str)
6682      char * str;
6683 {
6684   int rd;
6685   int rn;
6686
6687   skip_whitespace (str);
6688
6689   if ((rd = reg_required_here (& str, 12)) == FAIL)
6690     {
6691       inst.error = BAD_ARGS;
6692       return;
6693     }
6694
6695   if (skip_past_comma (& str) == FAIL
6696       || (rn = ld_mode_required_here (& str)) == FAIL)
6697     {
6698       if (!inst.error)
6699         inst.error = BAD_ARGS;
6700       return;
6701     }
6702
6703   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6704   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
6705     {
6706       inst.error = _("destination register must be even");
6707       return;
6708     }
6709
6710   if (rd == REG_LR)
6711     {
6712       inst.error = _("r14 not allowed here");
6713       return;
6714     }
6715
6716   if (((rd == rn) || (rd + 1 == rn))
6717       && ((inst.instruction & WRITE_BACK)
6718           || (!(inst.instruction & PRE_INDEX))))
6719     as_warn (_("pre/post-indexing used when modified address register is destination"));
6720
6721   /* For an index-register load, the index register must not overlap the
6722      destination (even if not write-back).  */
6723   if ((inst.instruction & V4_STR_BIT) == 0
6724       && (inst.instruction & HWOFFSET_IMM) == 0)
6725     {
6726       int rm = inst.instruction & 0x0000000f;
6727
6728       if (rm == rd || (rm == rd + 1))
6729         as_warn (_("ldrd destination registers must not overlap index register"));
6730     }
6731
6732   end_of_line (str);
6733 }
6734
6735 /* Returns the index into fp_values of a floating point number,
6736    or -1 if not in the table.  */
6737
6738 static int
6739 my_get_float_expression (str)
6740      char ** str;
6741 {
6742   LITTLENUM_TYPE words[MAX_LITTLENUMS];
6743   char *         save_in;
6744   expressionS    exp;
6745   int            i;
6746   int            j;
6747
6748   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6749
6750   /* Look for a raw floating point number.  */
6751   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6752       && is_end_of_line[(unsigned char) *save_in])
6753     {
6754       for (i = 0; i < NUM_FLOAT_VALS; i++)
6755         {
6756           for (j = 0; j < MAX_LITTLENUMS; j++)
6757             {
6758               if (words[j] != fp_values[i][j])
6759                 break;
6760             }
6761
6762           if (j == MAX_LITTLENUMS)
6763             {
6764               *str = save_in;
6765               return i;
6766             }
6767         }
6768     }
6769
6770   /* Try and parse a more complex expression, this will probably fail
6771      unless the code uses a floating point prefix (eg "0f").  */
6772   save_in = input_line_pointer;
6773   input_line_pointer = *str;
6774   if (expression (&exp) == absolute_section
6775       && exp.X_op == O_big
6776       && exp.X_add_number < 0)
6777     {
6778       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6779          Ditto for 15.  */
6780       if (gen_to_words (words, 5, (long) 15) == 0)
6781         {
6782           for (i = 0; i < NUM_FLOAT_VALS; i++)
6783             {
6784               for (j = 0; j < MAX_LITTLENUMS; j++)
6785                 {
6786                   if (words[j] != fp_values[i][j])
6787                     break;
6788                 }
6789
6790               if (j == MAX_LITTLENUMS)
6791                 {
6792                   *str = input_line_pointer;
6793                   input_line_pointer = save_in;
6794                   return i;
6795                 }
6796             }
6797         }
6798     }
6799
6800   *str = input_line_pointer;
6801   input_line_pointer = save_in;
6802   return -1;
6803 }
6804
6805 /* Return TRUE if anything in the expression is a bignum.  */
6806
6807 static int
6808 walk_no_bignums (sp)
6809      symbolS * sp;
6810 {
6811   if (symbol_get_value_expression (sp)->X_op == O_big)
6812     return 1;
6813
6814   if (symbol_get_value_expression (sp)->X_add_symbol)
6815     {
6816       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6817               || (symbol_get_value_expression (sp)->X_op_symbol
6818                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6819     }
6820
6821   return 0;
6822 }
6823
6824 static int in_my_get_expression = 0;
6825
6826 static int
6827 my_get_expression (ep, str)
6828      expressionS * ep;
6829      char ** str;
6830 {
6831   char * save_in;
6832   segT   seg;
6833
6834   save_in = input_line_pointer;
6835   input_line_pointer = *str;
6836   in_my_get_expression = 1;
6837   seg = expression (ep);
6838   in_my_get_expression = 0;
6839
6840   if (ep->X_op == O_illegal)
6841     {
6842       /* We found a bad expression in md_operand().  */
6843       *str = input_line_pointer;
6844       input_line_pointer = save_in;
6845       return 1;
6846     }
6847
6848 #ifdef OBJ_AOUT
6849   if (seg != absolute_section
6850       && seg != text_section
6851       && seg != data_section
6852       && seg != bss_section
6853       && seg != undefined_section)
6854     {
6855       inst.error = _("bad_segment");
6856       *str = input_line_pointer;
6857       input_line_pointer = save_in;
6858       return 1;
6859     }
6860 #endif
6861
6862   /* Get rid of any bignums now, so that we don't generate an error for which
6863      we can't establish a line number later on.  Big numbers are never valid
6864      in instructions, which is where this routine is always called.  */
6865   if (ep->X_op == O_big
6866       || (ep->X_add_symbol
6867           && (walk_no_bignums (ep->X_add_symbol)
6868               || (ep->X_op_symbol
6869                   && walk_no_bignums (ep->X_op_symbol)))))
6870     {
6871       inst.error = _("invalid constant");
6872       *str = input_line_pointer;
6873       input_line_pointer = save_in;
6874       return 1;
6875     }
6876
6877   *str = input_line_pointer;
6878   input_line_pointer = save_in;
6879   return 0;
6880 }
6881
6882 /* We handle all bad expressions here, so that we can report the faulty
6883    instruction in the error message.  */
6884 void
6885 md_operand (expr)
6886      expressionS *expr;
6887 {
6888   if (in_my_get_expression)
6889     {
6890       expr->X_op = O_illegal;
6891       if (inst.error == NULL)
6892         inst.error = _("bad expression");
6893     }
6894 }
6895
6896 /* KIND indicates what kind of shifts are accepted.  */
6897
6898 static int
6899 decode_shift (str, kind)
6900      char ** str;
6901      int     kind;
6902 {
6903   const struct asm_shift_name * shift;
6904   char * p;
6905   char   c;
6906
6907   skip_whitespace (* str);
6908
6909   for (p = * str; ISALPHA (* p); p ++)
6910     ;
6911
6912   if (p == * str)
6913     {
6914       inst.error = _("shift expression expected");
6915       return FAIL;
6916     }
6917
6918   c = * p;
6919   * p = '\0';
6920   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6921   * p = c;
6922
6923   if (shift == NULL)
6924     {
6925       inst.error = _("shift expression expected");
6926       return FAIL;
6927     }
6928
6929   assert (shift->properties->index == shift_properties[shift->properties->index].index);
6930
6931   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6932       && shift->properties->index != SHIFT_LSL
6933       && shift->properties->index != SHIFT_ASR)
6934     {
6935       inst.error = _("'LSL' or 'ASR' required");
6936       return FAIL;
6937     }
6938   else if (kind == SHIFT_LSL_IMMEDIATE
6939            && shift->properties->index != SHIFT_LSL)
6940     {
6941       inst.error = _("'LSL' required");
6942       return FAIL;
6943     }
6944   else if (kind == SHIFT_ASR_IMMEDIATE
6945            && shift->properties->index != SHIFT_ASR)
6946     {
6947       inst.error = _("'ASR' required");
6948       return FAIL;
6949     }
6950     
6951   if (shift->properties->index == SHIFT_RRX)
6952     {
6953       * str = p;
6954       inst.instruction |= shift->properties->bit_field;
6955       return SUCCESS;
6956     }
6957
6958   skip_whitespace (p);
6959
6960   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6961     {
6962       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6963       * str = p;
6964       return SUCCESS;
6965     }
6966   else if (! is_immediate_prefix (* p))
6967     {
6968       inst.error = (NO_SHIFT_RESTRICT
6969                     ? _("shift requires register or #expression")
6970                     : _("shift requires #expression"));
6971       * str = p;
6972       return FAIL;
6973     }
6974
6975   inst.error = NULL;
6976   p ++;
6977
6978   if (my_get_expression (& inst.reloc.exp, & p))
6979     return FAIL;
6980
6981   /* Validate some simple #expressions.  */
6982   if (inst.reloc.exp.X_op == O_constant)
6983     {
6984       unsigned num = inst.reloc.exp.X_add_number;
6985
6986       /* Reject operations greater than 32.  */
6987       if (num > 32
6988           /* Reject a shift of 0 unless the mode allows it.  */
6989           || (num == 0 && shift->properties->allows_0 == 0)
6990           /* Reject a shift of 32 unless the mode allows it.  */
6991           || (num == 32 && shift->properties->allows_32 == 0)
6992           )
6993         {
6994           /* As a special case we allow a shift of zero for
6995              modes that do not support it to be recoded as an
6996              logical shift left of zero (ie nothing).  We warn
6997              about this though.  */
6998           if (num == 0)
6999             {
7000               as_warn (_("shift of 0 ignored."));
7001               shift = & shift_names[0];
7002               assert (shift->properties->index == SHIFT_LSL);
7003             }
7004           else
7005             {
7006               inst.error = _("invalid immediate shift");
7007               return FAIL;
7008             }
7009         }
7010
7011       /* Shifts of 32 are encoded as 0, for those shifts that
7012          support it.  */
7013       if (num == 32)
7014         num = 0;
7015
7016       inst.instruction |= (num << 7) | shift->properties->bit_field;
7017     }
7018   else
7019     {
7020       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
7021       inst.reloc.pc_rel = 0;
7022       inst.instruction |= shift->properties->bit_field;
7023     }
7024
7025   * str = p;
7026   return SUCCESS;
7027 }
7028
7029 /* Do those data_ops which can take a negative immediate constant
7030    by altering the instruction.  A bit of a hack really.
7031         MOV <-> MVN
7032         AND <-> BIC
7033         ADC <-> SBC
7034         by inverting the second operand, and
7035         ADD <-> SUB
7036         CMP <-> CMN
7037         by negating the second operand.  */
7038
7039 static int
7040 negate_data_op (instruction, value)
7041      unsigned long * instruction;
7042      unsigned long   value;
7043 {
7044   int op, new_inst;
7045   unsigned long negated, inverted;
7046
7047   negated = validate_immediate (-value);
7048   inverted = validate_immediate (~value);
7049
7050   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7051   switch (op)
7052     {
7053       /* First negates.  */
7054     case OPCODE_SUB:             /* ADD <-> SUB  */
7055       new_inst = OPCODE_ADD;
7056       value = negated;
7057       break;
7058
7059     case OPCODE_ADD:
7060       new_inst = OPCODE_SUB;
7061       value = negated;
7062       break;
7063
7064     case OPCODE_CMP:             /* CMP <-> CMN  */
7065       new_inst = OPCODE_CMN;
7066       value = negated;
7067       break;
7068
7069     case OPCODE_CMN:
7070       new_inst = OPCODE_CMP;
7071       value = negated;
7072       break;
7073
7074       /* Now Inverted ops.  */
7075     case OPCODE_MOV:             /* MOV <-> MVN  */
7076       new_inst = OPCODE_MVN;
7077       value = inverted;
7078       break;
7079
7080     case OPCODE_MVN:
7081       new_inst = OPCODE_MOV;
7082       value = inverted;
7083       break;
7084
7085     case OPCODE_AND:             /* AND <-> BIC  */
7086       new_inst = OPCODE_BIC;
7087       value = inverted;
7088       break;
7089
7090     case OPCODE_BIC:
7091       new_inst = OPCODE_AND;
7092       value = inverted;
7093       break;
7094
7095     case OPCODE_ADC:              /* ADC <-> SBC  */
7096       new_inst = OPCODE_SBC;
7097       value = inverted;
7098       break;
7099
7100     case OPCODE_SBC:
7101       new_inst = OPCODE_ADC;
7102       value = inverted;
7103       break;
7104
7105       /* We cannot do anything.  */
7106     default:
7107       return FAIL;
7108     }
7109
7110   if (value == (unsigned) FAIL)
7111     return FAIL;
7112
7113   *instruction &= OPCODE_MASK;
7114   *instruction |= new_inst << DATA_OP_SHIFT;
7115   return value;
7116 }
7117
7118 static int
7119 data_op2 (str)
7120      char ** str;
7121 {
7122   int value;
7123   expressionS expr;
7124
7125   skip_whitespace (* str);
7126
7127   if (reg_required_here (str, 0) != FAIL)
7128     {
7129       if (skip_past_comma (str) == SUCCESS)
7130         /* Shift operation on register.  */
7131         return decode_shift (str, NO_SHIFT_RESTRICT);
7132
7133       return SUCCESS;
7134     }
7135   else
7136     {
7137       /* Immediate expression.  */
7138       if (is_immediate_prefix (**str))
7139         {
7140           (*str)++;
7141           inst.error = NULL;
7142
7143           if (my_get_expression (&inst.reloc.exp, str))
7144             return FAIL;
7145
7146           if (inst.reloc.exp.X_add_symbol)
7147             {
7148               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7149               inst.reloc.pc_rel = 0;
7150             }
7151           else
7152             {
7153               if (skip_past_comma (str) == SUCCESS)
7154                 {
7155                   /* #x, y -- ie explicit rotation by Y.  */
7156                   if (my_get_expression (&expr, str))
7157                     return FAIL;
7158
7159                   if (expr.X_op != O_constant)
7160                     {
7161                       inst.error = _("constant expression expected");
7162                       return FAIL;
7163                     }
7164
7165                   /* Rotate must be a multiple of 2.  */
7166                   if (((unsigned) expr.X_add_number) > 30
7167                       || (expr.X_add_number & 1) != 0
7168                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7169                     {
7170                       inst.error = _("invalid constant");
7171                       return FAIL;
7172                     }
7173                   inst.instruction |= INST_IMMEDIATE;
7174                   inst.instruction |= inst.reloc.exp.X_add_number;
7175                   inst.instruction |= expr.X_add_number << 7;
7176                   return SUCCESS;
7177                 }
7178
7179               /* Implicit rotation, select a suitable one.  */
7180               value = validate_immediate (inst.reloc.exp.X_add_number);
7181
7182               if (value == FAIL)
7183                 {
7184                   /* Can't be done.  Perhaps the code reads something like
7185                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7186                   if ((value = negate_data_op (&inst.instruction,
7187                                                inst.reloc.exp.X_add_number))
7188                       == FAIL)
7189                     {
7190                       inst.error = _("invalid constant");
7191                       return FAIL;
7192                     }
7193                 }
7194
7195               inst.instruction |= value;
7196             }
7197
7198           inst.instruction |= INST_IMMEDIATE;
7199           return SUCCESS;
7200         }
7201
7202       (*str)++;
7203       inst.error = _("register or shift expression expected");
7204       return FAIL;
7205     }
7206 }
7207
7208 static int
7209 fp_op2 (str)
7210      char ** str;
7211 {
7212   skip_whitespace (* str);
7213
7214   if (fp_reg_required_here (str, 0) != FAIL)
7215     return SUCCESS;
7216   else
7217     {
7218       /* Immediate expression.  */
7219       if (*((*str)++) == '#')
7220         {
7221           int i;
7222
7223           inst.error = NULL;
7224
7225           skip_whitespace (* str);
7226
7227           /* First try and match exact strings, this is to guarantee
7228              that some formats will work even for cross assembly.  */
7229
7230           for (i = 0; fp_const[i]; i++)
7231             {
7232               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7233                 {
7234                   char *start = *str;
7235
7236                   *str += strlen (fp_const[i]);
7237                   if (is_end_of_line[(unsigned char) **str])
7238                     {
7239                       inst.instruction |= i + 8;
7240                       return SUCCESS;
7241                     }
7242                   *str = start;
7243                 }
7244             }
7245
7246           /* Just because we didn't get a match doesn't mean that the
7247              constant isn't valid, just that it is in a format that we
7248              don't automatically recognize.  Try parsing it with
7249              the standard expression routines.  */
7250           if ((i = my_get_float_expression (str)) >= 0)
7251             {
7252               inst.instruction |= i + 8;
7253               return SUCCESS;
7254             }
7255
7256           inst.error = _("invalid floating point immediate expression");
7257           return FAIL;
7258         }
7259       inst.error =
7260         _("floating point register or immediate expression expected");
7261       return FAIL;
7262     }
7263 }
7264
7265 static void
7266 do_arit (str)
7267      char * str;
7268 {
7269   skip_whitespace (str);
7270
7271   if (reg_required_here (&str, 12) == FAIL
7272       || skip_past_comma (&str) == FAIL
7273       || reg_required_here (&str, 16) == FAIL
7274       || skip_past_comma (&str) == FAIL
7275       || data_op2 (&str) == FAIL)
7276     {
7277       if (!inst.error)
7278         inst.error = BAD_ARGS;
7279       return;
7280     }
7281
7282   end_of_line (str);
7283 }
7284
7285 static void
7286 do_adr (str)
7287      char * str;
7288 {
7289   /* This is a pseudo-op of the form "adr rd, label" to be converted
7290      into a relative address of the form "add rd, pc, #label-.-8".  */
7291   skip_whitespace (str);
7292
7293   if (reg_required_here (&str, 12) == FAIL
7294       || skip_past_comma (&str) == FAIL
7295       || my_get_expression (&inst.reloc.exp, &str))
7296     {
7297       if (!inst.error)
7298         inst.error = BAD_ARGS;
7299       return;
7300     }
7301
7302   /* Frag hacking will turn this into a sub instruction if the offset turns
7303      out to be negative.  */
7304   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7305 #ifndef TE_WINCE
7306   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7307 #endif
7308   inst.reloc.pc_rel = 1;
7309
7310   end_of_line (str);
7311 }
7312
7313 static void
7314 do_adrl (str)
7315      char * str;
7316 {
7317   /* This is a pseudo-op of the form "adrl rd, label" to be converted
7318      into a relative address of the form:
7319      add rd, pc, #low(label-.-8)"
7320      add rd, rd, #high(label-.-8)"  */
7321
7322   skip_whitespace (str);
7323
7324   if (reg_required_here (&str, 12) == FAIL
7325       || skip_past_comma (&str) == FAIL
7326       || my_get_expression (&inst.reloc.exp, &str))
7327     {
7328       if (!inst.error)
7329         inst.error = BAD_ARGS;
7330
7331       return;
7332     }
7333
7334   end_of_line (str);
7335   /* Frag hacking will turn this into a sub instruction if the offset turns
7336      out to be negative.  */
7337   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7338 #ifndef TE_WINCE  
7339   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7340 #endif
7341   inst.reloc.pc_rel            = 1;
7342   inst.size                    = INSN_SIZE * 2;
7343 }
7344
7345 static void
7346 do_cmp (str)
7347      char * str;
7348 {
7349   skip_whitespace (str);
7350
7351   if (reg_required_here (&str, 16) == FAIL)
7352     {
7353       if (!inst.error)
7354         inst.error = BAD_ARGS;
7355       return;
7356     }
7357
7358   if (skip_past_comma (&str) == FAIL
7359       || data_op2 (&str) == FAIL)
7360     {
7361       if (!inst.error)
7362         inst.error = BAD_ARGS;
7363       return;
7364     }
7365
7366   end_of_line (str);
7367 }
7368
7369 static void
7370 do_mov (str)
7371      char * str;
7372 {
7373   skip_whitespace (str);
7374
7375   if (reg_required_here (&str, 12) == FAIL)
7376     {
7377       if (!inst.error)
7378         inst.error = BAD_ARGS;
7379       return;
7380     }
7381
7382   if (skip_past_comma (&str) == FAIL
7383       || data_op2 (&str) == FAIL)
7384     {
7385       if (!inst.error)
7386         inst.error = BAD_ARGS;
7387       return;
7388     }
7389
7390   end_of_line (str);
7391 }
7392
7393 static int
7394 ldst_extend (str)
7395      char ** str;
7396 {
7397   int add = INDEX_UP;
7398
7399   switch (**str)
7400     {
7401     case '#':
7402     case '$':
7403       (*str)++;
7404       if (my_get_expression (& inst.reloc.exp, str))
7405         return FAIL;
7406
7407       if (inst.reloc.exp.X_op == O_constant)
7408         {
7409           int value = inst.reloc.exp.X_add_number;
7410
7411           if (value < -4095 || value > 4095)
7412             {
7413               inst.error = _("address offset too large");
7414               return FAIL;
7415             }
7416
7417           if (value < 0)
7418             {
7419               value = -value;
7420               add = 0;
7421             }
7422
7423           inst.instruction |= add | value;
7424         }
7425       else
7426         {
7427           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7428           inst.reloc.pc_rel = 0;
7429         }
7430       return SUCCESS;
7431
7432     case '-':
7433       add = 0;
7434       /* Fall through.  */
7435
7436     case '+':
7437       (*str)++;
7438       /* Fall through.  */
7439
7440     default:
7441       if (reg_required_here (str, 0) == FAIL)
7442         return FAIL;
7443
7444       inst.instruction |= add | OFFSET_REG;
7445       if (skip_past_comma (str) == SUCCESS)
7446         return decode_shift (str, SHIFT_IMMEDIATE);
7447
7448       return SUCCESS;
7449     }
7450 }
7451
7452 static void
7453 do_ldst (str)
7454      char *        str;
7455 {
7456   int pre_inc = 0;
7457   int conflict_reg;
7458   int value;
7459
7460   skip_whitespace (str);
7461
7462   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7463     {
7464       if (!inst.error)
7465         inst.error = BAD_ARGS;
7466       return;
7467     }
7468
7469   if (skip_past_comma (&str) == FAIL)
7470     {
7471       inst.error = _("address expected");
7472       return;
7473     }
7474
7475   if (*str == '[')
7476     {
7477       int reg;
7478
7479       str++;
7480
7481       skip_whitespace (str);
7482
7483       if ((reg = reg_required_here (&str, 16)) == FAIL)
7484         return;
7485
7486       /* Conflicts can occur on stores as well as loads.  */
7487       conflict_reg = (conflict_reg == reg);
7488
7489       skip_whitespace (str);
7490
7491       if (*str == ']')
7492         {
7493           str ++;
7494
7495           if (skip_past_comma (&str) == SUCCESS)
7496             {
7497               /* [Rn],... (post inc)  */
7498               if (ldst_extend (&str) == FAIL)
7499                 return;
7500               if (conflict_reg)
7501                 as_warn (_("%s register same as write-back base"),
7502                          ((inst.instruction & LOAD_BIT)
7503                           ? _("destination") : _("source")));
7504             }
7505           else
7506             {
7507               /* [Rn]  */
7508               skip_whitespace (str);
7509
7510               if (*str == '!')
7511                 {
7512                   if (conflict_reg)
7513                     as_warn (_("%s register same as write-back base"),
7514                              ((inst.instruction & LOAD_BIT)
7515                               ? _("destination") : _("source")));
7516                   str++;
7517                   inst.instruction |= WRITE_BACK;
7518                 }
7519
7520               inst.instruction |= INDEX_UP;
7521               pre_inc = 1;
7522             }
7523         }
7524       else
7525         {
7526           /* [Rn,...]  */
7527           if (skip_past_comma (&str) == FAIL)
7528             {
7529               inst.error = _("pre-indexed expression expected");
7530               return;
7531             }
7532
7533           pre_inc = 1;
7534           if (ldst_extend (&str) == FAIL)
7535             return;
7536
7537           skip_whitespace (str);
7538
7539           if (*str++ != ']')
7540             {
7541               inst.error = _("missing ]");
7542               return;
7543             }
7544
7545           skip_whitespace (str);
7546
7547           if (*str == '!')
7548             {
7549               if (conflict_reg)
7550                 as_warn (_("%s register same as write-back base"),
7551                          ((inst.instruction & LOAD_BIT)
7552                           ? _("destination") : _("source")));
7553               str++;
7554               inst.instruction |= WRITE_BACK;
7555             }
7556         }
7557     }
7558   else if (*str == '=')
7559     {
7560       if ((inst.instruction & LOAD_BIT) == 0)
7561         {
7562           inst.error = _("invalid pseudo operation");
7563           return;
7564         }
7565
7566       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7567       str++;
7568
7569       skip_whitespace (str);
7570
7571       if (my_get_expression (&inst.reloc.exp, &str))
7572         return;
7573
7574       if (inst.reloc.exp.X_op != O_constant
7575           && inst.reloc.exp.X_op != O_symbol)
7576         {
7577           inst.error = _("constant expression expected");
7578           return;
7579         }
7580
7581       if (inst.reloc.exp.X_op == O_constant)
7582         {
7583           value = validate_immediate (inst.reloc.exp.X_add_number);
7584
7585           if (value != FAIL)
7586             {
7587               /* This can be done with a mov instruction.  */
7588               inst.instruction &= LITERAL_MASK;
7589               inst.instruction |= (INST_IMMEDIATE
7590                                    | (OPCODE_MOV << DATA_OP_SHIFT));
7591               inst.instruction |= value & 0xfff;
7592               end_of_line (str);
7593               return;
7594             }
7595
7596           value = validate_immediate (~inst.reloc.exp.X_add_number);
7597
7598           if (value != FAIL)
7599             {
7600               /* This can be done with a mvn instruction.  */
7601               inst.instruction &= LITERAL_MASK;
7602               inst.instruction |= (INST_IMMEDIATE
7603                                    | (OPCODE_MVN << DATA_OP_SHIFT));
7604               inst.instruction |= value & 0xfff;
7605               end_of_line (str);
7606               return;
7607             }
7608         }
7609
7610       /* Insert into literal pool.  */
7611       if (add_to_lit_pool () == FAIL)
7612         {
7613           if (!inst.error)
7614             inst.error = _("literal pool insertion failed");
7615           return;
7616         }
7617
7618       /* Change the instruction exp to point to the pool.  */
7619       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7620       inst.reloc.pc_rel = 1;
7621       inst.instruction |= (REG_PC << 16);
7622       pre_inc = 1;
7623     }
7624   else
7625     {
7626       if (my_get_expression (&inst.reloc.exp, &str))
7627         return;
7628
7629       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7630 #ifndef TE_WINCE
7631       /* PC rel adjust.  */
7632       inst.reloc.exp.X_add_number -= 8;
7633 #endif
7634       inst.reloc.pc_rel = 1;
7635       inst.instruction |= (REG_PC << 16);
7636       pre_inc = 1;
7637     }
7638
7639   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7640   end_of_line (str);
7641 }
7642
7643 static void
7644 do_ldstt (str)
7645      char *        str;
7646 {
7647   int conflict_reg;
7648
7649   skip_whitespace (str);
7650
7651   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7652     {
7653       if (!inst.error)
7654         inst.error = BAD_ARGS;
7655       return;
7656     }
7657
7658   if (skip_past_comma (& str) == FAIL)
7659     {
7660       inst.error = _("address expected");
7661       return;
7662     }
7663
7664   if (*str == '[')
7665     {
7666       int reg;
7667
7668       str++;
7669
7670       skip_whitespace (str);
7671
7672       if ((reg = reg_required_here (&str, 16)) == FAIL)
7673         return;
7674
7675       /* ldrt/strt always use post-indexed addressing, so if the base is
7676          the same as Rd, we warn.  */
7677       if (conflict_reg == reg)
7678         as_warn (_("%s register same as write-back base"),
7679                  ((inst.instruction & LOAD_BIT)
7680                   ? _("destination") : _("source")));
7681
7682       skip_whitespace (str);
7683
7684       if (*str == ']')
7685         {
7686           str ++;
7687
7688           if (skip_past_comma (&str) == SUCCESS)
7689             {
7690               /* [Rn],... (post inc)  */
7691               if (ldst_extend (&str) == FAIL)
7692                 return;
7693             }
7694           else
7695             {
7696               /* [Rn]  */
7697               skip_whitespace (str);
7698
7699               /* Skip a write-back '!'.  */
7700               if (*str == '!')
7701                 str++;
7702
7703               inst.instruction |= INDEX_UP;
7704             }
7705         }
7706       else
7707         {
7708           inst.error = _("post-indexed expression expected");
7709           return;
7710         }
7711     }
7712   else
7713     {
7714       inst.error = _("post-indexed expression expected");
7715       return;
7716     }
7717
7718   end_of_line (str);
7719 }
7720
7721 static int
7722 ldst_extend_v4 (str)
7723      char ** str;
7724 {
7725   int add = INDEX_UP;
7726
7727   switch (**str)
7728     {
7729     case '#':
7730     case '$':
7731       (*str)++;
7732       if (my_get_expression (& inst.reloc.exp, str))
7733         return FAIL;
7734
7735       if (inst.reloc.exp.X_op == O_constant)
7736         {
7737           int value = inst.reloc.exp.X_add_number;
7738
7739           if (value < -255 || value > 255)
7740             {
7741               inst.error = _("address offset too large");
7742               return FAIL;
7743             }
7744
7745           if (value < 0)
7746             {
7747               value = -value;
7748               add = 0;
7749             }
7750
7751           /* Halfword and signextension instructions have the
7752              immediate value split across bits 11..8 and bits 3..0.  */
7753           inst.instruction |= (add | HWOFFSET_IMM
7754                                | ((value >> 4) << 8) | (value & 0xF));
7755         }
7756       else
7757         {
7758           inst.instruction |= HWOFFSET_IMM;
7759           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7760           inst.reloc.pc_rel = 0;
7761         }
7762       return SUCCESS;
7763
7764     case '-':
7765       add = 0;
7766       /* Fall through.  */
7767
7768     case '+':
7769       (*str)++;
7770       /* Fall through.  */
7771
7772     default:
7773       if (reg_required_here (str, 0) == FAIL)
7774         return FAIL;
7775
7776       inst.instruction |= add;
7777       return SUCCESS;
7778     }
7779 }
7780
7781 /* Halfword and signed-byte load/store operations.  */
7782 static void
7783 do_ldstv4 (str)
7784      char *        str;
7785 {
7786   int pre_inc = 0;
7787   int conflict_reg;
7788   int value;
7789
7790   skip_whitespace (str);
7791
7792   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7793     {
7794       if (!inst.error)
7795         inst.error = BAD_ARGS;
7796       return;
7797     }
7798
7799   if (skip_past_comma (& str) == FAIL)
7800     {
7801       inst.error = _("address expected");
7802       return;
7803     }
7804
7805   if (*str == '[')
7806     {
7807       int reg;
7808
7809       str++;
7810
7811       skip_whitespace (str);
7812
7813       if ((reg = reg_required_here (&str, 16)) == FAIL)
7814         return;
7815
7816       /* Conflicts can occur on stores as well as loads.  */
7817       conflict_reg = (conflict_reg == reg);
7818
7819       skip_whitespace (str);
7820
7821       if (*str == ']')
7822         {
7823           str ++;
7824
7825           if (skip_past_comma (&str) == SUCCESS)
7826             {
7827               /* [Rn],... (post inc)  */
7828               if (ldst_extend_v4 (&str) == FAIL)
7829                 return;
7830               if (conflict_reg)
7831                 as_warn (_("%s register same as write-back base"),
7832                          ((inst.instruction & LOAD_BIT)
7833                           ? _("destination") : _("source")));
7834             }
7835           else
7836             {
7837               /* [Rn]  */
7838               inst.instruction |= HWOFFSET_IMM;
7839
7840               skip_whitespace (str);
7841
7842               if (*str == '!')
7843                 {
7844                   if (conflict_reg)
7845                     as_warn (_("%s register same as write-back base"),
7846                              ((inst.instruction & LOAD_BIT)
7847                               ? _("destination") : _("source")));
7848                   str++;
7849                   inst.instruction |= WRITE_BACK;
7850                 }
7851
7852               inst.instruction |= INDEX_UP;
7853               pre_inc = 1;
7854             }
7855         }
7856       else
7857         {
7858           /* [Rn,...]  */
7859           if (skip_past_comma (&str) == FAIL)
7860             {
7861               inst.error = _("pre-indexed expression expected");
7862               return;
7863             }
7864
7865           pre_inc = 1;
7866           if (ldst_extend_v4 (&str) == FAIL)
7867             return;
7868
7869           skip_whitespace (str);
7870
7871           if (*str++ != ']')
7872             {
7873               inst.error = _("missing ]");
7874               return;
7875             }
7876
7877           skip_whitespace (str);
7878
7879           if (*str == '!')
7880             {
7881               if (conflict_reg)
7882                 as_warn (_("%s register same as write-back base"),
7883                          ((inst.instruction & LOAD_BIT)
7884                           ? _("destination") : _("source")));
7885               str++;
7886               inst.instruction |= WRITE_BACK;
7887             }
7888         }
7889     }
7890   else if (*str == '=')
7891     {
7892       if ((inst.instruction & LOAD_BIT) == 0)
7893         {
7894           inst.error = _("invalid pseudo operation");
7895           return;
7896         }
7897
7898       /* XXX Does this work correctly for half-word/byte ops?  */
7899       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7900       str++;
7901
7902       skip_whitespace (str);
7903
7904       if (my_get_expression (&inst.reloc.exp, &str))
7905         return;
7906
7907       if (inst.reloc.exp.X_op != O_constant
7908           && inst.reloc.exp.X_op != O_symbol)
7909         {
7910           inst.error = _("constant expression expected");
7911           return;
7912         }
7913
7914       if (inst.reloc.exp.X_op == O_constant)
7915         {
7916           value = validate_immediate (inst.reloc.exp.X_add_number);
7917
7918           if (value != FAIL)
7919             {
7920               /* This can be done with a mov instruction.  */
7921               inst.instruction &= LITERAL_MASK;
7922               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7923               inst.instruction |= value & 0xfff;
7924               end_of_line (str);
7925               return;
7926             }
7927
7928           value = validate_immediate (~ inst.reloc.exp.X_add_number);
7929
7930           if (value != FAIL)
7931             {
7932               /* This can be done with a mvn instruction.  */
7933               inst.instruction &= LITERAL_MASK;
7934               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7935               inst.instruction |= value & 0xfff;
7936               end_of_line (str);
7937               return;
7938             }
7939         }
7940
7941       /* Insert into literal pool.  */
7942       if (add_to_lit_pool () == FAIL)
7943         {
7944           if (!inst.error)
7945             inst.error = _("literal pool insertion failed");
7946           return;
7947         }
7948
7949       /* Change the instruction exp to point to the pool.  */
7950       inst.instruction |= HWOFFSET_IMM;
7951       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7952       inst.reloc.pc_rel = 1;
7953       inst.instruction |= (REG_PC << 16);
7954       pre_inc = 1;
7955     }
7956   else
7957     {
7958       if (my_get_expression (&inst.reloc.exp, &str))
7959         return;
7960
7961       inst.instruction |= HWOFFSET_IMM;
7962       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7963 #ifndef TE_WINCE
7964       /* PC rel adjust.  */
7965       inst.reloc.exp.X_add_number -= 8;
7966 #endif
7967       inst.reloc.pc_rel = 1;
7968       inst.instruction |= (REG_PC << 16);
7969       pre_inc = 1;
7970     }
7971
7972   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7973   end_of_line (str);
7974 }
7975
7976 static long
7977 reg_list (strp)
7978      char ** strp;
7979 {
7980   char * str = * strp;
7981   long   range = 0;
7982   int    another_range;
7983
7984   /* We come back here if we get ranges concatenated by '+' or '|'.  */
7985   do
7986     {
7987       another_range = 0;
7988
7989       if (*str == '{')
7990         {
7991           int in_range = 0;
7992           int cur_reg = -1;
7993
7994           str++;
7995           do
7996             {
7997               int reg;
7998
7999               skip_whitespace (str);
8000
8001               if ((reg = reg_required_here (& str, -1)) == FAIL)
8002                 return FAIL;
8003
8004               if (in_range)
8005                 {
8006                   int i;
8007
8008                   if (reg <= cur_reg)
8009                     {
8010                       inst.error = _("bad range in register list");
8011                       return FAIL;
8012                     }
8013
8014                   for (i = cur_reg + 1; i < reg; i++)
8015                     {
8016                       if (range & (1 << i))
8017                         as_tsktsk
8018                           (_("Warning: duplicated register (r%d) in register list"),
8019                            i);
8020                       else
8021                         range |= 1 << i;
8022                     }
8023                   in_range = 0;
8024                 }
8025
8026               if (range & (1 << reg))
8027                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8028                            reg);
8029               else if (reg <= cur_reg)
8030                 as_tsktsk (_("Warning: register range not in ascending order"));
8031
8032               range |= 1 << reg;
8033               cur_reg = reg;
8034             }
8035           while (skip_past_comma (&str) != FAIL
8036                  || (in_range = 1, *str++ == '-'));
8037           str--;
8038           skip_whitespace (str);
8039
8040           if (*str++ != '}')
8041             {
8042               inst.error = _("missing `}'");
8043               return FAIL;
8044             }
8045         }
8046       else
8047         {
8048           expressionS expr;
8049
8050           if (my_get_expression (&expr, &str))
8051             return FAIL;
8052
8053           if (expr.X_op == O_constant)
8054             {
8055               if (expr.X_add_number
8056                   != (expr.X_add_number & 0x0000ffff))
8057                 {
8058                   inst.error = _("invalid register mask");
8059                   return FAIL;
8060                 }
8061
8062               if ((range & expr.X_add_number) != 0)
8063                 {
8064                   int regno = range & expr.X_add_number;
8065
8066                   regno &= -regno;
8067                   regno = (1 << regno) - 1;
8068                   as_tsktsk
8069                     (_("Warning: duplicated register (r%d) in register list"),
8070                      regno);
8071                 }
8072
8073               range |= expr.X_add_number;
8074             }
8075           else
8076             {
8077               if (inst.reloc.type != 0)
8078                 {
8079                   inst.error = _("expression too complex");
8080                   return FAIL;
8081                 }
8082
8083               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8084               inst.reloc.type = BFD_RELOC_ARM_MULTI;
8085               inst.reloc.pc_rel = 0;
8086             }
8087         }
8088
8089       skip_whitespace (str);
8090
8091       if (*str == '|' || *str == '+')
8092         {
8093           str++;
8094           another_range = 1;
8095         }
8096     }
8097   while (another_range);
8098
8099   *strp = str;
8100   return range;
8101 }
8102
8103 static void
8104 do_ldmstm (str)
8105      char * str;
8106 {
8107   int base_reg;
8108   long range;
8109
8110   skip_whitespace (str);
8111
8112   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8113     return;
8114
8115   if (base_reg == REG_PC)
8116     {
8117       inst.error = _("r15 not allowed as base register");
8118       return;
8119     }
8120
8121   skip_whitespace (str);
8122
8123   if (*str == '!')
8124     {
8125       inst.instruction |= WRITE_BACK;
8126       str++;
8127     }
8128
8129   if (skip_past_comma (&str) == FAIL
8130       || (range = reg_list (&str)) == FAIL)
8131     {
8132       if (! inst.error)
8133         inst.error = BAD_ARGS;
8134       return;
8135     }
8136
8137   if (*str == '^')
8138     {
8139       str++;
8140       inst.instruction |= LDM_TYPE_2_OR_3;
8141     }
8142
8143   if (inst.instruction & WRITE_BACK)
8144     {
8145       /* Check for unpredictable uses of writeback.  */
8146       if (inst.instruction & LOAD_BIT)
8147         {
8148           /* Not allowed in LDM type 2.  */
8149           if ((inst.instruction & LDM_TYPE_2_OR_3)
8150               && ((range & (1 << REG_PC)) == 0))
8151             as_warn (_("writeback of base register is UNPREDICTABLE"));
8152           /* Only allowed if base reg not in list for other types.  */
8153           else if (range & (1 << base_reg))
8154             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8155         }
8156       else /* STM.  */
8157         {
8158           /* Not allowed for type 2.  */
8159           if (inst.instruction & LDM_TYPE_2_OR_3)
8160             as_warn (_("writeback of base register is UNPREDICTABLE"));
8161           /* Only allowed if base reg not in list, or first in list.  */
8162           else if ((range & (1 << base_reg))
8163                    && (range & ((1 << base_reg) - 1)))
8164             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8165         }
8166     }
8167
8168   inst.instruction |= range;
8169   end_of_line (str);
8170 }
8171
8172 static void
8173 do_swi (str)
8174      char * str;
8175 {
8176   skip_whitespace (str);
8177
8178   /* Allow optional leading '#'.  */
8179   if (is_immediate_prefix (*str))
8180     str++;
8181
8182   if (my_get_expression (& inst.reloc.exp, & str))
8183     return;
8184
8185   inst.reloc.type = BFD_RELOC_ARM_SWI;
8186   inst.reloc.pc_rel = 0;
8187   end_of_line (str);
8188 }
8189
8190 static void
8191 do_swap (str)
8192      char * str;
8193 {
8194   int reg;
8195
8196   skip_whitespace (str);
8197
8198   if ((reg = reg_required_here (&str, 12)) == FAIL)
8199     return;
8200
8201   if (reg == REG_PC)
8202     {
8203       inst.error = _("r15 not allowed in swap");
8204       return;
8205     }
8206
8207   if (skip_past_comma (&str) == FAIL
8208       || (reg = reg_required_here (&str, 0)) == FAIL)
8209     {
8210       if (!inst.error)
8211         inst.error = BAD_ARGS;
8212       return;
8213     }
8214
8215   if (reg == REG_PC)
8216     {
8217       inst.error = _("r15 not allowed in swap");
8218       return;
8219     }
8220
8221   if (skip_past_comma (&str) == FAIL
8222       || *str++ != '[')
8223     {
8224       inst.error = BAD_ARGS;
8225       return;
8226     }
8227
8228   skip_whitespace (str);
8229
8230   if ((reg = reg_required_here (&str, 16)) == FAIL)
8231     return;
8232
8233   if (reg == REG_PC)
8234     {
8235       inst.error = BAD_PC;
8236       return;
8237     }
8238
8239   skip_whitespace (str);
8240
8241   if (*str++ != ']')
8242     {
8243       inst.error = _("missing ]");
8244       return;
8245     }
8246
8247   end_of_line (str);
8248 }
8249
8250 static void
8251 do_branch (str)
8252      char * str;
8253 {
8254   if (my_get_expression (&inst.reloc.exp, &str))
8255     return;
8256
8257 #ifdef OBJ_ELF
8258   {
8259     char * save_in;
8260
8261     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8262        required for the instruction.  */
8263
8264     /* arm_parse_reloc () works on input_line_pointer.
8265        We actually want to parse the operands to the branch instruction
8266        passed in 'str'.  Save the input pointer and restore it later.  */
8267     save_in = input_line_pointer;
8268     input_line_pointer = str;
8269     if (inst.reloc.exp.X_op == O_symbol
8270         && *str == '('
8271         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8272       {
8273         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8274         inst.reloc.pc_rel = 0;
8275         /* Modify str to point to after parsed operands, otherwise
8276            end_of_line() will complain about the (PLT) left in str.  */
8277         str = input_line_pointer;
8278       }
8279     else
8280       {
8281         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8282         inst.reloc.pc_rel = 1;
8283       }
8284     input_line_pointer = save_in;
8285   }
8286 #else
8287   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8288   inst.reloc.pc_rel = 1;
8289 #endif /* OBJ_ELF  */
8290
8291   end_of_line (str);
8292 }
8293
8294 static void
8295 do_bx (str)
8296      char * str;
8297 {
8298   int reg;
8299
8300   skip_whitespace (str);
8301
8302   if ((reg = reg_required_here (&str, 0)) == FAIL)
8303     {
8304       inst.error = BAD_ARGS;
8305       return;
8306     }
8307
8308   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8309   if (reg == REG_PC)
8310     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8311
8312   end_of_line (str);
8313 }
8314
8315 static void
8316 do_cdp (str)
8317      char * str;
8318 {
8319   /* Co-processor data operation.
8320      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8321   skip_whitespace (str);
8322
8323   if (co_proc_number (&str) == FAIL)
8324     {
8325       if (!inst.error)
8326         inst.error = BAD_ARGS;
8327       return;
8328     }
8329
8330   if (skip_past_comma (&str) == FAIL
8331       || cp_opc_expr (&str, 20,4) == FAIL)
8332     {
8333       if (!inst.error)
8334         inst.error = BAD_ARGS;
8335       return;
8336     }
8337
8338   if (skip_past_comma (&str) == FAIL
8339       || cp_reg_required_here (&str, 12) == FAIL)
8340     {
8341       if (!inst.error)
8342         inst.error = BAD_ARGS;
8343       return;
8344     }
8345
8346   if (skip_past_comma (&str) == FAIL
8347       || cp_reg_required_here (&str, 16) == FAIL)
8348     {
8349       if (!inst.error)
8350         inst.error = BAD_ARGS;
8351       return;
8352     }
8353
8354   if (skip_past_comma (&str) == FAIL
8355       || cp_reg_required_here (&str, 0) == FAIL)
8356     {
8357       if (!inst.error)
8358         inst.error = BAD_ARGS;
8359       return;
8360     }
8361
8362   if (skip_past_comma (&str) == SUCCESS)
8363     {
8364       if (cp_opc_expr (&str, 5, 3) == FAIL)
8365         {
8366           if (!inst.error)
8367             inst.error = BAD_ARGS;
8368           return;
8369         }
8370     }
8371
8372   end_of_line (str);
8373 }
8374
8375 static void
8376 do_lstc (str)
8377      char * str;
8378 {
8379   /* Co-processor register load/store.
8380      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8381
8382   skip_whitespace (str);
8383
8384   if (co_proc_number (&str) == FAIL)
8385     {
8386       if (!inst.error)
8387         inst.error = BAD_ARGS;
8388       return;
8389     }
8390
8391   if (skip_past_comma (&str) == FAIL
8392       || cp_reg_required_here (&str, 12) == FAIL)
8393     {
8394       if (!inst.error)
8395         inst.error = BAD_ARGS;
8396       return;
8397     }
8398
8399   if (skip_past_comma (&str) == FAIL
8400       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8401     {
8402       if (! inst.error)
8403         inst.error = BAD_ARGS;
8404       return;
8405     }
8406
8407   end_of_line (str);
8408 }
8409
8410 static void
8411 do_co_reg (str)
8412      char * str;
8413 {
8414   /* Co-processor register transfer.
8415      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8416
8417   skip_whitespace (str);
8418
8419   if (co_proc_number (&str) == FAIL)
8420     {
8421       if (!inst.error)
8422         inst.error = BAD_ARGS;
8423       return;
8424     }
8425
8426   if (skip_past_comma (&str) == FAIL
8427       || cp_opc_expr (&str, 21, 3) == FAIL)
8428     {
8429       if (!inst.error)
8430         inst.error = BAD_ARGS;
8431       return;
8432     }
8433
8434   if (skip_past_comma (&str) == FAIL
8435       || reg_required_here (&str, 12) == FAIL)
8436     {
8437       if (!inst.error)
8438         inst.error = BAD_ARGS;
8439       return;
8440     }
8441
8442   if (skip_past_comma (&str) == FAIL
8443       || cp_reg_required_here (&str, 16) == FAIL)
8444     {
8445       if (!inst.error)
8446         inst.error = BAD_ARGS;
8447       return;
8448     }
8449
8450   if (skip_past_comma (&str) == FAIL
8451       || cp_reg_required_here (&str, 0) == FAIL)
8452     {
8453       if (!inst.error)
8454         inst.error = BAD_ARGS;
8455       return;
8456     }
8457
8458   if (skip_past_comma (&str) == SUCCESS)
8459     {
8460       if (cp_opc_expr (&str, 5, 3) == FAIL)
8461         {
8462           if (!inst.error)
8463             inst.error = BAD_ARGS;
8464           return;
8465         }
8466     }
8467
8468   end_of_line (str);
8469 }
8470
8471 static void
8472 do_fpa_ctrl (str)
8473      char * str;
8474 {
8475   /* FP control registers.
8476      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8477
8478   skip_whitespace (str);
8479
8480   if (reg_required_here (&str, 12) == FAIL)
8481     {
8482       if (!inst.error)
8483         inst.error = BAD_ARGS;
8484       return;
8485     }
8486
8487   end_of_line (str);
8488 }
8489
8490 static void
8491 do_fpa_ldst (str)
8492      char * str;
8493 {
8494   skip_whitespace (str);
8495
8496   if (fp_reg_required_here (&str, 12) == FAIL)
8497     {
8498       if (!inst.error)
8499         inst.error = BAD_ARGS;
8500       return;
8501     }
8502
8503   if (skip_past_comma (&str) == FAIL
8504       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8505     {
8506       if (!inst.error)
8507         inst.error = BAD_ARGS;
8508       return;
8509     }
8510
8511   end_of_line (str);
8512 }
8513
8514 static void
8515 do_fpa_ldmstm (str)
8516      char * str;
8517 {
8518   int num_regs;
8519
8520   skip_whitespace (str);
8521
8522   if (fp_reg_required_here (&str, 12) == FAIL)
8523     {
8524       if (! inst.error)
8525         inst.error = BAD_ARGS;
8526       return;
8527     }
8528
8529   /* Get Number of registers to transfer.  */
8530   if (skip_past_comma (&str) == FAIL
8531       || my_get_expression (&inst.reloc.exp, &str))
8532     {
8533       if (! inst.error)
8534         inst.error = _("constant expression expected");
8535       return;
8536     }
8537
8538   if (inst.reloc.exp.X_op != O_constant)
8539     {
8540       inst.error = _("constant value required for number of registers");
8541       return;
8542     }
8543
8544   num_regs = inst.reloc.exp.X_add_number;
8545
8546   if (num_regs < 1 || num_regs > 4)
8547     {
8548       inst.error = _("number of registers must be in the range [1:4]");
8549       return;
8550     }
8551
8552   switch (num_regs)
8553     {
8554     case 1:
8555       inst.instruction |= CP_T_X;
8556       break;
8557     case 2:
8558       inst.instruction |= CP_T_Y;
8559       break;
8560     case 3:
8561       inst.instruction |= CP_T_Y | CP_T_X;
8562       break;
8563     case 4:
8564       break;
8565     default:
8566       abort ();
8567     }
8568
8569   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8570     {
8571       int reg;
8572       int write_back;
8573       int offset;
8574
8575       /* The instruction specified "ea" or "fd", so we can only accept
8576          [Rn]{!}.  The instruction does not really support stacking or
8577          unstacking, so we have to emulate these by setting appropriate
8578          bits and offsets.  */
8579       if (skip_past_comma (&str) == FAIL
8580           || *str != '[')
8581         {
8582           if (! inst.error)
8583             inst.error = BAD_ARGS;
8584           return;
8585         }
8586
8587       str++;
8588       skip_whitespace (str);
8589
8590       if ((reg = reg_required_here (&str, 16)) == FAIL)
8591         return;
8592
8593       skip_whitespace (str);
8594
8595       if (*str != ']')
8596         {
8597           inst.error = BAD_ARGS;
8598           return;
8599         }
8600
8601       str++;
8602       if (*str == '!')
8603         {
8604           write_back = 1;
8605           str++;
8606           if (reg == REG_PC)
8607             {
8608               inst.error =
8609                 _("r15 not allowed as base register with write-back");
8610               return;
8611             }
8612         }
8613       else
8614         write_back = 0;
8615
8616       if (inst.instruction & CP_T_Pre)
8617         {
8618           /* Pre-decrement.  */
8619           offset = 3 * num_regs;
8620           if (write_back)
8621             inst.instruction |= CP_T_WB;
8622         }
8623       else
8624         {
8625           /* Post-increment.  */
8626           if (write_back)
8627             {
8628               inst.instruction |= CP_T_WB;
8629               offset = 3 * num_regs;
8630             }
8631           else
8632             {
8633               /* No write-back, so convert this into a standard pre-increment
8634                  instruction -- aesthetically more pleasing.  */
8635               inst.instruction |= CP_T_Pre | CP_T_UD;
8636               offset = 0;
8637             }
8638         }
8639
8640       inst.instruction |= offset;
8641     }
8642   else if (skip_past_comma (&str) == FAIL
8643            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8644     {
8645       if (! inst.error)
8646         inst.error = BAD_ARGS;
8647       return;
8648     }
8649
8650   end_of_line (str);
8651 }
8652
8653 static void
8654 do_fpa_dyadic (str)
8655      char * str;
8656 {
8657   skip_whitespace (str);
8658
8659   if (fp_reg_required_here (&str, 12) == FAIL)
8660     {
8661       if (! inst.error)
8662         inst.error = BAD_ARGS;
8663       return;
8664     }
8665
8666   if (skip_past_comma (&str) == FAIL
8667       || fp_reg_required_here (&str, 16) == FAIL)
8668     {
8669       if (! inst.error)
8670         inst.error = BAD_ARGS;
8671       return;
8672     }
8673
8674   if (skip_past_comma (&str) == FAIL
8675       || fp_op2 (&str) == FAIL)
8676     {
8677       if (! inst.error)
8678         inst.error = BAD_ARGS;
8679       return;
8680     }
8681
8682   end_of_line (str);
8683 }
8684
8685 static void
8686 do_fpa_monadic (str)
8687      char * str;
8688 {
8689   skip_whitespace (str);
8690
8691   if (fp_reg_required_here (&str, 12) == FAIL)
8692     {
8693       if (! inst.error)
8694         inst.error = BAD_ARGS;
8695       return;
8696     }
8697
8698   if (skip_past_comma (&str) == FAIL
8699       || fp_op2 (&str) == FAIL)
8700     {
8701       if (! inst.error)
8702         inst.error = BAD_ARGS;
8703       return;
8704     }
8705
8706   end_of_line (str);
8707 }
8708
8709 static void
8710 do_fpa_cmp (str)
8711      char * str;
8712 {
8713   skip_whitespace (str);
8714
8715   if (fp_reg_required_here (&str, 16) == FAIL)
8716     {
8717       if (! inst.error)
8718         inst.error = BAD_ARGS;
8719       return;
8720     }
8721
8722   if (skip_past_comma (&str) == FAIL
8723       || fp_op2 (&str) == FAIL)
8724     {
8725       if (! inst.error)
8726         inst.error = BAD_ARGS;
8727       return;
8728     }
8729
8730   end_of_line (str);
8731 }
8732
8733 static void
8734 do_fpa_from_reg (str)
8735      char * str;
8736 {
8737   skip_whitespace (str);
8738
8739   if (fp_reg_required_here (&str, 16) == FAIL)
8740     {
8741       if (! inst.error)
8742         inst.error = BAD_ARGS;
8743       return;
8744     }
8745
8746   if (skip_past_comma (&str) == FAIL
8747       || reg_required_here (&str, 12) == FAIL)
8748     {
8749       if (! inst.error)
8750         inst.error = BAD_ARGS;
8751       return;
8752     }
8753
8754   end_of_line (str);
8755 }
8756
8757 static void
8758 do_fpa_to_reg (str)
8759      char * str;
8760 {
8761   skip_whitespace (str);
8762
8763   if (reg_required_here (&str, 12) == FAIL)
8764     return;
8765
8766   if (skip_past_comma (&str) == FAIL
8767       || fp_reg_required_here (&str, 0) == FAIL)
8768     {
8769       if (! inst.error)
8770         inst.error = BAD_ARGS;
8771       return;
8772     }
8773
8774   end_of_line (str);
8775 }
8776
8777 static int
8778 vfp_sp_reg_required_here (str, pos)
8779      char **str;
8780      enum vfp_sp_reg_pos pos;
8781 {
8782   int    reg;
8783   char *start = *str;
8784
8785   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8786     {
8787       switch (pos)
8788         {
8789         case VFP_REG_Sd:
8790           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8791           break;
8792
8793         case VFP_REG_Sn:
8794           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8795           break;
8796
8797         case VFP_REG_Sm:
8798           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8799           break;
8800
8801         default:
8802           abort ();
8803         }
8804       return reg;
8805     }
8806
8807   /* In the few cases where we might be able to accept something else
8808      this error can be overridden.  */
8809   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8810
8811   /* Restore the start point.  */
8812   *str = start;
8813   return FAIL;
8814 }
8815
8816 static int
8817 vfp_dp_reg_required_here (str, pos)
8818      char **str;
8819      enum vfp_dp_reg_pos pos;
8820 {
8821   int   reg;
8822   char *start = *str;
8823
8824   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8825     {
8826       switch (pos)
8827         {
8828         case VFP_REG_Dd:
8829           inst.instruction |= reg << 12;
8830           break;
8831
8832         case VFP_REG_Dn:
8833           inst.instruction |= reg << 16;
8834           break;
8835
8836         case VFP_REG_Dm:
8837           inst.instruction |= reg << 0;
8838           break;
8839
8840         default:
8841           abort ();
8842         }
8843       return reg;
8844     }
8845
8846   /* In the few cases where we might be able to accept something else
8847      this error can be overridden.  */
8848   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8849
8850   /* Restore the start point.  */
8851   *str = start;
8852   return FAIL;
8853 }
8854
8855 static void
8856 do_vfp_sp_monadic (str)
8857      char *str;
8858 {
8859   skip_whitespace (str);
8860
8861   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8862     return;
8863
8864   if (skip_past_comma (&str) == FAIL
8865       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8866     {
8867       if (! inst.error)
8868         inst.error = BAD_ARGS;
8869       return;
8870     }
8871
8872   end_of_line (str);
8873 }
8874
8875 static void
8876 do_vfp_dp_monadic (str)
8877      char *str;
8878 {
8879   skip_whitespace (str);
8880
8881   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8882     return;
8883
8884   if (skip_past_comma (&str) == FAIL
8885       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8886     {
8887       if (! inst.error)
8888         inst.error = BAD_ARGS;
8889       return;
8890     }
8891
8892   end_of_line (str);
8893 }
8894
8895 static void
8896 do_vfp_sp_dyadic (str)
8897      char *str;
8898 {
8899   skip_whitespace (str);
8900
8901   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8902     return;
8903
8904   if (skip_past_comma (&str) == FAIL
8905       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8906       || skip_past_comma (&str) == FAIL
8907       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8908     {
8909       if (! inst.error)
8910         inst.error = BAD_ARGS;
8911       return;
8912     }
8913
8914   end_of_line (str);
8915 }
8916
8917 static void
8918 do_vfp_dp_dyadic (str)
8919      char *str;
8920 {
8921   skip_whitespace (str);
8922
8923   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8924     return;
8925
8926   if (skip_past_comma (&str) == FAIL
8927       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8928       || skip_past_comma (&str) == FAIL
8929       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8930     {
8931       if (! inst.error)
8932         inst.error = BAD_ARGS;
8933       return;
8934     }
8935
8936   end_of_line (str);
8937 }
8938
8939 static void
8940 do_vfp_reg_from_sp (str)
8941      char *str;
8942 {
8943   skip_whitespace (str);
8944
8945   if (reg_required_here (&str, 12) == FAIL)
8946     return;
8947
8948   if (skip_past_comma (&str) == FAIL
8949       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8950     {
8951       if (! inst.error)
8952         inst.error = BAD_ARGS;
8953       return;
8954     }
8955
8956   end_of_line (str);
8957 }
8958
8959 static void
8960 do_vfp_reg2_from_sp2 (str)
8961      char *str;
8962 {
8963   skip_whitespace (str);
8964
8965   if (reg_required_here (&str, 12) == FAIL
8966       || skip_past_comma (&str) == FAIL
8967       || reg_required_here (&str, 16) == FAIL
8968       || skip_past_comma (&str) == FAIL)
8969     {
8970       if (! inst.error)
8971         inst.error = BAD_ARGS;
8972       return;
8973     }
8974
8975   /* We require exactly two consecutive SP registers.  */
8976   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8977     {
8978       if (! inst.error)
8979         inst.error = _("only two consecutive VFP SP registers allowed here");
8980     }
8981
8982   end_of_line (str);
8983 }
8984
8985 static void
8986 do_vfp_sp_from_reg (str)
8987      char *str;
8988 {
8989   skip_whitespace (str);
8990
8991   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8992     return;
8993
8994   if (skip_past_comma (&str) == FAIL
8995       || reg_required_here (&str, 12) == FAIL)
8996     {
8997       if (! inst.error)
8998         inst.error = BAD_ARGS;
8999       return;
9000     }
9001
9002   end_of_line (str);
9003 }
9004
9005 static void
9006 do_vfp_sp2_from_reg2 (str)
9007      char *str;
9008 {
9009   skip_whitespace (str);
9010
9011   /* We require exactly two consecutive SP registers.  */
9012   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
9013     {
9014       if (! inst.error)
9015         inst.error = _("only two consecutive VFP SP registers allowed here");
9016     }
9017
9018   if (skip_past_comma (&str) == FAIL
9019       || reg_required_here (&str, 12) == FAIL
9020       || skip_past_comma (&str) == FAIL
9021       || reg_required_here (&str, 16) == FAIL)
9022     {
9023       if (! inst.error)
9024         inst.error = BAD_ARGS;
9025       return;
9026     }
9027
9028   end_of_line (str);
9029 }
9030
9031 static void
9032 do_vfp_reg_from_dp (str)
9033      char *str;
9034 {
9035   skip_whitespace (str);
9036
9037   if (reg_required_here (&str, 12) == FAIL)
9038     return;
9039
9040   if (skip_past_comma (&str) == FAIL
9041       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9042     {
9043       if (! inst.error)
9044         inst.error = BAD_ARGS;
9045       return;
9046     }
9047
9048   end_of_line (str);
9049 }
9050
9051 static void
9052 do_vfp_reg2_from_dp (str)
9053      char *str;
9054 {
9055   skip_whitespace (str);
9056
9057   if (reg_required_here (&str, 12) == FAIL)
9058     return;
9059
9060   if (skip_past_comma (&str) == FAIL
9061       || reg_required_here (&str, 16) == FAIL
9062       || skip_past_comma (&str) == FAIL
9063       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9064     {
9065       if (! inst.error)
9066         inst.error = BAD_ARGS;
9067       return;
9068     }
9069
9070   end_of_line (str);
9071 }
9072
9073 static void
9074 do_vfp_dp_from_reg (str)
9075      char *str;
9076 {
9077   skip_whitespace (str);
9078
9079   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9080     return;
9081
9082   if (skip_past_comma (&str) == FAIL
9083       || reg_required_here (&str, 12) == FAIL)
9084     {
9085       if (! inst.error)
9086         inst.error = BAD_ARGS;
9087       return;
9088     }
9089
9090   end_of_line (str);
9091 }
9092
9093 static void
9094 do_vfp_dp_from_reg2 (str)
9095      char *str;
9096 {
9097   skip_whitespace (str);
9098
9099   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9100     return;
9101
9102   if (skip_past_comma (&str) == FAIL
9103       || reg_required_here (&str, 12) == FAIL
9104       || skip_past_comma (&str) == FAIL
9105       || reg_required_here (&str, 16) == FAIL)
9106     {
9107       if (! inst.error)
9108         inst.error = BAD_ARGS;
9109       return;
9110     }
9111
9112   end_of_line (str);
9113 }
9114
9115 static const struct vfp_reg *
9116 vfp_psr_parse (str)
9117      char **str;
9118 {
9119   char *start = *str;
9120   char  c;
9121   char *p;
9122   const struct vfp_reg *vreg;
9123
9124   p = start;
9125
9126   /* Find the end of the current token.  */
9127   do
9128     {
9129       c = *p++;
9130     }
9131   while (ISALPHA (c));
9132
9133   /* Mark it.  */
9134   *--p = 0;
9135
9136   for (vreg = vfp_regs + 0;
9137        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9138        vreg++)
9139     {
9140       if (strcmp (start, vreg->name) == 0)
9141         {
9142           *p = c;
9143           *str = p;
9144           return vreg;
9145         }
9146     }
9147
9148   *p = c;
9149   return NULL;
9150 }
9151
9152 static int
9153 vfp_psr_required_here (str)
9154      char **str;
9155 {
9156   char *start = *str;
9157   const struct vfp_reg *vreg;
9158
9159   vreg = vfp_psr_parse (str);
9160
9161   if (vreg)
9162     {
9163       inst.instruction |= vreg->regno;
9164       return SUCCESS;
9165     }
9166
9167   inst.error = _("VFP system register expected");
9168
9169   *str = start;
9170   return FAIL;
9171 }
9172
9173 static void
9174 do_vfp_reg_from_ctrl (str)
9175      char *str;
9176 {
9177   skip_whitespace (str);
9178
9179   if (reg_required_here (&str, 12) == FAIL)
9180     return;
9181
9182   if (skip_past_comma (&str) == FAIL
9183       || vfp_psr_required_here (&str) == FAIL)
9184     {
9185       if (! inst.error)
9186         inst.error = BAD_ARGS;
9187       return;
9188     }
9189
9190   end_of_line (str);
9191 }
9192
9193 static void
9194 do_vfp_ctrl_from_reg (str)
9195      char *str;
9196 {
9197   skip_whitespace (str);
9198
9199   if (vfp_psr_required_here (&str) == FAIL)
9200     return;
9201
9202   if (skip_past_comma (&str) == FAIL
9203       || reg_required_here (&str, 12) == FAIL)
9204     {
9205       if (! inst.error)
9206         inst.error = BAD_ARGS;
9207       return;
9208     }
9209
9210   end_of_line (str);
9211 }
9212
9213 static void
9214 do_vfp_sp_ldst (str)
9215      char *str;
9216 {
9217   skip_whitespace (str);
9218
9219   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9220     {
9221       if (!inst.error)
9222         inst.error = BAD_ARGS;
9223       return;
9224     }
9225
9226   if (skip_past_comma (&str) == FAIL
9227       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9228     {
9229       if (!inst.error)
9230         inst.error = BAD_ARGS;
9231       return;
9232     }
9233
9234   end_of_line (str);
9235 }
9236
9237 static void
9238 do_vfp_dp_ldst (str)
9239      char *str;
9240 {
9241   skip_whitespace (str);
9242
9243   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9244     {
9245       if (!inst.error)
9246         inst.error = BAD_ARGS;
9247       return;
9248     }
9249
9250   if (skip_past_comma (&str) == FAIL
9251       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9252     {
9253       if (!inst.error)
9254         inst.error = BAD_ARGS;
9255       return;
9256     }
9257
9258   end_of_line (str);
9259 }
9260
9261 /* Parse and encode a VFP SP register list, storing the initial
9262    register in position POS and returning the range as the result.  If
9263    the string is invalid return FAIL (an invalid range).  */
9264 static long
9265 vfp_sp_reg_list (str, pos)
9266      char **str;
9267      enum vfp_sp_reg_pos pos;
9268 {
9269   long range = 0;
9270   int base_reg = 0;
9271   int new_base;
9272   long base_bits = 0;
9273   int count = 0;
9274   long tempinst;
9275   unsigned long mask = 0;
9276   int warned = 0;
9277
9278   if (**str != '{')
9279     return FAIL;
9280
9281   (*str)++;
9282   skip_whitespace (*str);
9283
9284   tempinst = inst.instruction;
9285
9286   do
9287     {
9288       inst.instruction = 0;
9289
9290       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9291         return FAIL;
9292
9293       if (count == 0 || base_reg > new_base)
9294         {
9295           base_reg = new_base;
9296           base_bits = inst.instruction;
9297         }
9298
9299       if (mask & (1 << new_base))
9300         {
9301           inst.error = _("invalid register list");
9302           return FAIL;
9303         }
9304
9305       if ((mask >> new_base) != 0 && ! warned)
9306         {
9307           as_tsktsk (_("register list not in ascending order"));
9308           warned = 1;
9309         }
9310
9311       mask |= 1 << new_base;
9312       count++;
9313
9314       skip_whitespace (*str);
9315
9316       if (**str == '-') /* We have the start of a range expression */
9317         {
9318           int high_range;
9319
9320           (*str)++;
9321
9322           if ((high_range
9323                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9324               == FAIL)
9325             {
9326               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9327               return FAIL;
9328             }
9329
9330           if (high_range <= new_base)
9331             {
9332               inst.error = _("register range not in ascending order");
9333               return FAIL;
9334             }
9335
9336           for (new_base++; new_base <= high_range; new_base++)
9337             {
9338               if (mask & (1 << new_base))
9339                 {
9340                   inst.error = _("invalid register list");
9341                   return FAIL;
9342                 }
9343
9344               mask |= 1 << new_base;
9345               count++;
9346             }
9347         }
9348     }
9349   while (skip_past_comma (str) != FAIL);
9350
9351   if (**str != '}')
9352     {
9353       inst.error = _("invalid register list");
9354       return FAIL;
9355     }
9356
9357   (*str)++;
9358
9359   range = count;
9360
9361   /* Sanity check -- should have raised a parse error above.  */
9362   if (count == 0 || count > 32)
9363     abort ();
9364
9365   /* Final test -- the registers must be consecutive.  */
9366   while (count--)
9367     {
9368       if ((mask & (1 << base_reg++)) == 0)
9369         {
9370           inst.error = _("non-contiguous register range");
9371           return FAIL;
9372         }
9373     }
9374
9375   inst.instruction = tempinst | base_bits;
9376   return range;
9377 }
9378
9379 static long
9380 vfp_dp_reg_list (str)
9381      char **str;
9382 {
9383   long range = 0;
9384   int base_reg = 0;
9385   int new_base;
9386   int count = 0;
9387   long tempinst;
9388   unsigned long mask = 0;
9389   int warned = 0;
9390
9391   if (**str != '{')
9392     return FAIL;
9393
9394   (*str)++;
9395   skip_whitespace (*str);
9396
9397   tempinst = inst.instruction;
9398
9399   do
9400     {
9401       inst.instruction = 0;
9402
9403       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9404         return FAIL;
9405
9406       if (count == 0 || base_reg > new_base)
9407         {
9408           base_reg = new_base;
9409           range = inst.instruction;
9410         }
9411
9412       if (mask & (1 << new_base))
9413         {
9414           inst.error = _("invalid register list");
9415           return FAIL;
9416         }
9417
9418       if ((mask >> new_base) != 0 && ! warned)
9419         {
9420           as_tsktsk (_("register list not in ascending order"));
9421           warned = 1;
9422         }
9423
9424       mask |= 1 << new_base;
9425       count++;
9426
9427       skip_whitespace (*str);
9428
9429       if (**str == '-') /* We have the start of a range expression */
9430         {
9431           int high_range;
9432
9433           (*str)++;
9434
9435           if ((high_range
9436                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9437               == FAIL)
9438             {
9439               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9440               return FAIL;
9441             }
9442
9443           if (high_range <= new_base)
9444             {
9445               inst.error = _("register range not in ascending order");
9446               return FAIL;
9447             }
9448
9449           for (new_base++; new_base <= high_range; new_base++)
9450             {
9451               if (mask & (1 << new_base))
9452                 {
9453                   inst.error = _("invalid register list");
9454                   return FAIL;
9455                 }
9456
9457               mask |= 1 << new_base;
9458               count++;
9459             }
9460         }
9461     }
9462   while (skip_past_comma (str) != FAIL);
9463
9464   if (**str != '}')
9465     {
9466       inst.error = _("invalid register list");
9467       return FAIL;
9468     }
9469
9470   (*str)++;
9471
9472   range |= 2 * count;
9473
9474   /* Sanity check -- should have raised a parse error above.  */
9475   if (count == 0 || count > 16)
9476     abort ();
9477
9478   /* Final test -- the registers must be consecutive.  */
9479   while (count--)
9480     {
9481       if ((mask & (1 << base_reg++)) == 0)
9482         {
9483           inst.error = _("non-contiguous register range");
9484           return FAIL;
9485         }
9486     }
9487
9488   inst.instruction = tempinst;
9489   return range;
9490 }
9491
9492 static void
9493 vfp_sp_ldstm (str, ldstm_type)
9494      char *str;
9495      enum vfp_ldstm_type ldstm_type;
9496 {
9497   long range;
9498
9499   skip_whitespace (str);
9500
9501   if (reg_required_here (&str, 16) == FAIL)
9502     return;
9503
9504   skip_whitespace (str);
9505
9506   if (*str == '!')
9507     {
9508       inst.instruction |= WRITE_BACK;
9509       str++;
9510     }
9511   else if (ldstm_type != VFP_LDSTMIA)
9512     {
9513       inst.error = _("this addressing mode requires base-register writeback");
9514       return;
9515     }
9516
9517   if (skip_past_comma (&str) == FAIL
9518       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9519     {
9520       if (!inst.error)
9521         inst.error = BAD_ARGS;
9522       return;
9523     }
9524
9525   inst.instruction |= range;
9526   end_of_line (str);
9527 }
9528
9529 static void
9530 vfp_dp_ldstm (str, ldstm_type)
9531      char *str;
9532      enum vfp_ldstm_type ldstm_type;
9533 {
9534   long range;
9535
9536   skip_whitespace (str);
9537
9538   if (reg_required_here (&str, 16) == FAIL)
9539     return;
9540
9541   skip_whitespace (str);
9542
9543   if (*str == '!')
9544     {
9545       inst.instruction |= WRITE_BACK;
9546       str++;
9547     }
9548   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9549     {
9550       inst.error = _("this addressing mode requires base-register writeback");
9551       return;
9552     }
9553
9554   if (skip_past_comma (&str) == FAIL
9555       || (range = vfp_dp_reg_list (&str)) == FAIL)
9556     {
9557       if (!inst.error)
9558         inst.error = BAD_ARGS;
9559       return;
9560     }
9561
9562   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9563     range += 1;
9564
9565   inst.instruction |= range;
9566   end_of_line (str);
9567 }
9568
9569 static void
9570 do_vfp_sp_ldstmia (str)
9571      char *str;
9572 {
9573   vfp_sp_ldstm (str, VFP_LDSTMIA);
9574 }
9575
9576 static void
9577 do_vfp_sp_ldstmdb (str)
9578      char *str;
9579 {
9580   vfp_sp_ldstm (str, VFP_LDSTMDB);
9581 }
9582
9583 static void
9584 do_vfp_dp_ldstmia (str)
9585      char *str;
9586 {
9587   vfp_dp_ldstm (str, VFP_LDSTMIA);
9588 }
9589
9590 static void
9591 do_vfp_dp_ldstmdb (str)
9592      char *str;
9593 {
9594   vfp_dp_ldstm (str, VFP_LDSTMDB);
9595 }
9596
9597 static void
9598 do_vfp_xp_ldstmia (str)
9599      char *str;
9600 {
9601   vfp_dp_ldstm (str, VFP_LDSTMIAX);
9602 }
9603
9604 static void
9605 do_vfp_xp_ldstmdb (str)
9606      char *str;
9607 {
9608   vfp_dp_ldstm (str, VFP_LDSTMDBX);
9609 }
9610
9611 static void
9612 do_vfp_sp_compare_z (str)
9613      char *str;
9614 {
9615   skip_whitespace (str);
9616
9617   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9618     {
9619       if (!inst.error)
9620         inst.error = BAD_ARGS;
9621       return;
9622     }
9623
9624   end_of_line (str);
9625 }
9626
9627 static void
9628 do_vfp_dp_compare_z (str)
9629      char *str;
9630 {
9631   skip_whitespace (str);
9632
9633   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9634     {
9635       if (!inst.error)
9636         inst.error = BAD_ARGS;
9637       return;
9638     }
9639
9640   end_of_line (str);
9641 }
9642
9643 static void
9644 do_vfp_dp_sp_cvt (str)
9645      char *str;
9646 {
9647   skip_whitespace (str);
9648
9649   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9650     return;
9651
9652   if (skip_past_comma (&str) == FAIL
9653       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9654     {
9655       if (! inst.error)
9656         inst.error = BAD_ARGS;
9657       return;
9658     }
9659
9660   end_of_line (str);
9661 }
9662
9663 static void
9664 do_vfp_sp_dp_cvt (str)
9665      char *str;
9666 {
9667   skip_whitespace (str);
9668
9669   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9670     return;
9671
9672   if (skip_past_comma (&str) == FAIL
9673       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9674     {
9675       if (! inst.error)
9676         inst.error = BAD_ARGS;
9677       return;
9678     }
9679
9680   end_of_line (str);
9681 }
9682
9683 /* Thumb specific routines.  */
9684
9685 /* Parse and validate that a register is of the right form, this saves
9686    repeated checking of this information in many similar cases.
9687    Unlike the 32-bit case we do not insert the register into the opcode
9688    here, since the position is often unknown until the full instruction
9689    has been parsed.  */
9690
9691 static int
9692 thumb_reg (strp, hi_lo)
9693      char ** strp;
9694      int     hi_lo;
9695 {
9696   int reg;
9697
9698   if ((reg = reg_required_here (strp, -1)) == FAIL)
9699     return FAIL;
9700
9701   switch (hi_lo)
9702     {
9703     case THUMB_REG_LO:
9704       if (reg > 7)
9705         {
9706           inst.error = _("lo register required");
9707           return FAIL;
9708         }
9709       break;
9710
9711     case THUMB_REG_HI:
9712       if (reg < 8)
9713         {
9714           inst.error = _("hi register required");
9715           return FAIL;
9716         }
9717       break;
9718
9719     default:
9720       break;
9721     }
9722
9723   return reg;
9724 }
9725
9726 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9727    was SUB.  */
9728
9729 static void
9730 thumb_add_sub (str, subtract)
9731      char * str;
9732      int    subtract;
9733 {
9734   int Rd, Rs, Rn = FAIL;
9735
9736   skip_whitespace (str);
9737
9738   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9739       || skip_past_comma (&str) == FAIL)
9740     {
9741       if (! inst.error)
9742         inst.error = BAD_ARGS;
9743       return;
9744     }
9745
9746   if (is_immediate_prefix (*str))
9747     {
9748       Rs = Rd;
9749       str++;
9750       if (my_get_expression (&inst.reloc.exp, &str))
9751         return;
9752     }
9753   else
9754     {
9755       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9756         return;
9757
9758       if (skip_past_comma (&str) == FAIL)
9759         {
9760           /* Two operand format, shuffle the registers
9761              and pretend there are 3.  */
9762           Rn = Rs;
9763           Rs = Rd;
9764         }
9765       else if (is_immediate_prefix (*str))
9766         {
9767           str++;
9768           if (my_get_expression (&inst.reloc.exp, &str))
9769             return;
9770         }
9771       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9772         return;
9773     }
9774
9775   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9776      for the latter case, EXPR contains the immediate that was found.  */
9777   if (Rn != FAIL)
9778     {
9779       /* All register format.  */
9780       if (Rd > 7 || Rs > 7 || Rn > 7)
9781         {
9782           if (Rs != Rd)
9783             {
9784               inst.error = _("dest and source1 must be the same register");
9785               return;
9786             }
9787
9788           /* Can't do this for SUB.  */
9789           if (subtract)
9790             {
9791               inst.error = _("subtract valid only on lo regs");
9792               return;
9793             }
9794
9795           inst.instruction = (T_OPCODE_ADD_HI
9796                               | (Rd > 7 ? THUMB_H1 : 0)
9797                               | (Rn > 7 ? THUMB_H2 : 0));
9798           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9799         }
9800       else
9801         {
9802           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9803           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9804         }
9805     }
9806   else
9807     {
9808       /* Immediate expression, now things start to get nasty.  */
9809
9810       /* First deal with HI regs, only very restricted cases allowed:
9811          Adjusting SP, and using PC or SP to get an address.  */
9812       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9813           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9814         {
9815           inst.error = _("invalid Hi register with immediate");
9816           return;
9817         }
9818
9819       if (inst.reloc.exp.X_op != O_constant)
9820         {
9821           /* Value isn't known yet, all we can do is store all the fragments
9822              we know about in the instruction and let the reloc hacking
9823              work it all out.  */
9824           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9825           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9826         }
9827       else
9828         {
9829           int offset = inst.reloc.exp.X_add_number;
9830
9831           if (subtract)
9832             offset = - offset;
9833
9834           if (offset < 0)
9835             {
9836               offset = - offset;
9837               subtract = 1;
9838
9839               /* Quick check, in case offset is MIN_INT.  */
9840               if (offset < 0)
9841                 {
9842                   inst.error = _("immediate value out of range");
9843                   return;
9844                 }
9845             }
9846           /* Note - you cannot convert a subtract of 0 into an
9847              add of 0 because the carry flag is set differently.  */
9848           else if (offset > 0)
9849             subtract = 0;
9850
9851           if (Rd == REG_SP)
9852             {
9853               if (offset & ~0x1fc)
9854                 {
9855                   inst.error = _("invalid immediate value for stack adjust");
9856                   return;
9857                 }
9858               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9859               inst.instruction |= offset >> 2;
9860             }
9861           else if (Rs == REG_PC || Rs == REG_SP)
9862             {
9863               if (subtract
9864                   || (offset & ~0x3fc))
9865                 {
9866                   inst.error = _("invalid immediate for address calculation");
9867                   return;
9868                 }
9869               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9870                                   : T_OPCODE_ADD_SP);
9871               inst.instruction |= (Rd << 8) | (offset >> 2);
9872             }
9873           else if (Rs == Rd)
9874             {
9875               if (offset & ~0xff)
9876                 {
9877                   inst.error = _("immediate value out of range");
9878                   return;
9879                 }
9880               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9881               inst.instruction |= (Rd << 8) | offset;
9882             }
9883           else
9884             {
9885               if (offset & ~0x7)
9886                 {
9887                   inst.error = _("immediate value out of range");
9888                   return;
9889                 }
9890               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9891               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9892             }
9893         }
9894     }
9895
9896   end_of_line (str);
9897 }
9898
9899 static void
9900 thumb_shift (str, shift)
9901      char * str;
9902      int    shift;
9903 {
9904   int Rd, Rs, Rn = FAIL;
9905
9906   skip_whitespace (str);
9907
9908   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9909       || skip_past_comma (&str) == FAIL)
9910     {
9911       if (! inst.error)
9912         inst.error = BAD_ARGS;
9913       return;
9914     }
9915
9916   if (is_immediate_prefix (*str))
9917     {
9918       /* Two operand immediate format, set Rs to Rd.  */
9919       Rs = Rd;
9920       str ++;
9921       if (my_get_expression (&inst.reloc.exp, &str))
9922         return;
9923     }
9924   else
9925     {
9926       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9927         return;
9928
9929       if (skip_past_comma (&str) == FAIL)
9930         {
9931           /* Two operand format, shuffle the registers
9932              and pretend there are 3.  */
9933           Rn = Rs;
9934           Rs = Rd;
9935         }
9936       else if (is_immediate_prefix (*str))
9937         {
9938           str++;
9939           if (my_get_expression (&inst.reloc.exp, &str))
9940             return;
9941         }
9942       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9943         return;
9944     }
9945
9946   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9947      for the latter case, EXPR contains the immediate that was found.  */
9948
9949   if (Rn != FAIL)
9950     {
9951       if (Rs != Rd)
9952         {
9953           inst.error = _("source1 and dest must be same register");
9954           return;
9955         }
9956
9957       switch (shift)
9958         {
9959         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9960         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9961         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9962         }
9963
9964       inst.instruction |= Rd | (Rn << 3);
9965     }
9966   else
9967     {
9968       switch (shift)
9969         {
9970         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9971         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9972         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9973         }
9974
9975       if (inst.reloc.exp.X_op != O_constant)
9976         {
9977           /* Value isn't known yet, create a dummy reloc and let reloc
9978              hacking fix it up.  */
9979           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9980         }
9981       else
9982         {
9983           unsigned shift_value = inst.reloc.exp.X_add_number;
9984
9985           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9986             {
9987               inst.error = _("invalid immediate for shift");
9988               return;
9989             }
9990
9991           /* Shifts of zero are handled by converting to LSL.  */
9992           if (shift_value == 0)
9993             inst.instruction = T_OPCODE_LSL_I;
9994
9995           /* Shifts of 32 are encoded as a shift of zero.  */
9996           if (shift_value == 32)
9997             shift_value = 0;
9998
9999           inst.instruction |= shift_value << 6;
10000         }
10001
10002       inst.instruction |= Rd | (Rs << 3);
10003     }
10004
10005   end_of_line (str);
10006 }
10007
10008 static void
10009 thumb_mov_compare (str, move)
10010      char * str;
10011      int    move;
10012 {
10013   int Rd, Rs = FAIL;
10014
10015   skip_whitespace (str);
10016
10017   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
10018       || skip_past_comma (&str) == FAIL)
10019     {
10020       if (! inst.error)
10021         inst.error = BAD_ARGS;
10022       return;
10023     }
10024
10025   if (move != THUMB_CPY && is_immediate_prefix (*str))
10026     {
10027       str++;
10028       if (my_get_expression (&inst.reloc.exp, &str))
10029         return;
10030     }
10031   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10032     return;
10033
10034   if (Rs != FAIL)
10035     {
10036       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10037         {
10038           if (move == THUMB_MOVE)
10039             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10040                since a MOV instruction produces unpredictable results.  */
10041             inst.instruction = T_OPCODE_ADD_I3;
10042           else
10043             inst.instruction = T_OPCODE_CMP_LR;
10044           inst.instruction |= Rd | (Rs << 3);
10045         }
10046       else
10047         {
10048           if (move == THUMB_MOVE)
10049             inst.instruction = T_OPCODE_MOV_HR;
10050           else if (move != THUMB_CPY)
10051             inst.instruction = T_OPCODE_CMP_HR;
10052
10053           if (Rd > 7)
10054             inst.instruction |= THUMB_H1;
10055
10056           if (Rs > 7)
10057             inst.instruction |= THUMB_H2;
10058
10059           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10060         }
10061     }
10062   else
10063     {
10064       if (Rd > 7)
10065         {
10066           inst.error = _("only lo regs allowed with immediate");
10067           return;
10068         }
10069
10070       if (move == THUMB_MOVE)
10071         inst.instruction = T_OPCODE_MOV_I8;
10072       else
10073         inst.instruction = T_OPCODE_CMP_I8;
10074
10075       inst.instruction |= Rd << 8;
10076
10077       if (inst.reloc.exp.X_op != O_constant)
10078         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10079       else
10080         {
10081           unsigned value = inst.reloc.exp.X_add_number;
10082
10083           if (value > 255)
10084             {
10085               inst.error = _("invalid immediate");
10086               return;
10087             }
10088
10089           inst.instruction |= value;
10090         }
10091     }
10092
10093   end_of_line (str);
10094 }
10095
10096 static void
10097 thumb_load_store (str, load_store, size)
10098      char * str;
10099      int    load_store;
10100      int    size;
10101 {
10102   int Rd, Rb, Ro = FAIL;
10103
10104   skip_whitespace (str);
10105
10106   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10107       || skip_past_comma (&str) == FAIL)
10108     {
10109       if (! inst.error)
10110         inst.error = BAD_ARGS;
10111       return;
10112     }
10113
10114   if (*str == '[')
10115     {
10116       str++;
10117       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10118         return;
10119
10120       if (skip_past_comma (&str) != FAIL)
10121         {
10122           if (is_immediate_prefix (*str))
10123             {
10124               str++;
10125               if (my_get_expression (&inst.reloc.exp, &str))
10126                 return;
10127             }
10128           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10129             return;
10130         }
10131       else
10132         {
10133           inst.reloc.exp.X_op = O_constant;
10134           inst.reloc.exp.X_add_number = 0;
10135         }
10136
10137       if (*str != ']')
10138         {
10139           inst.error = _("expected ']'");
10140           return;
10141         }
10142       str++;
10143     }
10144   else if (*str == '=')
10145     {
10146       if (load_store != THUMB_LOAD)
10147         {
10148           inst.error = _("invalid pseudo operation");
10149           return;
10150         }
10151
10152       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10153       str++;
10154
10155       skip_whitespace (str);
10156
10157       if (my_get_expression (& inst.reloc.exp, & str))
10158         return;
10159
10160       end_of_line (str);
10161
10162       if (   inst.reloc.exp.X_op != O_constant
10163           && inst.reloc.exp.X_op != O_symbol)
10164         {
10165           inst.error = "Constant expression expected";
10166           return;
10167         }
10168
10169       if (inst.reloc.exp.X_op == O_constant
10170           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10171         {
10172           /* This can be done with a mov instruction.  */
10173
10174           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10175           inst.instruction |= inst.reloc.exp.X_add_number;
10176           return;
10177         }
10178
10179       /* Insert into literal pool.  */
10180       if (add_to_lit_pool () == FAIL)
10181         {
10182           if (!inst.error)
10183             inst.error = "literal pool insertion failed";
10184           return;
10185         }
10186
10187       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10188       inst.reloc.pc_rel = 1;
10189       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10190       /* Adjust ARM pipeline offset to Thumb.  */
10191       inst.reloc.exp.X_add_number += 4;
10192
10193       return;
10194     }
10195   else
10196     {
10197       if (my_get_expression (&inst.reloc.exp, &str))
10198         return;
10199
10200       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10201       inst.reloc.pc_rel = 1;
10202       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10203       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10204       end_of_line (str);
10205       return;
10206     }
10207
10208   if (Rb == REG_PC || Rb == REG_SP)
10209     {
10210       if (size != THUMB_WORD)
10211         {
10212           inst.error = _("byte or halfword not valid for base register");
10213           return;
10214         }
10215       else if (Rb == REG_PC && load_store != THUMB_LOAD)
10216         {
10217           inst.error = _("r15 based store not allowed");
10218           return;
10219         }
10220       else if (Ro != FAIL)
10221         {
10222           inst.error = _("invalid base register for register offset");
10223           return;
10224         }
10225
10226       if (Rb == REG_PC)
10227         inst.instruction = T_OPCODE_LDR_PC;
10228       else if (load_store == THUMB_LOAD)
10229         inst.instruction = T_OPCODE_LDR_SP;
10230       else
10231         inst.instruction = T_OPCODE_STR_SP;
10232
10233       inst.instruction |= Rd << 8;
10234       if (inst.reloc.exp.X_op == O_constant)
10235         {
10236           unsigned offset = inst.reloc.exp.X_add_number;
10237
10238           if (offset & ~0x3fc)
10239             {
10240               inst.error = _("invalid offset");
10241               return;
10242             }
10243
10244           inst.instruction |= offset >> 2;
10245         }
10246       else
10247         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10248     }
10249   else if (Rb > 7)
10250     {
10251       inst.error = _("invalid base register in load/store");
10252       return;
10253     }
10254   else if (Ro == FAIL)
10255     {
10256       /* Immediate offset.  */
10257       if (size == THUMB_WORD)
10258         inst.instruction = (load_store == THUMB_LOAD
10259                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10260       else if (size == THUMB_HALFWORD)
10261         inst.instruction = (load_store == THUMB_LOAD
10262                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10263       else
10264         inst.instruction = (load_store == THUMB_LOAD
10265                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10266
10267       inst.instruction |= Rd | (Rb << 3);
10268
10269       if (inst.reloc.exp.X_op == O_constant)
10270         {
10271           unsigned offset = inst.reloc.exp.X_add_number;
10272
10273           if (offset & ~(0x1f << size))
10274             {
10275               inst.error = _("invalid offset");
10276               return;
10277             }
10278           inst.instruction |= (offset >> size) << 6;
10279         }
10280       else
10281         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10282     }
10283   else
10284     {
10285       /* Register offset.  */
10286       if (size == THUMB_WORD)
10287         inst.instruction = (load_store == THUMB_LOAD
10288                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10289       else if (size == THUMB_HALFWORD)
10290         inst.instruction = (load_store == THUMB_LOAD
10291                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10292       else
10293         inst.instruction = (load_store == THUMB_LOAD
10294                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10295
10296       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10297     }
10298
10299   end_of_line (str);
10300 }
10301
10302 /* A register must be given at this point.
10303
10304    Shift is the place to put it in inst.instruction.
10305
10306    Restores input start point on err.
10307    Returns the reg#, or FAIL.  */
10308
10309 static int
10310 mav_reg_required_here (str, shift, regtype)
10311      char ** str;
10312      int shift;
10313      enum arm_reg_type regtype;
10314 {
10315   int   reg;
10316   char *start = *str;
10317
10318   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10319     {
10320       if (shift >= 0)
10321         inst.instruction |= reg << shift;
10322
10323       return reg;
10324     }
10325
10326   /* Restore the start point.  */
10327   *str = start;
10328
10329   /* In the few cases where we might be able to accept something else
10330      this error can be overridden.  */
10331   inst.error = _(all_reg_maps[regtype].expected);
10332
10333   return FAIL;
10334 }
10335
10336 /* Cirrus Maverick Instructions.  */
10337
10338 /* Wrapper functions.  */
10339
10340 static void
10341 do_mav_binops_1a (str)
10342      char * str;
10343 {
10344   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10345 }
10346
10347 static void
10348 do_mav_binops_1b (str)
10349      char * str;
10350 {
10351   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10352 }
10353
10354 static void
10355 do_mav_binops_1c (str)
10356      char * str;
10357 {
10358   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10359 }
10360
10361 static void
10362 do_mav_binops_1d (str)
10363      char * str;
10364 {
10365   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10366 }
10367
10368 static void
10369 do_mav_binops_1e (str)
10370      char * str;
10371 {
10372   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10373 }
10374
10375 static void
10376 do_mav_binops_1f (str)
10377      char * str;
10378 {
10379   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10380 }
10381
10382 static void
10383 do_mav_binops_1g (str)
10384      char * str;
10385 {
10386   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10387 }
10388
10389 static void
10390 do_mav_binops_1h (str)
10391      char * str;
10392 {
10393   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10394 }
10395
10396 static void
10397 do_mav_binops_1i (str)
10398      char * str;
10399 {
10400   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10401 }
10402
10403 static void
10404 do_mav_binops_1j (str)
10405      char * str;
10406 {
10407   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10408 }
10409
10410 static void
10411 do_mav_binops_1k (str)
10412      char * str;
10413 {
10414   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10415 }
10416
10417 static void
10418 do_mav_binops_1l (str)
10419      char * str;
10420 {
10421   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10422 }
10423
10424 static void
10425 do_mav_binops_1m (str)
10426      char * str;
10427 {
10428   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10429 }
10430
10431 static void
10432 do_mav_binops_1n (str)
10433      char * str;
10434 {
10435   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10436 }
10437
10438 static void
10439 do_mav_binops_1o (str)
10440      char * str;
10441 {
10442   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10443 }
10444
10445 static void
10446 do_mav_binops_2a (str)
10447      char * str;
10448 {
10449   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10450 }
10451
10452 static void
10453 do_mav_binops_2b (str)
10454      char * str;
10455 {
10456   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10457 }
10458
10459 static void
10460 do_mav_binops_2c (str)
10461      char * str;
10462 {
10463   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10464 }
10465
10466 static void
10467 do_mav_binops_3a (str)
10468      char * str;
10469 {
10470   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10471 }
10472
10473 static void
10474 do_mav_binops_3b (str)
10475      char * str;
10476 {
10477   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10478 }
10479
10480 static void
10481 do_mav_binops_3c (str)
10482      char * str;
10483 {
10484   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10485 }
10486
10487 static void
10488 do_mav_binops_3d (str)
10489      char * str;
10490 {
10491   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10492 }
10493
10494 static void
10495 do_mav_triple_4a (str)
10496      char * str;
10497 {
10498   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10499 }
10500
10501 static void
10502 do_mav_triple_4b (str)
10503      char * str;
10504 {
10505   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10506 }
10507
10508 static void
10509 do_mav_triple_5a (str)
10510      char * str;
10511 {
10512   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10513 }
10514
10515 static void
10516 do_mav_triple_5b (str)
10517      char * str;
10518 {
10519   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10520 }
10521
10522 static void
10523 do_mav_triple_5c (str)
10524      char * str;
10525 {
10526   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10527 }
10528
10529 static void
10530 do_mav_triple_5d (str)
10531      char * str;
10532 {
10533   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10534 }
10535
10536 static void
10537 do_mav_triple_5e (str)
10538      char * str;
10539 {
10540   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10541 }
10542
10543 static void
10544 do_mav_triple_5f (str)
10545      char * str;
10546 {
10547   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10548 }
10549
10550 static void
10551 do_mav_triple_5g (str)
10552      char * str;
10553 {
10554   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10555 }
10556
10557 static void
10558 do_mav_triple_5h (str)
10559      char * str;
10560 {
10561   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10562 }
10563
10564 static void
10565 do_mav_quad_6a (str)
10566      char * str;
10567 {
10568   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10569              REG_TYPE_MVFX);
10570 }
10571
10572 static void
10573 do_mav_quad_6b (str)
10574      char * str;
10575 {
10576   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10577              REG_TYPE_MVFX);
10578 }
10579
10580 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
10581 static void
10582 do_mav_dspsc_1 (str)
10583      char * str;
10584 {
10585   skip_whitespace (str);
10586
10587   /* cfmvsc32.  */
10588   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10589       || skip_past_comma (&str) == FAIL
10590       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10591     {
10592       if (!inst.error)
10593         inst.error = BAD_ARGS;
10594
10595       return;
10596     }
10597
10598   end_of_line (str);
10599 }
10600
10601 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
10602 static void
10603 do_mav_dspsc_2 (str)
10604      char * str;
10605 {
10606   skip_whitespace (str);
10607
10608   /* cfmv32sc.  */
10609   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10610       || skip_past_comma (&str) == FAIL
10611       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10612     {
10613       if (!inst.error)
10614         inst.error = BAD_ARGS;
10615
10616       return;
10617     }
10618
10619   end_of_line (str);
10620 }
10621
10622 static void
10623 do_mav_shift_1 (str)
10624      char * str;
10625 {
10626   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10627 }
10628
10629 static void
10630 do_mav_shift_2 (str)
10631      char * str;
10632 {
10633   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10634 }
10635
10636 static void
10637 do_mav_ldst_1 (str)
10638      char * str;
10639 {
10640   do_mav_ldst (str, REG_TYPE_MVF);
10641 }
10642
10643 static void
10644 do_mav_ldst_2 (str)
10645      char * str;
10646 {
10647   do_mav_ldst (str, REG_TYPE_MVD);
10648 }
10649
10650 static void
10651 do_mav_ldst_3 (str)
10652      char * str;
10653 {
10654   do_mav_ldst (str, REG_TYPE_MVFX);
10655 }
10656
10657 static void
10658 do_mav_ldst_4 (str)
10659      char * str;
10660 {
10661   do_mav_ldst (str, REG_TYPE_MVDX);
10662 }
10663
10664 /* Isnsn like "foo X,Y".  */
10665
10666 static void
10667 do_mav_binops (str, mode, reg0, reg1)
10668      char * str;
10669      int mode;
10670      enum arm_reg_type reg0;
10671      enum arm_reg_type reg1;
10672 {
10673   int shift0, shift1;
10674
10675   shift0 = mode & 0xff;
10676   shift1 = (mode >> 8) & 0xff;
10677
10678   skip_whitespace (str);
10679
10680   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10681       || skip_past_comma (&str) == FAIL
10682       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10683     {
10684       if (!inst.error)
10685         inst.error = BAD_ARGS;
10686     }
10687   else
10688     end_of_line (str);
10689 }
10690
10691 /* Isnsn like "foo X,Y,Z".  */
10692
10693 static void
10694 do_mav_triple (str, mode, reg0, reg1, reg2)
10695      char * str;
10696      int mode;
10697      enum arm_reg_type reg0;
10698      enum arm_reg_type reg1;
10699      enum arm_reg_type reg2;
10700 {
10701   int shift0, shift1, shift2;
10702
10703   shift0 = mode & 0xff;
10704   shift1 = (mode >> 8) & 0xff;
10705   shift2 = (mode >> 16) & 0xff;
10706
10707   skip_whitespace (str);
10708
10709   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10710       || skip_past_comma (&str) == FAIL
10711       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10712       || skip_past_comma (&str) == FAIL
10713       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10714     {
10715       if (!inst.error)
10716         inst.error = BAD_ARGS;
10717     }
10718   else
10719     end_of_line (str);
10720 }
10721
10722 /* Isnsn like "foo W,X,Y,Z".
10723     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10724
10725 static void
10726 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10727      char * str;
10728      int mode;
10729      enum arm_reg_type reg0;
10730      enum arm_reg_type reg1;
10731      enum arm_reg_type reg2;
10732      enum arm_reg_type reg3;
10733 {
10734   int shift0, shift1, shift2, shift3;
10735
10736   shift0= mode & 0xff;
10737   shift1 = (mode >> 8) & 0xff;
10738   shift2 = (mode >> 16) & 0xff;
10739   shift3 = (mode >> 24) & 0xff;
10740
10741   skip_whitespace (str);
10742
10743   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10744       || skip_past_comma (&str) == FAIL
10745       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10746       || skip_past_comma (&str) == FAIL
10747       || mav_reg_required_here (&str, shift2, reg2) == FAIL
10748       || skip_past_comma (&str) == FAIL
10749       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10750     {
10751       if (!inst.error)
10752         inst.error = BAD_ARGS;
10753     }
10754   else
10755     end_of_line (str);
10756 }
10757
10758 /* Maverick shift immediate instructions.
10759    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10760    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10761
10762 static void
10763 do_mav_shift (str, reg0, reg1)
10764      char * str;
10765      enum arm_reg_type reg0;
10766      enum arm_reg_type reg1;
10767 {
10768   int error;
10769   int imm, neg = 0;
10770
10771   skip_whitespace (str);
10772
10773   error = 0;
10774
10775   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10776       || skip_past_comma (&str) == FAIL
10777       || mav_reg_required_here (&str, 16, reg1) == FAIL
10778       || skip_past_comma  (&str) == FAIL)
10779     {
10780       if (!inst.error)
10781         inst.error = BAD_ARGS;
10782       return;
10783     }
10784
10785   /* Calculate the immediate operand.
10786      The operand is a 7bit signed number.  */
10787   skip_whitespace (str);
10788
10789   if (*str == '#')
10790     ++str;
10791
10792   if (!ISDIGIT (*str) && *str != '-')
10793     {
10794       inst.error = _("expecting immediate, 7bit operand");
10795       return;
10796     }
10797
10798   if (*str == '-')
10799     {
10800       neg = 1;
10801       ++str;
10802     }
10803
10804   for (imm = 0; *str && ISDIGIT (*str); ++str)
10805     imm = imm * 10 + *str - '0';
10806
10807   if (imm > 64)
10808     {
10809       inst.error = _("immediate out of range");
10810       return;
10811     }
10812
10813   /* Make negative imm's into 7bit signed numbers.  */
10814   if (neg)
10815     {
10816       imm = -imm;
10817       imm &= 0x0000007f;
10818     }
10819
10820   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10821      Bits 5-7 of the insn should have bits 4-6 of the immediate.
10822      Bit 4 should be 0.  */
10823   imm = (imm & 0xf) | ((imm & 0x70) << 1);
10824
10825   inst.instruction |= imm;
10826   end_of_line (str);
10827 }
10828
10829 static int
10830 mav_parse_offset (str, negative)
10831      char ** str;
10832      int *negative;
10833 {
10834   char * p = *str;
10835   int offset;
10836
10837   *negative = 0;
10838
10839   skip_whitespace (p);
10840
10841   if (*p == '#')
10842     ++p;
10843
10844   if (*p == '-')
10845     {
10846       *negative = 1;
10847       ++p;
10848     }
10849
10850   if (!ISDIGIT (*p))
10851     {
10852       inst.error = _("offset expected");
10853       return 0;
10854     }
10855
10856   for (offset = 0; *p && ISDIGIT (*p); ++p)
10857     offset = offset * 10 + *p - '0';
10858
10859   if (offset > 0xff)
10860     {
10861       inst.error = _("offset out of range");
10862       return 0;
10863     }
10864
10865   *str = p;
10866
10867   return *negative ? -offset : offset;
10868 }
10869
10870 /* Maverick load/store instructions.
10871   <insn><cond> CRd,[Rn,<offset>]{!}.
10872   <insn><cond> CRd,[Rn],<offset>.  */
10873
10874 static void
10875 do_mav_ldst (str, reg0)
10876      char * str;
10877      enum arm_reg_type reg0;
10878 {
10879   int offset, negative;
10880
10881   skip_whitespace (str);
10882
10883   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10884       || skip_past_comma (&str) == FAIL
10885       || *str++ != '['
10886       || reg_required_here (&str, 16) == FAIL)
10887     goto fail_ldst;
10888
10889   if (skip_past_comma (&str) == SUCCESS)
10890     {
10891       /* You are here: "<offset>]{!}".  */
10892       inst.instruction |= PRE_INDEX;
10893
10894       offset = mav_parse_offset (&str, &negative);
10895
10896       if (inst.error)
10897         return;
10898
10899       if (*str++ != ']')
10900         {
10901           inst.error = _("missing ]");
10902           return;
10903         }
10904
10905       if (*str == '!')
10906         {
10907           inst.instruction |= WRITE_BACK;
10908           ++str;
10909         }
10910     }
10911   else
10912     {
10913       /* You are here: "], <offset>".  */
10914       if (*str++ != ']')
10915         {
10916           inst.error = _("missing ]");
10917           return;
10918         }
10919
10920       if (skip_past_comma (&str) == FAIL
10921           || (offset = mav_parse_offset (&str, &negative), inst.error))
10922         goto fail_ldst;
10923
10924       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10925     }
10926
10927   if (negative)
10928     offset = -offset;
10929   else
10930     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10931
10932   inst.instruction |= offset >> 2;
10933   end_of_line (str);
10934   return;
10935
10936 fail_ldst:
10937   if (!inst.error)
10938      inst.error = BAD_ARGS;
10939 }
10940
10941 static void
10942 do_t_nop (str)
10943      char * str;
10944 {
10945   /* Do nothing.  */
10946   end_of_line (str);
10947 }
10948
10949 /* Handle the Format 4 instructions that do not have equivalents in other
10950    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10951    BIC and MVN.  */
10952
10953 static void
10954 do_t_arit (str)
10955      char * str;
10956 {
10957   int Rd, Rs, Rn;
10958
10959   skip_whitespace (str);
10960
10961   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10962       || skip_past_comma (&str) == FAIL
10963       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10964     {
10965       inst.error = BAD_ARGS;
10966       return;
10967     }
10968
10969   if (skip_past_comma (&str) != FAIL)
10970     {
10971       /* Three operand format not allowed for TST, CMN, NEG and MVN.
10972          (It isn't allowed for CMP either, but that isn't handled by this
10973          function.)  */
10974       if (inst.instruction == T_OPCODE_TST
10975           || inst.instruction == T_OPCODE_CMN
10976           || inst.instruction == T_OPCODE_NEG
10977           || inst.instruction == T_OPCODE_MVN)
10978         {
10979           inst.error = BAD_ARGS;
10980           return;
10981         }
10982
10983       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10984         return;
10985
10986       if (Rs != Rd)
10987         {
10988           inst.error = _("dest and source1 must be the same register");
10989           return;
10990         }
10991       Rs = Rn;
10992     }
10993
10994   if (inst.instruction == T_OPCODE_MUL
10995       && Rs == Rd)
10996     as_tsktsk (_("Rs and Rd must be different in MUL"));
10997
10998   inst.instruction |= Rd | (Rs << 3);
10999   end_of_line (str);
11000 }
11001
11002 static void
11003 do_t_add (str)
11004      char * str;
11005 {
11006   thumb_add_sub (str, 0);
11007 }
11008
11009 static void
11010 do_t_asr (str)
11011      char * str;
11012 {
11013   thumb_shift (str, THUMB_ASR);
11014 }
11015
11016 static void
11017 do_t_branch9 (str)
11018      char * str;
11019 {
11020   if (my_get_expression (&inst.reloc.exp, &str))
11021     return;
11022   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
11023   inst.reloc.pc_rel = 1;
11024   end_of_line (str);
11025 }
11026
11027 static void
11028 do_t_branch12 (str)
11029      char * str;
11030 {
11031   if (my_get_expression (&inst.reloc.exp, &str))
11032     return;
11033   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11034   inst.reloc.pc_rel = 1;
11035   end_of_line (str);
11036 }
11037
11038 /* Find the real, Thumb encoded start of a Thumb function.  */
11039
11040 static symbolS *
11041 find_real_start (symbolP)
11042      symbolS * symbolP;
11043 {
11044   char *       real_start;
11045   const char * name = S_GET_NAME (symbolP);
11046   symbolS *    new_target;
11047
11048   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11049 #define STUB_NAME ".real_start_of"
11050
11051   if (name == NULL)
11052     abort ();
11053
11054   /* Names that start with '.' are local labels, not function entry points.
11055      The compiler may generate BL instructions to these labels because it
11056      needs to perform a branch to a far away location.  */
11057   if (name[0] == '.')
11058     return symbolP;
11059
11060   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11061   sprintf (real_start, "%s%s", STUB_NAME, name);
11062
11063   new_target = symbol_find (real_start);
11064
11065   if (new_target == NULL)
11066     {
11067       as_warn ("Failed to find real start of function: %s\n", name);
11068       new_target = symbolP;
11069     }
11070
11071   free (real_start);
11072
11073   return new_target;
11074 }
11075
11076 static void
11077 do_t_branch23 (str)
11078      char * str;
11079 {
11080   if (my_get_expression (& inst.reloc.exp, & str))
11081     return;
11082
11083   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11084   inst.reloc.pc_rel = 1;
11085   end_of_line (str);
11086
11087   /* If the destination of the branch is a defined symbol which does not have
11088      the THUMB_FUNC attribute, then we must be calling a function which has
11089      the (interfacearm) attribute.  We look for the Thumb entry point to that
11090      function and change the branch to refer to that function instead.  */
11091   if (   inst.reloc.exp.X_op == O_symbol
11092       && inst.reloc.exp.X_add_symbol != NULL
11093       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11094       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11095     inst.reloc.exp.X_add_symbol =
11096       find_real_start (inst.reloc.exp.X_add_symbol);
11097 }
11098
11099 static void
11100 do_t_bx (str)
11101      char * str;
11102 {
11103   int reg;
11104
11105   skip_whitespace (str);
11106
11107   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11108     return;
11109
11110   /* This sets THUMB_H2 from the top bit of reg.  */
11111   inst.instruction |= reg << 3;
11112
11113   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11114      should cause the alignment to be checked once it is known.  This is
11115      because BX PC only works if the instruction is word aligned.  */
11116
11117   end_of_line (str);
11118 }
11119
11120 static void
11121 do_t_compare (str)
11122      char * str;
11123 {
11124   thumb_mov_compare (str, THUMB_COMPARE);
11125 }
11126
11127 static void
11128 do_t_ldmstm (str)
11129      char * str;
11130 {
11131   int Rb;
11132   long range;
11133
11134   skip_whitespace (str);
11135
11136   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11137     return;
11138
11139   if (*str != '!')
11140     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11141   else
11142     str++;
11143
11144   if (skip_past_comma (&str) == FAIL
11145       || (range = reg_list (&str)) == FAIL)
11146     {
11147       if (! inst.error)
11148         inst.error = BAD_ARGS;
11149       return;
11150     }
11151
11152   if (inst.reloc.type != BFD_RELOC_NONE)
11153     {
11154       /* This really doesn't seem worth it.  */
11155       inst.reloc.type = BFD_RELOC_NONE;
11156       inst.error = _("expression too complex");
11157       return;
11158     }
11159
11160   if (range & ~0xff)
11161     {
11162       inst.error = _("only lo-regs valid in load/store multiple");
11163       return;
11164     }
11165
11166   inst.instruction |= (Rb << 8) | range;
11167   end_of_line (str);
11168 }
11169
11170 static void
11171 do_t_ldr (str)
11172      char * str;
11173 {
11174   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11175 }
11176
11177 static void
11178 do_t_ldrb (str)
11179      char * str;
11180 {
11181   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11182 }
11183
11184 static void
11185 do_t_ldrh (str)
11186      char * str;
11187 {
11188   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11189 }
11190
11191 static void
11192 do_t_lds (str)
11193      char * str;
11194 {
11195   int Rd, Rb, Ro;
11196
11197   skip_whitespace (str);
11198
11199   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11200       || skip_past_comma (&str) == FAIL
11201       || *str++ != '['
11202       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11203       || skip_past_comma (&str) == FAIL
11204       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11205       || *str++ != ']')
11206     {
11207       if (! inst.error)
11208         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11209       return;
11210     }
11211
11212   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11213   end_of_line (str);
11214 }
11215
11216 static void
11217 do_t_lsl (str)
11218      char * str;
11219 {
11220   thumb_shift (str, THUMB_LSL);
11221 }
11222
11223 static void
11224 do_t_lsr (str)
11225      char * str;
11226 {
11227   thumb_shift (str, THUMB_LSR);
11228 }
11229
11230 static void
11231 do_t_mov (str)
11232      char * str;
11233 {
11234   thumb_mov_compare (str, THUMB_MOVE);
11235 }
11236
11237 static void
11238 do_t_push_pop (str)
11239      char * str;
11240 {
11241   long range;
11242
11243   skip_whitespace (str);
11244
11245   if ((range = reg_list (&str)) == FAIL)
11246     {
11247       if (! inst.error)
11248         inst.error = BAD_ARGS;
11249       return;
11250     }
11251
11252   if (inst.reloc.type != BFD_RELOC_NONE)
11253     {
11254       /* This really doesn't seem worth it.  */
11255       inst.reloc.type = BFD_RELOC_NONE;
11256       inst.error = _("expression too complex");
11257       return;
11258     }
11259
11260   if (range & ~0xff)
11261     {
11262       if ((inst.instruction == T_OPCODE_PUSH
11263            && (range & ~0xff) == 1 << REG_LR)
11264           || (inst.instruction == T_OPCODE_POP
11265               && (range & ~0xff) == 1 << REG_PC))
11266         {
11267           inst.instruction |= THUMB_PP_PC_LR;
11268           range &= 0xff;
11269         }
11270       else
11271         {
11272           inst.error = _("invalid register list to push/pop instruction");
11273           return;
11274         }
11275     }
11276
11277   inst.instruction |= range;
11278   end_of_line (str);
11279 }
11280
11281 static void
11282 do_t_str (str)
11283      char * str;
11284 {
11285   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11286 }
11287
11288 static void
11289 do_t_strb (str)
11290      char * str;
11291 {
11292   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11293 }
11294
11295 static void
11296 do_t_strh (str)
11297      char * str;
11298 {
11299   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11300 }
11301
11302 static void
11303 do_t_sub (str)
11304      char * str;
11305 {
11306   thumb_add_sub (str, 1);
11307 }
11308
11309 static void
11310 do_t_swi (str)
11311      char * str;
11312 {
11313   skip_whitespace (str);
11314
11315   if (my_get_expression (&inst.reloc.exp, &str))
11316     return;
11317
11318   inst.reloc.type = BFD_RELOC_ARM_SWI;
11319   end_of_line (str);
11320 }
11321
11322 static void
11323 do_t_adr (str)
11324      char * str;
11325 {
11326   int reg;
11327
11328   /* This is a pseudo-op of the form "adr rd, label" to be converted
11329      into a relative address of the form "add rd, pc, #label-.-4".  */
11330   skip_whitespace (str);
11331
11332   /* Store Rd in temporary location inside instruction.  */
11333   if ((reg = reg_required_here (&str, 4)) == FAIL
11334       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11335       || skip_past_comma (&str) == FAIL
11336       || my_get_expression (&inst.reloc.exp, &str))
11337     {
11338       if (!inst.error)
11339         inst.error = BAD_ARGS;
11340       return;
11341     }
11342
11343   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11344   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11345   inst.reloc.pc_rel = 1;
11346   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11347
11348   end_of_line (str);
11349 }
11350
11351 static void
11352 insert_reg (r, htab)
11353      const struct reg_entry *r;
11354      struct hash_control *htab;
11355 {
11356   int    len  = strlen (r->name) + 2;
11357   char * buf  = (char *) xmalloc (len);
11358   char * buf2 = (char *) xmalloc (len);
11359   int    i    = 0;
11360
11361 #ifdef REGISTER_PREFIX
11362   buf[i++] = REGISTER_PREFIX;
11363 #endif
11364
11365   strcpy (buf + i, r->name);
11366
11367   for (i = 0; buf[i]; i++)
11368     buf2[i] = TOUPPER (buf[i]);
11369
11370   buf2[i] = '\0';
11371
11372   hash_insert (htab, buf,  (PTR) r);
11373   hash_insert (htab, buf2, (PTR) r);
11374 }
11375
11376 static void
11377 build_reg_hsh (map)
11378      struct reg_map *map;
11379 {
11380   const struct reg_entry *r;
11381
11382   if ((map->htab = hash_new ()) == NULL)
11383     as_fatal (_("virtual memory exhausted"));
11384
11385   for (r = map->names; r->name != NULL; r++)
11386     insert_reg (r, map->htab);
11387 }
11388
11389 static void
11390 insert_reg_alias (str, regnum, htab)
11391      char *str;
11392      int regnum;
11393      struct hash_control *htab;
11394 {
11395   const char *error;
11396   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11397   const char *name = xmalloc (strlen (str) + 1);
11398   
11399   strcpy ((char *) name, str);
11400   
11401   new->name = name;
11402   new->number = regnum;
11403   new->builtin = FALSE;
11404
11405   error = hash_insert (htab, name, (PTR) new);
11406   if (error)
11407     {
11408       as_bad (_("failed to create an alias for %s, reason: %s"),
11409             str, error);
11410       free ((char *) name);
11411       free (new);
11412     }
11413 }
11414
11415 /* Look for the .req directive.  This is of the form:
11416
11417         new_register_name .req existing_register_name
11418
11419    If we find one, or if it looks sufficiently like one that we want to
11420    handle any error here, return non-zero.  Otherwise return zero.  */
11421 static int
11422 create_register_alias (newname, p)
11423      char *newname;
11424      char *p;
11425 {
11426   char *q;
11427   char c;
11428
11429   q = p;
11430   skip_whitespace (q);
11431
11432   c = *p;
11433   *p = '\0';
11434
11435   if (*q && !strncmp (q, ".req ", 5))
11436     {
11437       char *copy_of_str;
11438       char *r;
11439
11440 #ifdef IGNORE_OPCODE_CASE
11441       newname = original_case_string;
11442 #endif
11443       copy_of_str = newname;
11444
11445       q += 4;
11446       skip_whitespace (q);
11447
11448       for (r = q; *r != '\0'; r++)
11449         if (*r == ' ')
11450           break;
11451
11452       if (r != q)
11453         {
11454           enum arm_reg_type new_type, old_type;
11455           int old_regno;
11456           char d = *r;
11457
11458           *r = '\0';
11459           old_type = arm_reg_parse_any (q);
11460           *r = d;
11461
11462           new_type = arm_reg_parse_any (newname);
11463
11464           if (new_type == REG_TYPE_MAX)
11465             {
11466               if (old_type != REG_TYPE_MAX)
11467                 {
11468                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11469                   insert_reg_alias (newname, old_regno,
11470                                     all_reg_maps[old_type].htab);
11471                 }
11472               else
11473                 as_warn (_("register '%s' does not exist\n"), q);
11474             }
11475           else if (old_type == REG_TYPE_MAX)
11476             {
11477               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11478                        copy_of_str, q);
11479             }
11480           else
11481             {
11482               /* Do not warn about redefinitions to the same alias.  */
11483               if (new_type != old_type
11484                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11485                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11486                 as_warn (_("ignoring redefinition of register alias '%s'"),
11487                          copy_of_str);
11488
11489             }
11490         }
11491       else
11492         as_warn (_("ignoring incomplete .req pseuso op"));
11493
11494       *p = c;
11495       return 1;
11496     }
11497   
11498   *p = c;
11499   return 0;
11500 }
11501
11502 static void
11503 set_constant_flonums ()
11504 {
11505   int i;
11506
11507   for (i = 0; i < NUM_FLOAT_VALS; i++)
11508     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11509       abort ();
11510 }
11511
11512 /* Iterate over the base tables to create the instruction patterns.  */
11513 static void
11514 build_arm_ops_hsh ()
11515 {
11516   unsigned int i;
11517   unsigned int j;
11518   static struct obstack insn_obstack;
11519
11520   obstack_begin (&insn_obstack, 4000);
11521
11522   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11523     {
11524       const struct asm_opcode *insn = insns + i;
11525
11526       if (insn->cond_offset != 0)
11527         {
11528           /* Insn supports conditional execution.  Build the varaints
11529              and insert them in the hash table.  */
11530           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11531             {
11532               unsigned len = strlen (insn->template);
11533               struct asm_opcode *new;
11534               char *template;
11535
11536               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11537               /* All condition codes are two characters.  */
11538               template = obstack_alloc (&insn_obstack, len + 3);
11539
11540               strncpy (template, insn->template, insn->cond_offset);
11541               strcpy (template + insn->cond_offset, conds[j].template);
11542               if (len > insn->cond_offset)
11543                 strcpy (template + insn->cond_offset + 2,
11544                         insn->template + insn->cond_offset);
11545               new->template = template;
11546               new->cond_offset = 0;
11547               new->variant = insn->variant;
11548               new->parms = insn->parms;
11549               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11550
11551               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11552             }
11553         }
11554       /* Finally, insert the unconditional insn in the table directly;
11555          no need to build a copy.  */
11556       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11557     }
11558 }
11559
11560 #if 0 /* Suppressed - for now.  */
11561 #if defined OBJ_ELF || defined OBJ_COFF
11562
11563 #ifdef OBJ_ELF
11564 #define arm_Note Elf_External_Note
11565 #else
11566 typedef struct
11567 {
11568   unsigned char namesz[4];      /* Size of entry's owner string.  */
11569   unsigned char descsz[4];      /* Size of the note descriptor.  */
11570   unsigned char type[4];        /* Interpretation of the descriptor.  */
11571   char          name[1];        /* Start of the name+desc data.  */
11572 } arm_Note;
11573 #endif
11574
11575 /* The description is kept to a fix sized in order to make updating
11576    it and merging it easier.  */
11577 #define ARM_NOTE_DESCRIPTION_LENGTH     8
11578
11579 static void
11580 arm_add_note (name, description, type)
11581      const char * name;
11582      const char * description;
11583      unsigned int type;
11584 {
11585   arm_Note     note ATTRIBUTE_UNUSED;
11586   char *       p;
11587   unsigned int name_len;
11588
11589   name_len = (strlen (name) + 1 + 3) & ~3;
11590   
11591   p = frag_more (sizeof (note.namesz));
11592   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11593
11594   p = frag_more (sizeof (note.descsz));
11595   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11596
11597   p = frag_more (sizeof (note.type));
11598   md_number_to_chars (p, (valueT) type, sizeof (note.type));
11599
11600   p = frag_more (name_len);
11601   strcpy (p, name);
11602
11603   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11604   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11605   frag_align (2, 0, 0);
11606 }
11607 #endif
11608 #endif
11609
11610 void
11611 md_begin ()
11612 {
11613   unsigned mach;
11614   unsigned int i;
11615
11616   if (   (arm_ops_hsh = hash_new ()) == NULL
11617       || (arm_tops_hsh = hash_new ()) == NULL
11618       || (arm_cond_hsh = hash_new ()) == NULL
11619       || (arm_shift_hsh = hash_new ()) == NULL
11620       || (arm_psr_hsh = hash_new ()) == NULL)
11621     as_fatal (_("virtual memory exhausted"));
11622
11623   build_arm_ops_hsh ();
11624   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11625     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11626   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11627     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11628   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11629     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11630   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11631     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11632
11633   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11634     build_reg_hsh (all_reg_maps + i);
11635
11636   set_constant_flonums ();
11637
11638   /* Set the cpu variant based on the command-line options.  We prefer
11639      -mcpu= over -march= if both are set (as for GCC); and we prefer
11640      -mfpu= over any other way of setting the floating point unit.
11641      Use of legacy options with new options are faulted.  */
11642   if (legacy_cpu != -1)
11643     {
11644       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11645         as_bad (_("use of old and new-style options to set CPU type"));
11646
11647       mcpu_cpu_opt = legacy_cpu;
11648     }
11649   else if (mcpu_cpu_opt == -1)
11650     mcpu_cpu_opt = march_cpu_opt;
11651
11652   if (legacy_fpu != -1)
11653     {
11654       if (mfpu_opt != -1)
11655         as_bad (_("use of old and new-style options to set FPU type"));
11656
11657       mfpu_opt = legacy_fpu;
11658     }
11659   else if (mfpu_opt == -1)
11660     {
11661 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11662       /* Some environments specify a default FPU.  If they don't, infer it
11663          from the processor.  */
11664       if (mcpu_fpu_opt != -1)
11665         mfpu_opt = mcpu_fpu_opt;
11666       else
11667         mfpu_opt = march_fpu_opt;
11668 #else
11669       mfpu_opt = FPU_DEFAULT;
11670 #endif
11671     }
11672
11673   if (mfpu_opt == -1)
11674     {
11675       if (mcpu_cpu_opt == -1)
11676         mfpu_opt = FPU_DEFAULT;
11677       else if (mcpu_cpu_opt & ARM_EXT_V5)
11678         mfpu_opt = FPU_ARCH_VFP_V2;
11679       else
11680         mfpu_opt = FPU_ARCH_FPA;
11681     }
11682
11683   if (mcpu_cpu_opt == -1)
11684     mcpu_cpu_opt = CPU_DEFAULT;
11685
11686   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11687
11688 #if defined OBJ_COFF || defined OBJ_ELF
11689   {
11690     unsigned int flags = 0;
11691
11692     /* Set the flags in the private structure.  */
11693     if (uses_apcs_26)      flags |= F_APCS26;
11694     if (support_interwork) flags |= F_INTERWORK;
11695     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11696     if (pic_code)          flags |= F_PIC;
11697     if ((cpu_variant & FPU_ANY) == FPU_NONE
11698          || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11699       {
11700         flags |= F_SOFT_FLOAT;
11701       }
11702     switch (mfloat_abi_opt)
11703       {
11704       case ARM_FLOAT_ABI_SOFT:
11705       case ARM_FLOAT_ABI_SOFTFP:
11706         flags |= F_SOFT_FLOAT;
11707         break;
11708
11709       case ARM_FLOAT_ABI_HARD:
11710         if (flags & F_SOFT_FLOAT)
11711           as_bad (_("hard-float conflicts with specified fpu"));
11712         break;
11713       }
11714     /* Using VFP conventions (even if soft-float).  */
11715     if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
11716
11717 #if defined OBJ_ELF
11718     if (cpu_variant & FPU_ARCH_MAVERICK)
11719         flags |= EF_ARM_MAVERICK_FLOAT;
11720 #endif
11721
11722     bfd_set_private_flags (stdoutput, flags);
11723
11724     /* We have run out flags in the COFF header to encode the
11725        status of ATPCS support, so instead we create a dummy,
11726        empty, debug section called .arm.atpcs.  */
11727     if (atpcs)
11728       {
11729         asection * sec;
11730
11731         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11732
11733         if (sec != NULL)
11734           {
11735             bfd_set_section_flags
11736               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11737             bfd_set_section_size (stdoutput, sec, 0);
11738             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11739           }
11740       }
11741   }
11742 #endif
11743
11744   /* Record the CPU type as well.  */
11745   switch (cpu_variant & ARM_CPU_MASK)
11746     {
11747     case ARM_2:
11748       mach = bfd_mach_arm_2;
11749       break;
11750
11751     case ARM_3:                 /* Also ARM_250.  */
11752       mach = bfd_mach_arm_2a;
11753       break;
11754
11755     case ARM_6:                 /* Also ARM_7.  */
11756       mach = bfd_mach_arm_3;
11757       break;
11758
11759     default:
11760       mach = bfd_mach_arm_unknown;
11761       break;
11762     }
11763
11764   /* Catch special cases.  */
11765   if (cpu_variant & ARM_CEXT_IWMMXT)
11766     mach = bfd_mach_arm_iWMMXt;
11767   else if (cpu_variant & ARM_CEXT_XSCALE)
11768     mach = bfd_mach_arm_XScale;
11769   else if (cpu_variant & ARM_CEXT_MAVERICK)
11770     mach = bfd_mach_arm_ep9312;
11771   else if (cpu_variant & ARM_EXT_V5E)
11772     mach = bfd_mach_arm_5TE;
11773   else if (cpu_variant & ARM_EXT_V5)
11774     {
11775       if (cpu_variant & ARM_EXT_V4T)
11776         mach = bfd_mach_arm_5T;
11777       else
11778         mach = bfd_mach_arm_5;
11779     }
11780   else if (cpu_variant & ARM_EXT_V4)
11781     {
11782       if (cpu_variant & ARM_EXT_V4T)
11783         mach = bfd_mach_arm_4T;
11784       else
11785         mach = bfd_mach_arm_4;
11786     }
11787   else if (cpu_variant & ARM_EXT_V3M)
11788     mach = bfd_mach_arm_3M;
11789
11790 #if 0 /* Suppressed - for now.  */
11791 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11792
11793   /* Create a .note section to fully identify this arm binary.  */
11794
11795 #define NOTE_ARCH_STRING        "arch: "
11796
11797 #if defined OBJ_COFF && ! defined NT_VERSION
11798 #define NT_VERSION  1
11799 #define NT_ARCH     2
11800 #endif
11801   
11802   {
11803     segT current_seg = now_seg;
11804     subsegT current_subseg = now_subseg;
11805     asection * arm_arch;
11806     const char * arch_string;
11807
11808     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11809
11810 #ifdef OBJ_COFF
11811     bfd_set_section_flags (stdoutput, arm_arch,
11812                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11813                            | SEC_HAS_CONTENTS);
11814 #else
11815     bfd_set_section_flags (stdoutput, arm_arch,
11816                            SEC_READONLY | SEC_HAS_CONTENTS);
11817 #endif
11818     arm_arch->output_section = arm_arch;
11819     subseg_set (arm_arch, 0);
11820
11821     switch (mach)
11822       {
11823       default:
11824       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11825       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11826       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11827       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11828       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11829       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11830       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11831       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11832       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11833       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11834       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11835       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11836       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break; 
11837       }
11838
11839     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11840
11841     subseg_set (current_seg, current_subseg);
11842   }
11843 #endif
11844 #endif /* Suppressed code.  */
11845   
11846   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11847 }
11848
11849 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11850    for use in the a.out file, and stores them in the array pointed to by buf.
11851    This knows about the endian-ness of the target machine and does
11852    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11853    2 (short) and 4 (long)  Floating numbers are put out as a series of
11854    LITTLENUMS (shorts, here at least).  */
11855
11856 void
11857 md_number_to_chars (buf, val, n)
11858      char * buf;
11859      valueT val;
11860      int    n;
11861 {
11862   if (target_big_endian)
11863     number_to_chars_bigendian (buf, val, n);
11864   else
11865     number_to_chars_littleendian (buf, val, n);
11866 }
11867
11868 static valueT
11869 md_chars_to_number (buf, n)
11870      char * buf;
11871      int    n;
11872 {
11873   valueT result = 0;
11874   unsigned char * where = (unsigned char *) buf;
11875
11876   if (target_big_endian)
11877     {
11878       while (n--)
11879         {
11880           result <<= 8;
11881           result |= (*where++ & 255);
11882         }
11883     }
11884   else
11885     {
11886       while (n--)
11887         {
11888           result <<= 8;
11889           result |= (where[n] & 255);
11890         }
11891     }
11892
11893   return result;
11894 }
11895
11896 /* Turn a string in input_line_pointer into a floating point constant
11897    of type TYPE, and store the appropriate bytes in *LITP.  The number
11898    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11899    returned, or NULL on OK.
11900
11901    Note that fp constants aren't represent in the normal way on the ARM.
11902    In big endian mode, things are as expected.  However, in little endian
11903    mode fp constants are big-endian word-wise, and little-endian byte-wise
11904    within the words.  For example, (double) 1.1 in big endian mode is
11905    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11906    the byte sequence 99 99 f1 3f 9a 99 99 99.
11907
11908    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11909
11910 char *
11911 md_atof (type, litP, sizeP)
11912      char   type;
11913      char * litP;
11914      int *  sizeP;
11915 {
11916   int prec;
11917   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11918   char *t;
11919   int i;
11920
11921   switch (type)
11922     {
11923     case 'f':
11924     case 'F':
11925     case 's':
11926     case 'S':
11927       prec = 2;
11928       break;
11929
11930     case 'd':
11931     case 'D':
11932     case 'r':
11933     case 'R':
11934       prec = 4;
11935       break;
11936
11937     case 'x':
11938     case 'X':
11939       prec = 6;
11940       break;
11941
11942     case 'p':
11943     case 'P':
11944       prec = 6;
11945       break;
11946
11947     default:
11948       *sizeP = 0;
11949       return _("bad call to MD_ATOF()");
11950     }
11951
11952   t = atof_ieee (input_line_pointer, type, words);
11953   if (t)
11954     input_line_pointer = t;
11955   *sizeP = prec * 2;
11956
11957   if (target_big_endian)
11958     {
11959       for (i = 0; i < prec; i++)
11960         {
11961           md_number_to_chars (litP, (valueT) words[i], 2);
11962           litP += 2;
11963         }
11964     }
11965   else
11966     {
11967       if (cpu_variant & FPU_ARCH_VFP)
11968         for (i = prec - 1; i >= 0; i--)
11969           {
11970             md_number_to_chars (litP, (valueT) words[i], 2);
11971             litP += 2;
11972           }
11973       else
11974         /* For a 4 byte float the order of elements in `words' is 1 0.
11975            For an 8 byte float the order is 1 0 3 2.  */
11976         for (i = 0; i < prec; i += 2)
11977           {
11978             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11979             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11980             litP += 4;
11981           }
11982     }
11983
11984   return 0;
11985 }
11986
11987 /* The knowledge of the PC's pipeline offset is built into the insns
11988    themselves.  */
11989
11990 long
11991 md_pcrel_from (fixP)
11992      fixS * fixP;
11993 {
11994   if (fixP->fx_addsy
11995       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11996       && fixP->fx_subsy == NULL)
11997     return 0;
11998
11999   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
12000     {
12001       /* PC relative addressing on the Thumb is slightly odd
12002          as the bottom two bits of the PC are forced to zero
12003          for the calculation.  */
12004       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
12005     }
12006
12007 #ifdef TE_WINCE
12008   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12009      so we un-adjust here to compensate for the accommodation.  */
12010   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
12011 #else
12012   return fixP->fx_where + fixP->fx_frag->fr_address;
12013 #endif
12014 }
12015
12016 /* Round up a section size to the appropriate boundary.  */
12017
12018 valueT
12019 md_section_align (segment, size)
12020      segT   segment ATTRIBUTE_UNUSED;
12021      valueT size;
12022 {
12023 #ifdef OBJ_ELF
12024   return size;
12025 #else
12026   /* Round all sects to multiple of 4.  */
12027   return (size + 3) & ~3;
12028 #endif
12029 }
12030
12031 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12032    Otherwise we have no need to default values of symbols.  */
12033
12034 symbolS *
12035 md_undefined_symbol (name)
12036      char * name ATTRIBUTE_UNUSED;
12037 {
12038 #ifdef OBJ_ELF
12039   if (name[0] == '_' && name[1] == 'G'
12040       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12041     {
12042       if (!GOT_symbol)
12043         {
12044           if (symbol_find (name))
12045             as_bad ("GOT already in the symbol table");
12046
12047           GOT_symbol = symbol_new (name, undefined_section,
12048                                    (valueT) 0, & zero_address_frag);
12049         }
12050
12051       return GOT_symbol;
12052     }
12053 #endif
12054
12055   return 0;
12056 }
12057
12058 /* arm_reg_parse () := if it looks like a register, return its token and
12059    advance the pointer.  */
12060
12061 static int
12062 arm_reg_parse (ccp, htab)
12063      register char ** ccp;
12064      struct hash_control *htab;
12065 {
12066   char * start = * ccp;
12067   char   c;
12068   char * p;
12069   struct reg_entry * reg;
12070
12071 #ifdef REGISTER_PREFIX
12072   if (*start != REGISTER_PREFIX)
12073     return FAIL;
12074   p = start + 1;
12075 #else
12076   p = start;
12077 #ifdef OPTIONAL_REGISTER_PREFIX
12078   if (*p == OPTIONAL_REGISTER_PREFIX)
12079     p++, start++;
12080 #endif
12081 #endif
12082   if (!ISALPHA (*p) || !is_name_beginner (*p))
12083     return FAIL;
12084
12085   c = *p++;
12086   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12087     c = *p++;
12088
12089   *--p = 0;
12090   reg = (struct reg_entry *) hash_find (htab, start);
12091   *p = c;
12092
12093   if (reg)
12094     {
12095       *ccp = p;
12096       return reg->number;
12097     }
12098
12099   return FAIL;
12100 }
12101
12102 /* Search for the following register name in each of the possible reg name
12103    tables.  Return the classification if found, or REG_TYPE_MAX if not
12104    present.  */
12105 static enum arm_reg_type
12106 arm_reg_parse_any (cp)
12107      char *cp;
12108 {
12109   int i;
12110
12111   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12112     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12113       return (enum arm_reg_type) i;
12114
12115   return REG_TYPE_MAX;
12116 }
12117
12118 void
12119 md_apply_fix3 (fixP, valP, seg)
12120      fixS *   fixP;
12121      valueT * valP;
12122      segT     seg;
12123 {
12124   offsetT        value = * valP;
12125   offsetT        newval;
12126   unsigned int   newimm;
12127   unsigned long  temp;
12128   int            sign;
12129   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12130   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12131
12132   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12133
12134   /* Note whether this will delete the relocation.  */
12135 #if 0
12136   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12137      doesn't work fully.)  */
12138   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12139       && !fixP->fx_pcrel)
12140 #else
12141   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12142 #endif
12143     fixP->fx_done = 1;
12144
12145   /* If this symbol is in a different section then we need to leave it for
12146      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12147      so we have to undo it's effects here.  */
12148   if (fixP->fx_pcrel)
12149     {
12150       if (fixP->fx_addsy != NULL
12151           && S_IS_DEFINED (fixP->fx_addsy)
12152           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12153         {
12154           if (target_oabi
12155               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12156                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12157                   ))
12158             value = 0;
12159           else
12160             value += md_pcrel_from (fixP);
12161         }
12162     }
12163
12164   /* Remember value for emit_reloc.  */
12165   fixP->fx_addnumber = value;
12166
12167   switch (fixP->fx_r_type)
12168     {
12169     case BFD_RELOC_ARM_IMMEDIATE:
12170       newimm = validate_immediate (value);
12171       temp = md_chars_to_number (buf, INSN_SIZE);
12172
12173       /* If the instruction will fail, see if we can fix things up by
12174          changing the opcode.  */
12175       if (newimm == (unsigned int) FAIL
12176           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12177         {
12178           as_bad_where (fixP->fx_file, fixP->fx_line,
12179                         _("invalid constant (%lx) after fixup"),
12180                         (unsigned long) value);
12181           break;
12182         }
12183
12184       newimm |= (temp & 0xfffff000);
12185       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12186       fixP->fx_done = 1;
12187       break;
12188
12189     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12190       {
12191         unsigned int highpart = 0;
12192         unsigned int newinsn  = 0xe1a00000; /* nop.  */
12193
12194         newimm = validate_immediate (value);
12195         temp = md_chars_to_number (buf, INSN_SIZE);
12196
12197         /* If the instruction will fail, see if we can fix things up by
12198            changing the opcode.  */
12199         if (newimm == (unsigned int) FAIL
12200             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12201           {
12202             /* No ?  OK - try using two ADD instructions to generate
12203                the value.  */
12204             newimm = validate_immediate_twopart (value, & highpart);
12205
12206             /* Yes - then make sure that the second instruction is
12207                also an add.  */
12208             if (newimm != (unsigned int) FAIL)
12209               newinsn = temp;
12210             /* Still No ?  Try using a negated value.  */
12211             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12212               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12213             /* Otherwise - give up.  */
12214             else
12215               {
12216                 as_bad_where (fixP->fx_file, fixP->fx_line,
12217                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12218                               (long) value);
12219                 break;
12220               }
12221
12222             /* Replace the first operand in the 2nd instruction (which
12223                is the PC) with the destination register.  We have
12224                already added in the PC in the first instruction and we
12225                do not want to do it again.  */
12226             newinsn &= ~ 0xf0000;
12227             newinsn |= ((newinsn & 0x0f000) << 4);
12228           }
12229
12230         newimm |= (temp & 0xfffff000);
12231         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12232
12233         highpart |= (newinsn & 0xfffff000);
12234         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12235       }
12236       break;
12237
12238     case BFD_RELOC_ARM_OFFSET_IMM:
12239       sign = value >= 0;
12240
12241       if (value < 0)
12242         value = - value;
12243
12244       if (validate_offset_imm (value, 0) == FAIL)
12245         {
12246           as_bad_where (fixP->fx_file, fixP->fx_line,
12247                         _("bad immediate value for offset (%ld)"),
12248                         (long) value);
12249           break;
12250         }
12251
12252       newval = md_chars_to_number (buf, INSN_SIZE);
12253       newval &= 0xff7ff000;
12254       newval |= value | (sign ? INDEX_UP : 0);
12255       md_number_to_chars (buf, newval, INSN_SIZE);
12256       break;
12257
12258     case BFD_RELOC_ARM_OFFSET_IMM8:
12259     case BFD_RELOC_ARM_HWLITERAL:
12260       sign = value >= 0;
12261
12262       if (value < 0)
12263         value = - value;
12264
12265       if (validate_offset_imm (value, 1) == FAIL)
12266         {
12267           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12268             as_bad_where (fixP->fx_file, fixP->fx_line,
12269                           _("invalid literal constant: pool needs to be closer"));
12270           else
12271             as_bad (_("bad immediate value for half-word offset (%ld)"),
12272                     (long) value);
12273           break;
12274         }
12275
12276       newval = md_chars_to_number (buf, INSN_SIZE);
12277       newval &= 0xff7ff0f0;
12278       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12279       md_number_to_chars (buf, newval, INSN_SIZE);
12280       break;
12281
12282     case BFD_RELOC_ARM_LITERAL:
12283       sign = value >= 0;
12284
12285       if (value < 0)
12286         value = - value;
12287
12288       if (validate_offset_imm (value, 0) == FAIL)
12289         {
12290           as_bad_where (fixP->fx_file, fixP->fx_line,
12291                         _("invalid literal constant: pool needs to be closer"));
12292           break;
12293         }
12294
12295       newval = md_chars_to_number (buf, INSN_SIZE);
12296       newval &= 0xff7ff000;
12297       newval |= value | (sign ? INDEX_UP : 0);
12298       md_number_to_chars (buf, newval, INSN_SIZE);
12299       break;
12300
12301     case BFD_RELOC_ARM_SHIFT_IMM:
12302       newval = md_chars_to_number (buf, INSN_SIZE);
12303       if (((unsigned long) value) > 32
12304           || (value == 32
12305               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12306         {
12307           as_bad_where (fixP->fx_file, fixP->fx_line,
12308                         _("shift expression is too large"));
12309           break;
12310         }
12311
12312       if (value == 0)
12313         /* Shifts of zero must be done as lsl.  */
12314         newval &= ~0x60;
12315       else if (value == 32)
12316         value = 0;
12317       newval &= 0xfffff07f;
12318       newval |= (value & 0x1f) << 7;
12319       md_number_to_chars (buf, newval, INSN_SIZE);
12320       break;
12321
12322     case BFD_RELOC_ARM_SWI:
12323       if (arm_data->thumb_mode)
12324         {
12325           if (((unsigned long) value) > 0xff)
12326             as_bad_where (fixP->fx_file, fixP->fx_line,
12327                           _("invalid swi expression"));
12328           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12329           newval |= value;
12330           md_number_to_chars (buf, newval, THUMB_SIZE);
12331         }
12332       else
12333         {
12334           if (((unsigned long) value) > 0x00ffffff)
12335             as_bad_where (fixP->fx_file, fixP->fx_line,
12336                           _("invalid swi expression"));
12337           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12338           newval |= value;
12339           md_number_to_chars (buf, newval, INSN_SIZE);
12340         }
12341       break;
12342
12343     case BFD_RELOC_ARM_MULTI:
12344       if (((unsigned long) value) > 0xffff)
12345         as_bad_where (fixP->fx_file, fixP->fx_line,
12346                       _("invalid expression in load/store multiple"));
12347       newval = value | md_chars_to_number (buf, INSN_SIZE);
12348       md_number_to_chars (buf, newval, INSN_SIZE);
12349       break;
12350
12351     case BFD_RELOC_ARM_PCREL_BRANCH:
12352       newval = md_chars_to_number (buf, INSN_SIZE);
12353
12354       /* Sign-extend a 24-bit number.  */
12355 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12356
12357 #ifdef OBJ_ELF
12358       if (! target_oabi)
12359         value = fixP->fx_offset;
12360 #endif
12361
12362       /* We are going to store value (shifted right by two) in the
12363          instruction, in a 24 bit, signed field.  Thus we need to check
12364          that none of the top 8 bits of the shifted value (top 7 bits of
12365          the unshifted, unsigned value) are set, or that they are all set.  */
12366       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12367           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12368         {
12369 #ifdef OBJ_ELF
12370           /* Normally we would be stuck at this point, since we cannot store
12371              the absolute address that is the destination of the branch in the
12372              24 bits of the branch instruction.  If however, we happen to know
12373              that the destination of the branch is in the same section as the
12374              branch instruction itself, then we can compute the relocation for
12375              ourselves and not have to bother the linker with it.
12376
12377              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12378              because I have not worked out how to do this for OBJ_COFF or
12379              target_oabi.  */
12380           if (! target_oabi
12381               && fixP->fx_addsy != NULL
12382               && S_IS_DEFINED (fixP->fx_addsy)
12383               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12384             {
12385               /* Get pc relative value to go into the branch.  */
12386               value = * valP;
12387
12388               /* Permit a backward branch provided that enough bits
12389                  are set.  Allow a forwards branch, provided that
12390                  enough bits are clear.  */
12391               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12392                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12393                 fixP->fx_done = 1;
12394             }
12395
12396           if (! fixP->fx_done)
12397 #endif
12398             as_bad_where (fixP->fx_file, fixP->fx_line,
12399                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12400         }
12401
12402       value >>= 2;
12403       value += SEXT24 (newval);
12404
12405       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12406           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12407         as_bad_where (fixP->fx_file, fixP->fx_line,
12408                       _("out of range branch"));
12409
12410       newval = (value & 0x00ffffff) | (newval & 0xff000000);
12411       md_number_to_chars (buf, newval, INSN_SIZE);
12412       break;
12413
12414     case BFD_RELOC_ARM_PCREL_BLX:
12415       {
12416         offsetT hbit;
12417         newval = md_chars_to_number (buf, INSN_SIZE);
12418
12419 #ifdef OBJ_ELF
12420         if (! target_oabi)
12421           value = fixP->fx_offset;
12422 #endif
12423         hbit   = (value >> 1) & 1;
12424         value  = (value >> 2) & 0x00ffffff;
12425         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12426         newval = value | (newval & 0xfe000000) | (hbit << 24);
12427         md_number_to_chars (buf, newval, INSN_SIZE);
12428       }
12429       break;
12430
12431     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12432       newval = md_chars_to_number (buf, THUMB_SIZE);
12433       {
12434         addressT diff = (newval & 0xff) << 1;
12435         if (diff & 0x100)
12436           diff |= ~0xff;
12437
12438         value += diff;
12439         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12440           as_bad_where (fixP->fx_file, fixP->fx_line,
12441                         _("branch out of range"));
12442         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12443       }
12444       md_number_to_chars (buf, newval, THUMB_SIZE);
12445       break;
12446
12447     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12448       newval = md_chars_to_number (buf, THUMB_SIZE);
12449       {
12450         addressT diff = (newval & 0x7ff) << 1;
12451         if (diff & 0x800)
12452           diff |= ~0x7ff;
12453
12454         value += diff;
12455         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12456           as_bad_where (fixP->fx_file, fixP->fx_line,
12457                         _("branch out of range"));
12458         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12459       }
12460       md_number_to_chars (buf, newval, THUMB_SIZE);
12461       break;
12462
12463     case BFD_RELOC_THUMB_PCREL_BLX:
12464     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12465       {
12466         offsetT newval2;
12467         addressT diff;
12468
12469         newval  = md_chars_to_number (buf, THUMB_SIZE);
12470         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12471         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12472         if (diff & 0x400000)
12473           diff |= ~0x3fffff;
12474 #ifdef OBJ_ELF
12475         value = fixP->fx_offset;
12476 #endif
12477         value += diff;
12478
12479         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12480           as_bad_where (fixP->fx_file, fixP->fx_line,
12481                         _("branch with link out of range"));
12482
12483         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12484         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12485         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12486           /* For a BLX instruction, make sure that the relocation is rounded up
12487              to a word boundary.  This follows the semantics of the instruction
12488              which specifies that bit 1 of the target address will come from bit
12489              1 of the base address.  */
12490           newval2 = (newval2 + 1) & ~ 1;
12491         md_number_to_chars (buf, newval, THUMB_SIZE);
12492         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12493       }
12494       break;
12495
12496     case BFD_RELOC_8:
12497       if (fixP->fx_done || fixP->fx_pcrel)
12498         md_number_to_chars (buf, value, 1);
12499 #ifdef OBJ_ELF
12500       else if (!target_oabi)
12501         {
12502           value = fixP->fx_offset;
12503           md_number_to_chars (buf, value, 1);
12504         }
12505 #endif
12506       break;
12507
12508     case BFD_RELOC_16:
12509       if (fixP->fx_done || fixP->fx_pcrel)
12510         md_number_to_chars (buf, value, 2);
12511 #ifdef OBJ_ELF
12512       else if (!target_oabi)
12513         {
12514           value = fixP->fx_offset;
12515           md_number_to_chars (buf, value, 2);
12516         }
12517 #endif
12518       break;
12519
12520 #ifdef OBJ_ELF
12521     case BFD_RELOC_ARM_GOT32:
12522     case BFD_RELOC_ARM_GOTOFF:
12523       md_number_to_chars (buf, 0, 4);
12524       break;
12525 #endif
12526
12527     case BFD_RELOC_RVA:
12528     case BFD_RELOC_32:
12529       if (fixP->fx_done || fixP->fx_pcrel)
12530         md_number_to_chars (buf, value, 4);
12531 #ifdef OBJ_ELF
12532       else if (!target_oabi)
12533         {
12534           value = fixP->fx_offset;
12535           md_number_to_chars (buf, value, 4);
12536         }
12537 #endif
12538       break;
12539
12540 #ifdef OBJ_ELF
12541     case BFD_RELOC_ARM_PLT32:
12542       /* It appears the instruction is fully prepared at this point.  */
12543       break;
12544 #endif
12545
12546     case BFD_RELOC_ARM_CP_OFF_IMM:
12547       sign = value >= 0;
12548       if (value < -1023 || value > 1023 || (value & 3))
12549         as_bad_where (fixP->fx_file, fixP->fx_line,
12550                       _("illegal value for co-processor offset"));
12551       if (value < 0)
12552         value = -value;
12553       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12554       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12555       md_number_to_chars (buf, newval, INSN_SIZE);
12556       break;
12557
12558     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12559       sign = value >= 0;
12560       if (value < -255 || value > 255)
12561         as_bad_where (fixP->fx_file, fixP->fx_line,
12562                       _("Illegal value for co-processor offset"));
12563       if (value < 0)
12564         value = -value;
12565       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12566       newval |= value | (sign ?  INDEX_UP : 0);
12567       md_number_to_chars (buf, newval , INSN_SIZE);
12568       break;
12569
12570     case BFD_RELOC_ARM_THUMB_OFFSET:
12571       newval = md_chars_to_number (buf, THUMB_SIZE);
12572       /* Exactly what ranges, and where the offset is inserted depends
12573          on the type of instruction, we can establish this from the
12574          top 4 bits.  */
12575       switch (newval >> 12)
12576         {
12577         case 4: /* PC load.  */
12578           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12579              forced to zero for these loads, so we will need to round
12580              up the offset if the instruction address is not word
12581              aligned (since the final address produced must be, and
12582              we can only describe word-aligned immediate offsets).  */
12583
12584           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12585             as_bad_where (fixP->fx_file, fixP->fx_line,
12586                           _("invalid offset, target not word aligned (0x%08X)"),
12587                           (unsigned int) (fixP->fx_frag->fr_address
12588                                           + fixP->fx_where + value));
12589
12590           if ((value + 2) & ~0x3fe)
12591             as_bad_where (fixP->fx_file, fixP->fx_line,
12592                           _("invalid offset, value too big (0x%08lX)"),
12593                           (long) value);
12594
12595           /* Round up, since pc will be rounded down.  */
12596           newval |= (value + 2) >> 2;
12597           break;
12598
12599         case 9: /* SP load/store.  */
12600           if (value & ~0x3fc)
12601             as_bad_where (fixP->fx_file, fixP->fx_line,
12602                           _("invalid offset, value too big (0x%08lX)"),
12603                           (long) value);
12604           newval |= value >> 2;
12605           break;
12606
12607         case 6: /* Word load/store.  */
12608           if (value & ~0x7c)
12609             as_bad_where (fixP->fx_file, fixP->fx_line,
12610                           _("invalid offset, value too big (0x%08lX)"),
12611                           (long) value);
12612           newval |= value << 4; /* 6 - 2.  */
12613           break;
12614
12615         case 7: /* Byte load/store.  */
12616           if (value & ~0x1f)
12617             as_bad_where (fixP->fx_file, fixP->fx_line,
12618                           _("invalid offset, value too big (0x%08lX)"),
12619                           (long) value);
12620           newval |= value << 6;
12621           break;
12622
12623         case 8: /* Halfword load/store.  */
12624           if (value & ~0x3e)
12625             as_bad_where (fixP->fx_file, fixP->fx_line,
12626                           _("invalid offset, value too big (0x%08lX)"),
12627                           (long) value);
12628           newval |= value << 5; /* 6 - 1.  */
12629           break;
12630
12631         default:
12632           as_bad_where (fixP->fx_file, fixP->fx_line,
12633                         "Unable to process relocation for thumb opcode: %lx",
12634                         (unsigned long) newval);
12635           break;
12636         }
12637       md_number_to_chars (buf, newval, THUMB_SIZE);
12638       break;
12639
12640     case BFD_RELOC_ARM_THUMB_ADD:
12641       /* This is a complicated relocation, since we use it for all of
12642          the following immediate relocations:
12643
12644             3bit ADD/SUB
12645             8bit ADD/SUB
12646             9bit ADD/SUB SP word-aligned
12647            10bit ADD PC/SP word-aligned
12648
12649          The type of instruction being processed is encoded in the
12650          instruction field:
12651
12652            0x8000  SUB
12653            0x00F0  Rd
12654            0x000F  Rs
12655       */
12656       newval = md_chars_to_number (buf, THUMB_SIZE);
12657       {
12658         int rd = (newval >> 4) & 0xf;
12659         int rs = newval & 0xf;
12660         int subtract = newval & 0x8000;
12661
12662         if (rd == REG_SP)
12663           {
12664             if (value & ~0x1fc)
12665               as_bad_where (fixP->fx_file, fixP->fx_line,
12666                             _("invalid immediate for stack address calculation"));
12667             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12668             newval |= value >> 2;
12669           }
12670         else if (rs == REG_PC || rs == REG_SP)
12671           {
12672             if (subtract ||
12673                 value & ~0x3fc)
12674               as_bad_where (fixP->fx_file, fixP->fx_line,
12675                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12676                             (unsigned long) value);
12677             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12678             newval |= rd << 8;
12679             newval |= value >> 2;
12680           }
12681         else if (rs == rd)
12682           {
12683             if (value & ~0xff)
12684               as_bad_where (fixP->fx_file, fixP->fx_line,
12685                             _("invalid 8bit immediate"));
12686             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12687             newval |= (rd << 8) | value;
12688           }
12689         else
12690           {
12691             if (value & ~0x7)
12692               as_bad_where (fixP->fx_file, fixP->fx_line,
12693                             _("invalid 3bit immediate"));
12694             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12695             newval |= rd | (rs << 3) | (value << 6);
12696           }
12697       }
12698       md_number_to_chars (buf, newval, THUMB_SIZE);
12699       break;
12700
12701     case BFD_RELOC_ARM_THUMB_IMM:
12702       newval = md_chars_to_number (buf, THUMB_SIZE);
12703       switch (newval >> 11)
12704         {
12705         case 0x04: /* 8bit immediate MOV.  */
12706         case 0x05: /* 8bit immediate CMP.  */
12707           if (value < 0 || value > 255)
12708             as_bad_where (fixP->fx_file, fixP->fx_line,
12709                           _("invalid immediate: %ld is too large"),
12710                           (long) value);
12711           newval |= value;
12712           break;
12713
12714         default:
12715           abort ();
12716         }
12717       md_number_to_chars (buf, newval, THUMB_SIZE);
12718       break;
12719
12720     case BFD_RELOC_ARM_THUMB_SHIFT:
12721       /* 5bit shift value (0..31).  */
12722       if (value < 0 || value > 31)
12723         as_bad_where (fixP->fx_file, fixP->fx_line,
12724                       _("illegal Thumb shift value: %ld"), (long) value);
12725       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12726       newval |= value << 6;
12727       md_number_to_chars (buf, newval, THUMB_SIZE);
12728       break;
12729
12730     case BFD_RELOC_VTABLE_INHERIT:
12731     case BFD_RELOC_VTABLE_ENTRY:
12732       fixP->fx_done = 0;
12733       return;
12734
12735     case BFD_RELOC_NONE:
12736     default:
12737       as_bad_where (fixP->fx_file, fixP->fx_line,
12738                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12739     }
12740 }
12741
12742 /* Translate internal representation of relocation info to BFD target
12743    format.  */
12744
12745 arelent *
12746 tc_gen_reloc (section, fixp)
12747      asection * section ATTRIBUTE_UNUSED;
12748      fixS * fixp;
12749 {
12750   arelent * reloc;
12751   bfd_reloc_code_real_type code;
12752
12753   reloc = (arelent *) xmalloc (sizeof (arelent));
12754
12755   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12756   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12757   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12758
12759   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12760 #ifndef OBJ_ELF
12761   if (fixp->fx_pcrel == 0)
12762     reloc->addend = fixp->fx_offset;
12763   else
12764     reloc->addend = fixp->fx_offset = reloc->address;
12765 #else  /* OBJ_ELF */
12766   reloc->addend = fixp->fx_offset;
12767 #endif
12768
12769   switch (fixp->fx_r_type)
12770     {
12771     case BFD_RELOC_8:
12772       if (fixp->fx_pcrel)
12773         {
12774           code = BFD_RELOC_8_PCREL;
12775           break;
12776         }
12777
12778     case BFD_RELOC_16:
12779       if (fixp->fx_pcrel)
12780         {
12781           code = BFD_RELOC_16_PCREL;
12782           break;
12783         }
12784
12785     case BFD_RELOC_32:
12786       if (fixp->fx_pcrel)
12787         {
12788           code = BFD_RELOC_32_PCREL;
12789           break;
12790         }
12791
12792     case BFD_RELOC_ARM_PCREL_BRANCH:
12793     case BFD_RELOC_ARM_PCREL_BLX:
12794     case BFD_RELOC_RVA:
12795     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12796     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12797     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12798     case BFD_RELOC_THUMB_PCREL_BLX:
12799     case BFD_RELOC_VTABLE_ENTRY:
12800     case BFD_RELOC_VTABLE_INHERIT:
12801       code = fixp->fx_r_type;
12802       break;
12803
12804     case BFD_RELOC_ARM_LITERAL:
12805     case BFD_RELOC_ARM_HWLITERAL:
12806       /* If this is called then the a literal has
12807          been referenced across a section boundary.  */
12808       as_bad_where (fixp->fx_file, fixp->fx_line,
12809                     _("literal referenced across section boundary"));
12810       return NULL;
12811
12812 #ifdef OBJ_ELF
12813     case BFD_RELOC_ARM_GOT32:
12814     case BFD_RELOC_ARM_GOTOFF:
12815     case BFD_RELOC_ARM_PLT32:
12816       code = fixp->fx_r_type;
12817       break;
12818 #endif
12819
12820     case BFD_RELOC_ARM_IMMEDIATE:
12821       as_bad_where (fixp->fx_file, fixp->fx_line,
12822                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12823       return NULL;
12824
12825     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12826       as_bad_where (fixp->fx_file, fixp->fx_line,
12827                     _("ADRL used for a symbol not defined in the same file"));
12828       return NULL;
12829
12830     case BFD_RELOC_ARM_OFFSET_IMM:
12831       if (fixp->fx_addsy != NULL
12832           && !S_IS_DEFINED (fixp->fx_addsy)
12833           && S_IS_LOCAL (fixp->fx_addsy))
12834         {
12835           as_bad_where (fixp->fx_file, fixp->fx_line,
12836                         _("undefined local label `%s'"),
12837                         S_GET_NAME (fixp->fx_addsy));
12838           return NULL;
12839         }
12840
12841       as_bad_where (fixp->fx_file, fixp->fx_line,
12842                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12843       return NULL;
12844
12845     default:
12846       {
12847         char * type;
12848
12849         switch (fixp->fx_r_type)
12850           {
12851           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12852           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12853           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12854           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12855           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12856           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12857           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12858           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12859           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12860           default:                         type = _("<unknown>"); break;
12861           }
12862         as_bad_where (fixp->fx_file, fixp->fx_line,
12863                       _("cannot represent %s relocation in this object file format"),
12864                       type);
12865         return NULL;
12866       }
12867     }
12868
12869 #ifdef OBJ_ELF
12870   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12871       && GOT_symbol
12872       && fixp->fx_addsy == GOT_symbol)
12873     {
12874       code = BFD_RELOC_ARM_GOTPC;
12875       reloc->addend = fixp->fx_offset = reloc->address;
12876     }
12877 #endif
12878
12879   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12880
12881   if (reloc->howto == NULL)
12882     {
12883       as_bad_where (fixp->fx_file, fixp->fx_line,
12884                     _("cannot represent %s relocation in this object file format"),
12885                     bfd_get_reloc_code_name (code));
12886       return NULL;
12887     }
12888
12889   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12890      vtable entry to be used in the relocation's section offset.  */
12891   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12892     reloc->address = fixp->fx_offset;
12893
12894   return reloc;
12895 }
12896
12897 int
12898 md_estimate_size_before_relax (fragP, segtype)
12899      fragS * fragP ATTRIBUTE_UNUSED;
12900      segT    segtype ATTRIBUTE_UNUSED;
12901 {
12902   as_fatal (_("md_estimate_size_before_relax\n"));
12903   return 1;
12904 }
12905
12906 static void
12907 output_inst (str)
12908      const char *str;
12909 {
12910   char * to = NULL;
12911
12912   if (inst.error)
12913     {
12914       as_bad ("%s -- `%s'", inst.error, str);
12915       return;
12916     }
12917
12918   to = frag_more (inst.size);
12919
12920   if (thumb_mode && (inst.size > THUMB_SIZE))
12921     {
12922       assert (inst.size == (2 * THUMB_SIZE));
12923       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12924       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12925     }
12926   else if (inst.size > INSN_SIZE)
12927     {
12928       assert (inst.size == (2 * INSN_SIZE));
12929       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12930       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12931     }
12932   else
12933     md_number_to_chars (to, inst.instruction, inst.size);
12934
12935   if (inst.reloc.type != BFD_RELOC_NONE)
12936     fix_new_arm (frag_now, to - frag_now->fr_literal,
12937                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12938                  inst.reloc.type);
12939
12940 #ifdef OBJ_ELF
12941   dwarf2_emit_insn (inst.size);
12942 #endif
12943 }
12944
12945 void
12946 md_assemble (str)
12947      char * str;
12948 {
12949   char  c;
12950   char *p;
12951   char *start;
12952
12953   /* Align the instruction.
12954      This may not be the right thing to do but ...  */
12955 #if 0
12956   arm_align (2, 0);
12957 #endif
12958
12959   /* Align the previous label if needed.  */
12960   if (last_label_seen != NULL)
12961     {
12962       symbol_set_frag (last_label_seen, frag_now);
12963       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12964       S_SET_SEGMENT (last_label_seen, now_seg);
12965     }
12966
12967   memset (&inst, '\0', sizeof (inst));
12968   inst.reloc.type = BFD_RELOC_NONE;
12969
12970   skip_whitespace (str);
12971
12972   /* Scan up to the end of the op-code, which must end in white space or
12973      end of string.  */
12974   for (start = p = str; *p != '\0'; p++)
12975     if (*p == ' ')
12976       break;
12977
12978   if (p == str)
12979     {
12980       as_bad (_("no operator -- statement `%s'\n"), str);
12981       return;
12982     }
12983
12984   if (thumb_mode)
12985     {
12986       const struct thumb_opcode * opcode;
12987
12988       c = *p;
12989       *p = '\0';
12990       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12991       *p = c;
12992
12993       if (opcode)
12994         {
12995           /* Check that this instruction is supported for this CPU.  */
12996           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12997             {
12998               as_bad (_("selected processor does not support `%s'"), str);
12999               return;
13000             }
13001
13002           mapping_state (MAP_THUMB);
13003           inst.instruction = opcode->value;
13004           inst.size = opcode->size;
13005           (*opcode->parms) (p);
13006           output_inst (str);
13007           return;
13008         }
13009     }
13010   else
13011     {
13012       const struct asm_opcode * opcode;
13013
13014       c = *p;
13015       *p = '\0';
13016       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13017       *p = c;
13018
13019       if (opcode)
13020         {
13021           /* Check that this instruction is supported for this CPU.  */
13022           if ((opcode->variant & cpu_variant) == 0)
13023             {
13024               as_bad (_("selected processor does not support `%s'"), str);
13025               return;
13026             }
13027
13028           mapping_state (MAP_ARM);
13029           inst.instruction = opcode->value;
13030           inst.size = INSN_SIZE;
13031           (*opcode->parms) (p);
13032           output_inst (str);
13033           return;
13034         }
13035     }
13036
13037   /* It wasn't an instruction, but it might be a register alias of the form
13038      alias .req reg.  */
13039   if (create_register_alias (str, p))
13040     return;
13041
13042   as_bad (_("bad instruction `%s'"), start);
13043 }
13044
13045 /* md_parse_option
13046       Invocation line includes a switch not recognized by the base assembler.
13047       See if it's a processor-specific option.
13048
13049       This routine is somewhat complicated by the need for backwards
13050       compatibility (since older releases of gcc can't be changed).
13051       The new options try to make the interface as compatible as
13052       possible with GCC.
13053
13054       New options (supported) are:
13055
13056               -mcpu=<cpu name>           Assemble for selected processor
13057               -march=<architecture name> Assemble for selected architecture
13058               -mfpu=<fpu architecture>   Assemble for selected FPU.
13059               -EB/-mbig-endian           Big-endian
13060               -EL/-mlittle-endian        Little-endian
13061               -k                         Generate PIC code
13062               -mthumb                    Start in Thumb mode
13063               -mthumb-interwork          Code supports ARM/Thumb interworking
13064
13065       For now we will also provide support for:
13066
13067               -mapcs-32                  32-bit Program counter
13068               -mapcs-26                  26-bit Program counter
13069               -macps-float               Floats passed in FP registers
13070               -mapcs-reentrant           Reentrant code
13071               -matpcs
13072       (sometime these will probably be replaced with -mapcs=<list of options>
13073       and -matpcs=<list of options>)
13074
13075       The remaining options are only supported for back-wards compatibility.
13076       Cpu variants, the arm part is optional:
13077               -m[arm]1                Currently not supported.
13078               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13079               -m[arm]3                Arm 3 processor
13080               -m[arm]6[xx],           Arm 6 processors
13081               -m[arm]7[xx][t][[d]m]   Arm 7 processors
13082               -m[arm]8[10]            Arm 8 processors
13083               -m[arm]9[20][tdmi]      Arm 9 processors
13084               -mstrongarm[110[0]]     StrongARM processors
13085               -mxscale                XScale processors
13086               -m[arm]v[2345[t[e]]]    Arm architectures
13087               -mall                   All (except the ARM1)
13088       FP variants:
13089               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13090               -mfpe-old               (No float load/store multiples)
13091               -mvfpxd                 VFP Single precision
13092               -mvfp                   All VFP
13093               -mno-fpu                Disable all floating point instructions
13094
13095       The following CPU names are recognized:
13096               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13097               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13098               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13099               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13100               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13101               arm10t arm10e, arm1020t, arm1020e, arm10200e,
13102               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13103
13104       */
13105
13106 const char * md_shortopts = "m:k";
13107
13108 #ifdef ARM_BI_ENDIAN
13109 #define OPTION_EB (OPTION_MD_BASE + 0)
13110 #define OPTION_EL (OPTION_MD_BASE + 1)
13111 #else
13112 #if TARGET_BYTES_BIG_ENDIAN
13113 #define OPTION_EB (OPTION_MD_BASE + 0)
13114 #else
13115 #define OPTION_EL (OPTION_MD_BASE + 1)
13116 #endif
13117 #endif
13118
13119 struct option md_longopts[] =
13120 {
13121 #ifdef OPTION_EB
13122   {"EB", no_argument, NULL, OPTION_EB},
13123 #endif
13124 #ifdef OPTION_EL
13125   {"EL", no_argument, NULL, OPTION_EL},
13126 #endif
13127   {NULL, no_argument, NULL, 0}
13128 };
13129
13130 size_t md_longopts_size = sizeof (md_longopts);
13131
13132 struct arm_option_table
13133 {
13134   char *option;         /* Option name to match.  */
13135   char *help;           /* Help information.  */
13136   int  *var;            /* Variable to change.  */
13137   int   value;          /* What to change it to.  */
13138   char *deprecated;     /* If non-null, print this message.  */
13139 };
13140
13141 struct arm_option_table arm_opts[] =
13142 {
13143   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13144   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13145   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13146    &support_interwork, 1, NULL},
13147   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13148   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13149   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13150   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13151    1, NULL},
13152   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13153   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13154   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13155   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13156    NULL},
13157
13158   /* These are recognized by the assembler, but have no affect on code.  */
13159   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13160   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13161
13162   /* DON'T add any new processors to this list -- we want the whole list
13163      to go away...  Add them to the processors table instead.  */
13164   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13165   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13166   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13167   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13168   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13169   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13170   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13171   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13172   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13173   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13174   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13175   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13176   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13177   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13178   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13179   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13180   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13181   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13182   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13183   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13184   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13185   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13186   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13187   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13188   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13189   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13190   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13191   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13192   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13193   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13194   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13195   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13196   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13197   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13198   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13199   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13200   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13201   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13202   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13203   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13204   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13205   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13206   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13207   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13208   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13209   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13210   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13211   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13212   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13213   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13214   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13215   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13216   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13217   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13218   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13219   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13220   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13221   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13222   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13223   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13224   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13225   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13226   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13227   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13228   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13229   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13230   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13231   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13232   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13233   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13234    N_("use -mcpu=strongarm110")},
13235   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13236    N_("use -mcpu=strongarm1100")},
13237   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13238    N_("use -mcpu=strongarm1110")},
13239   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13240   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13241   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13242
13243   /* Architecture variants -- don't add any more to this list either.  */
13244   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13245   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13246   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13247   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13248   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13249   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13250   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13251   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13252   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13253   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13254   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13255   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13256   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13257   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13258   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13259   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13260   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13261   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13262
13263   /* Floating point variants -- don't add any more to this list either.  */
13264   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13265   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13266   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13267   {"mno-fpu",  NULL, &legacy_fpu, 0,
13268    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13269
13270   {NULL, NULL, NULL, 0, NULL}
13271 };
13272
13273 struct arm_cpu_option_table
13274 {
13275   char *name;
13276   int   value;
13277   /* For some CPUs we assume an FPU unless the user explicitly sets
13278      -mfpu=...  */
13279   int   default_fpu;
13280 };
13281
13282 /* This list should, at a minimum, contain all the cpu names
13283    recognized by GCC.  */
13284 static struct arm_cpu_option_table arm_cpus[] =
13285 {
13286   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13287   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13288   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13289   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13290   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13291   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13292   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13293   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13294   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13295   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13296   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13297   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13298   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13299   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13300   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13301   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13302   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13303   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13304   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13305   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13306   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13307   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13308   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13309   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13310   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13311   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13312   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13313   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13314   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13315   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13316   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13317   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13318   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13319   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13320   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13321   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13322   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13323   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13324   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13325   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13326   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13327   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13328   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13329   /* For V5 or later processors we default to using VFP; but the user
13330      should really set the FPU type explicitly.  */
13331   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13332   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13333   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13334   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13335   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13336   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13337   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13338   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13339   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13340   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13341   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13342   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13343   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13344   {"arm1026ejs",        ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13345   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13346   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13347   /* ??? XSCALE is really an architecture.  */
13348   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13349   /* ??? iwmmxt is not a processor.  */
13350   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13351   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13352   /* Maverick */
13353   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13354   {NULL, 0, 0}
13355 };
13356
13357 struct arm_arch_option_table
13358 {
13359   char *name;
13360   int   value;
13361   int   default_fpu;
13362 };
13363
13364 /* This list should, at a minimum, contain all the architecture names
13365    recognized by GCC.  */
13366 static struct arm_arch_option_table arm_archs[] =
13367 {
13368   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13369   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13370   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13371   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13372   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13373   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13374   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13375   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13376   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13377   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13378   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13379   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13380   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13381   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13382   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13383   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13384   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13385   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13386   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13387   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13388   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13389   {NULL, 0, 0}
13390 };
13391
13392 /* ISA extensions in the co-processor space.  */
13393 struct arm_arch_extension_table
13394 {
13395   char *name;
13396   int value;
13397 };
13398
13399 static struct arm_arch_extension_table arm_extensions[] =
13400 {
13401   {"maverick",          ARM_CEXT_MAVERICK},
13402   {"xscale",            ARM_CEXT_XSCALE},
13403   {"iwmmxt",            ARM_CEXT_IWMMXT},
13404   {NULL,                0}
13405 };
13406
13407 struct arm_fpu_option_table
13408 {
13409   char *name;
13410   int   value;
13411 };
13412
13413 /* This list should, at a minimum, contain all the fpu names
13414    recognized by GCC.  */
13415 static struct arm_fpu_option_table arm_fpus[] =
13416 {
13417   {"softfpa",           FPU_NONE},
13418   {"fpe",               FPU_ARCH_FPE},
13419   {"fpe2",              FPU_ARCH_FPE},
13420   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13421   {"fpa",               FPU_ARCH_FPA},
13422   {"fpa10",             FPU_ARCH_FPA},
13423   {"fpa11",             FPU_ARCH_FPA},
13424   {"arm7500fe",         FPU_ARCH_FPA},
13425   {"softvfp",           FPU_ARCH_VFP},
13426   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13427   {"vfp",               FPU_ARCH_VFP_V2},
13428   {"vfp9",              FPU_ARCH_VFP_V2},
13429   {"vfp10",             FPU_ARCH_VFP_V2},
13430   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13431   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13432   {"arm1020t",          FPU_ARCH_VFP_V1},
13433   {"arm1020e",          FPU_ARCH_VFP_V2},
13434   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13435   {"maverick",          FPU_ARCH_MAVERICK},
13436   {NULL, 0}
13437 };
13438
13439 struct arm_float_abi_option_table
13440 {
13441   char *name;
13442   int value;
13443 };
13444
13445 static struct arm_float_abi_option_table arm_float_abis[] =
13446 {
13447   {"hard",      ARM_FLOAT_ABI_HARD},
13448   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13449   {"soft",      ARM_FLOAT_ABI_SOFT},
13450   {NULL, 0}
13451 };
13452
13453 struct arm_long_option_table
13454 {
13455   char *option;         /* Substring to match.  */
13456   char *help;           /* Help information.  */
13457   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
13458   char *deprecated;     /* If non-null, print this message.  */
13459 };
13460
13461 static int
13462 arm_parse_extension (str, opt_p)
13463      char *str;
13464      int *opt_p;
13465 {
13466   while (str != NULL && *str != 0)
13467     {
13468       struct arm_arch_extension_table *opt;
13469       char *ext;
13470       int optlen;
13471
13472       if (*str != '+')
13473         {
13474           as_bad (_("invalid architectural extension"));
13475           return 0;
13476         }
13477
13478       str++;
13479       ext = strchr (str, '+');
13480
13481       if (ext != NULL)
13482         optlen = ext - str;
13483       else
13484         optlen = strlen (str);
13485
13486       if (optlen == 0)
13487         {
13488           as_bad (_("missing architectural extension"));
13489           return 0;
13490         }
13491
13492       for (opt = arm_extensions; opt->name != NULL; opt++)
13493         if (strncmp (opt->name, str, optlen) == 0)
13494           {
13495             *opt_p |= opt->value;
13496             break;
13497           }
13498
13499       if (opt->name == NULL)
13500         {
13501           as_bad (_("unknown architectural extnsion `%s'"), str);
13502           return 0;
13503         }
13504
13505       str = ext;
13506     };
13507
13508   return 1;
13509 }
13510
13511 static int
13512 arm_parse_cpu (str)
13513      char *str;
13514 {
13515   struct arm_cpu_option_table *opt;
13516   char *ext = strchr (str, '+');
13517   int optlen;
13518
13519   if (ext != NULL)
13520     optlen = ext - str;
13521   else
13522     optlen = strlen (str);
13523
13524   if (optlen == 0)
13525     {
13526       as_bad (_("missing cpu name `%s'"), str);
13527       return 0;
13528     }
13529
13530   for (opt = arm_cpus; opt->name != NULL; opt++)
13531     if (strncmp (opt->name, str, optlen) == 0)
13532       {
13533         mcpu_cpu_opt = opt->value;
13534         mcpu_fpu_opt = opt->default_fpu;
13535
13536         if (ext != NULL)
13537           return arm_parse_extension (ext, &mcpu_cpu_opt);
13538
13539         return 1;
13540       }
13541
13542   as_bad (_("unknown cpu `%s'"), str);
13543   return 0;
13544 }
13545
13546 static int
13547 arm_parse_arch (str)
13548      char *str;
13549 {
13550   struct arm_arch_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 architecture name `%s'"), str);
13562       return 0;
13563     }
13564
13565
13566   for (opt = arm_archs; opt->name != NULL; opt++)
13567     if (strcmp (opt->name, str) == 0)
13568       {
13569         march_cpu_opt = opt->value;
13570         march_fpu_opt = opt->default_fpu;
13571
13572         if (ext != NULL)
13573           return arm_parse_extension (ext, &march_cpu_opt);
13574
13575         return 1;
13576       }
13577
13578   as_bad (_("unknown architecture `%s'\n"), str);
13579   return 0;
13580 }
13581
13582 static int
13583 arm_parse_fpu (str)
13584      char *str;
13585 {
13586   struct arm_fpu_option_table *opt;
13587
13588   for (opt = arm_fpus; opt->name != NULL; opt++)
13589     if (strcmp (opt->name, str) == 0)
13590       {
13591         mfpu_opt = opt->value;
13592         return 1;
13593       }
13594
13595   as_bad (_("unknown floating point format `%s'\n"), str);
13596   return 0;
13597 }
13598
13599 static int
13600 arm_parse_float_abi (str)
13601      char * str;
13602 {
13603   struct arm_float_abi_option_table *opt;
13604
13605   for (opt = arm_float_abis; opt->name != NULL; opt++)
13606     if (strcmp (opt->name, str) == 0)
13607       {
13608         mfloat_abi_opt = opt->value;
13609         return 1;
13610       }
13611
13612   as_bad (_("unknown floating point abi `%s'\n"), str);
13613   return 0;
13614 }
13615
13616 struct arm_long_option_table arm_long_opts[] =
13617 {
13618   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13619    arm_parse_cpu, NULL},
13620   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13621    arm_parse_arch, NULL},
13622   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13623    arm_parse_fpu, NULL},
13624   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13625    arm_parse_float_abi, NULL},
13626   {NULL, NULL, 0, NULL}
13627 };
13628
13629 int
13630 md_parse_option (c, arg)
13631      int    c;
13632      char * arg;
13633 {
13634   struct arm_option_table *opt;
13635   struct arm_long_option_table *lopt;
13636
13637   switch (c)
13638     {
13639 #ifdef OPTION_EB
13640     case OPTION_EB:
13641       target_big_endian = 1;
13642       break;
13643 #endif
13644
13645 #ifdef OPTION_EL
13646     case OPTION_EL:
13647       target_big_endian = 0;
13648       break;
13649 #endif
13650
13651     case 'a':
13652       /* Listing option.  Just ignore these, we don't support additional
13653          ones.  */
13654       return 0;
13655
13656     default:
13657       for (opt = arm_opts; opt->option != NULL; opt++)
13658         {
13659           if (c == opt->option[0]
13660               && ((arg == NULL && opt->option[1] == 0)
13661                   || strcmp (arg, opt->option + 1) == 0))
13662             {
13663 #if WARN_DEPRECATED
13664               /* If the option is deprecated, tell the user.  */
13665               if (opt->deprecated != NULL)
13666                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13667                            arg ? arg : "", _(opt->deprecated));
13668 #endif
13669
13670               if (opt->var != NULL)
13671                 *opt->var = opt->value;
13672
13673               return 1;
13674             }
13675         }
13676
13677       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13678         {
13679           /* These options are expected to have an argument.  */
13680           if (c == lopt->option[0]
13681               && arg != NULL
13682               && strncmp (arg, lopt->option + 1,
13683                           strlen (lopt->option + 1)) == 0)
13684             {
13685 #if WARN_DEPRECATED
13686               /* If the option is deprecated, tell the user.  */
13687               if (lopt->deprecated != NULL)
13688                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13689                            _(lopt->deprecated));
13690 #endif
13691
13692               /* Call the sup-option parser.  */
13693               return (*lopt->func)(arg + strlen (lopt->option) - 1);
13694             }
13695         }
13696
13697       as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13698       return 0;
13699     }
13700
13701   return 1;
13702 }
13703
13704 void
13705 md_show_usage (fp)
13706      FILE * fp;
13707 {
13708   struct arm_option_table *opt;
13709   struct arm_long_option_table *lopt;
13710
13711   fprintf (fp, _(" ARM-specific assembler options:\n"));
13712
13713   for (opt = arm_opts; opt->option != NULL; opt++)
13714     if (opt->help != NULL)
13715       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13716
13717   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13718     if (lopt->help != NULL)
13719       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13720
13721 #ifdef OPTION_EB
13722   fprintf (fp, _("\
13723   -EB                     assemble code for a big-endian cpu\n"));
13724 #endif
13725
13726 #ifdef OPTION_EL
13727   fprintf (fp, _("\
13728   -EL                     assemble code for a little-endian cpu\n"));
13729 #endif
13730 }
13731
13732 /* We need to be able to fix up arbitrary expressions in some statements.
13733    This is so that we can handle symbols that are an arbitrary distance from
13734    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13735    which returns part of an address in a form which will be valid for
13736    a data instruction.  We do this by pushing the expression into a symbol
13737    in the expr_section, and creating a fix for that.  */
13738
13739 static void
13740 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13741      fragS *       frag;
13742      int           where;
13743      short int     size;
13744      expressionS * exp;
13745      int           pc_rel;
13746      int           reloc;
13747 {
13748   fixS *           new_fix;
13749   arm_fix_data *   arm_data;
13750
13751   switch (exp->X_op)
13752     {
13753     case O_constant:
13754     case O_symbol:
13755     case O_add:
13756     case O_subtract:
13757       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13758       break;
13759
13760     default:
13761       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13762                          pc_rel, reloc);
13763       break;
13764     }
13765
13766   /* Mark whether the fix is to a THUMB instruction, or an ARM
13767      instruction.  */
13768   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13769   new_fix->tc_fix_data = (PTR) arm_data;
13770   arm_data->thumb_mode = thumb_mode;
13771 }
13772
13773 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13774
13775 void
13776 cons_fix_new_arm (frag, where, size, exp)
13777      fragS *       frag;
13778      int           where;
13779      int           size;
13780      expressionS * exp;
13781 {
13782   bfd_reloc_code_real_type type;
13783   int pcrel = 0;
13784
13785   /* Pick a reloc.
13786      FIXME: @@ Should look at CPU word size.  */
13787   switch (size)
13788     {
13789     case 1:
13790       type = BFD_RELOC_8;
13791       break;
13792     case 2:
13793       type = BFD_RELOC_16;
13794       break;
13795     case 4:
13796     default:
13797       type = BFD_RELOC_32;
13798       break;
13799     case 8:
13800       type = BFD_RELOC_64;
13801       break;
13802     }
13803
13804   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13805 }
13806
13807 /* A good place to do this, although this was probably not intended
13808    for this kind of use.  We need to dump the literal pool before
13809    references are made to a null symbol pointer.  */
13810
13811 void
13812 arm_cleanup ()
13813 {
13814   literal_pool * pool;
13815
13816   for (pool = list_of_pools; pool; pool = pool->next)
13817     {
13818       /* Put it at the end of the relevent section.  */
13819       subseg_set (pool->section, pool->sub_section);
13820       s_ltorg (0);
13821     }
13822 }
13823
13824 void
13825 arm_start_line_hook ()
13826 {
13827   last_label_seen = NULL;
13828 }
13829
13830 void
13831 arm_frob_label (sym)
13832      symbolS * sym;
13833 {
13834   last_label_seen = sym;
13835
13836   ARM_SET_THUMB (sym, thumb_mode);
13837
13838 #if defined OBJ_COFF || defined OBJ_ELF
13839   ARM_SET_INTERWORK (sym, support_interwork);
13840 #endif
13841
13842   /* Note - do not allow local symbols (.Lxxx) to be labeled
13843      as Thumb functions.  This is because these labels, whilst
13844      they exist inside Thumb code, are not the entry points for
13845      possible ARM->Thumb calls.  Also, these labels can be used
13846      as part of a computed goto or switch statement.  eg gcc
13847      can generate code that looks like this:
13848
13849                 ldr  r2, [pc, .Laaa]
13850                 lsl  r3, r3, #2
13851                 ldr  r2, [r3, r2]
13852                 mov  pc, r2
13853
13854        .Lbbb:  .word .Lxxx
13855        .Lccc:  .word .Lyyy
13856        ..etc...
13857        .Laaa:   .word Lbbb
13858
13859      The first instruction loads the address of the jump table.
13860      The second instruction converts a table index into a byte offset.
13861      The third instruction gets the jump address out of the table.
13862      The fourth instruction performs the jump.
13863
13864      If the address stored at .Laaa is that of a symbol which has the
13865      Thumb_Func bit set, then the linker will arrange for this address
13866      to have the bottom bit set, which in turn would mean that the
13867      address computation performed by the third instruction would end
13868      up with the bottom bit set.  Since the ARM is capable of unaligned
13869      word loads, the instruction would then load the incorrect address
13870      out of the jump table, and chaos would ensue.  */
13871   if (label_is_thumb_function_name
13872       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13873       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13874     {
13875       /* When the address of a Thumb function is taken the bottom
13876          bit of that address should be set.  This will allow
13877          interworking between Arm and Thumb functions to work
13878          correctly.  */
13879
13880       THUMB_SET_FUNC (sym, 1);
13881
13882       label_is_thumb_function_name = FALSE;
13883     }
13884 }
13885
13886 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13887    ARM ones.  */
13888
13889 void
13890 arm_adjust_symtab ()
13891 {
13892 #ifdef OBJ_COFF
13893   symbolS * sym;
13894
13895   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13896     {
13897       if (ARM_IS_THUMB (sym))
13898         {
13899           if (THUMB_IS_FUNC (sym))
13900             {
13901               /* Mark the symbol as a Thumb function.  */
13902               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13903                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13904                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13905
13906               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13907                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13908               else
13909                 as_bad (_("%s: unexpected function type: %d"),
13910                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13911             }
13912           else switch (S_GET_STORAGE_CLASS (sym))
13913             {
13914             case C_EXT:
13915               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13916               break;
13917             case C_STAT:
13918               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13919               break;
13920             case C_LABEL:
13921               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13922               break;
13923             default:
13924               /* Do nothing.  */
13925               break;
13926             }
13927         }
13928
13929       if (ARM_IS_INTERWORK (sym))
13930         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13931     }
13932 #endif
13933 #ifdef OBJ_ELF
13934   symbolS * sym;
13935   char      bind;
13936
13937   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13938     {
13939       if (ARM_IS_THUMB (sym))
13940         {
13941           elf_symbol_type * elf_sym;
13942
13943           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13944           bind = ELF_ST_BIND (elf_sym);
13945
13946           /* If it's a .thumb_func, declare it as so,
13947              otherwise tag label as .code 16.  */
13948           if (THUMB_IS_FUNC (sym))
13949             elf_sym->internal_elf_sym.st_info =
13950               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13951           else
13952             elf_sym->internal_elf_sym.st_info =
13953               ELF_ST_INFO (bind, STT_ARM_16BIT);
13954         }
13955     }
13956 #endif
13957 }
13958
13959 int
13960 arm_data_in_code ()
13961 {
13962   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13963     {
13964       *input_line_pointer = '/';
13965       input_line_pointer += 5;
13966       *input_line_pointer = 0;
13967       return 1;
13968     }
13969
13970   return 0;
13971 }
13972
13973 char *
13974 arm_canonicalize_symbol_name (name)
13975      char * name;
13976 {
13977   int len;
13978
13979   if (thumb_mode && (len = strlen (name)) > 5
13980       && streq (name + len - 5, "/data"))
13981     *(name + len - 5) = 0;
13982
13983   return name;
13984 }
13985
13986 #if defined OBJ_COFF || defined OBJ_ELF
13987 void
13988 arm_validate_fix (fixP)
13989      fixS * fixP;
13990 {
13991   /* If the destination of the branch is a defined symbol which does not have
13992      the THUMB_FUNC attribute, then we must be calling a function which has
13993      the (interfacearm) attribute.  We look for the Thumb entry point to that
13994      function and change the branch to refer to that function instead.  */
13995   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13996       && fixP->fx_addsy != NULL
13997       && S_IS_DEFINED (fixP->fx_addsy)
13998       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13999     {
14000       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
14001     }
14002 }
14003 #endif
14004
14005 int
14006 arm_force_relocation (fixp)
14007      struct fix * fixp;
14008 {
14009 #if defined (OBJ_COFF) && defined (TE_PE)
14010   if (fixp->fx_r_type == BFD_RELOC_RVA)
14011     return 1;
14012 #endif
14013 #ifdef OBJ_ELF
14014   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14015       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14016       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14017       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14018     return 1;
14019 #endif
14020
14021   /* Resolve these relocations even if the symbol is extern or weak.  */
14022   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14023       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14024       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14025     return 0;
14026
14027   return generic_force_reloc (fixp);
14028 }
14029
14030 #ifdef OBJ_COFF
14031 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
14032    local labels from being added to the output symbol table when they
14033    are used with the ADRL pseudo op.  The ADRL relocation should always
14034    be resolved before the binbary is emitted, so it is safe to say that
14035    it is adjustable.  */
14036
14037 bfd_boolean
14038 arm_fix_adjustable (fixP)
14039    fixS * fixP;
14040 {
14041   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14042     return 1;
14043   return 0;
14044 }
14045 #endif
14046
14047 #ifdef OBJ_ELF
14048 /* Relocations against Thumb function names must be left unadjusted,
14049    so that the linker can use this information to correctly set the
14050    bottom bit of their addresses.  The MIPS version of this function
14051    also prevents relocations that are mips-16 specific, but I do not
14052    know why it does this.
14053
14054    FIXME:
14055    There is one other problem that ought to be addressed here, but
14056    which currently is not:  Taking the address of a label (rather
14057    than a function) and then later jumping to that address.  Such
14058    addresses also ought to have their bottom bit set (assuming that
14059    they reside in Thumb code), but at the moment they will not.  */
14060
14061 bfd_boolean
14062 arm_fix_adjustable (fixP)
14063    fixS * fixP;
14064 {
14065   if (fixP->fx_addsy == NULL)
14066     return 1;
14067
14068   if (THUMB_IS_FUNC (fixP->fx_addsy)
14069       && fixP->fx_subsy == NULL)
14070     return 0;
14071
14072   /* We need the symbol name for the VTABLE entries.  */
14073   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14074       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14075     return 0;
14076
14077   /* Don't allow symbols to be discarded on GOT related relocs.  */
14078   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14079       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14080       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14081     return 0;
14082
14083   return 1;
14084 }
14085
14086 const char *
14087 elf32_arm_target_format ()
14088 {
14089   if (target_big_endian)
14090     {
14091       if (target_oabi)
14092         return "elf32-bigarm-oabi";
14093       else
14094         return "elf32-bigarm";
14095     }
14096   else
14097     {
14098       if (target_oabi)
14099         return "elf32-littlearm-oabi";
14100       else
14101         return "elf32-littlearm";
14102     }
14103 }
14104
14105 void
14106 armelf_frob_symbol (symp, puntp)
14107      symbolS * symp;
14108      int *     puntp;
14109 {
14110   elf_frob_symbol (symp, puntp);
14111 }
14112
14113 static bfd_reloc_code_real_type
14114 arm_parse_reloc ()
14115 {
14116   char         id [16];
14117   char *       ip;
14118   unsigned int i;
14119   static struct
14120   {
14121     char * str;
14122     int    len;
14123     bfd_reloc_code_real_type reloc;
14124   }
14125   reloc_map[] =
14126   {
14127 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14128     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14129     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14130     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14131        branch instructions generated by GCC for PLT relocs.  */
14132     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14133     { NULL, 0,         BFD_RELOC_UNUSED }
14134 #undef MAP
14135   };
14136
14137   for (i = 0, ip = input_line_pointer;
14138        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14139        i++, ip++)
14140     id[i] = TOLOWER (*ip);
14141
14142   for (i = 0; reloc_map[i].str; i++)
14143     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14144       break;
14145
14146   input_line_pointer += reloc_map[i].len;
14147
14148   return reloc_map[i].reloc;
14149 }
14150
14151 static void
14152 s_arm_elf_cons (nbytes)
14153      int nbytes;
14154 {
14155   expressionS exp;
14156
14157 #ifdef md_flush_pending_output
14158   md_flush_pending_output ();
14159 #endif
14160
14161   if (is_it_end_of_statement ())
14162     {
14163       demand_empty_rest_of_line ();
14164       return;
14165     }
14166
14167 #ifdef md_cons_align
14168   md_cons_align (nbytes);
14169 #endif
14170
14171   mapping_state (MAP_DATA);
14172   do
14173     {
14174       bfd_reloc_code_real_type reloc;
14175
14176       expression (& exp);
14177
14178       if (exp.X_op == O_symbol
14179           && * input_line_pointer == '('
14180           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14181         {
14182           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14183           int size = bfd_get_reloc_size (howto);
14184
14185           if (size > nbytes)
14186             as_bad ("%s relocations do not fit in %d bytes",
14187                     howto->name, nbytes);
14188           else
14189             {
14190               register char *p = frag_more ((int) nbytes);
14191               int offset = nbytes - size;
14192
14193               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14194                            &exp, 0, reloc);
14195             }
14196         }
14197       else
14198         emit_expr (&exp, (unsigned int) nbytes);
14199     }
14200   while (*input_line_pointer++ == ',');
14201
14202   /* Put terminator back into stream.  */
14203   input_line_pointer --;
14204   demand_empty_rest_of_line ();
14205 }
14206
14207 #endif /* OBJ_ELF */
14208
14209 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14210    of an rs_align_code fragment.  */
14211
14212 void
14213 arm_handle_align (fragP)
14214      fragS *fragP;
14215 {
14216   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14217   static char const thumb_noop[2] = { 0xc0, 0x46 };
14218   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14219   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14220
14221   int bytes, fix, noop_size;
14222   char * p;
14223   const char * noop;
14224
14225   if (fragP->fr_type != rs_align_code)
14226     return;
14227
14228   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14229   p = fragP->fr_literal + fragP->fr_fix;
14230   fix = 0;
14231
14232   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14233     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14234
14235   if (fragP->tc_frag_data)
14236     {
14237       if (target_big_endian)
14238         noop = thumb_bigend_noop;
14239       else
14240         noop = thumb_noop;
14241       noop_size = sizeof (thumb_noop);
14242     }
14243   else
14244     {
14245       if (target_big_endian)
14246         noop = arm_bigend_noop;
14247       else
14248         noop = arm_noop;
14249       noop_size = sizeof (arm_noop);
14250     }
14251
14252   if (bytes & (noop_size - 1))
14253     {
14254       fix = bytes & (noop_size - 1);
14255       memset (p, 0, fix);
14256       p += fix;
14257       bytes -= fix;
14258     }
14259
14260   while (bytes >= noop_size)
14261     {
14262       memcpy (p, noop, noop_size);
14263       p += noop_size;
14264       bytes -= noop_size;
14265       fix += noop_size;
14266     }
14267
14268   fragP->fr_fix += fix;
14269   fragP->fr_var = noop_size;
14270 }
14271
14272 /* Called from md_do_align.  Used to create an alignment
14273    frag in a code section.  */
14274
14275 void
14276 arm_frag_align_code (n, max)
14277      int n;
14278      int max;
14279 {
14280   char * p;
14281
14282   /* We assume that there will never be a requirement
14283      to support alignments greater than 32 bytes.  */
14284   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14285     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14286
14287   p = frag_var (rs_align_code,
14288                 MAX_MEM_FOR_RS_ALIGN_CODE,
14289                 1,
14290                 (relax_substateT) max,
14291                 (symbolS *) NULL,
14292                 (offsetT) n,
14293                 (char *) NULL);
14294   *p = 0;
14295
14296 }
14297
14298 /* Perform target specific initialisation of a frag.  */
14299
14300 void
14301 arm_init_frag (fragP)
14302      fragS *fragP;
14303 {
14304   /* Record whether this frag is in an ARM or a THUMB area.  */
14305   fragP->tc_frag_data = thumb_mode;
14306 }