* tc.h (struct relax_type, relax_typeS): Move from here..
[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    2004, 2005
4    Free Software Foundation, Inc.
5    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
6         Modified by David Taylor (dtaylor@armltd.co.uk)
7         Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
8         Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
9         Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
10
11    This file is part of GAS, the GNU Assembler.
12
13    GAS is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2, or (at your option)
16    any later version.
17
18    GAS is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with GAS; see the file COPYING.  If not, write to the Free
25    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26    02111-1307, USA.  */
27
28 #include <string.h>
29 #define  NO_RELOC 0
30 #include "as.h"
31 #include "safe-ctype.h"
32
33 /* Need TARGET_CPU.  */
34 #include "config.h"
35 #include "subsegs.h"
36 #include "obstack.h"
37 #include "symbols.h"
38 #include "listing.h"
39
40 #include "opcode/arm.h"
41
42 #ifdef OBJ_ELF
43 #include "elf/arm.h"
44 #include "dwarf2dbg.h"
45 #include "dw2gencfi.h"
46 #endif
47
48 /* XXX Set this to 1 after the next binutils release.  */
49 #define WARN_DEPRECATED 0
50
51 #ifdef OBJ_ELF
52 /* Must be at least the size of the largest unwind opcode (currently two).  */
53 #define ARM_OPCODE_CHUNK_SIZE 8
54
55 /* This structure holds the unwinding state.  */
56
57 static struct
58 {
59   symbolS *       proc_start;
60   symbolS *       table_entry;
61   symbolS *       personality_routine;
62   int             personality_index;
63   /* The segment containing the function.  */
64   segT            saved_seg;
65   subsegT         saved_subseg;
66   /* Opcodes generated from this function.  */
67   unsigned char * opcodes;
68   int             opcode_count;
69   int             opcode_alloc;
70   /* The number of bytes pushed to the stack.  */
71   offsetT         frame_size;
72   /* We don't add stack adjustment opcodes immediately so that we can merge
73      multiple adjustments.  We can also omit the final adjustment
74      when using a frame pointer.  */
75   offsetT         pending_offset;
76   /* These two fields are set by both unwind_movsp and unwind_setfp.  They
77      hold the reg+offset to use when restoring sp from a frame pointer.  */
78   offsetT         fp_offset;
79   int             fp_reg;
80   /* Nonzero if an unwind_setfp directive has been seen.  */
81   unsigned        fp_used:1;
82   /* Nonzero if the last opcode restores sp from fp_reg.  */
83   unsigned        sp_restored:1;
84 } unwind;
85
86 #endif /* OBJ_ELF */
87
88 enum arm_float_abi
89 {
90   ARM_FLOAT_ABI_HARD,
91   ARM_FLOAT_ABI_SOFTFP,
92   ARM_FLOAT_ABI_SOFT
93 };
94
95 /* Types of processor to assemble for.  */
96 #define ARM_1           ARM_ARCH_V1
97 #define ARM_2           ARM_ARCH_V2
98 #define ARM_3           ARM_ARCH_V2S
99 #define ARM_250         ARM_ARCH_V2S
100 #define ARM_6           ARM_ARCH_V3
101 #define ARM_7           ARM_ARCH_V3
102 #define ARM_8           ARM_ARCH_V4
103 #define ARM_9           ARM_ARCH_V4T
104 #define ARM_STRONG      ARM_ARCH_V4
105 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
106
107 #ifndef CPU_DEFAULT
108 #if defined __XSCALE__
109 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
110 #else
111 #if defined __thumb__
112 #define CPU_DEFAULT     (ARM_ARCH_V5T)
113 #else
114 #define CPU_DEFAULT     ARM_ANY
115 #endif
116 #endif
117 #endif
118
119 #ifndef FPU_DEFAULT
120 # ifdef TE_LINUX
121 #  define FPU_DEFAULT FPU_ARCH_FPA
122 # elif defined (TE_NetBSD)
123 #  ifdef OBJ_ELF
124 #   define FPU_DEFAULT FPU_ARCH_VFP     /* Soft-float, but VFP order.  */
125 #  else
126     /* Legacy a.out format.  */
127 #   define FPU_DEFAULT FPU_ARCH_FPA     /* Soft-float, but FPA order.  */
128 #  endif
129 # elif defined (TE_VXWORKS)
130 #  define FPU_DEFAULT FPU_ARCH_VFP      /* Soft-float, VFP order.  */
131 # else
132    /* For backwards compatibility, default to FPA.  */
133 #  define FPU_DEFAULT FPU_ARCH_FPA
134 # endif
135 #endif /* ifndef FPU_DEFAULT */
136
137 #define streq(a, b)           (strcmp (a, b) == 0)
138 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
139
140 static unsigned long cpu_variant;
141
142 /* Flags stored in private area of BFD structure.  */
143 static int uses_apcs_26      = FALSE;
144 static int atpcs             = FALSE;
145 static int support_interwork = FALSE;
146 static int uses_apcs_float   = FALSE;
147 static int pic_code          = FALSE;
148
149 /* Variables that we set while parsing command-line options.  Once all
150    options have been read we re-process these values to set the real
151    assembly flags.  */
152 static int legacy_cpu = -1;
153 static int legacy_fpu = -1;
154
155 static int mcpu_cpu_opt = -1;
156 static int mcpu_fpu_opt = -1;
157 static int march_cpu_opt = -1;
158 static int march_fpu_opt = -1;
159 static int mfpu_opt = -1;
160 static int mfloat_abi_opt = -1;
161 #ifdef OBJ_ELF
162 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
163 #endif
164
165 /* This array holds the chars that always start a comment.  If the
166    pre-processor is disabled, these aren't very useful.  */
167 const char comment_chars[] = "@";
168
169 /* This array holds the chars that only start a comment at the beginning of
170    a line.  If the line seems to have the form '# 123 filename'
171    .line and .file directives will appear in the pre-processed output.  */
172 /* Note that input_file.c hand checks for '#' at the beginning of the
173    first line of the input file.  This is because the compiler outputs
174    #NO_APP at the beginning of its output.  */
175 /* Also note that comments like this one will always work.  */
176 const char line_comment_chars[] = "#";
177
178 const char line_separator_chars[] = ";";
179
180 /* Chars that can be used to separate mant
181    from exp in floating point numbers.  */
182 const char EXP_CHARS[] = "eE";
183
184 /* Chars that mean this number is a floating point constant.  */
185 /* As in 0f12.456  */
186 /* or    0d1.2345e12  */
187
188 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
189
190 /* Prefix characters that indicate the start of an immediate
191    value.  */
192 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
193
194 #ifdef OBJ_ELF
195 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
196 symbolS * GOT_symbol;
197 #endif
198
199 /* Size of relocation record.  */
200 const int md_reloc_size = 8;
201
202 /* 0: assemble for ARM,
203    1: assemble for Thumb,
204    2: assemble for Thumb even though target CPU does not support thumb
205       instructions.  */
206 static int thumb_mode = 0;
207
208 typedef struct arm_fix
209 {
210   int thumb_mode;
211 } arm_fix_data;
212
213 struct arm_it
214 {
215   const char *  error;
216   unsigned long instruction;
217   int           size;
218   struct
219   {
220     bfd_reloc_code_real_type type;
221     expressionS              exp;
222     int                      pc_rel;
223   } reloc;
224 };
225
226 struct arm_it inst;
227
228 enum asm_shift_index
229 {
230   SHIFT_LSL = 0,
231   SHIFT_LSR,
232   SHIFT_ASR,
233   SHIFT_ROR,
234   SHIFT_RRX
235 };
236
237 struct asm_shift_properties
238 {
239   enum asm_shift_index index;
240   unsigned long        bit_field;
241   unsigned int         allows_0  : 1;
242   unsigned int         allows_32 : 1;
243 };
244
245 static const struct asm_shift_properties shift_properties [] =
246 {
247   { SHIFT_LSL, 0,    1, 0},
248   { SHIFT_LSR, 0x20, 0, 1},
249   { SHIFT_ASR, 0x40, 0, 1},
250   { SHIFT_ROR, 0x60, 0, 0},
251   { SHIFT_RRX, 0x60, 0, 0}
252 };
253
254 struct asm_shift_name
255 {
256   const char *                        name;
257   const struct asm_shift_properties * properties;
258 };
259
260 static const struct asm_shift_name shift_names [] =
261 {
262   { "asl", shift_properties + SHIFT_LSL },
263   { "lsl", shift_properties + SHIFT_LSL },
264   { "lsr", shift_properties + SHIFT_LSR },
265   { "asr", shift_properties + SHIFT_ASR },
266   { "ror", shift_properties + SHIFT_ROR },
267   { "rrx", shift_properties + SHIFT_RRX },
268   { "ASL", shift_properties + SHIFT_LSL },
269   { "LSL", shift_properties + SHIFT_LSL },
270   { "LSR", shift_properties + SHIFT_LSR },
271   { "ASR", shift_properties + SHIFT_ASR },
272   { "ROR", shift_properties + SHIFT_ROR },
273   { "RRX", shift_properties + SHIFT_RRX }
274 };
275
276 /* Any kind of shift is accepted.  */
277 #define NO_SHIFT_RESTRICT 1
278 /* The shift operand must be an immediate value, not a register.  */
279 #define SHIFT_IMMEDIATE   0
280 /* The shift must be LSL or ASR and the operand must be an immediate.  */
281 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
282 /* The shift must be ASR and the operand must be an immediate.  */
283 #define SHIFT_ASR_IMMEDIATE 3
284 /* The shift must be LSL and the operand must be an immediate.  */
285 #define SHIFT_LSL_IMMEDIATE 4
286
287 #define NUM_FLOAT_VALS 8
288
289 const char * fp_const[] =
290 {
291   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
292 };
293
294 /* Number of littlenums required to hold an extended precision number.  */
295 #define MAX_LITTLENUMS 6
296
297 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
298
299 #define FAIL    (-1)
300 #define SUCCESS (0)
301
302 /* Whether a Co-processor load/store operation accepts write-back forms.  */
303 #define CP_WB_OK 1
304 #define CP_NO_WB 0
305
306 #define SUFF_S 1
307 #define SUFF_D 2
308 #define SUFF_E 3
309 #define SUFF_P 4
310
311 #define CP_T_X   0x00008000
312 #define CP_T_Y   0x00400000
313 #define CP_T_Pre 0x01000000
314 #define CP_T_UD  0x00800000
315 #define CP_T_WB  0x00200000
316
317 #define CONDS_BIT        0x00100000
318 #define LOAD_BIT         0x00100000
319
320 #define DOUBLE_LOAD_FLAG 0x00000001
321
322 struct asm_cond
323 {
324   const char *  template;
325   unsigned long value;
326 };
327
328 #define COND_ALWAYS 0xe0000000
329 #define COND_MASK   0xf0000000
330
331 static const struct asm_cond conds[] =
332 {
333   {"eq", 0x00000000},
334   {"ne", 0x10000000},
335   {"cs", 0x20000000}, {"hs", 0x20000000},
336   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
337   {"mi", 0x40000000},
338   {"pl", 0x50000000},
339   {"vs", 0x60000000},
340   {"vc", 0x70000000},
341   {"hi", 0x80000000},
342   {"ls", 0x90000000},
343   {"ge", 0xa0000000},
344   {"lt", 0xb0000000},
345   {"gt", 0xc0000000},
346   {"le", 0xd0000000},
347   {"al", 0xe0000000},
348   {"nv", 0xf0000000}
349 };
350
351 struct asm_psr
352 {
353   const char *template;
354   bfd_boolean cpsr;
355   unsigned long field;
356 };
357
358 /* The bit that distinguishes CPSR and SPSR.  */
359 #define SPSR_BIT   (1 << 22)
360
361 /* How many bits to shift the PSR_xxx bits up by.  */
362 #define PSR_SHIFT  16
363
364 #define PSR_c   (1 << 0)
365 #define PSR_x   (1 << 1)
366 #define PSR_s   (1 << 2)
367 #define PSR_f   (1 << 3)
368
369 static const struct asm_psr psrs[] =
370 {
371   {"CPSR",      TRUE,  PSR_c | PSR_f},
372   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
373   {"SPSR",      FALSE, PSR_c | PSR_f},
374   {"SPSR_all",  FALSE, PSR_c | PSR_f},
375   {"CPSR_flg",  TRUE,  PSR_f},
376   {"CPSR_f",    TRUE,  PSR_f},
377   {"SPSR_flg",  FALSE, PSR_f},
378   {"SPSR_f",    FALSE, PSR_f},
379   {"CPSR_c",    TRUE,  PSR_c},
380   {"CPSR_ctl",  TRUE,  PSR_c},
381   {"SPSR_c",    FALSE, PSR_c},
382   {"SPSR_ctl",  FALSE, PSR_c},
383   {"CPSR_x",    TRUE,  PSR_x},
384   {"CPSR_s",    TRUE,  PSR_s},
385   {"SPSR_x",    FALSE, PSR_x},
386   {"SPSR_s",    FALSE, PSR_s},
387   /* Combinations of flags.  */
388   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
389   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
390   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
391   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
392   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
393   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
394   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
395   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
396   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
397   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
398   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
399   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
400   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
401   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
402   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
403   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
404   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
405   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
406   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
407   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
408   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
409   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
410   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
411   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
412   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
413   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
414   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
415   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
416   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
417   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
418   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
419   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
420   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
421   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
422   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
423   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
424   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
425   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
426   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
427   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
428   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
429   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
430   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
431   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
432   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
433   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
434   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
435   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
436   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
437   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
438   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
439   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
440   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
441   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
442   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
443   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
444   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
445   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
446   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
447   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
448   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
449   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
450   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
451   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
452   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
453   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
454   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
455   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
456   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
457   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
458   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
459   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
460   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
461   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
462   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
463   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
464   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
465   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
466   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
467   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
468   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
469   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
470   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
471   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
472   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
473   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
474   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
475   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
476   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
477   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
478   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
479   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
480   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
481   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
482   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
483   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
484   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
485   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
486   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
487   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
488   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
489   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
490   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
491   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
492   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
493   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
494   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
495   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
496   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
497   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
498   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
499   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
500   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
501   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
502   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
503   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
504   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
505   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
506   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
507   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
508 };
509
510 enum wreg_type
511   {
512     IWMMXT_REG_WR = 0,
513     IWMMXT_REG_WC = 1,
514     IWMMXT_REG_WR_OR_WC = 2,
515     IWMMXT_REG_WCG
516   };
517
518 enum iwmmxt_insn_type
519 {
520   check_rd,
521   check_wr,
522   check_wrwr,
523   check_wrwrwr,
524   check_wrwrwcg,
525   check_tbcst,
526   check_tmovmsk,
527   check_tmia,
528   check_tmcrr,
529   check_tmrrc,
530   check_tmcr,
531   check_tmrc,
532   check_tinsr,
533   check_textrc,
534   check_waligni,
535   check_textrm,
536   check_wshufh
537 };
538
539 enum vfp_dp_reg_pos
540 {
541   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
542 };
543
544 enum vfp_sp_reg_pos
545 {
546   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
547 };
548
549 enum vfp_ldstm_type
550 {
551   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
552 };
553
554 /* VFP system registers.  */
555 struct vfp_reg
556 {
557   const char *name;
558   unsigned long regno;
559 };
560
561 static const struct vfp_reg vfp_regs[] =
562 {
563   {"fpsid", 0x00000000},
564   {"FPSID", 0x00000000},
565   {"fpscr", 0x00010000},
566   {"FPSCR", 0x00010000},
567   {"fpexc", 0x00080000},
568   {"FPEXC", 0x00080000}
569 };
570
571 /* Structure for a hash table entry for a register.  */
572 struct reg_entry
573 {
574   const char * name;
575   int          number;
576   bfd_boolean  builtin;
577 };
578
579 /* Some well known registers that we refer to directly elsewhere.  */
580 #define REG_SP  13
581 #define REG_LR  14
582 #define REG_PC  15
583
584 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
585 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
586 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
587
588 /* These are the standard names.  Users can add aliases with .req.
589    and delete them with .unreq.  */
590
591 /* Integer Register Numbers.  */
592 static const struct reg_entry rn_table[] =
593 {
594   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
595   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
596   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
597   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
598   /* ATPCS Synonyms.  */
599   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
600   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
601   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
602   /* Well-known aliases.  */
603   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
604   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
605   {NULL, 0, TRUE}
606 };
607
608 #define WR_PREFIX 0x200
609 #define WC_PREFIX 0x400
610
611 static const struct reg_entry iwmmxt_table[] =
612 {
613   /* Intel Wireless MMX technology register names.  */
614   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
615   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
616   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
617   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
618   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
619   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
620   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
621   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
622   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
623   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
624   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
625   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
626
627   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
628   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
629   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
630   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
631   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
632   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
633   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
634   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
635   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
636   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
637   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
638   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
639   {NULL, 0, TRUE}
640 };
641
642 /* Co-processor Numbers.  */
643 static const struct reg_entry cp_table[] =
644 {
645   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
646   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
647   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
648   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
649   {NULL, 0, TRUE}
650 };
651
652 /* Co-processor Register Numbers.  */
653 static const struct reg_entry cn_table[] =
654 {
655   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
656   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
657   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
658   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
659   /* Not really valid, but kept for back-wards compatibility.  */
660   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
661   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
662   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
663   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
664   {NULL, 0, TRUE}
665 };
666
667 /* FPA Registers.  */
668 static const struct reg_entry fn_table[] =
669 {
670   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
671   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
672   {NULL, 0, TRUE}
673 };
674
675 /* VFP SP Registers.  */
676 static const struct reg_entry sn_table[] =
677 {
678   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
679   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
680   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
681   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
682   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
683   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
684   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
685   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
686   {NULL, 0, TRUE}
687 };
688
689 /* VFP DP Registers.  */
690 static const struct reg_entry dn_table[] =
691 {
692   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
693   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
694   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
695   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
696   {NULL, 0, TRUE}
697 };
698
699 /* Maverick DSP coprocessor registers.  */
700 static const struct reg_entry mav_mvf_table[] =
701 {
702   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
703   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
704   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
705   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
706   {NULL, 0, TRUE}
707 };
708
709 static const struct reg_entry mav_mvd_table[] =
710 {
711   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
712   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
713   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
714   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
715   {NULL, 0, TRUE}
716 };
717
718 static const struct reg_entry mav_mvfx_table[] =
719 {
720   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
721   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
722   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
723   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
724   {NULL, 0, TRUE}
725 };
726
727 static const struct reg_entry mav_mvdx_table[] =
728 {
729   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
730   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
731   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
732   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
733   {NULL, 0, TRUE}
734 };
735
736 static const struct reg_entry mav_mvax_table[] =
737 {
738   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
739   {NULL, 0, TRUE}
740 };
741
742 static const struct reg_entry mav_dspsc_table[] =
743 {
744   {"dspsc", 0, TRUE},
745   {NULL, 0, TRUE}
746 };
747
748 struct reg_map
749 {
750   const struct reg_entry * names;
751   int                      max_regno;
752   struct hash_control *    htab;
753   const char *             expected;
754 };
755
756 struct reg_map all_reg_maps[] =
757 {
758   {rn_table,        15, NULL, N_("ARM register expected")},
759   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
760   {cn_table,        15, NULL, N_("co-processor register expected")},
761   {fn_table,         7, NULL, N_("FPA register expected")},
762   {sn_table,        31, NULL, N_("VFP single precision register expected")},
763   {dn_table,        15, NULL, N_("VFP double precision register expected")},
764   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
765   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
766   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
767   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
768   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
769   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
770   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
771 };
772
773 /* Enumeration matching entries in table above.  */
774 enum arm_reg_type
775 {
776   REG_TYPE_RN = 0,
777 #define REG_TYPE_FIRST REG_TYPE_RN
778   REG_TYPE_CP = 1,
779   REG_TYPE_CN = 2,
780   REG_TYPE_FN = 3,
781   REG_TYPE_SN = 4,
782   REG_TYPE_DN = 5,
783   REG_TYPE_MVF = 6,
784   REG_TYPE_MVD = 7,
785   REG_TYPE_MVFX = 8,
786   REG_TYPE_MVDX = 9,
787   REG_TYPE_MVAX = 10,
788   REG_TYPE_DSPSC = 11,
789   REG_TYPE_IWMMXT = 12,
790
791   REG_TYPE_MAX = 13
792 };
793
794 /* ARM instructions take 4bytes in the object file, Thumb instructions
795    take 2:  */
796 #define INSN_SIZE       4
797
798 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
799 #define MAV_MODE1       0x100c
800
801 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
802 #define MAV_MODE2       0x0c10
803
804 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
805 #define MAV_MODE3       0x100c
806
807 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
808 #define MAV_MODE4       0x0c0010
809
810 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
811 #define MAV_MODE5       0x00100c
812
813 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
814 #define MAV_MODE6       0x00100c05
815
816 struct asm_opcode
817 {
818   /* Basic string to match.  */
819   const char * template;
820
821   /* Basic instruction code.  */
822   unsigned long value;
823
824   /* Offset into the template where the condition code (if any) will be.
825      If zero, then the instruction is never conditional.  */
826   unsigned cond_offset;
827
828   /* Which architecture variant provides this instruction.  */
829   unsigned long variant;
830
831   /* Function to call to parse args.  */
832   void (* parms) (char *);
833 };
834
835 /* Defines for various bits that we will want to toggle.  */
836 #define INST_IMMEDIATE  0x02000000
837 #define OFFSET_REG      0x02000000
838 #define HWOFFSET_IMM    0x00400000
839 #define SHIFT_BY_REG    0x00000010
840 #define PRE_INDEX       0x01000000
841 #define INDEX_UP        0x00800000
842 #define WRITE_BACK      0x00200000
843 #define LDM_TYPE_2_OR_3 0x00400000
844
845 #define LITERAL_MASK    0xf000f000
846 #define OPCODE_MASK     0xfe1fffff
847 #define V4_STR_BIT      0x00000020
848
849 #define DATA_OP_SHIFT   21
850
851 /* Codes to distinguish the arithmetic instructions.  */
852 #define OPCODE_AND      0
853 #define OPCODE_EOR      1
854 #define OPCODE_SUB      2
855 #define OPCODE_RSB      3
856 #define OPCODE_ADD      4
857 #define OPCODE_ADC      5
858 #define OPCODE_SBC      6
859 #define OPCODE_RSC      7
860 #define OPCODE_TST      8
861 #define OPCODE_TEQ      9
862 #define OPCODE_CMP      10
863 #define OPCODE_CMN      11
864 #define OPCODE_ORR      12
865 #define OPCODE_MOV      13
866 #define OPCODE_BIC      14
867 #define OPCODE_MVN      15
868
869 #define T_OPCODE_MUL 0x4340
870 #define T_OPCODE_TST 0x4200
871 #define T_OPCODE_CMN 0x42c0
872 #define T_OPCODE_NEG 0x4240
873 #define T_OPCODE_MVN 0x43c0
874
875 #define T_OPCODE_ADD_R3 0x1800
876 #define T_OPCODE_SUB_R3 0x1a00
877 #define T_OPCODE_ADD_HI 0x4400
878 #define T_OPCODE_ADD_ST 0xb000
879 #define T_OPCODE_SUB_ST 0xb080
880 #define T_OPCODE_ADD_SP 0xa800
881 #define T_OPCODE_ADD_PC 0xa000
882 #define T_OPCODE_ADD_I8 0x3000
883 #define T_OPCODE_SUB_I8 0x3800
884 #define T_OPCODE_ADD_I3 0x1c00
885 #define T_OPCODE_SUB_I3 0x1e00
886
887 #define T_OPCODE_ASR_R  0x4100
888 #define T_OPCODE_LSL_R  0x4080
889 #define T_OPCODE_LSR_R  0x40c0
890 #define T_OPCODE_ASR_I  0x1000
891 #define T_OPCODE_LSL_I  0x0000
892 #define T_OPCODE_LSR_I  0x0800
893
894 #define T_OPCODE_MOV_I8 0x2000
895 #define T_OPCODE_CMP_I8 0x2800
896 #define T_OPCODE_CMP_LR 0x4280
897 #define T_OPCODE_MOV_HR 0x4600
898 #define T_OPCODE_CMP_HR 0x4500
899
900 #define T_OPCODE_LDR_PC 0x4800
901 #define T_OPCODE_LDR_SP 0x9800
902 #define T_OPCODE_STR_SP 0x9000
903 #define T_OPCODE_LDR_IW 0x6800
904 #define T_OPCODE_STR_IW 0x6000
905 #define T_OPCODE_LDR_IH 0x8800
906 #define T_OPCODE_STR_IH 0x8000
907 #define T_OPCODE_LDR_IB 0x7800
908 #define T_OPCODE_STR_IB 0x7000
909 #define T_OPCODE_LDR_RW 0x5800
910 #define T_OPCODE_STR_RW 0x5000
911 #define T_OPCODE_LDR_RH 0x5a00
912 #define T_OPCODE_STR_RH 0x5200
913 #define T_OPCODE_LDR_RB 0x5c00
914 #define T_OPCODE_STR_RB 0x5400
915
916 #define T_OPCODE_PUSH   0xb400
917 #define T_OPCODE_POP    0xbc00
918
919 #define T_OPCODE_BRANCH 0xe7fe
920
921 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
922 #define THUMB_REG_LO    0x1
923 #define THUMB_REG_HI    0x2
924 #define THUMB_REG_ANY   0x3
925
926 #define THUMB_H1        0x0080
927 #define THUMB_H2        0x0040
928
929 #define THUMB_ASR 0
930 #define THUMB_LSL 1
931 #define THUMB_LSR 2
932
933 #define THUMB_MOVE 0
934 #define THUMB_COMPARE 1
935 #define THUMB_CPY 2
936
937 #define THUMB_LOAD 0
938 #define THUMB_STORE 1
939
940 #define THUMB_PP_PC_LR 0x0100
941
942 /* These three are used for immediate shifts, do not alter.  */
943 #define THUMB_WORD 2
944 #define THUMB_HALFWORD 1
945 #define THUMB_BYTE 0
946
947 struct thumb_opcode
948 {
949   /* Basic string to match.  */
950   const char * template;
951
952   /* Basic instruction code.  */
953   unsigned long value;
954
955   int size;
956
957   /* Which CPU variants this exists for.  */
958   unsigned long variant;
959
960   /* Function to call to parse args.  */
961   void (* parms) (char *);
962 };
963
964 #define BAD_ARGS        _("bad arguments to instruction")
965 #define BAD_PC          _("r15 not allowed here")
966 #define BAD_COND        _("instruction is not conditional")
967 #define ERR_NO_ACCUM    _("acc0 expected")
968
969 static struct hash_control * arm_ops_hsh   = NULL;
970 static struct hash_control * arm_tops_hsh  = NULL;
971 static struct hash_control * arm_cond_hsh  = NULL;
972 static struct hash_control * arm_shift_hsh = NULL;
973 static struct hash_control * arm_psr_hsh   = NULL;
974
975 /* Stuff needed to resolve the label ambiguity
976    As:
977      ...
978      label:   <insn>
979    may differ from:
980      ...
981      label:
982               <insn>
983 */
984
985 symbolS *  last_label_seen;
986 static int label_is_thumb_function_name = FALSE;
987 \f
988 /* Literal Pool stuff.  */
989
990 #define MAX_LITERAL_POOL_SIZE 1024
991
992 /* Literal pool structure.  Held on a per-section
993    and per-sub-section basis.  */
994
995 typedef struct literal_pool
996 {
997   expressionS    literals [MAX_LITERAL_POOL_SIZE];
998   unsigned int   next_free_entry;
999   unsigned int   id;
1000   symbolS *      symbol;
1001   segT           section;
1002   subsegT        sub_section;
1003   struct literal_pool * next;
1004 } literal_pool;
1005
1006 /* Pointer to a linked list of literal pools.  */
1007 literal_pool * list_of_pools = NULL;
1008
1009 static literal_pool *
1010 find_literal_pool (void)
1011 {
1012   literal_pool * pool;
1013
1014   for (pool = list_of_pools; pool != NULL; pool = pool->next)
1015     {
1016       if (pool->section == now_seg
1017           && pool->sub_section == now_subseg)
1018         break;
1019     }
1020
1021   return pool;
1022 }
1023
1024 static literal_pool *
1025 find_or_make_literal_pool (void)
1026 {
1027   /* Next literal pool ID number.  */
1028   static unsigned int latest_pool_num = 1;
1029   literal_pool *      pool;
1030
1031   pool = find_literal_pool ();
1032
1033   if (pool == NULL)
1034     {
1035       /* Create a new pool.  */
1036       pool = xmalloc (sizeof (* pool));
1037       if (! pool)
1038         return NULL;
1039
1040       pool->next_free_entry = 0;
1041       pool->section         = now_seg;
1042       pool->sub_section     = now_subseg;
1043       pool->next            = list_of_pools;
1044       pool->symbol          = NULL;
1045
1046       /* Add it to the list.  */
1047       list_of_pools = pool;
1048     }
1049
1050   /* New pools, and emptied pools, will have a NULL symbol.  */
1051   if (pool->symbol == NULL)
1052     {
1053       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
1054                                     (valueT) 0, &zero_address_frag);
1055       pool->id = latest_pool_num ++;
1056     }
1057
1058   /* Done.  */
1059   return pool;
1060 }
1061
1062 /* Add the literal in the global 'inst'
1063    structure to the relevent literal pool.  */
1064
1065 static int
1066 add_to_lit_pool (void)
1067 {
1068   literal_pool * pool;
1069   unsigned int entry;
1070
1071   pool = find_or_make_literal_pool ();
1072
1073   /* Check if this literal value is already in the pool.  */
1074   for (entry = 0; entry < pool->next_free_entry; entry ++)
1075     {
1076       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1077           && (inst.reloc.exp.X_op == O_constant)
1078           && (pool->literals[entry].X_add_number
1079               == inst.reloc.exp.X_add_number)
1080           && (pool->literals[entry].X_unsigned
1081               == inst.reloc.exp.X_unsigned))
1082         break;
1083
1084       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1085           && (inst.reloc.exp.X_op == O_symbol)
1086           && (pool->literals[entry].X_add_number
1087               == inst.reloc.exp.X_add_number)
1088           && (pool->literals[entry].X_add_symbol
1089               == inst.reloc.exp.X_add_symbol)
1090           && (pool->literals[entry].X_op_symbol
1091               == inst.reloc.exp.X_op_symbol))
1092         break;
1093     }
1094
1095   /* Do we need to create a new entry?  */
1096   if (entry == pool->next_free_entry)
1097     {
1098       if (entry >= MAX_LITERAL_POOL_SIZE)
1099         {
1100           inst.error = _("literal pool overflow");
1101           return FAIL;
1102         }
1103
1104       pool->literals[entry] = inst.reloc.exp;
1105       pool->next_free_entry += 1;
1106     }
1107
1108   inst.reloc.exp.X_op         = O_symbol;
1109   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
1110   inst.reloc.exp.X_add_symbol = pool->symbol;
1111
1112   return SUCCESS;
1113 }
1114
1115 /* Can't use symbol_new here, so have to create a symbol and then at
1116    a later date assign it a value. Thats what these functions do.  */
1117
1118 static void
1119 symbol_locate (symbolS *    symbolP,
1120                const char * name,       /* It is copied, the caller can modify.  */
1121                segT         segment,    /* Segment identifier (SEG_<something>).  */
1122                valueT       valu,       /* Symbol value.  */
1123                fragS *      frag)       /* Associated fragment.  */
1124 {
1125   unsigned int name_length;
1126   char * preserved_copy_of_name;
1127
1128   name_length = strlen (name) + 1;   /* +1 for \0.  */
1129   obstack_grow (&notes, name, name_length);
1130   preserved_copy_of_name = obstack_finish (&notes);
1131 #ifdef STRIP_UNDERSCORE
1132   if (preserved_copy_of_name[0] == '_')
1133     preserved_copy_of_name++;
1134 #endif
1135
1136 #ifdef tc_canonicalize_symbol_name
1137   preserved_copy_of_name =
1138     tc_canonicalize_symbol_name (preserved_copy_of_name);
1139 #endif
1140
1141   S_SET_NAME (symbolP, preserved_copy_of_name);
1142
1143   S_SET_SEGMENT (symbolP, segment);
1144   S_SET_VALUE (symbolP, valu);
1145   symbol_clear_list_pointers (symbolP);
1146
1147   symbol_set_frag (symbolP, frag);
1148
1149   /* Link to end of symbol chain.  */
1150   {
1151     extern int symbol_table_frozen;
1152
1153     if (symbol_table_frozen)
1154       abort ();
1155   }
1156
1157   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1158
1159   obj_symbol_new_hook (symbolP);
1160
1161 #ifdef tc_symbol_new_hook
1162   tc_symbol_new_hook (symbolP);
1163 #endif
1164
1165 #ifdef DEBUG_SYMS
1166   verify_symbol_chain (symbol_rootP, symbol_lastP);
1167 #endif /* DEBUG_SYMS  */
1168 }
1169
1170 /* Check that an immediate is valid.
1171    If so, convert it to the right format.  */
1172
1173 static unsigned int
1174 validate_immediate (unsigned int val)
1175 {
1176   unsigned int a;
1177   unsigned int i;
1178
1179 #define rotate_left(v, n) (v << n | v >> (32 - n))
1180
1181   for (i = 0; i < 32; i += 2)
1182     if ((a = rotate_left (val, i)) <= 0xff)
1183       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
1184
1185   return FAIL;
1186 }
1187
1188 /* Check to see if an immediate can be computed as two separate immediate
1189    values, added together.  We already know that this value cannot be
1190    computed by just one ARM instruction.  */
1191
1192 static unsigned int
1193 validate_immediate_twopart (unsigned int   val,
1194                             unsigned int * highpart)
1195 {
1196   unsigned int a;
1197   unsigned int i;
1198
1199   for (i = 0; i < 32; i += 2)
1200     if (((a = rotate_left (val, i)) & 0xff) != 0)
1201       {
1202         if (a & 0xff00)
1203           {
1204             if (a & ~ 0xffff)
1205               continue;
1206             * highpart = (a  >> 8) | ((i + 24) << 7);
1207           }
1208         else if (a & 0xff0000)
1209           {
1210             if (a & 0xff000000)
1211               continue;
1212             * highpart = (a >> 16) | ((i + 16) << 7);
1213           }
1214         else
1215           {
1216             assert (a & 0xff000000);
1217             * highpart = (a >> 24) | ((i + 8) << 7);
1218           }
1219
1220         return (a & 0xff) | (i << 7);
1221       }
1222
1223   return FAIL;
1224 }
1225
1226 static int
1227 validate_offset_imm (unsigned int val, int hwse)
1228 {
1229   if ((hwse && val > 255) || val > 4095)
1230     return FAIL;
1231   return val;
1232 }
1233
1234 \f
1235 #ifdef OBJ_ELF
1236 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
1237    (This text is taken from version B-02 of the spec):
1238
1239       4.4.7 Mapping and tagging symbols
1240
1241       A section of an ARM ELF file can contain a mixture of ARM code,
1242       Thumb code, and data.  There are inline transitions between code
1243       and data at literal pool boundaries. There can also be inline
1244       transitions between ARM code and Thumb code, for example in
1245       ARM-Thumb inter-working veneers.  Linkers, machine-level
1246       debuggers, profiling tools, and disassembly tools need to map
1247       images accurately. For example, setting an ARM breakpoint on a
1248       Thumb location, or in a literal pool, can crash the program
1249       being debugged, ruining the debugging session.
1250
1251       ARM ELF entities are mapped (see section 4.4.7.1 below) and
1252       tagged (see section 4.4.7.2 below) using local symbols (with
1253       binding STB_LOCAL).  To assist consumers, mapping and tagging
1254       symbols should be collated first in the symbol table, before
1255       other symbols with binding STB_LOCAL.
1256
1257       To allow properly collated mapping and tagging symbols to be
1258       skipped by consumers that have no interest in them, the first
1259       such symbol should have the name $m and its st_value field equal
1260       to the total number of mapping and tagging symbols (including
1261       the $m) in the symbol table.
1262
1263       4.4.7.1 Mapping symbols
1264
1265       $a    Labels the first byte of a sequence of ARM instructions.
1266             Its type is STT_FUNC.
1267
1268       $d    Labels the first byte of a sequence of data items.
1269             Its type is STT_OBJECT.
1270
1271       $t    Labels the first byte of a sequence of Thumb instructions.
1272             Its type is STT_FUNC.
1273
1274       This list of mapping symbols may be extended in the future.
1275
1276       Section-relative mapping symbols
1277
1278       Mapping symbols defined in a section define a sequence of
1279       half-open address intervals that cover the address range of the
1280       section. Each interval starts at the address defined by a
1281       mapping symbol, and continues up to, but not including, the
1282       address defined by the next (in address order) mapping symbol or
1283       the end of the section. A corollary is that there must be a
1284       mapping symbol defined at the beginning of each section.
1285       Consumers can ignore the size of a section-relative mapping
1286       symbol. Producers can set it to 0.
1287
1288       Absolute mapping symbols
1289
1290       Because of the need to crystallize a Thumb address with the
1291       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
1292       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
1293       or $t.
1294
1295       The extent of a mapping symbol defined in SHN_ABS is [st_value,
1296       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
1297       where [x, y) denotes the half-open address range from x,
1298       inclusive, to y, exclusive.
1299
1300       In the absence of a mapping symbol, a consumer can interpret a
1301       function symbol with an odd value as the Thumb code address
1302       obtained by clearing the least significant bit of the
1303       value. This interpretation is deprecated, and it may not work in
1304       the future.
1305
1306    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
1307    the EABI (which is still under development), so they are not
1308    implemented here.  */
1309
1310 static enum mstate mapstate = MAP_UNDEFINED;
1311
1312 static void
1313 mapping_state (enum mstate state)
1314 {
1315   symbolS * symbolP;
1316   const char * symname;
1317   int type;
1318
1319   if (mapstate == state)
1320     /* The mapping symbol has already been emitted.
1321        There is nothing else to do.  */
1322     return;
1323
1324   mapstate = state;
1325
1326   switch (state)
1327     {
1328     case MAP_DATA:
1329       symname = "$d";
1330       type = BSF_OBJECT;
1331       break;
1332     case MAP_ARM:
1333       symname = "$a";
1334       type = BSF_FUNCTION;
1335       break;
1336     case MAP_THUMB:
1337       symname = "$t";
1338       type = BSF_FUNCTION;
1339       break;
1340     case MAP_UNDEFINED:
1341       return;
1342     default:
1343       abort ();
1344     }
1345
1346   seg_info (now_seg)->tc_segment_info_data = state;
1347
1348   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
1349   symbol_table_insert (symbolP);
1350   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1351
1352   switch (state)
1353     {
1354     case MAP_ARM:
1355       THUMB_SET_FUNC (symbolP, 0);
1356       ARM_SET_THUMB (symbolP, 0);
1357       ARM_SET_INTERWORK (symbolP, support_interwork);
1358       break;
1359
1360     case MAP_THUMB:
1361       THUMB_SET_FUNC (symbolP, 1);
1362       ARM_SET_THUMB (symbolP, 1);
1363       ARM_SET_INTERWORK (symbolP, support_interwork);
1364       break;
1365
1366     case MAP_DATA:
1367     default:
1368       return;
1369     }
1370 }
1371
1372 /* When we change sections we need to issue a new mapping symbol.  */
1373
1374 void
1375 arm_elf_change_section (void)
1376 {
1377   flagword flags;
1378
1379   /* Link an unlinked unwind index table section to the .text section.  */
1380   if (elf_section_type (now_seg) == SHT_ARM_EXIDX
1381       && elf_linked_to_section (now_seg) == NULL)
1382     elf_linked_to_section (now_seg) = text_section;
1383
1384   if (!SEG_NORMAL (now_seg))
1385     return;
1386
1387   flags = bfd_get_section_flags (stdoutput, now_seg);
1388
1389   /* We can ignore sections that only contain debug info.  */
1390   if ((flags & SEC_ALLOC) == 0)
1391     return;
1392
1393   mapstate = seg_info (now_seg)->tc_segment_info_data;
1394 }
1395
1396 int
1397 arm_elf_section_type (const char * str, size_t len)
1398 {
1399   if (len == 5 && strncmp (str, "exidx", 5) == 0)
1400     return SHT_ARM_EXIDX;
1401
1402   return -1;
1403 }
1404 #else
1405 #define mapping_state(a)
1406 #endif /* OBJ_ELF */
1407 \f
1408 /* arm_reg_parse () := if it looks like a register, return its token and
1409    advance the pointer.  */
1410
1411 static int
1412 arm_reg_parse (char ** ccp, struct hash_control * htab)
1413 {
1414   char * start = * ccp;
1415   char   c;
1416   char * p;
1417   struct reg_entry * reg;
1418
1419 #ifdef REGISTER_PREFIX
1420   if (*start != REGISTER_PREFIX)
1421     return FAIL;
1422   p = start + 1;
1423 #else
1424   p = start;
1425 #ifdef OPTIONAL_REGISTER_PREFIX
1426   if (*p == OPTIONAL_REGISTER_PREFIX)
1427     p++, start++;
1428 #endif
1429 #endif
1430   if (!ISALPHA (*p) || !is_name_beginner (*p))
1431     return FAIL;
1432
1433   c = *p++;
1434   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
1435     c = *p++;
1436
1437   *--p = 0;
1438   reg = (struct reg_entry *) hash_find (htab, start);
1439   *p = c;
1440
1441   if (reg)
1442     {
1443       *ccp = p;
1444       return reg->number;
1445     }
1446
1447   return FAIL;
1448 }
1449
1450 /* Search for the following register name in each of the possible reg name
1451    tables.  Return the classification if found, or REG_TYPE_MAX if not
1452    present.  */
1453
1454 static enum arm_reg_type
1455 arm_reg_parse_any (char *cp)
1456 {
1457   int i;
1458
1459   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
1460     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
1461       return (enum arm_reg_type) i;
1462
1463   return REG_TYPE_MAX;
1464 }
1465
1466 static void
1467 opcode_select (int width)
1468 {
1469   switch (width)
1470     {
1471     case 16:
1472       if (! thumb_mode)
1473         {
1474           if (! (cpu_variant & ARM_EXT_V4T))
1475             as_bad (_("selected processor does not support THUMB opcodes"));
1476
1477           thumb_mode = 1;
1478           /* No need to force the alignment, since we will have been
1479              coming from ARM mode, which is word-aligned.  */
1480           record_alignment (now_seg, 1);
1481         }
1482       mapping_state (MAP_THUMB);
1483       break;
1484
1485     case 32:
1486       if (thumb_mode)
1487         {
1488           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
1489             as_bad (_("selected processor does not support ARM opcodes"));
1490
1491           thumb_mode = 0;
1492
1493           if (!need_pass_2)
1494             frag_align (2, 0, 0);
1495
1496           record_alignment (now_seg, 1);
1497         }
1498       mapping_state (MAP_ARM);
1499       break;
1500
1501     default:
1502       as_bad (_("invalid instruction size selected (%d)"), width);
1503     }
1504 }
1505
1506 static void
1507 s_req (int a ATTRIBUTE_UNUSED)
1508 {
1509   as_bad (_("invalid syntax for .req directive"));
1510 }
1511
1512 /* The .unreq directive deletes an alias which was previously defined
1513    by .req.  For example:
1514
1515        my_alias .req r11
1516        .unreq my_alias    */
1517
1518 static void
1519 s_unreq (int a ATTRIBUTE_UNUSED)
1520 {
1521   char * name;
1522   char saved_char;
1523
1524   skip_whitespace (input_line_pointer);
1525   name = input_line_pointer;
1526
1527   while (*input_line_pointer != 0
1528          && *input_line_pointer != ' '
1529          && *input_line_pointer != '\n')
1530     ++input_line_pointer;
1531
1532   saved_char = *input_line_pointer;
1533   *input_line_pointer = 0;
1534
1535   if (*name)
1536     {
1537       enum arm_reg_type req_type = arm_reg_parse_any (name);
1538
1539       if (req_type != REG_TYPE_MAX)
1540         {
1541           char *temp_name = name;
1542           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
1543
1544           if (req_no != FAIL)
1545             {
1546               struct reg_entry *req_entry;
1547
1548               /* Check to see if this alias is a builtin one.  */
1549               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
1550
1551               if (!req_entry)
1552                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
1553               else if (req_entry->builtin)
1554                 /* FIXME: We are deleting a built in register alias which
1555                    points to a const data structure, so we only need to
1556                    free up the memory used by the key in the hash table.
1557                    Unfortunately we have not recorded this value, so this
1558                    is a memory leak.  */
1559                   /* FIXME: Should we issue a warning message ?  */
1560                 ;
1561               else
1562                 {
1563                   /* Deleting a user defined alias.  We need to free the
1564                      key and the value, but fortunately the key is the same
1565                      as the value->name field.  */
1566                   free ((char *) req_entry->name);
1567                   free (req_entry);
1568                 }
1569             }
1570           else
1571             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1572         }
1573       else
1574         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1575     }
1576   else
1577     as_bad (_("invalid syntax for .unreq directive"));
1578
1579   *input_line_pointer = saved_char;
1580   demand_empty_rest_of_line ();
1581 }
1582
1583 static void
1584 s_bss (int ignore ATTRIBUTE_UNUSED)
1585 {
1586   /* We don't support putting frags in the BSS segment, we fake it by
1587      marking in_bss, then looking at s_skip for clues.  */
1588   subseg_set (bss_section, 0);
1589   demand_empty_rest_of_line ();
1590   mapping_state (MAP_DATA);
1591 }
1592
1593 static void
1594 s_even (int ignore ATTRIBUTE_UNUSED)
1595 {
1596   /* Never make frag if expect extra pass.  */
1597   if (!need_pass_2)
1598     frag_align (1, 0, 0);
1599
1600   record_alignment (now_seg, 1);
1601
1602   demand_empty_rest_of_line ();
1603 }
1604
1605 static void
1606 s_ltorg (int ignored ATTRIBUTE_UNUSED)
1607 {
1608   unsigned int entry;
1609   literal_pool * pool;
1610   char sym_name[20];
1611
1612   pool = find_literal_pool ();
1613   if (pool == NULL
1614       || pool->symbol == NULL
1615       || pool->next_free_entry == 0)
1616     return;
1617
1618   mapping_state (MAP_DATA);
1619
1620   /* Align pool as you have word accesses.
1621      Only make a frag if we have to.  */
1622   if (!need_pass_2)
1623     frag_align (2, 0, 0);
1624
1625   record_alignment (now_seg, 2);
1626
1627   sprintf (sym_name, "$$lit_\002%x", pool->id);
1628
1629   symbol_locate (pool->symbol, sym_name, now_seg,
1630                  (valueT) frag_now_fix (), frag_now);
1631   symbol_table_insert (pool->symbol);
1632
1633   ARM_SET_THUMB (pool->symbol, thumb_mode);
1634
1635 #if defined OBJ_COFF || defined OBJ_ELF
1636   ARM_SET_INTERWORK (pool->symbol, support_interwork);
1637 #endif
1638
1639   for (entry = 0; entry < pool->next_free_entry; entry ++)
1640     /* First output the expression in the instruction to the pool.  */
1641     emit_expr (&(pool->literals[entry]), 4); /* .word  */
1642
1643   /* Mark the pool as empty.  */
1644   pool->next_free_entry = 0;
1645   pool->symbol = NULL;
1646 }
1647
1648 /* Same as s_align_ptwo but align 0 => align 2.  */
1649
1650 static void
1651 s_align (int unused ATTRIBUTE_UNUSED)
1652 {
1653   int temp;
1654   long temp_fill;
1655   long max_alignment = 15;
1656
1657   temp = get_absolute_expression ();
1658   if (temp > max_alignment)
1659     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
1660   else if (temp < 0)
1661     {
1662       as_bad (_("alignment negative. 0 assumed."));
1663       temp = 0;
1664     }
1665
1666   if (*input_line_pointer == ',')
1667     {
1668       input_line_pointer++;
1669       temp_fill = get_absolute_expression ();
1670     }
1671   else
1672     temp_fill = 0;
1673
1674   if (!temp)
1675     temp = 2;
1676
1677   /* Only make a frag if we HAVE to.  */
1678   if (temp && !need_pass_2)
1679     frag_align (temp, (int) temp_fill, 0);
1680   demand_empty_rest_of_line ();
1681
1682   record_alignment (now_seg, temp);
1683 }
1684
1685 static void
1686 s_force_thumb (int ignore ATTRIBUTE_UNUSED)
1687 {
1688   /* If we are not already in thumb mode go into it, EVEN if
1689      the target processor does not support thumb instructions.
1690      This is used by gcc/config/arm/lib1funcs.asm for example
1691      to compile interworking support functions even if the
1692      target processor should not support interworking.  */
1693   if (! thumb_mode)
1694     {
1695       thumb_mode = 2;
1696
1697       record_alignment (now_seg, 1);
1698     }
1699
1700   demand_empty_rest_of_line ();
1701 }
1702
1703 static void
1704 s_thumb_func (int ignore ATTRIBUTE_UNUSED)
1705 {
1706   if (! thumb_mode)
1707     opcode_select (16);
1708
1709   /* The following label is the name/address of the start of a Thumb function.
1710      We need to know this for the interworking support.  */
1711   label_is_thumb_function_name = TRUE;
1712
1713   demand_empty_rest_of_line ();
1714 }
1715
1716 /* Perform a .set directive, but also mark the alias as
1717    being a thumb function.  */
1718
1719 static void
1720 s_thumb_set (int equiv)
1721 {
1722   /* XXX the following is a duplicate of the code for s_set() in read.c
1723      We cannot just call that code as we need to get at the symbol that
1724      is created.  */
1725   char *    name;
1726   char      delim;
1727   char *    end_name;
1728   symbolS * symbolP;
1729
1730   /* Especial apologies for the random logic:
1731      This just grew, and could be parsed much more simply!
1732      Dean - in haste.  */
1733   name      = input_line_pointer;
1734   delim     = get_symbol_end ();
1735   end_name  = input_line_pointer;
1736   *end_name = delim;
1737
1738   SKIP_WHITESPACE ();
1739
1740   if (*input_line_pointer != ',')
1741     {
1742       *end_name = 0;
1743       as_bad (_("expected comma after name \"%s\""), name);
1744       *end_name = delim;
1745       ignore_rest_of_line ();
1746       return;
1747     }
1748
1749   input_line_pointer++;
1750   *end_name = 0;
1751
1752   if (name[0] == '.' && name[1] == '\0')
1753     {
1754       /* XXX - this should not happen to .thumb_set.  */
1755       abort ();
1756     }
1757
1758   if ((symbolP = symbol_find (name)) == NULL
1759       && (symbolP = md_undefined_symbol (name)) == NULL)
1760     {
1761 #ifndef NO_LISTING
1762       /* When doing symbol listings, play games with dummy fragments living
1763          outside the normal fragment chain to record the file and line info
1764          for this symbol.  */
1765       if (listing & LISTING_SYMBOLS)
1766         {
1767           extern struct list_info_struct * listing_tail;
1768           fragS * dummy_frag = xmalloc (sizeof (fragS));
1769
1770           memset (dummy_frag, 0, sizeof (fragS));
1771           dummy_frag->fr_type = rs_fill;
1772           dummy_frag->line = listing_tail;
1773           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1774           dummy_frag->fr_symbol = symbolP;
1775         }
1776       else
1777 #endif
1778         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1779
1780 #ifdef OBJ_COFF
1781       /* "set" symbols are local unless otherwise specified.  */
1782       SF_SET_LOCAL (symbolP);
1783 #endif /* OBJ_COFF  */
1784     }                           /* Make a new symbol.  */
1785
1786   symbol_table_insert (symbolP);
1787
1788   * end_name = delim;
1789
1790   if (equiv
1791       && S_IS_DEFINED (symbolP)
1792       && S_GET_SEGMENT (symbolP) != reg_section)
1793     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1794
1795   pseudo_set (symbolP);
1796
1797   demand_empty_rest_of_line ();
1798
1799   /* XXX Now we come to the Thumb specific bit of code.  */
1800
1801   THUMB_SET_FUNC (symbolP, 1);
1802   ARM_SET_THUMB (symbolP, 1);
1803 #if defined OBJ_ELF || defined OBJ_COFF
1804   ARM_SET_INTERWORK (symbolP, support_interwork);
1805 #endif
1806 }
1807
1808 static void
1809 s_arm (int ignore ATTRIBUTE_UNUSED)
1810 {
1811   opcode_select (32);
1812   demand_empty_rest_of_line ();
1813 }
1814
1815 static void
1816 s_thumb (int ignore ATTRIBUTE_UNUSED)
1817 {
1818   opcode_select (16);
1819   demand_empty_rest_of_line ();
1820 }
1821
1822 static void
1823 s_code (int unused ATTRIBUTE_UNUSED)
1824 {
1825   int temp;
1826
1827   temp = get_absolute_expression ();
1828   switch (temp)
1829     {
1830     case 16:
1831     case 32:
1832       opcode_select (temp);
1833       break;
1834
1835     default:
1836       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1837     }
1838 }
1839
1840 static void
1841 end_of_line (char * str)
1842 {
1843   skip_whitespace (str);
1844
1845   if (*str != '\0' && !inst.error)
1846     inst.error = _("garbage following instruction");
1847 }
1848
1849 static int
1850 skip_past_comma (char ** str)
1851 {
1852   char * p = * str, c;
1853   int comma = 0;
1854
1855   while ((c = *p) == ' ' || c == ',')
1856     {
1857       p++;
1858       if (c == ',' && comma++)
1859         return FAIL;
1860     }
1861
1862   if (c == '\0')
1863     return FAIL;
1864
1865   *str = p;
1866   return comma ? SUCCESS : FAIL;
1867 }
1868
1869 /* Return TRUE if anything in the expression is a bignum.  */
1870
1871 static int
1872 walk_no_bignums (symbolS * sp)
1873 {
1874   if (symbol_get_value_expression (sp)->X_op == O_big)
1875     return 1;
1876
1877   if (symbol_get_value_expression (sp)->X_add_symbol)
1878     {
1879       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1880               || (symbol_get_value_expression (sp)->X_op_symbol
1881                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
1882     }
1883
1884   return 0;
1885 }
1886
1887 static int in_my_get_expression = 0;
1888
1889 static int
1890 my_get_expression (expressionS * ep, char ** str)
1891 {
1892   char * save_in;
1893   segT   seg;
1894
1895   save_in = input_line_pointer;
1896   input_line_pointer = *str;
1897   in_my_get_expression = 1;
1898   seg = expression (ep);
1899   in_my_get_expression = 0;
1900
1901   if (ep->X_op == O_illegal)
1902     {
1903       /* We found a bad expression in md_operand().  */
1904       *str = input_line_pointer;
1905       input_line_pointer = save_in;
1906       return 1;
1907     }
1908
1909 #ifdef OBJ_AOUT
1910   if (seg != absolute_section
1911       && seg != text_section
1912       && seg != data_section
1913       && seg != bss_section
1914       && seg != undefined_section)
1915     {
1916       inst.error = _("bad_segment");
1917       *str = input_line_pointer;
1918       input_line_pointer = save_in;
1919       return 1;
1920     }
1921 #endif
1922
1923   /* Get rid of any bignums now, so that we don't generate an error for which
1924      we can't establish a line number later on.  Big numbers are never valid
1925      in instructions, which is where this routine is always called.  */
1926   if (ep->X_op == O_big
1927       || (ep->X_add_symbol
1928           && (walk_no_bignums (ep->X_add_symbol)
1929               || (ep->X_op_symbol
1930                   && walk_no_bignums (ep->X_op_symbol)))))
1931     {
1932       inst.error = _("invalid constant");
1933       *str = input_line_pointer;
1934       input_line_pointer = save_in;
1935       return 1;
1936     }
1937
1938   *str = input_line_pointer;
1939   input_line_pointer = save_in;
1940   return 0;
1941 }
1942
1943 /* A standard register must be given at this point.
1944    SHIFT is the place to put it in inst.instruction.
1945    Restores input start point on error.
1946    Returns the reg#, or FAIL.  */
1947
1948 static int
1949 reg_required_here (char ** str, int shift)
1950 {
1951   static char buff [128]; /* XXX  */
1952   int         reg;
1953   char *      start = * str;
1954
1955   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
1956     {
1957       if (shift >= 0)
1958         inst.instruction |= reg << shift;
1959       return reg;
1960     }
1961
1962   /* Restore the start point, we may have got a reg of the wrong class.  */
1963   *str = start;
1964
1965   /* In the few cases where we might be able to accept something else
1966      this error can be overridden.  */
1967   sprintf (buff, _("register expected, not '%.100s'"), start);
1968   inst.error = buff;
1969
1970   return FAIL;
1971 }
1972
1973 /* A Intel Wireless MMX technology register
1974    must be given at this point.
1975    Shift is the place to put it in inst.instruction.
1976    Restores input start point on err.
1977    Returns the reg#, or FAIL.  */
1978
1979 static int
1980 wreg_required_here (char ** str,
1981                     int shift,
1982                     enum wreg_type reg_type)
1983 {
1984   static char buff [128];
1985   int    reg;
1986   char * start = *str;
1987
1988   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
1989     {
1990       if (wr_register (reg)
1991           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
1992         {
1993           if (shift >= 0)
1994             inst.instruction |= (reg ^ WR_PREFIX) << shift;
1995           return reg;
1996         }
1997       else if (wc_register (reg)
1998                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
1999         {
2000           if (shift >= 0)
2001             inst.instruction |= (reg ^ WC_PREFIX) << shift;
2002           return reg;
2003         }
2004       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
2005         {
2006           if (shift >= 0)
2007             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
2008           return reg;
2009         }
2010     }
2011
2012   /* Restore the start point, we may have got a reg of the wrong class.  */
2013   *str = start;
2014
2015   /* In the few cases where we might be able to accept
2016      something else this error can be overridden.  */
2017   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
2018   inst.error = buff;
2019
2020   return FAIL;
2021 }
2022
2023 static const struct asm_psr *
2024 arm_psr_parse (char ** ccp)
2025 {
2026   char * start = * ccp;
2027   char   c;
2028   char * p;
2029   const struct asm_psr * psr;
2030
2031   p = start;
2032
2033   /* Skip to the end of the next word in the input stream.  */
2034   do
2035     {
2036       c = *p++;
2037     }
2038   while (ISALPHA (c) || c == '_');
2039
2040   /* Terminate the word.  */
2041   *--p = 0;
2042
2043   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
2044      feature for ease of use and backwards compatibility.  */
2045   if (!strncmp (start, "cpsr", 4))
2046     strncpy (start, "CPSR", 4);
2047   else if (!strncmp (start, "spsr", 4))
2048     strncpy (start, "SPSR", 4);
2049
2050   /* Now locate the word in the psr hash table.  */
2051   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2052
2053   /* Restore the input stream.  */
2054   *p = c;
2055
2056   /* If we found a valid match, advance the
2057      stream pointer past the end of the word.  */
2058   *ccp = p;
2059
2060   return psr;
2061 }
2062
2063 /* Parse the input looking for a PSR flag.  */
2064
2065 static int
2066 psr_required_here (char ** str)
2067 {
2068   char * start = * str;
2069   const struct asm_psr * psr;
2070
2071   psr = arm_psr_parse (str);
2072
2073   if (psr)
2074     {
2075       /* If this is the SPSR that is being modified, set the R bit.  */
2076       if (! psr->cpsr)
2077         inst.instruction |= SPSR_BIT;
2078
2079       /* Set the psr flags in the MSR instruction.  */
2080       inst.instruction |= psr->field << PSR_SHIFT;
2081
2082       return SUCCESS;
2083     }
2084
2085   /* In the few cases where we might be able to accept
2086      something else this error can be overridden.  */
2087   inst.error = _("flag for {c}psr instruction expected");
2088
2089   /* Restore the start point.  */
2090   *str = start;
2091   return FAIL;
2092 }
2093
2094 static int
2095 co_proc_number (char ** str)
2096 {
2097   int processor, pchar;
2098   char *start;
2099
2100   skip_whitespace (*str);
2101   start = *str;
2102
2103   /* The data sheet seems to imply that just a number on its own is valid
2104      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
2105      accept either.  */
2106   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2107       == FAIL)
2108     {
2109       *str = start;
2110
2111       pchar = *(*str)++;
2112       if (pchar >= '0' && pchar <= '9')
2113         {
2114           processor = pchar - '0';
2115           if (**str >= '0' && **str <= '9')
2116             {
2117               processor = processor * 10 + *(*str)++ - '0';
2118               if (processor > 15)
2119                 {
2120                   inst.error = _("illegal co-processor number");
2121                   return FAIL;
2122                 }
2123             }
2124         }
2125       else
2126         {
2127           inst.error = all_reg_maps[REG_TYPE_CP].expected;
2128           return FAIL;
2129         }
2130     }
2131
2132   inst.instruction |= processor << 8;
2133   return SUCCESS;
2134 }
2135
2136 static int
2137 cp_opc_expr (char ** str, int where, int length)
2138 {
2139   expressionS expr;
2140
2141   skip_whitespace (* str);
2142
2143   memset (&expr, '\0', sizeof (expr));
2144
2145   if (my_get_expression (&expr, str))
2146     return FAIL;
2147   if (expr.X_op != O_constant)
2148     {
2149       inst.error = _("bad or missing expression");
2150       return FAIL;
2151     }
2152
2153   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2154     {
2155       inst.error = _("immediate co-processor expression too large");
2156       return FAIL;
2157     }
2158
2159   inst.instruction |= expr.X_add_number << where;
2160   return SUCCESS;
2161 }
2162
2163 static int
2164 cp_reg_required_here (char ** str, int where)
2165 {
2166   int    reg;
2167   char * start = *str;
2168
2169   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2170     {
2171       inst.instruction |= reg << where;
2172       return reg;
2173     }
2174
2175   /* In the few cases where we might be able to accept something else
2176      this error can be overridden.  */
2177   inst.error = all_reg_maps[REG_TYPE_CN].expected;
2178
2179   /* Restore the start point.  */
2180   *str = start;
2181   return FAIL;
2182 }
2183
2184 static int
2185 fp_reg_required_here (char ** str, int where)
2186 {
2187   int    reg;
2188   char * start = * str;
2189
2190   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2191     {
2192       inst.instruction |= reg << where;
2193       return reg;
2194     }
2195
2196   /* In the few cases where we might be able to accept something else
2197      this error can be overridden.  */
2198   inst.error = all_reg_maps[REG_TYPE_FN].expected;
2199
2200   /* Restore the start point.  */
2201   *str = start;
2202   return FAIL;
2203 }
2204
2205 static int
2206 cp_address_offset (char ** str)
2207 {
2208   int offset;
2209
2210   skip_whitespace (* str);
2211
2212   if (! is_immediate_prefix (**str))
2213     {
2214       inst.error = _("immediate expression expected");
2215       return FAIL;
2216     }
2217
2218   (*str)++;
2219
2220   if (my_get_expression (& inst.reloc.exp, str))
2221     return FAIL;
2222
2223   if (inst.reloc.exp.X_op == O_constant)
2224     {
2225       offset = inst.reloc.exp.X_add_number;
2226
2227       if (offset & 3)
2228         {
2229           inst.error = _("co-processor address must be word aligned");
2230           return FAIL;
2231         }
2232
2233       if (offset > 1023 || offset < -1023)
2234         {
2235           inst.error = _("offset too large");
2236           return FAIL;
2237         }
2238
2239       if (offset >= 0)
2240         inst.instruction |= INDEX_UP;
2241       else
2242         offset = -offset;
2243
2244       inst.instruction |= offset >> 2;
2245     }
2246   else
2247     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2248
2249   return SUCCESS;
2250 }
2251
2252 static int
2253 cp_address_required_here (char ** str, int wb_ok)
2254 {
2255   char * p = * str;
2256   int    pre_inc = 0;
2257   int    write_back = 0;
2258
2259   if (*p == '[')
2260     {
2261       int reg;
2262
2263       p++;
2264       skip_whitespace (p);
2265
2266       if ((reg = reg_required_here (& p, 16)) == FAIL)
2267         return FAIL;
2268
2269       skip_whitespace (p);
2270
2271       if (*p == ']')
2272         {
2273           p++;
2274
2275           skip_whitespace (p);
2276
2277           if (*p == '\0')
2278             {
2279               /* As an extension to the official ARM syntax we allow:
2280                    [Rn]
2281                  as a short hand for:
2282                    [Rn,#0]  */
2283               inst.instruction |= PRE_INDEX | INDEX_UP;
2284               *str = p;
2285               return SUCCESS;
2286             }
2287
2288           if (skip_past_comma (& p) == FAIL)
2289             {
2290               inst.error = _("comma expected after closing square bracket");
2291               return FAIL;
2292             }
2293
2294           skip_whitespace (p);
2295
2296           if (*p == '#')
2297             {
2298               if (wb_ok)
2299                 {
2300                   /* [Rn], #expr  */
2301                   write_back = WRITE_BACK;
2302
2303                   if (reg == REG_PC)
2304                     {
2305                       inst.error = _("pc may not be used in post-increment");
2306                       return FAIL;
2307                     }
2308
2309                   if (cp_address_offset (& p) == FAIL)
2310                     return FAIL;
2311                 }
2312               else
2313                 pre_inc = PRE_INDEX | INDEX_UP;
2314             }
2315           else if (*p == '{')
2316             {
2317               int option;
2318
2319               /* [Rn], {<expr>}  */
2320               p++;
2321
2322               skip_whitespace (p);
2323
2324               if (my_get_expression (& inst.reloc.exp, & p))
2325                 return FAIL;
2326
2327               if (inst.reloc.exp.X_op == O_constant)
2328                 {
2329                   option = inst.reloc.exp.X_add_number;
2330
2331                   if (option > 255 || option < 0)
2332                     {
2333                       inst.error = _("'option' field too large");
2334                       return FAIL;
2335                     }
2336
2337                   skip_whitespace (p);
2338
2339                   if (*p != '}')
2340                     {
2341                       inst.error = _("'}' expected at end of 'option' field");
2342                       return FAIL;
2343                     }
2344                   else
2345                     {
2346                       p++;
2347                       inst.instruction |= option;
2348                       inst.instruction |= INDEX_UP;
2349                     }
2350                 }
2351               else
2352                 {
2353                   inst.error = _("non-constant expressions for 'option' field not supported");
2354                   return FAIL;
2355                 }
2356             }
2357           else
2358             {
2359               inst.error = _("# or { expected after comma");
2360               return FAIL;
2361             }
2362         }
2363       else
2364         {
2365           /* '['Rn, #expr']'[!]  */
2366
2367           if (skip_past_comma (& p) == FAIL)
2368             {
2369               inst.error = _("pre-indexed expression expected");
2370               return FAIL;
2371             }
2372
2373           pre_inc = PRE_INDEX;
2374
2375           if (cp_address_offset (& p) == FAIL)
2376             return FAIL;
2377
2378           skip_whitespace (p);
2379
2380           if (*p++ != ']')
2381             {
2382               inst.error = _("missing ]");
2383               return FAIL;
2384             }
2385
2386           skip_whitespace (p);
2387
2388           if (wb_ok && *p == '!')
2389             {
2390               if (reg == REG_PC)
2391                 {
2392                   inst.error = _("pc may not be used with write-back");
2393                   return FAIL;
2394                 }
2395
2396               p++;
2397               write_back = WRITE_BACK;
2398             }
2399         }
2400     }
2401   else
2402     {
2403       if (my_get_expression (&inst.reloc.exp, &p))
2404         return FAIL;
2405
2406       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2407       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2408       inst.reloc.pc_rel = 1;
2409       inst.instruction |= (REG_PC << 16);
2410       pre_inc = PRE_INDEX;
2411     }
2412
2413   inst.instruction |= write_back | pre_inc;
2414   *str = p;
2415   return SUCCESS;
2416 }
2417
2418 static int
2419 cp_byte_address_offset (char ** str)
2420 {
2421   int offset;
2422
2423   skip_whitespace (* str);
2424
2425   if (! is_immediate_prefix (**str))
2426     {
2427       inst.error = _("immediate expression expected");
2428       return FAIL;
2429     }
2430
2431   (*str)++;
2432
2433   if (my_get_expression (& inst.reloc.exp, str))
2434     return FAIL;
2435
2436   if (inst.reloc.exp.X_op == O_constant)
2437     {
2438       offset = inst.reloc.exp.X_add_number;
2439
2440       if (offset > 255 || offset < -255)
2441         {
2442           inst.error = _("offset too large");
2443           return FAIL;
2444         }
2445
2446       if (offset >= 0)
2447         inst.instruction |= INDEX_UP;
2448       else
2449         offset = -offset;
2450
2451       inst.instruction |= offset;
2452     }
2453   else
2454     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2455
2456   return SUCCESS;
2457 }
2458
2459 static int
2460 cp_byte_address_required_here (char ** str)
2461 {
2462   char * p = * str;
2463   int    pre_inc = 0;
2464   int    write_back = 0;
2465
2466   if (*p == '[')
2467     {
2468       int reg;
2469
2470       p++;
2471       skip_whitespace (p);
2472
2473       if ((reg = reg_required_here (& p, 16)) == FAIL)
2474         return FAIL;
2475
2476       skip_whitespace (p);
2477
2478       if (*p == ']')
2479         {
2480           p++;
2481
2482           if (skip_past_comma (& p) == SUCCESS)
2483             {
2484               /* [Rn], #expr */
2485               write_back = WRITE_BACK;
2486
2487               if (reg == REG_PC)
2488                 {
2489                   inst.error = _("pc may not be used in post-increment");
2490                   return FAIL;
2491                 }
2492
2493               if (cp_byte_address_offset (& p) == FAIL)
2494                 return FAIL;
2495             }
2496           else
2497             pre_inc = PRE_INDEX | INDEX_UP;
2498         }
2499       else
2500         {
2501           /* '['Rn, #expr']'[!] */
2502
2503           if (skip_past_comma (& p) == FAIL)
2504             {
2505               inst.error = _("pre-indexed expression expected");
2506               return FAIL;
2507             }
2508
2509           pre_inc = PRE_INDEX;
2510
2511           if (cp_byte_address_offset (& p) == FAIL)
2512             return FAIL;
2513
2514           skip_whitespace (p);
2515
2516           if (*p++ != ']')
2517             {
2518               inst.error = _("missing ]");
2519               return FAIL;
2520             }
2521
2522           skip_whitespace (p);
2523
2524           if (*p == '!')
2525             {
2526               if (reg == REG_PC)
2527                 {
2528                   inst.error = _("pc may not be used with write-back");
2529                   return FAIL;
2530                 }
2531
2532               p++;
2533               write_back = WRITE_BACK;
2534             }
2535         }
2536     }
2537   else
2538     {
2539       if (my_get_expression (&inst.reloc.exp, &p))
2540         return FAIL;
2541
2542       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2543       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2544       inst.reloc.pc_rel = 1;
2545       inst.instruction |= (REG_PC << 16);
2546       pre_inc = PRE_INDEX;
2547     }
2548
2549   inst.instruction |= write_back | pre_inc;
2550   *str = p;
2551   return SUCCESS;
2552 }
2553
2554 static void
2555 do_nop (char * str)
2556 {
2557   skip_whitespace (str);
2558   if (*str == '{')
2559     {
2560       str++;
2561
2562       if (my_get_expression (&inst.reloc.exp, &str))
2563         inst.reloc.exp.X_op = O_illegal;
2564       else
2565         {
2566           skip_whitespace (str);
2567           if (*str == '}')
2568             str++;
2569           else
2570             inst.reloc.exp.X_op = O_illegal;
2571         }
2572
2573       if (inst.reloc.exp.X_op != O_constant
2574           || inst.reloc.exp.X_add_number > 255
2575           || inst.reloc.exp.X_add_number < 0)
2576         {
2577           inst.error = _("Invalid NOP hint");
2578           return;
2579         }
2580
2581       /* Arcitectural NOP hints are CPSR sets with no bits selected.  */
2582       inst.instruction &= 0xf0000000;
2583       inst.instruction |= 0x0320f000 + inst.reloc.exp.X_add_number;
2584     }
2585
2586   end_of_line (str);
2587 }
2588
2589 static void
2590 do_empty (char * str)
2591 {
2592   /* Do nothing really.  */
2593   end_of_line (str);
2594 }
2595
2596 static void
2597 do_mrs (char * str)
2598 {
2599   int skip = 0;
2600
2601   /* Only one syntax.  */
2602   skip_whitespace (str);
2603
2604   if (reg_required_here (&str, 12) == FAIL)
2605     {
2606       inst.error = BAD_ARGS;
2607       return;
2608     }
2609
2610   if (skip_past_comma (&str) == FAIL)
2611     {
2612       inst.error = _("comma expected after register name");
2613       return;
2614     }
2615
2616   skip_whitespace (str);
2617
2618   if (   streq (str, "CPSR")
2619       || streq (str, "SPSR")
2620          /* Lower case versions for backwards compatibility.  */
2621       || streq (str, "cpsr")
2622       || streq (str, "spsr"))
2623     skip = 4;
2624
2625   /* This is for backwards compatibility with older toolchains.  */
2626   else if (   streq (str, "cpsr_all")
2627            || streq (str, "spsr_all"))
2628     skip = 8;
2629   else
2630     {
2631       inst.error = _("CPSR or SPSR expected");
2632       return;
2633     }
2634
2635   if (* str == 's' || * str == 'S')
2636     inst.instruction |= SPSR_BIT;
2637   str += skip;
2638
2639   end_of_line (str);
2640 }
2641
2642 /* Two possible forms:
2643       "{C|S}PSR_<field>, Rm",
2644       "{C|S}PSR_f, #expression".  */
2645
2646 static void
2647 do_msr (char * str)
2648 {
2649   skip_whitespace (str);
2650
2651   if (psr_required_here (& str) == FAIL)
2652     return;
2653
2654   if (skip_past_comma (& str) == FAIL)
2655     {
2656       inst.error = _("comma missing after psr flags");
2657       return;
2658     }
2659
2660   skip_whitespace (str);
2661
2662   if (reg_required_here (& str, 0) != FAIL)
2663     {
2664       inst.error = NULL;
2665       end_of_line (str);
2666       return;
2667     }
2668
2669   if (! is_immediate_prefix (* str))
2670     {
2671       inst.error =
2672         _("only a register or immediate value can follow a psr flag");
2673       return;
2674     }
2675
2676   str ++;
2677   inst.error = NULL;
2678
2679   if (my_get_expression (& inst.reloc.exp, & str))
2680     {
2681       inst.error =
2682         _("only a register or immediate value can follow a psr flag");
2683       return;
2684     }
2685
2686   inst.instruction |= INST_IMMEDIATE;
2687
2688   if (inst.reloc.exp.X_add_symbol)
2689     {
2690       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2691       inst.reloc.pc_rel = 0;
2692     }
2693   else
2694     {
2695       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2696
2697       if (value == (unsigned) FAIL)
2698         {
2699           inst.error = _("invalid constant");
2700           return;
2701         }
2702
2703       inst.instruction |= value;
2704     }
2705
2706   inst.error = NULL;
2707   end_of_line (str);
2708 }
2709
2710 /* Long Multiply Parser
2711    UMULL RdLo, RdHi, Rm, Rs
2712    SMULL RdLo, RdHi, Rm, Rs
2713    UMLAL RdLo, RdHi, Rm, Rs
2714    SMLAL RdLo, RdHi, Rm, Rs.  */
2715
2716 static void
2717 do_mull (char * str)
2718 {
2719   int rdlo, rdhi, rm, rs;
2720
2721   /* Only one format "rdlo, rdhi, rm, rs".  */
2722   skip_whitespace (str);
2723
2724   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2725     {
2726       inst.error = BAD_ARGS;
2727       return;
2728     }
2729
2730   if (skip_past_comma (&str) == FAIL
2731       || (rdhi = reg_required_here (&str, 16)) == FAIL)
2732     {
2733       inst.error = BAD_ARGS;
2734       return;
2735     }
2736
2737   if (skip_past_comma (&str) == FAIL
2738       || (rm = reg_required_here (&str, 0)) == FAIL)
2739     {
2740       inst.error = BAD_ARGS;
2741       return;
2742     }
2743
2744   /* rdhi, rdlo and rm must all be different.  */
2745   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2746     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2747
2748   if (skip_past_comma (&str) == FAIL
2749       || (rs = reg_required_here (&str, 8)) == FAIL)
2750     {
2751       inst.error = BAD_ARGS;
2752       return;
2753     }
2754
2755   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2756     {
2757       inst.error = BAD_PC;
2758       return;
2759     }
2760
2761   end_of_line (str);
2762 }
2763
2764 static void
2765 do_mul (char * str)
2766 {
2767   int rd, rm;
2768
2769   /* Only one format "rd, rm, rs".  */
2770   skip_whitespace (str);
2771
2772   if ((rd = reg_required_here (&str, 16)) == FAIL)
2773     {
2774       inst.error = BAD_ARGS;
2775       return;
2776     }
2777
2778   if (rd == REG_PC)
2779     {
2780       inst.error = BAD_PC;
2781       return;
2782     }
2783
2784   if (skip_past_comma (&str) == FAIL
2785       || (rm = reg_required_here (&str, 0)) == FAIL)
2786     {
2787       inst.error = BAD_ARGS;
2788       return;
2789     }
2790
2791   if (rm == REG_PC)
2792     {
2793       inst.error = BAD_PC;
2794       return;
2795     }
2796
2797   if (rm == rd)
2798     as_tsktsk (_("rd and rm should be different in mul"));
2799
2800   if (skip_past_comma (&str) == FAIL
2801       || (rm = reg_required_here (&str, 8)) == FAIL)
2802     {
2803       inst.error = BAD_ARGS;
2804       return;
2805     }
2806
2807   if (rm == REG_PC)
2808     {
2809       inst.error = BAD_PC;
2810       return;
2811     }
2812
2813   end_of_line (str);
2814 }
2815
2816 static void
2817 do_mla (char * str)
2818 {
2819   int rd, rm;
2820
2821   /* Only one format "rd, rm, rs, rn".  */
2822   skip_whitespace (str);
2823
2824   if ((rd = reg_required_here (&str, 16)) == FAIL)
2825     {
2826       inst.error = BAD_ARGS;
2827       return;
2828     }
2829
2830   if (rd == REG_PC)
2831     {
2832       inst.error = BAD_PC;
2833       return;
2834     }
2835
2836   if (skip_past_comma (&str) == FAIL
2837       || (rm = reg_required_here (&str, 0)) == FAIL)
2838     {
2839       inst.error = BAD_ARGS;
2840       return;
2841     }
2842
2843   if (rm == REG_PC)
2844     {
2845       inst.error = BAD_PC;
2846       return;
2847     }
2848
2849   if (rm == rd)
2850     as_tsktsk (_("rd and rm should be different in mla"));
2851
2852   if (skip_past_comma (&str) == FAIL
2853       || (rd = reg_required_here (&str, 8)) == FAIL
2854       || skip_past_comma (&str) == FAIL
2855       || (rm = reg_required_here (&str, 12)) == FAIL)
2856     {
2857       inst.error = BAD_ARGS;
2858       return;
2859     }
2860
2861   if (rd == REG_PC || rm == REG_PC)
2862     {
2863       inst.error = BAD_PC;
2864       return;
2865     }
2866
2867   end_of_line (str);
2868 }
2869
2870 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2871    Advances *str to the next non-alphanumeric.
2872    Returns 0, or else FAIL (in which case sets inst.error).
2873
2874   (In a future XScale, there may be accumulators other than zero.
2875   At that time this routine and its callers can be upgraded to suit.)  */
2876
2877 static int
2878 accum0_required_here (char ** str)
2879 {
2880   static char buff [128];       /* Note the address is taken.  Hence, static.  */
2881   char * p = * str;
2882   char   c;
2883   int result = 0;               /* The accum number.  */
2884
2885   skip_whitespace (p);
2886
2887   *str = p;                     /* Advance caller's string pointer too.  */
2888   c = *p++;
2889   while (ISALNUM (c))
2890     c = *p++;
2891
2892   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
2893
2894   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2895     {
2896       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2897       inst.error = buff;
2898       result = FAIL;
2899     }
2900
2901   *p = c;                       /* Unzap.  */
2902   *str = p;                     /* Caller's string pointer to after match.  */
2903   return result;
2904 }
2905
2906 static int
2907 ldst_extend_v4 (char ** str)
2908 {
2909   int add = INDEX_UP;
2910
2911   switch (**str)
2912     {
2913     case '#':
2914     case '$':
2915       (*str)++;
2916       if (my_get_expression (& inst.reloc.exp, str))
2917         return FAIL;
2918
2919       if (inst.reloc.exp.X_op == O_constant)
2920         {
2921           int value = inst.reloc.exp.X_add_number;
2922
2923           if (value < -255 || value > 255)
2924             {
2925               inst.error = _("address offset too large");
2926               return FAIL;
2927             }
2928
2929           if (value < 0)
2930             {
2931               value = -value;
2932               add = 0;
2933             }
2934
2935           /* Halfword and signextension instructions have the
2936              immediate value split across bits 11..8 and bits 3..0.  */
2937           inst.instruction |= (add | HWOFFSET_IMM
2938                                | ((value >> 4) << 8) | (value & 0xF));
2939         }
2940       else
2941         {
2942           inst.instruction |= HWOFFSET_IMM;
2943           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2944           inst.reloc.pc_rel = 0;
2945         }
2946       return SUCCESS;
2947
2948     case '-':
2949       add = 0;
2950       /* Fall through.  */
2951
2952     case '+':
2953       (*str)++;
2954       /* Fall through.  */
2955
2956     default:
2957       if (reg_required_here (str, 0) == FAIL)
2958         return FAIL;
2959
2960       inst.instruction |= add;
2961       return SUCCESS;
2962     }
2963 }
2964
2965 /* Expects **str -> after a comma. May be leading blanks.
2966    Advances *str, recognizing a load  mode, and setting inst.instruction.
2967    Returns rn, or else FAIL (in which case may set inst.error
2968    and not advance str)
2969
2970    Note: doesn't know Rd, so no err checks that require such knowledge.  */
2971
2972 static int
2973 ld_mode_required_here (char ** string)
2974 {
2975   char * str = * string;
2976   int    rn;
2977   int    pre_inc = 0;
2978
2979   skip_whitespace (str);
2980
2981   if (* str == '[')
2982     {
2983       str++;
2984
2985       skip_whitespace (str);
2986
2987       if ((rn = reg_required_here (& str, 16)) == FAIL)
2988         return FAIL;
2989
2990       skip_whitespace (str);
2991
2992       if (* str == ']')
2993         {
2994           str ++;
2995
2996           if (skip_past_comma (& str) == SUCCESS)
2997             {
2998               /* [Rn],... (post inc) */
2999               if (ldst_extend_v4 (&str) == FAIL)
3000                 return FAIL;
3001             }
3002           else        /* [Rn] */
3003             {
3004               skip_whitespace (str);
3005
3006               if (* str == '!')
3007                 {
3008                   str ++;
3009                   inst.instruction |= WRITE_BACK;
3010                 }
3011
3012               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3013               pre_inc = 1;
3014             }
3015         }
3016       else        /* [Rn,...] */
3017         {
3018           if (skip_past_comma (& str) == FAIL)
3019             {
3020               inst.error = _("pre-indexed expression expected");
3021               return FAIL;
3022             }
3023
3024           pre_inc = 1;
3025
3026           if (ldst_extend_v4 (&str) == FAIL)
3027             return FAIL;
3028
3029           skip_whitespace (str);
3030
3031           if (* str ++ != ']')
3032             {
3033               inst.error = _("missing ]");
3034               return FAIL;
3035             }
3036
3037           skip_whitespace (str);
3038
3039           if (* str == '!')
3040             {
3041               str ++;
3042               inst.instruction |= WRITE_BACK;
3043             }
3044         }
3045     }
3046   else if (* str == '=')        /* ldr's "r,=label" syntax */
3047     /* We should never reach here, because <text> = <expression> is
3048        caught gas/read.c read_a_source_file() as a .set operation.  */
3049     return FAIL;
3050   else                          /* PC +- 8 bit immediate offset.  */
3051     {
3052       if (my_get_expression (& inst.reloc.exp, & str))
3053         return FAIL;
3054
3055       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3056       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3057       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3058       inst.reloc.pc_rel            = 1;
3059       inst.instruction            |= (REG_PC << 16);
3060
3061       rn = REG_PC;
3062       pre_inc = 1;
3063     }
3064
3065   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3066   * string = str;
3067
3068   return rn;
3069 }
3070
3071 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3072    SMLAxy{cond} Rd,Rm,Rs,Rn
3073    SMLAWy{cond} Rd,Rm,Rs,Rn
3074    Error if any register is R15.  */
3075
3076 static void
3077 do_smla (char * str)
3078 {
3079   int rd, rm, rs, rn;
3080
3081   skip_whitespace (str);
3082
3083   if ((rd = reg_required_here (& str, 16)) == FAIL
3084       || skip_past_comma (& str) == FAIL
3085       || (rm = reg_required_here (& str, 0)) == FAIL
3086       || skip_past_comma (& str) == FAIL
3087       || (rs = reg_required_here (& str, 8)) == FAIL
3088       || skip_past_comma (& str) == FAIL
3089       || (rn = reg_required_here (& str, 12)) == FAIL)
3090     inst.error = BAD_ARGS;
3091
3092   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3093     inst.error = BAD_PC;
3094
3095   else
3096     end_of_line (str);
3097 }
3098
3099 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3100    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3101    Error if any register is R15.
3102    Warning if Rdlo == Rdhi.  */
3103
3104 static void
3105 do_smlal (char * str)
3106 {
3107   int rdlo, rdhi, rm, rs;
3108
3109   skip_whitespace (str);
3110
3111   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3112       || skip_past_comma (& str) == FAIL
3113       || (rdhi = reg_required_here (& str, 16)) == FAIL
3114       || skip_past_comma (& str) == FAIL
3115       || (rm = reg_required_here (& str, 0)) == FAIL
3116       || skip_past_comma (& str) == FAIL
3117       || (rs = reg_required_here (& str, 8)) == FAIL)
3118     {
3119       inst.error = BAD_ARGS;
3120       return;
3121     }
3122
3123   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3124     {
3125       inst.error = BAD_PC;
3126       return;
3127     }
3128
3129   if (rdlo == rdhi)
3130     as_tsktsk (_("rdhi and rdlo must be different"));
3131
3132   end_of_line (str);
3133 }
3134
3135 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3136    SMULxy{cond} Rd,Rm,Rs
3137    Error if any register is R15.  */
3138
3139 static void
3140 do_smul (char * str)
3141 {
3142   int rd, rm, rs;
3143
3144   skip_whitespace (str);
3145
3146   if ((rd = reg_required_here (& str, 16)) == FAIL
3147       || skip_past_comma (& str) == FAIL
3148       || (rm = reg_required_here (& str, 0)) == FAIL
3149       || skip_past_comma (& str) == FAIL
3150       || (rs = reg_required_here (& str, 8)) == FAIL)
3151     inst.error = BAD_ARGS;
3152
3153   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3154     inst.error = BAD_PC;
3155
3156   else
3157     end_of_line (str);
3158 }
3159
3160 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3161    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3162    Error if any register is R15.  */
3163
3164 static void
3165 do_qadd (char * str)
3166 {
3167   int rd, rm, rn;
3168
3169   skip_whitespace (str);
3170
3171   if ((rd = reg_required_here (& str, 12)) == FAIL
3172       || skip_past_comma (& str) == FAIL
3173       || (rm = reg_required_here (& str, 0)) == FAIL
3174       || skip_past_comma (& str) == FAIL
3175       || (rn = reg_required_here (& str, 16)) == FAIL)
3176     inst.error = BAD_ARGS;
3177
3178   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3179     inst.error = BAD_PC;
3180
3181   else
3182     end_of_line (str);
3183 }
3184
3185 /* ARM V5E (el Segundo)
3186    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3187    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3188
3189    These are equivalent to the XScale instructions MAR and MRA,
3190    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3191
3192    Result unpredicatable if Rd or Rn is R15.  */
3193
3194 static void
3195 do_co_reg2c (char * str)
3196 {
3197   int rd, rn;
3198
3199   skip_whitespace (str);
3200
3201   if (co_proc_number (& str) == FAIL)
3202     {
3203       if (!inst.error)
3204         inst.error = BAD_ARGS;
3205       return;
3206     }
3207
3208   if (skip_past_comma (& str) == FAIL
3209       || cp_opc_expr (& str, 4, 4) == FAIL)
3210     {
3211       if (!inst.error)
3212         inst.error = BAD_ARGS;
3213       return;
3214     }
3215
3216   if (skip_past_comma (& str) == FAIL
3217       || (rd = reg_required_here (& str, 12)) == FAIL)
3218     {
3219       if (!inst.error)
3220         inst.error = BAD_ARGS;
3221       return;
3222     }
3223
3224   if (skip_past_comma (& str) == FAIL
3225       || (rn = reg_required_here (& str, 16)) == FAIL)
3226     {
3227       if (!inst.error)
3228         inst.error = BAD_ARGS;
3229       return;
3230     }
3231
3232   /* Unpredictable result if rd or rn is R15.  */
3233   if (rd == REG_PC || rn == REG_PC)
3234     as_tsktsk
3235       (_("Warning: instruction unpredictable when using r15"));
3236
3237   if (skip_past_comma (& str) == FAIL
3238       || cp_reg_required_here (& str, 0) == FAIL)
3239     {
3240       if (!inst.error)
3241         inst.error = BAD_ARGS;
3242       return;
3243     }
3244
3245   end_of_line (str);
3246 }
3247
3248 /* ARM V5 count-leading-zeroes instruction (argument parse)
3249      CLZ{<cond>} <Rd>, <Rm>
3250      Condition defaults to COND_ALWAYS.
3251      Error if Rd or Rm are R15.  */
3252
3253 static void
3254 do_clz (char * str)
3255 {
3256   int rd, rm;
3257
3258   skip_whitespace (str);
3259
3260   if (((rd = reg_required_here (& str, 12)) == FAIL)
3261       || (skip_past_comma (& str) == FAIL)
3262       || ((rm = reg_required_here (& str, 0)) == FAIL))
3263     inst.error = BAD_ARGS;
3264
3265   else if (rd == REG_PC || rm == REG_PC )
3266     inst.error = BAD_PC;
3267
3268   else
3269     end_of_line (str);
3270 }
3271
3272 /* ARM V5 (argument parse)
3273      LDC2{L} <coproc>, <CRd>, <addressing mode>
3274      STC2{L} <coproc>, <CRd>, <addressing mode>
3275      Instruction is not conditional, and has 0xf in the condition field.
3276      Otherwise, it's the same as LDC/STC.  */
3277
3278 static void
3279 do_lstc2 (char * str)
3280 {
3281   skip_whitespace (str);
3282
3283   if (co_proc_number (& str) == FAIL)
3284     {
3285       if (!inst.error)
3286         inst.error = BAD_ARGS;
3287     }
3288   else if (skip_past_comma (& str) == FAIL
3289            || cp_reg_required_here (& str, 12) == FAIL)
3290     {
3291       if (!inst.error)
3292         inst.error = BAD_ARGS;
3293     }
3294   else if (skip_past_comma (& str) == FAIL
3295            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3296     {
3297       if (! inst.error)
3298         inst.error = BAD_ARGS;
3299     }
3300   else
3301     end_of_line (str);
3302 }
3303
3304 /* ARM V5 (argument parse)
3305      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3306      Instruction is not conditional, and has 0xf in the condition field.
3307      Otherwise, it's the same as CDP.  */
3308
3309 static void
3310 do_cdp2 (char * str)
3311 {
3312   skip_whitespace (str);
3313
3314   if (co_proc_number (& str) == FAIL)
3315     {
3316       if (!inst.error)
3317         inst.error = BAD_ARGS;
3318       return;
3319     }
3320
3321   if (skip_past_comma (& str) == FAIL
3322       || cp_opc_expr (& str, 20,4) == FAIL)
3323     {
3324       if (!inst.error)
3325         inst.error = BAD_ARGS;
3326       return;
3327     }
3328
3329   if (skip_past_comma (& str) == FAIL
3330       || cp_reg_required_here (& str, 12) == FAIL)
3331     {
3332       if (!inst.error)
3333         inst.error = BAD_ARGS;
3334       return;
3335     }
3336
3337   if (skip_past_comma (& str) == FAIL
3338       || cp_reg_required_here (& str, 16) == FAIL)
3339     {
3340       if (!inst.error)
3341         inst.error = BAD_ARGS;
3342       return;
3343     }
3344
3345   if (skip_past_comma (& str) == FAIL
3346       || cp_reg_required_here (& str, 0) == FAIL)
3347     {
3348       if (!inst.error)
3349         inst.error = BAD_ARGS;
3350       return;
3351     }
3352
3353   if (skip_past_comma (& str) == SUCCESS)
3354     {
3355       if (cp_opc_expr (& str, 5, 3) == FAIL)
3356         {
3357           if (!inst.error)
3358             inst.error = BAD_ARGS;
3359           return;
3360         }
3361     }
3362
3363   end_of_line (str);
3364 }
3365
3366 /* ARM V5 (argument parse)
3367      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3368      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3369      Instruction is not conditional, and has 0xf in the condition field.
3370      Otherwise, it's the same as MCR/MRC.  */
3371
3372 static void
3373 do_co_reg2 (char * str)
3374 {
3375   skip_whitespace (str);
3376
3377   if (co_proc_number (& str) == FAIL)
3378     {
3379       if (!inst.error)
3380         inst.error = BAD_ARGS;
3381       return;
3382     }
3383
3384   if (skip_past_comma (& str) == FAIL
3385       || cp_opc_expr (& str, 21, 3) == FAIL)
3386     {
3387       if (!inst.error)
3388         inst.error = BAD_ARGS;
3389       return;
3390     }
3391
3392   if (skip_past_comma (& str) == FAIL
3393       || reg_required_here (& str, 12) == FAIL)
3394     {
3395       if (!inst.error)
3396         inst.error = BAD_ARGS;
3397       return;
3398     }
3399
3400   if (skip_past_comma (& str) == FAIL
3401       || cp_reg_required_here (& str, 16) == FAIL)
3402     {
3403       if (!inst.error)
3404         inst.error = BAD_ARGS;
3405       return;
3406     }
3407
3408   if (skip_past_comma (& str) == FAIL
3409       || cp_reg_required_here (& str, 0) == FAIL)
3410     {
3411       if (!inst.error)
3412         inst.error = BAD_ARGS;
3413       return;
3414     }
3415
3416   if (skip_past_comma (& str) == SUCCESS)
3417     {
3418       if (cp_opc_expr (& str, 5, 3) == FAIL)
3419         {
3420           if (!inst.error)
3421             inst.error = BAD_ARGS;
3422           return;
3423         }
3424     }
3425
3426   end_of_line (str);
3427 }
3428
3429 static void
3430 do_bx (char * str)
3431 {
3432   int reg;
3433
3434   skip_whitespace (str);
3435
3436   if ((reg = reg_required_here (&str, 0)) == FAIL)
3437     {
3438       inst.error = BAD_ARGS;
3439       return;
3440     }
3441
3442   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
3443   if (reg == REG_PC)
3444     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
3445
3446   end_of_line (str);
3447 }
3448
3449 /* ARM v5TEJ.  Jump to Jazelle code.  */
3450
3451 static void
3452 do_bxj (char * str)
3453 {
3454   int reg;
3455
3456   skip_whitespace (str);
3457
3458   if ((reg = reg_required_here (&str, 0)) == FAIL)
3459     {
3460       inst.error = BAD_ARGS;
3461       return;
3462     }
3463
3464   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3465   if (reg == REG_PC)
3466     as_tsktsk (_("use of r15 in bxj is not really useful"));
3467
3468   end_of_line (str);
3469 }
3470
3471 /* ARM V6 umaal (argument parse).  */
3472
3473 static void
3474 do_umaal (char * str)
3475 {
3476   int rdlo, rdhi, rm, rs;
3477
3478   skip_whitespace (str);
3479   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3480       || skip_past_comma (& str) == FAIL
3481       || (rdhi = reg_required_here (& str, 16)) == FAIL
3482       || skip_past_comma (& str) == FAIL
3483       || (rm = reg_required_here (& str, 0)) == FAIL
3484       || skip_past_comma (& str) == FAIL
3485       || (rs = reg_required_here (& str, 8)) == FAIL)
3486     {
3487       inst.error = BAD_ARGS;
3488       return;
3489     }
3490
3491   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3492     {
3493       inst.error = BAD_PC;
3494       return;
3495     }
3496
3497   end_of_line (str);
3498 }
3499
3500 /* ARM V6 strex (argument parse).  */
3501
3502 static void
3503 do_strex (char * str)
3504 {
3505   int rd, rm, rn;
3506
3507   /* Parse Rd, Rm,.  */
3508   skip_whitespace (str);
3509   if ((rd = reg_required_here (& str, 12)) == FAIL
3510       || skip_past_comma (& str) == FAIL
3511       || (rm = reg_required_here (& str, 0)) == FAIL
3512       || skip_past_comma (& str) == FAIL)
3513     {
3514       inst.error = BAD_ARGS;
3515       return;
3516     }
3517   if (rd == REG_PC || rm == REG_PC)
3518     {
3519       inst.error = BAD_PC;
3520       return;
3521     }
3522   if (rd == rm)
3523     {
3524       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3525       return;
3526     }
3527
3528   /* Skip past '['.  */
3529   if ((strlen (str) >= 1)
3530       && strncmp (str, "[", 1) == 0)
3531     str += 1;
3532
3533   skip_whitespace (str);
3534
3535   /* Parse Rn.  */
3536   if ((rn = reg_required_here (& str, 16)) == FAIL)
3537     {
3538       inst.error = BAD_ARGS;
3539       return;
3540     }
3541   else if (rn == REG_PC)
3542     {
3543       inst.error = BAD_PC;
3544       return;
3545     }
3546   if (rd == rn)
3547     {
3548       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3549       return;
3550     }
3551   skip_whitespace (str);
3552
3553   /* Skip past ']'.  */
3554   if ((strlen (str) >= 1)
3555       && strncmp (str, "]", 1) == 0)
3556     str += 1;
3557
3558   end_of_line (str);
3559 }
3560
3561 /* KIND indicates what kind of shifts are accepted.  */
3562
3563 static int
3564 decode_shift (char ** str, int kind)
3565 {
3566   const struct asm_shift_name * shift;
3567   char * p;
3568   char   c;
3569
3570   skip_whitespace (* str);
3571
3572   for (p = * str; ISALPHA (* p); p ++)
3573     ;
3574
3575   if (p == * str)
3576     {
3577       inst.error = _("shift expression expected");
3578       return FAIL;
3579     }
3580
3581   c = * p;
3582   * p = '\0';
3583   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3584   * p = c;
3585
3586   if (shift == NULL)
3587     {
3588       inst.error = _("shift expression expected");
3589       return FAIL;
3590     }
3591
3592   assert (shift->properties->index == shift_properties[shift->properties->index].index);
3593
3594   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
3595       && shift->properties->index != SHIFT_LSL
3596       && shift->properties->index != SHIFT_ASR)
3597     {
3598       inst.error = _("'LSL' or 'ASR' required");
3599       return FAIL;
3600     }
3601   else if (kind == SHIFT_LSL_IMMEDIATE
3602            && shift->properties->index != SHIFT_LSL)
3603     {
3604       inst.error = _("'LSL' required");
3605       return FAIL;
3606     }
3607   else if (kind == SHIFT_ASR_IMMEDIATE
3608            && shift->properties->index != SHIFT_ASR)
3609     {
3610       inst.error = _("'ASR' required");
3611       return FAIL;
3612     }
3613
3614   if (shift->properties->index == SHIFT_RRX)
3615     {
3616       * str = p;
3617       inst.instruction |= shift->properties->bit_field;
3618       return SUCCESS;
3619     }
3620
3621   skip_whitespace (p);
3622
3623   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
3624     {
3625       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3626       * str = p;
3627       return SUCCESS;
3628     }
3629   else if (! is_immediate_prefix (* p))
3630     {
3631       inst.error = (NO_SHIFT_RESTRICT
3632                     ? _("shift requires register or #expression")
3633                     : _("shift requires #expression"));
3634       * str = p;
3635       return FAIL;
3636     }
3637
3638   inst.error = NULL;
3639   p ++;
3640
3641   if (my_get_expression (& inst.reloc.exp, & p))
3642     return FAIL;
3643
3644   /* Validate some simple #expressions.  */
3645   if (inst.reloc.exp.X_op == O_constant)
3646     {
3647       unsigned num = inst.reloc.exp.X_add_number;
3648
3649       /* Reject operations greater than 32.  */
3650       if (num > 32
3651           /* Reject a shift of 0 unless the mode allows it.  */
3652           || (num == 0 && shift->properties->allows_0 == 0)
3653           /* Reject a shift of 32 unless the mode allows it.  */
3654           || (num == 32 && shift->properties->allows_32 == 0)
3655           )
3656         {
3657           /* As a special case we allow a shift of zero for
3658              modes that do not support it to be recoded as an
3659              logical shift left of zero (ie nothing).  We warn
3660              about this though.  */
3661           if (num == 0)
3662             {
3663               as_warn (_("shift of 0 ignored."));
3664               shift = & shift_names[0];
3665               assert (shift->properties->index == SHIFT_LSL);
3666             }
3667           else
3668             {
3669               inst.error = _("invalid immediate shift");
3670               return FAIL;
3671             }
3672         }
3673
3674       /* Shifts of 32 are encoded as 0, for those shifts that
3675          support it.  */
3676       if (num == 32)
3677         num = 0;
3678
3679       inst.instruction |= (num << 7) | shift->properties->bit_field;
3680     }
3681   else
3682     {
3683       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
3684       inst.reloc.pc_rel = 0;
3685       inst.instruction |= shift->properties->bit_field;
3686     }
3687
3688   * str = p;
3689   return SUCCESS;
3690 }
3691
3692 static void
3693 do_sat (char ** str, int bias)
3694 {
3695   int rd, rm;
3696   expressionS expr;
3697
3698   skip_whitespace (*str);
3699
3700   /* Parse <Rd>, field.  */
3701   if ((rd = reg_required_here (str, 12)) == FAIL
3702       || skip_past_comma (str) == FAIL)
3703     {
3704       inst.error = BAD_ARGS;
3705       return;
3706     }
3707   if (rd == REG_PC)
3708     {
3709       inst.error = BAD_PC;
3710       return;
3711     }
3712
3713   /* Parse #<immed>,  field.  */
3714   if (is_immediate_prefix (**str))
3715     (*str)++;
3716   else
3717     {
3718       inst.error = _("immediate expression expected");
3719       return;
3720     }
3721   if (my_get_expression (&expr, str))
3722     {
3723       inst.error = _("bad expression");
3724       return;
3725     }
3726   if (expr.X_op != O_constant)
3727     {
3728       inst.error = _("constant expression expected");
3729       return;
3730     }
3731   if (expr.X_add_number + bias < 0
3732       || expr.X_add_number + bias > 31)
3733     {
3734       inst.error = _("immediate value out of range");
3735       return;
3736     }
3737   inst.instruction |= (expr.X_add_number + bias) << 16;
3738   if (skip_past_comma (str) == FAIL)
3739     {
3740       inst.error = BAD_ARGS;
3741       return;
3742     }
3743
3744   /* Parse <Rm> field.  */
3745   if ((rm = reg_required_here (str, 0)) == FAIL)
3746     {
3747       inst.error = BAD_ARGS;
3748       return;
3749     }
3750   if (rm == REG_PC)
3751     {
3752       inst.error = BAD_PC;
3753       return;
3754     }
3755
3756   if (skip_past_comma (str) == SUCCESS)
3757     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
3758 }
3759
3760 /* ARM V6 ssat (argument parse).  */
3761
3762 static void
3763 do_ssat (char * str)
3764 {
3765   do_sat (&str, /*bias=*/-1);
3766   end_of_line (str);
3767 }
3768
3769 /* ARM V6 usat (argument parse).  */
3770
3771 static void
3772 do_usat (char * str)
3773 {
3774   do_sat (&str, /*bias=*/0);
3775   end_of_line (str);
3776 }
3777
3778 static void
3779 do_sat16 (char ** str, int bias)
3780 {
3781   int rd, rm;
3782   expressionS expr;
3783
3784   skip_whitespace (*str);
3785
3786   /* Parse the <Rd> field.  */
3787   if ((rd = reg_required_here (str, 12)) == FAIL
3788       || skip_past_comma (str) == FAIL)
3789     {
3790       inst.error = BAD_ARGS;
3791       return;
3792     }
3793   if (rd == REG_PC)
3794     {
3795       inst.error = BAD_PC;
3796       return;
3797     }
3798
3799   /* Parse #<immed>, field.  */
3800   if (is_immediate_prefix (**str))
3801     (*str)++;
3802   else
3803     {
3804       inst.error = _("immediate expression expected");
3805       return;
3806     }
3807   if (my_get_expression (&expr, str))
3808     {
3809       inst.error = _("bad expression");
3810       return;
3811     }
3812   if (expr.X_op != O_constant)
3813     {
3814       inst.error = _("constant expression expected");
3815       return;
3816     }
3817   if (expr.X_add_number + bias < 0
3818       || expr.X_add_number + bias > 15)
3819     {
3820       inst.error = _("immediate value out of range");
3821       return;
3822     }
3823   inst.instruction |= (expr.X_add_number + bias) << 16;
3824   if (skip_past_comma (str) == FAIL)
3825     {
3826       inst.error = BAD_ARGS;
3827       return;
3828     }
3829
3830   /* Parse <Rm> field.  */
3831   if ((rm = reg_required_here (str, 0)) == FAIL)
3832     {
3833       inst.error = BAD_ARGS;
3834       return;
3835     }
3836   if (rm == REG_PC)
3837     {
3838       inst.error = BAD_PC;
3839       return;
3840     }
3841 }
3842
3843 /* ARM V6 ssat16 (argument parse).  */
3844
3845 static void
3846 do_ssat16 (char * str)
3847 {
3848   do_sat16 (&str, /*bias=*/-1);
3849   end_of_line (str);
3850 }
3851
3852 static void
3853 do_usat16 (char * str)
3854 {
3855   do_sat16 (&str, /*bias=*/0);
3856   end_of_line (str);
3857 }
3858
3859 static void
3860 do_cps_mode (char ** str)
3861 {
3862   expressionS expr;
3863
3864   skip_whitespace (*str);
3865
3866   if (! is_immediate_prefix (**str))
3867     {
3868       inst.error = _("immediate expression expected");
3869       return;
3870     }
3871
3872   (*str)++; /* Strip off the immediate signifier.  */
3873   if (my_get_expression (&expr, str))
3874     {
3875       inst.error = _("bad expression");
3876       return;
3877     }
3878
3879   if (expr.X_op != O_constant)
3880     {
3881       inst.error = _("constant expression expected");
3882       return;
3883     }
3884
3885   /* The mode is a 5 bit field.  Valid values are 0-31.  */
3886   if (((unsigned) expr.X_add_number) > 31
3887       || (inst.reloc.exp.X_add_number) < 0)
3888     {
3889       inst.error = _("invalid constant");
3890       return;
3891     }
3892
3893   inst.instruction |= expr.X_add_number;
3894 }
3895
3896 /* ARM V6 srs (argument parse).  */
3897
3898 static void
3899 do_srs (char * str)
3900 {
3901   char *exclam;
3902   skip_whitespace (str);
3903   exclam = strchr (str, '!');
3904   if (exclam)
3905     *exclam = '\0';
3906   do_cps_mode (&str);
3907   if (exclam)
3908     *exclam = '!';
3909   if (*str == '!')
3910     {
3911       inst.instruction |= WRITE_BACK;
3912       str++;
3913     }
3914   end_of_line (str);
3915 }
3916
3917 /* ARM V6 SMMUL (argument parse).  */
3918
3919 static void
3920 do_smmul (char * str)
3921 {
3922   int rd, rm, rs;
3923
3924   skip_whitespace (str);
3925   if ((rd = reg_required_here (&str, 16)) == FAIL
3926       || skip_past_comma (&str) == FAIL
3927       || (rm = reg_required_here (&str, 0)) == FAIL
3928       || skip_past_comma (&str) == FAIL
3929       || (rs = reg_required_here (&str, 8)) == FAIL)
3930     {
3931       inst.error = BAD_ARGS;
3932       return;
3933     }
3934
3935   if (   rd == REG_PC
3936       || rm == REG_PC
3937       || rs == REG_PC)
3938     {
3939       inst.error = BAD_PC;
3940       return;
3941     }
3942
3943   end_of_line (str);
3944 }
3945
3946 /* ARM V6 SMLALD (argument parse).  */
3947
3948 static void
3949 do_smlald (char * str)
3950 {
3951   int rdlo, rdhi, rm, rs;
3952
3953   skip_whitespace (str);
3954   if ((rdlo = reg_required_here (&str, 12)) == FAIL
3955       || skip_past_comma (&str) == FAIL
3956       || (rdhi = reg_required_here (&str, 16)) == FAIL
3957       || skip_past_comma (&str) == FAIL
3958       || (rm = reg_required_here (&str, 0)) == FAIL
3959       || skip_past_comma (&str) == FAIL
3960       || (rs = reg_required_here (&str, 8)) == FAIL)
3961     {
3962       inst.error = BAD_ARGS;
3963       return;
3964     }
3965
3966   if (   rdlo == REG_PC
3967       || rdhi == REG_PC
3968       || rm == REG_PC
3969       || rs == REG_PC)
3970     {
3971       inst.error = BAD_PC;
3972       return;
3973     }
3974
3975   end_of_line (str);
3976 }
3977
3978 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
3979    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
3980
3981 static void
3982 do_smlad (char * str)
3983 {
3984   int rd, rm, rs, rn;
3985
3986   skip_whitespace (str);
3987   if ((rd = reg_required_here (&str, 16)) == FAIL
3988       || skip_past_comma (&str) == FAIL
3989       || (rm = reg_required_here (&str, 0)) == FAIL
3990       || skip_past_comma (&str) == FAIL
3991       || (rs = reg_required_here (&str, 8)) == FAIL
3992       || skip_past_comma (&str) == FAIL
3993       || (rn = reg_required_here (&str, 12)) == FAIL)
3994     {
3995       inst.error = BAD_ARGS;
3996       return;
3997     }
3998
3999   if (   rd == REG_PC
4000       || rn == REG_PC
4001       || rs == REG_PC
4002       || rm == REG_PC)
4003     {
4004       inst.error = BAD_PC;
4005       return;
4006     }
4007
4008   end_of_line (str);
4009 }
4010
4011 /* Returns true if the endian-specifier indicates big-endianness.  */
4012
4013 static int
4014 do_endian_specifier (char * str)
4015 {
4016   int big_endian = 0;
4017
4018   skip_whitespace (str);
4019   if (strlen (str) < 2)
4020     inst.error = _("missing endian specifier");
4021   else if (strncasecmp (str, "BE", 2) == 0)
4022     {
4023       str += 2;
4024       big_endian = 1;
4025     }
4026   else if (strncasecmp (str, "LE", 2) == 0)
4027     str += 2;
4028   else
4029     inst.error = _("valid endian specifiers are be or le");
4030
4031   end_of_line (str);
4032
4033   return big_endian;
4034 }
4035
4036 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
4037    preserving the other bits.
4038
4039    setend <endian_specifier>, where <endian_specifier> is either
4040    BE or LE.  */
4041
4042 static void
4043 do_setend (char * str)
4044 {
4045   if (do_endian_specifier (str))
4046     inst.instruction |= 0x200;
4047 }
4048
4049 /* ARM V6 SXTH.
4050
4051    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
4052    Condition defaults to COND_ALWAYS.
4053    Error if any register uses R15.  */
4054
4055 static void
4056 do_sxth (char * str)
4057 {
4058   int rd, rm;
4059   expressionS expr;
4060   int rotation_clear_mask = 0xfffff3ff;
4061   int rotation_eight_mask = 0x00000400;
4062   int rotation_sixteen_mask = 0x00000800;
4063   int rotation_twenty_four_mask = 0x00000c00;
4064
4065   skip_whitespace (str);
4066   if ((rd = reg_required_here (&str, 12)) == FAIL
4067       || skip_past_comma (&str) == FAIL
4068       || (rm = reg_required_here (&str, 0)) == FAIL)
4069     {
4070       inst.error = BAD_ARGS;
4071       return;
4072     }
4073
4074   else if (rd == REG_PC || rm == REG_PC)
4075     {
4076       inst.error = BAD_PC;
4077       return;
4078     }
4079
4080   /* Zero out the rotation field.  */
4081   inst.instruction &= rotation_clear_mask;
4082
4083   /* Check for lack of optional rotation field.  */
4084   if (skip_past_comma (&str) == FAIL)
4085     {
4086       end_of_line (str);
4087       return;
4088     }
4089
4090   /* Move past 'ROR'.  */
4091   skip_whitespace (str);
4092   if (strncasecmp (str, "ROR", 3) == 0)
4093     str += 3;
4094   else
4095     {
4096       inst.error = _("missing rotation field after comma");
4097       return;
4098     }
4099
4100   /* Get the immediate constant.  */
4101   skip_whitespace (str);
4102   if (is_immediate_prefix (* str))
4103     str++;
4104   else
4105     {
4106       inst.error = _("immediate expression expected");
4107       return;
4108     }
4109
4110   if (my_get_expression (&expr, &str))
4111     {
4112       inst.error = _("bad expression");
4113       return;
4114     }
4115
4116   if (expr.X_op != O_constant)
4117     {
4118       inst.error = _("constant expression expected");
4119       return;
4120     }
4121
4122   switch (expr.X_add_number)
4123     {
4124     case 0:
4125       /* Rotation field has already been zeroed.  */
4126       break;
4127     case 8:
4128       inst.instruction |= rotation_eight_mask;
4129       break;
4130
4131     case 16:
4132       inst.instruction |= rotation_sixteen_mask;
4133       break;
4134
4135     case 24:
4136       inst.instruction |= rotation_twenty_four_mask;
4137       break;
4138
4139     default:
4140       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4141       break;
4142     }
4143
4144   end_of_line (str);
4145 }
4146
4147 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
4148    extends it to 32-bits, and adds the result to a value in another
4149    register.  You can specify a rotation by 0, 8, 16, or 24 bits
4150    before extracting the 16-bit value.
4151    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
4152    Condition defaults to COND_ALWAYS.
4153    Error if any register uses R15.  */
4154
4155 static void
4156 do_sxtah (char * str)
4157 {
4158   int rd, rn, rm;
4159   expressionS expr;
4160   int rotation_clear_mask = 0xfffff3ff;
4161   int rotation_eight_mask = 0x00000400;
4162   int rotation_sixteen_mask = 0x00000800;
4163   int rotation_twenty_four_mask = 0x00000c00;
4164
4165   skip_whitespace (str);
4166   if ((rd = reg_required_here (&str, 12)) == FAIL
4167       || skip_past_comma (&str) == FAIL
4168       || (rn = reg_required_here (&str, 16)) == FAIL
4169       || skip_past_comma (&str) == FAIL
4170       || (rm = reg_required_here (&str, 0)) == FAIL)
4171     {
4172       inst.error = BAD_ARGS;
4173       return;
4174     }
4175
4176   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4177     {
4178       inst.error = BAD_PC;
4179       return;
4180     }
4181
4182   /* Zero out the rotation field.  */
4183   inst.instruction &= rotation_clear_mask;
4184
4185   /* Check for lack of optional rotation field.  */
4186   if (skip_past_comma (&str) == FAIL)
4187     {
4188       end_of_line (str);
4189       return;
4190     }
4191
4192   /* Move past 'ROR'.  */
4193   skip_whitespace (str);
4194   if (strncasecmp (str, "ROR", 3) == 0)
4195     str += 3;
4196   else
4197     {
4198       inst.error = _("missing rotation field after comma");
4199       return;
4200     }
4201
4202   /* Get the immediate constant.  */
4203   skip_whitespace (str);
4204   if (is_immediate_prefix (* str))
4205     str++;
4206   else
4207     {
4208       inst.error = _("immediate expression expected");
4209       return;
4210     }
4211
4212   if (my_get_expression (&expr, &str))
4213     {
4214       inst.error = _("bad expression");
4215       return;
4216     }
4217
4218   if (expr.X_op != O_constant)
4219     {
4220       inst.error = _("constant expression expected");
4221       return;
4222     }
4223
4224   switch (expr.X_add_number)
4225     {
4226     case 0:
4227       /* Rotation field has already been zeroed.  */
4228       break;
4229
4230     case 8:
4231       inst.instruction |= rotation_eight_mask;
4232       break;
4233
4234     case 16:
4235       inst.instruction |= rotation_sixteen_mask;
4236       break;
4237
4238     case 24:
4239       inst.instruction |= rotation_twenty_four_mask;
4240       break;
4241
4242     default:
4243       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4244       break;
4245     }
4246
4247   end_of_line (str);
4248 }
4249
4250
4251 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
4252    word at the specified address and the following word
4253    respectively.
4254    Unconditionally executed.
4255    Error if Rn is R15.  */
4256
4257 static void
4258 do_rfe (char * str)
4259 {
4260   int rn;
4261
4262   skip_whitespace (str);
4263
4264   if ((rn = reg_required_here (&str, 16)) == FAIL)
4265     return;
4266
4267   if (rn == REG_PC)
4268     {
4269       inst.error = BAD_PC;
4270       return;
4271     }
4272
4273   skip_whitespace (str);
4274
4275   if (*str == '!')
4276     {
4277       inst.instruction |= WRITE_BACK;
4278       str++;
4279     }
4280   end_of_line (str);
4281 }
4282
4283 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
4284    register (argument parse).
4285    REV{<cond>} Rd, Rm.
4286    Condition defaults to COND_ALWAYS.
4287    Error if Rd or Rm are R15.  */
4288
4289 static void
4290 do_rev (char * str)
4291 {
4292   int rd, rm;
4293
4294   skip_whitespace (str);
4295
4296   if ((rd = reg_required_here (&str, 12)) == FAIL
4297       || skip_past_comma (&str) == FAIL
4298       || (rm = reg_required_here (&str, 0)) == FAIL)
4299     inst.error = BAD_ARGS;
4300
4301   else if (rd == REG_PC || rm == REG_PC)
4302     inst.error = BAD_PC;
4303
4304   else
4305     end_of_line (str);
4306 }
4307
4308 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
4309    QADD16{<cond>} <Rd>, <Rn>, <Rm>
4310    Condition defaults to COND_ALWAYS.
4311    Error if Rd, Rn or Rm are R15.  */
4312
4313 static void
4314 do_qadd16 (char * str)
4315 {
4316   int rd, rm, rn;
4317
4318   skip_whitespace (str);
4319
4320   if ((rd = reg_required_here (&str, 12)) == FAIL
4321       || skip_past_comma (&str) == FAIL
4322       || (rn = reg_required_here (&str, 16)) == FAIL
4323       || skip_past_comma (&str) == FAIL
4324       || (rm = reg_required_here (&str, 0)) == FAIL)
4325     inst.error = BAD_ARGS;
4326
4327   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4328     inst.error = BAD_PC;
4329
4330   else
4331     end_of_line (str);
4332 }
4333
4334 static void
4335 do_pkh_core (char * str, int shift)
4336 {
4337   int rd, rn, rm;
4338
4339   skip_whitespace (str);
4340   if (((rd = reg_required_here (&str, 12)) == FAIL)
4341       || (skip_past_comma (&str) == FAIL)
4342       || ((rn = reg_required_here (&str, 16)) == FAIL)
4343       || (skip_past_comma (&str) == FAIL)
4344       || ((rm = reg_required_here (&str, 0)) == FAIL))
4345     {
4346       inst.error = BAD_ARGS;
4347       return;
4348     }
4349
4350   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4351     {
4352       inst.error = BAD_PC;
4353       return;
4354     }
4355
4356   /* Check for optional shift immediate constant.  */
4357   if (skip_past_comma (&str) == FAIL)
4358     {
4359       if (shift == SHIFT_ASR_IMMEDIATE)
4360         {
4361           /* If the shift specifier is ommited, turn the instruction
4362              into pkhbt rd, rm, rn.  First, switch the instruction
4363              code, and clear the rn and rm fields.  */
4364           inst.instruction &= 0xfff0f010;
4365           /* Now, re-encode the registers.  */
4366           inst.instruction |= (rm << 16) | rn;
4367         }
4368       return;
4369     }
4370
4371   decode_shift (&str, shift);
4372 }
4373
4374 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
4375    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
4376    Condition defaults to COND_ALWAYS.
4377    Error if Rd, Rn or Rm are R15.  */
4378
4379 static void
4380 do_pkhbt (char * str)
4381 {
4382   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
4383 }
4384
4385 /* ARM V6 PKHTB (Argument Parse).  */
4386
4387 static void
4388 do_pkhtb (char * str)
4389 {
4390   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
4391 }
4392
4393 /* ARM V6 Load Register Exclusive instruction (argument parse).
4394    LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
4395    Condition defaults to COND_ALWAYS.
4396    Error if Rd or Rn are R15.
4397    See ARMARMv6 A4.1.27: LDREX.  */
4398
4399 static void
4400 do_ldrex (char * str)
4401 {
4402   int rd, rn;
4403
4404   skip_whitespace (str);
4405
4406   /* Parse Rd.  */
4407   if (((rd = reg_required_here (&str, 12)) == FAIL)
4408       || (skip_past_comma (&str) == FAIL))
4409     {
4410       inst.error = BAD_ARGS;
4411       return;
4412     }
4413   else if (rd == REG_PC)
4414     {
4415       inst.error = BAD_PC;
4416       return;
4417     }
4418   skip_whitespace (str);
4419
4420   /* Skip past '['.  */
4421   if ((strlen (str) >= 1)
4422       &&strncmp (str, "[", 1) == 0)
4423     str += 1;
4424   skip_whitespace (str);
4425
4426   /* Parse Rn.  */
4427   if ((rn = reg_required_here (&str, 16)) == FAIL)
4428     {
4429       inst.error = BAD_ARGS;
4430       return;
4431     }
4432   else if (rn == REG_PC)
4433     {
4434       inst.error = BAD_PC;
4435       return;
4436     }
4437   skip_whitespace (str);
4438
4439   /* Skip past ']'.  */
4440   if ((strlen (str) >= 1)
4441       && strncmp (str, "]", 1) == 0)
4442     str += 1;
4443
4444   end_of_line (str);
4445 }
4446
4447 /* ARM V6 change processor state instruction (argument parse)
4448       CPS, CPSIE, CSPID .  */
4449
4450 static void
4451 do_cps (char * str)
4452 {
4453   do_cps_mode (&str);
4454   end_of_line (str);
4455 }
4456
4457 static void
4458 do_cps_flags (char ** str, int thumb_p)
4459 {
4460   struct cps_flag
4461   {
4462     char character;
4463     unsigned long arm_value;
4464     unsigned long thumb_value;
4465   };
4466   static struct cps_flag flag_table[] =
4467   {
4468     {'a', 0x100, 0x4 },
4469     {'i', 0x080, 0x2 },
4470     {'f', 0x040, 0x1 }
4471   };
4472
4473   int saw_a_flag = 0;
4474
4475   skip_whitespace (*str);
4476
4477   /* Get the a, f and i flags.  */
4478   while (**str && **str != ',')
4479     {
4480       struct cps_flag *p;
4481       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
4482
4483       for (p = flag_table; p < q; ++p)
4484         if (strncasecmp (*str, &p->character, 1) == 0)
4485           {
4486             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
4487             saw_a_flag = 1;
4488             break;
4489           }
4490       if (p == q)
4491         {
4492           inst.error = _("unrecognized flag");
4493           return;
4494         }
4495       (*str)++;
4496     }
4497
4498   if (!saw_a_flag)
4499     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
4500 }
4501
4502 static void
4503 do_cpsi (char * str)
4504 {
4505   do_cps_flags (&str, /*thumb_p=*/0);
4506
4507   if (skip_past_comma (&str) == SUCCESS)
4508     {
4509       skip_whitespace (str);
4510       do_cps_mode (&str);
4511     }
4512   end_of_line (str);
4513 }
4514
4515 /* THUMB V5 breakpoint instruction (argument parse)
4516         BKPT <immed_8>.  */
4517
4518 static void
4519 do_t_bkpt (char * str)
4520 {
4521   expressionS expr;
4522   unsigned long number;
4523
4524   skip_whitespace (str);
4525
4526   /* Allow optional leading '#'.  */
4527   if (is_immediate_prefix (*str))
4528     str ++;
4529
4530   memset (& expr, '\0', sizeof (expr));
4531   if (my_get_expression (& expr, & str)
4532       || (expr.X_op != O_constant
4533           /* As a convenience we allow 'bkpt' without an operand.  */
4534           && expr.X_op != O_absent))
4535     {
4536       inst.error = _("bad expression");
4537       return;
4538     }
4539
4540   number = expr.X_add_number;
4541
4542   /* Check it fits an 8 bit unsigned.  */
4543   if (number != (number & 0xff))
4544     {
4545       inst.error = _("immediate value out of range");
4546       return;
4547     }
4548
4549   inst.instruction |= number;
4550
4551   end_of_line (str);
4552 }
4553
4554 #ifdef OBJ_ELF
4555 static bfd_reloc_code_real_type
4556 arm_parse_reloc (void)
4557 {
4558   char         id [16];
4559   char *       ip;
4560   unsigned int i;
4561   static struct
4562   {
4563     char * str;
4564     int    len;
4565     bfd_reloc_code_real_type reloc;
4566   }
4567   reloc_map[] =
4568   {
4569 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
4570     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
4571     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
4572     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
4573        branch instructions generated by GCC for PLT relocs.  */
4574     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
4575     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
4576     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
4577     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
4578     { NULL, 0,         BFD_RELOC_UNUSED }
4579 #undef MAP
4580   };
4581
4582   for (i = 0, ip = input_line_pointer;
4583        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
4584        i++, ip++)
4585     id[i] = TOLOWER (*ip);
4586
4587   for (i = 0; reloc_map[i].str; i++)
4588     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
4589       break;
4590
4591   input_line_pointer += reloc_map[i].len;
4592
4593   return reloc_map[i].reloc;
4594 }
4595 #endif
4596
4597 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4598    Expects inst.instruction is set for BLX(1).
4599    Note: this is cloned from do_branch, and the reloc changed to be a
4600         new one that can cope with setting one extra bit (the H bit).  */
4601
4602 static void
4603 do_branch25 (char * str)
4604 {
4605   if (my_get_expression (& inst.reloc.exp, & str))
4606     return;
4607
4608 #ifdef OBJ_ELF
4609   {
4610     char * save_in;
4611
4612     /* ScottB: February 5, 1998 */
4613     /* Check to see of PLT32 reloc required for the instruction.  */
4614
4615     /* arm_parse_reloc() works on input_line_pointer.
4616        We actually want to parse the operands to the branch instruction
4617        passed in 'str'.  Save the input pointer and restore it later.  */
4618     save_in = input_line_pointer;
4619     input_line_pointer = str;
4620
4621     if (inst.reloc.exp.X_op == O_symbol
4622         && *str == '('
4623         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4624       {
4625         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
4626         inst.reloc.pc_rel = 0;
4627         /* Modify str to point to after parsed operands, otherwise
4628            end_of_line() will complain about the (PLT) left in str.  */
4629         str = input_line_pointer;
4630       }
4631     else
4632       {
4633         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4634         inst.reloc.pc_rel = 1;
4635       }
4636
4637     input_line_pointer = save_in;
4638   }
4639 #else
4640   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4641   inst.reloc.pc_rel = 1;
4642 #endif /* OBJ_ELF */
4643
4644   end_of_line (str);
4645 }
4646
4647 /* ARM V5 branch-link-exchange instruction (argument parse)
4648      BLX <target_addr>          ie BLX(1)
4649      BLX{<condition>} <Rm>      ie BLX(2)
4650    Unfortunately, there are two different opcodes for this mnemonic.
4651    So, the insns[].value is not used, and the code here zaps values
4652         into inst.instruction.
4653    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4654
4655 static void
4656 do_blx (char * str)
4657 {
4658   char * mystr = str;
4659   int rm;
4660
4661   skip_whitespace (mystr);
4662   rm = reg_required_here (& mystr, 0);
4663
4664   /* The above may set inst.error.  Ignore his opinion.  */
4665   inst.error = 0;
4666
4667   if (rm != FAIL)
4668     {
4669       /* Arg is a register.
4670          Use the condition code our caller put in inst.instruction.
4671          Pass ourselves off as a BX with a funny opcode.  */
4672       inst.instruction |= 0x012fff30;
4673       do_bx (str);
4674     }
4675   else
4676     {
4677       /* This must be is BLX <target address>, no condition allowed.  */
4678       if (inst.instruction != COND_ALWAYS)
4679         {
4680           inst.error = BAD_COND;
4681           return;
4682         }
4683
4684       inst.instruction = 0xfafffffe;
4685
4686       /* Process like a B/BL, but with a different reloc.
4687          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4688       do_branch25 (str);
4689     }
4690 }
4691
4692 /* ARM V5 Thumb BLX (argument parse)
4693         BLX <target_addr>       which is BLX(1)
4694         BLX <Rm>                which is BLX(2)
4695    Unfortunately, there are two different opcodes for this mnemonic.
4696    So, the tinsns[].value is not used, and the code here zaps values
4697         into inst.instruction.  */
4698
4699 static void
4700 do_t_blx (char * str)
4701 {
4702   char * mystr = str;
4703   int rm;
4704
4705   skip_whitespace (mystr);
4706   inst.instruction = 0x4780;
4707
4708   /* Note that this call is to the ARM register recognizer.  BLX(2)
4709      uses the ARM register space, not the Thumb one, so a call to
4710      thumb_reg() would be wrong.  */
4711   rm = reg_required_here (& mystr, 3);
4712   inst.error = 0;
4713
4714   if (rm != FAIL)
4715     {
4716       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
4717       inst.size = 2;
4718     }
4719   else
4720     {
4721       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
4722       inst.instruction = 0xf7ffeffe;
4723       inst.size = 4;
4724
4725       if (my_get_expression (& inst.reloc.exp, & mystr))
4726         return;
4727
4728       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
4729       inst.reloc.pc_rel = 1;
4730     }
4731
4732   end_of_line (mystr);
4733 }
4734
4735 /* ARM V5 breakpoint instruction (argument parse)
4736      BKPT <16 bit unsigned immediate>
4737      Instruction is not conditional.
4738         The bit pattern given in insns[] has the COND_ALWAYS condition,
4739         and it is an error if the caller tried to override that.  */
4740
4741 static void
4742 do_bkpt (char * str)
4743 {
4744   expressionS expr;
4745   unsigned long number;
4746
4747   skip_whitespace (str);
4748
4749   /* Allow optional leading '#'.  */
4750   if (is_immediate_prefix (* str))
4751     str++;
4752
4753   memset (& expr, '\0', sizeof (expr));
4754
4755   if (my_get_expression (& expr, & str)
4756       || (expr.X_op != O_constant
4757           /* As a convenience we allow 'bkpt' without an operand.  */
4758           && expr.X_op != O_absent))
4759     {
4760       inst.error = _("bad expression");
4761       return;
4762     }
4763
4764   number = expr.X_add_number;
4765
4766   /* Check it fits a 16 bit unsigned.  */
4767   if (number != (number & 0xffff))
4768     {
4769       inst.error = _("immediate value out of range");
4770       return;
4771     }
4772
4773   /* Top 12 of 16 bits to bits 19:8.  */
4774   inst.instruction |= (number & 0xfff0) << 4;
4775
4776   /* Bottom 4 of 16 bits to bits 3:0.  */
4777   inst.instruction |= number & 0xf;
4778
4779   end_of_line (str);
4780 }
4781
4782 /* THUMB CPS instruction (argument parse).  */
4783
4784 static void
4785 do_t_cps (char * str)
4786 {
4787   do_cps_flags (&str, /*thumb_p=*/1);
4788   end_of_line (str);
4789 }
4790
4791 /* Parse and validate that a register is of the right form, this saves
4792    repeated checking of this information in many similar cases.
4793    Unlike the 32-bit case we do not insert the register into the opcode
4794    here, since the position is often unknown until the full instruction
4795    has been parsed.  */
4796
4797 static int
4798 thumb_reg (char ** strp, int hi_lo)
4799 {
4800   int reg;
4801
4802   if ((reg = reg_required_here (strp, -1)) == FAIL)
4803     return FAIL;
4804
4805   switch (hi_lo)
4806     {
4807     case THUMB_REG_LO:
4808       if (reg > 7)
4809         {
4810           inst.error = _("lo register required");
4811           return FAIL;
4812         }
4813       break;
4814
4815     case THUMB_REG_HI:
4816       if (reg < 8)
4817         {
4818           inst.error = _("hi register required");
4819           return FAIL;
4820         }
4821       break;
4822
4823     default:
4824       break;
4825     }
4826
4827   return reg;
4828 }
4829
4830 static void
4831 thumb_mov_compare (char * str, int move)
4832 {
4833   int Rd, Rs = FAIL;
4834
4835   skip_whitespace (str);
4836
4837   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4838       || skip_past_comma (&str) == FAIL)
4839     {
4840       if (! inst.error)
4841         inst.error = BAD_ARGS;
4842       return;
4843     }
4844
4845   if (move != THUMB_CPY && is_immediate_prefix (*str))
4846     {
4847       str++;
4848       if (my_get_expression (&inst.reloc.exp, &str))
4849         return;
4850     }
4851   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4852     return;
4853
4854   if (Rs != FAIL)
4855     {
4856       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
4857         {
4858           if (move == THUMB_MOVE)
4859             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4860                since a MOV instruction produces unpredictable results.  */
4861             inst.instruction = T_OPCODE_ADD_I3;
4862           else
4863             inst.instruction = T_OPCODE_CMP_LR;
4864           inst.instruction |= Rd | (Rs << 3);
4865         }
4866       else
4867         {
4868           if (move == THUMB_MOVE)
4869             inst.instruction = T_OPCODE_MOV_HR;
4870           else if (move != THUMB_CPY)
4871             inst.instruction = T_OPCODE_CMP_HR;
4872
4873           if (Rd > 7)
4874             inst.instruction |= THUMB_H1;
4875
4876           if (Rs > 7)
4877             inst.instruction |= THUMB_H2;
4878
4879           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4880         }
4881     }
4882   else
4883     {
4884       if (Rd > 7)
4885         {
4886           inst.error = _("only lo regs allowed with immediate");
4887           return;
4888         }
4889
4890       if (move == THUMB_MOVE)
4891         inst.instruction = T_OPCODE_MOV_I8;
4892       else
4893         inst.instruction = T_OPCODE_CMP_I8;
4894
4895       inst.instruction |= Rd << 8;
4896
4897       if (inst.reloc.exp.X_op != O_constant)
4898         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4899       else
4900         {
4901           unsigned value = inst.reloc.exp.X_add_number;
4902
4903           if (value > 255)
4904             {
4905               inst.error = _("invalid immediate");
4906               return;
4907             }
4908
4909           inst.instruction |= value;
4910         }
4911     }
4912
4913   end_of_line (str);
4914 }
4915
4916 /* THUMB CPY instruction (argument parse).  */
4917
4918 static void
4919 do_t_cpy (char * str)
4920 {
4921   thumb_mov_compare (str, THUMB_CPY);
4922 }
4923
4924 /* THUMB SETEND instruction (argument parse).  */
4925
4926 static void
4927 do_t_setend (char * str)
4928 {
4929   if (do_endian_specifier (str))
4930     inst.instruction |= 0x8;
4931 }
4932
4933 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
4934
4935 static unsigned long
4936 check_iwmmxt_insn (char * str,
4937                    enum iwmmxt_insn_type insn_type,
4938                    int immediate_size)
4939 {
4940   int reg = 0;
4941   const char *  inst_error;
4942   expressionS expr;
4943   unsigned long number;
4944
4945   inst_error = inst.error;
4946   if (!inst.error)
4947     inst.error = BAD_ARGS;
4948   skip_whitespace (str);
4949
4950   switch (insn_type)
4951     {
4952     case check_rd:
4953       if ((reg = reg_required_here (&str, 12)) == FAIL)
4954         return FAIL;
4955       break;
4956
4957     case check_wr:
4958        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4959          return FAIL;
4960        break;
4961
4962     case check_wrwr:
4963       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4964            || skip_past_comma (&str) == FAIL
4965            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4966         return FAIL;
4967       break;
4968
4969     case check_wrwrwr:
4970       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4971            || skip_past_comma (&str) == FAIL
4972            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4973            || skip_past_comma (&str) == FAIL
4974            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4975         return FAIL;
4976       break;
4977
4978     case check_wrwrwcg:
4979       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4980            || skip_past_comma (&str) == FAIL
4981            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4982            || skip_past_comma (&str) == FAIL
4983            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4984         return FAIL;
4985       break;
4986
4987     case check_tbcst:
4988       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4989            || skip_past_comma (&str) == FAIL
4990            || reg_required_here (&str, 12) == FAIL))
4991         return FAIL;
4992       break;
4993
4994     case check_tmovmsk:
4995       if ((reg_required_here (&str, 12) == FAIL
4996            || skip_past_comma (&str) == FAIL
4997            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4998         return FAIL;
4999       break;
5000
5001     case check_tmia:
5002       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5003            || skip_past_comma (&str) == FAIL
5004            || reg_required_here (&str, 0) == FAIL
5005            || skip_past_comma (&str) == FAIL
5006            || reg_required_here (&str, 12) == FAIL))
5007         return FAIL;
5008       break;
5009
5010     case check_tmcrr:
5011       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5012            || skip_past_comma (&str) == FAIL
5013            || reg_required_here (&str, 12) == FAIL
5014            || skip_past_comma (&str) == FAIL
5015            || reg_required_here (&str, 16) == FAIL))
5016         return FAIL;
5017       break;
5018
5019     case check_tmrrc:
5020       if ((reg_required_here (&str, 12) == FAIL
5021            || skip_past_comma (&str) == FAIL
5022            || reg_required_here (&str, 16) == FAIL
5023            || skip_past_comma (&str) == FAIL
5024            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5025         return FAIL;
5026       break;
5027
5028     case check_tmcr:
5029       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5030            || skip_past_comma (&str) == FAIL
5031            || reg_required_here (&str, 12) == FAIL))
5032         return FAIL;
5033       break;
5034
5035     case check_tmrc:
5036       if ((reg_required_here (&str, 12) == FAIL
5037            || skip_past_comma (&str) == FAIL
5038            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5039         return FAIL;
5040       break;
5041
5042     case check_tinsr:
5043       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5044            || skip_past_comma (&str) == FAIL
5045            || reg_required_here (&str, 12) == FAIL
5046            || skip_past_comma (&str) == FAIL))
5047         return FAIL;
5048       break;
5049
5050     case check_textrc:
5051       if ((reg_required_here (&str, 12) == FAIL
5052            || skip_past_comma (&str) == FAIL))
5053         return FAIL;
5054       break;
5055
5056     case check_waligni:
5057       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5058            || skip_past_comma (&str) == FAIL
5059            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5060            || skip_past_comma (&str) == FAIL
5061            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5062            || skip_past_comma (&str) == FAIL))
5063         return FAIL;
5064       break;
5065
5066     case check_textrm:
5067       if ((reg_required_here (&str, 12) == FAIL
5068            || skip_past_comma (&str) == FAIL
5069            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5070            || skip_past_comma (&str) == FAIL))
5071         return FAIL;
5072       break;
5073
5074     case check_wshufh:
5075       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5076            || skip_past_comma (&str) == FAIL
5077            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5078            || skip_past_comma (&str) == FAIL))
5079         return FAIL;
5080       break;
5081     }
5082
5083   if (immediate_size == 0)
5084     {
5085       end_of_line (str);
5086       inst.error = inst_error;
5087       return reg;
5088     }
5089   else
5090     {
5091       skip_whitespace (str);
5092
5093       /* Allow optional leading '#'.  */
5094       if (is_immediate_prefix (* str))
5095         str++;
5096
5097       memset (& expr, '\0', sizeof (expr));
5098
5099       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5100         {
5101           inst.error = _("bad or missing expression");
5102           return FAIL;
5103         }
5104
5105       number = expr.X_add_number;
5106
5107       if (number != (number & immediate_size))
5108         {
5109           inst.error = _("immediate value out of range");
5110           return FAIL;
5111         }
5112       end_of_line (str);
5113       inst.error = inst_error;
5114       return number;
5115     }
5116 }
5117
5118 static void
5119 do_iwmmxt_byte_addr (char * str)
5120 {
5121   int op = (inst.instruction & 0x300) >> 8;
5122   int reg;
5123
5124   inst.instruction &= ~0x300;
5125   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5126
5127   skip_whitespace (str);
5128
5129   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5130       || skip_past_comma (& str) == FAIL
5131       || cp_byte_address_required_here (&str) == FAIL)
5132     {
5133       if (! inst.error)
5134         inst.error = BAD_ARGS;
5135     }
5136   else
5137     end_of_line (str);
5138
5139   if (wc_register (reg))
5140     {
5141       as_bad (_("non-word size not supported with control register"));
5142       inst.instruction |=  0xf0000100;
5143       inst.instruction &= ~0x00400000;
5144     }
5145 }
5146
5147 static void
5148 do_iwmmxt_tandc (char * str)
5149 {
5150   int reg;
5151
5152   reg = check_iwmmxt_insn (str, check_rd, 0);
5153
5154   if (reg != REG_PC && !inst.error)
5155     inst.error = _("only r15 allowed here");
5156 }
5157
5158 static void
5159 do_iwmmxt_tbcst (char * str)
5160 {
5161   check_iwmmxt_insn (str, check_tbcst, 0);
5162 }
5163
5164 static void
5165 do_iwmmxt_textrc (char * str)
5166 {
5167   unsigned long number;
5168
5169   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5170     return;
5171
5172   inst.instruction |= number & 0x7;
5173 }
5174
5175 static void
5176 do_iwmmxt_textrm (char * str)
5177 {
5178   unsigned long number;
5179
5180   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5181     return;
5182
5183   inst.instruction |= number & 0x7;
5184 }
5185
5186 static void
5187 do_iwmmxt_tinsr (char * str)
5188 {
5189   unsigned long number;
5190
5191   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5192     return;
5193
5194   inst.instruction |= number & 0x7;
5195 }
5196
5197 static void
5198 do_iwmmxt_tmcr (char * str)
5199 {
5200   check_iwmmxt_insn (str, check_tmcr, 0);
5201 }
5202
5203 static void
5204 do_iwmmxt_tmcrr (char * str)
5205 {
5206   check_iwmmxt_insn (str, check_tmcrr, 0);
5207 }
5208
5209 static void
5210 do_iwmmxt_tmia (char * str)
5211 {
5212   check_iwmmxt_insn (str, check_tmia, 0);
5213 }
5214
5215 static void
5216 do_iwmmxt_tmovmsk (char * str)
5217 {
5218   check_iwmmxt_insn (str, check_tmovmsk, 0);
5219 }
5220
5221 static void
5222 do_iwmmxt_tmrc (char * str)
5223 {
5224   check_iwmmxt_insn (str, check_tmrc, 0);
5225 }
5226
5227 static void
5228 do_iwmmxt_tmrrc (char * str)
5229 {
5230   check_iwmmxt_insn (str, check_tmrrc, 0);
5231 }
5232
5233 static void
5234 do_iwmmxt_torc (char * str)
5235 {
5236   check_iwmmxt_insn (str, check_rd, 0);
5237 }
5238
5239 static void
5240 do_iwmmxt_waligni (char * str)
5241 {
5242   unsigned long number;
5243
5244   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5245     return;
5246
5247   inst.instruction |= ((number & 0x7) << 20);
5248 }
5249
5250 static void
5251 do_iwmmxt_wmov (char * str)
5252 {
5253   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5254     return;
5255
5256   inst.instruction |= ((inst.instruction >> 16) & 0xf);
5257 }
5258
5259 static void
5260 do_iwmmxt_word_addr (char * str)
5261 {
5262   int op = (inst.instruction & 0x300) >> 8;
5263   int reg;
5264
5265   inst.instruction &= ~0x300;
5266   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5267
5268   skip_whitespace (str);
5269
5270   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5271       || skip_past_comma (& str) == FAIL
5272       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5273     {
5274       if (! inst.error)
5275         inst.error = BAD_ARGS;
5276     }
5277   else
5278     end_of_line (str);
5279
5280   if (wc_register (reg))
5281     {
5282       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5283         as_bad (_("conditional execution not supported with control register"));
5284       if (op != 2)
5285         as_bad (_("non-word size not supported with control register"));
5286       inst.instruction |=  0xf0000100;
5287       inst.instruction &= ~0x00400000;
5288     }
5289 }
5290
5291 static void
5292 do_iwmmxt_wrwr (char * str)
5293 {
5294   check_iwmmxt_insn (str, check_wrwr, 0);
5295 }
5296
5297 static void
5298 do_iwmmxt_wrwrwcg (char * str)
5299 {
5300   check_iwmmxt_insn (str, check_wrwrwcg, 0);
5301 }
5302
5303 static void
5304 do_iwmmxt_wrwrwr (char * str)
5305 {
5306   check_iwmmxt_insn (str, check_wrwrwr, 0);
5307 }
5308
5309 static void
5310 do_iwmmxt_wshufh (char * str)
5311 {
5312   unsigned long number;
5313
5314   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5315     return;
5316
5317   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5318 }
5319
5320 static void
5321 do_iwmmxt_wzero (char * str)
5322 {
5323   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5324     return;
5325
5326   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5327 }
5328
5329 /* Xscale multiply-accumulate (argument parse)
5330      MIAcc   acc0,Rm,Rs
5331      MIAPHcc acc0,Rm,Rs
5332      MIAxycc acc0,Rm,Rs.  */
5333
5334 static void
5335 do_xsc_mia (char * str)
5336 {
5337   int rs;
5338   int rm;
5339
5340   if (accum0_required_here (& str) == FAIL)
5341     inst.error = ERR_NO_ACCUM;
5342
5343   else if (skip_past_comma (& str) == FAIL
5344            || (rm = reg_required_here (& str, 0)) == FAIL)
5345     inst.error = BAD_ARGS;
5346
5347   else if (skip_past_comma (& str) == FAIL
5348            || (rs = reg_required_here (& str, 12)) == FAIL)
5349     inst.error = BAD_ARGS;
5350
5351   /* inst.instruction has now been zapped with both rm and rs.  */
5352   else if (rm == REG_PC || rs == REG_PC)
5353     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
5354
5355   else
5356     end_of_line (str);
5357 }
5358
5359 /* Xscale move-accumulator-register (argument parse)
5360
5361      MARcc   acc0,RdLo,RdHi.  */
5362
5363 static void
5364 do_xsc_mar (char * str)
5365 {
5366   int rdlo, rdhi;
5367
5368   if (accum0_required_here (& str) == FAIL)
5369     inst.error = ERR_NO_ACCUM;
5370
5371   else if (skip_past_comma (& str) == FAIL
5372            || (rdlo = reg_required_here (& str, 12)) == FAIL)
5373     inst.error = BAD_ARGS;
5374
5375   else if (skip_past_comma (& str) == FAIL
5376            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5377     inst.error = BAD_ARGS;
5378
5379   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5380   else if (rdlo == REG_PC || rdhi == REG_PC)
5381     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5382
5383   else
5384     end_of_line (str);
5385 }
5386
5387 /* Xscale move-register-accumulator (argument parse)
5388
5389      MRAcc   RdLo,RdHi,acc0.  */
5390
5391 static void
5392 do_xsc_mra (char * str)
5393 {
5394   int rdlo;
5395   int rdhi;
5396
5397   skip_whitespace (str);
5398
5399   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5400     inst.error = BAD_ARGS;
5401
5402   else if (skip_past_comma (& str) == FAIL
5403            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5404     inst.error = BAD_ARGS;
5405
5406   else if  (skip_past_comma (& str) == FAIL
5407             || accum0_required_here (& str) == FAIL)
5408     inst.error = ERR_NO_ACCUM;
5409
5410   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5411   else if (rdlo == rdhi)
5412     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
5413
5414   else if (rdlo == REG_PC || rdhi == REG_PC)
5415     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5416   else
5417     end_of_line (str);
5418 }
5419
5420 static int
5421 ldst_extend (char ** str)
5422 {
5423   int add = INDEX_UP;
5424
5425   switch (**str)
5426     {
5427     case '#':
5428     case '$':
5429       (*str)++;
5430       if (my_get_expression (& inst.reloc.exp, str))
5431         return FAIL;
5432
5433       if (inst.reloc.exp.X_op == O_constant)
5434         {
5435           int value = inst.reloc.exp.X_add_number;
5436
5437           if (value < -4095 || value > 4095)
5438             {
5439               inst.error = _("address offset too large");
5440               return FAIL;
5441             }
5442
5443           if (value < 0)
5444             {
5445               value = -value;
5446               add = 0;
5447             }
5448
5449           inst.instruction |= add | value;
5450         }
5451       else
5452         {
5453           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5454           inst.reloc.pc_rel = 0;
5455         }
5456       return SUCCESS;
5457
5458     case '-':
5459       add = 0;
5460       /* Fall through.  */
5461
5462     case '+':
5463       (*str)++;
5464       /* Fall through.  */
5465
5466     default:
5467       if (reg_required_here (str, 0) == FAIL)
5468         return FAIL;
5469
5470       inst.instruction |= add | OFFSET_REG;
5471       if (skip_past_comma (str) == SUCCESS)
5472         return decode_shift (str, SHIFT_IMMEDIATE);
5473
5474       return SUCCESS;
5475     }
5476 }
5477
5478 /* ARMv5TE: Preload-Cache
5479
5480     PLD <addr_mode>
5481
5482   Syntactically, like LDR with B=1, W=0, L=1.  */
5483
5484 static void
5485 do_pld (char * str)
5486 {
5487   int rd;
5488
5489   skip_whitespace (str);
5490
5491   if (* str != '[')
5492     {
5493       inst.error = _("'[' expected after PLD mnemonic");
5494       return;
5495     }
5496
5497   ++str;
5498   skip_whitespace (str);
5499
5500   if ((rd = reg_required_here (& str, 16)) == FAIL)
5501     return;
5502
5503   skip_whitespace (str);
5504
5505   if (*str == ']')
5506     {
5507       /* [Rn], ... ?  */
5508       ++str;
5509       skip_whitespace (str);
5510
5511       /* Post-indexed addressing is not allowed with PLD.  */
5512       if (skip_past_comma (&str) == SUCCESS)
5513         {
5514           inst.error
5515             = _("post-indexed expression used in preload instruction");
5516           return;
5517         }
5518       else if (*str == '!') /* [Rn]! */
5519         {
5520           inst.error = _("writeback used in preload instruction");
5521           ++str;
5522         }
5523       else /* [Rn] */
5524         inst.instruction |= INDEX_UP | PRE_INDEX;
5525     }
5526   else /* [Rn, ...] */
5527     {
5528       if (skip_past_comma (& str) == FAIL)
5529         {
5530           inst.error = _("pre-indexed expression expected");
5531           return;
5532         }
5533
5534       if (ldst_extend (&str) == FAIL)
5535         return;
5536
5537       skip_whitespace (str);
5538
5539       if (* str != ']')
5540         {
5541           inst.error = _("missing ]");
5542           return;
5543         }
5544
5545       ++ str;
5546       skip_whitespace (str);
5547
5548       if (* str == '!') /* [Rn]! */
5549         {
5550           inst.error = _("writeback used in preload instruction");
5551           ++ str;
5552         }
5553
5554       inst.instruction |= PRE_INDEX;
5555     }
5556
5557   end_of_line (str);
5558 }
5559
5560 /* ARMv5TE load-consecutive (argument parse)
5561    Mode is like LDRH.
5562
5563      LDRccD R, mode
5564      STRccD R, mode.  */
5565
5566 static void
5567 do_ldrd (char * str)
5568 {
5569   int rd;
5570   int rn;
5571
5572   skip_whitespace (str);
5573
5574   if ((rd = reg_required_here (& str, 12)) == FAIL)
5575     {
5576       inst.error = BAD_ARGS;
5577       return;
5578     }
5579
5580   if (skip_past_comma (& str) == FAIL
5581       || (rn = ld_mode_required_here (& str)) == FAIL)
5582     {
5583       if (!inst.error)
5584         inst.error = BAD_ARGS;
5585       return;
5586     }
5587
5588   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
5589   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
5590     {
5591       inst.error = _("destination register must be even");
5592       return;
5593     }
5594
5595   if (rd == REG_LR)
5596     {
5597       inst.error = _("r14 not allowed here");
5598       return;
5599     }
5600
5601   if (((rd == rn) || (rd + 1 == rn))
5602       && ((inst.instruction & WRITE_BACK)
5603           || (!(inst.instruction & PRE_INDEX))))
5604     as_warn (_("pre/post-indexing used when modified address register is destination"));
5605
5606   /* For an index-register load, the index register must not overlap the
5607      destination (even if not write-back).  */
5608   if ((inst.instruction & V4_STR_BIT) == 0
5609       && (inst.instruction & HWOFFSET_IMM) == 0)
5610     {
5611       int rm = inst.instruction & 0x0000000f;
5612
5613       if (rm == rd || (rm == rd + 1))
5614         as_warn (_("ldrd destination registers must not overlap index register"));
5615     }
5616
5617   end_of_line (str);
5618 }
5619
5620 /* Returns the index into fp_values of a floating point number,
5621    or -1 if not in the table.  */
5622
5623 static int
5624 my_get_float_expression (char ** str)
5625 {
5626   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5627   char *         save_in;
5628   expressionS    exp;
5629   int            i;
5630   int            j;
5631
5632   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5633
5634   /* Look for a raw floating point number.  */
5635   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5636       && is_end_of_line[(unsigned char) *save_in])
5637     {
5638       for (i = 0; i < NUM_FLOAT_VALS; i++)
5639         {
5640           for (j = 0; j < MAX_LITTLENUMS; j++)
5641             {
5642               if (words[j] != fp_values[i][j])
5643                 break;
5644             }
5645
5646           if (j == MAX_LITTLENUMS)
5647             {
5648               *str = save_in;
5649               return i;
5650             }
5651         }
5652     }
5653
5654   /* Try and parse a more complex expression, this will probably fail
5655      unless the code uses a floating point prefix (eg "0f").  */
5656   save_in = input_line_pointer;
5657   input_line_pointer = *str;
5658   if (expression (&exp) == absolute_section
5659       && exp.X_op == O_big
5660       && exp.X_add_number < 0)
5661     {
5662       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5663          Ditto for 15.  */
5664       if (gen_to_words (words, 5, (long) 15) == 0)
5665         {
5666           for (i = 0; i < NUM_FLOAT_VALS; i++)
5667             {
5668               for (j = 0; j < MAX_LITTLENUMS; j++)
5669                 {
5670                   if (words[j] != fp_values[i][j])
5671                     break;
5672                 }
5673
5674               if (j == MAX_LITTLENUMS)
5675                 {
5676                   *str = input_line_pointer;
5677                   input_line_pointer = save_in;
5678                   return i;
5679                 }
5680             }
5681         }
5682     }
5683
5684   *str = input_line_pointer;
5685   input_line_pointer = save_in;
5686   return -1;
5687 }
5688
5689 /* We handle all bad expressions here, so that we can report the faulty
5690    instruction in the error message.  */
5691 void
5692 md_operand (expressionS * expr)
5693 {
5694   if (in_my_get_expression)
5695     {
5696       expr->X_op = O_illegal;
5697       if (inst.error == NULL)
5698         inst.error = _("bad expression");
5699     }
5700 }
5701
5702 /* Do those data_ops which can take a negative immediate constant
5703    by altering the instruction.  A bit of a hack really.
5704         MOV <-> MVN
5705         AND <-> BIC
5706         ADC <-> SBC
5707         by inverting the second operand, and
5708         ADD <-> SUB
5709         CMP <-> CMN
5710         by negating the second operand.  */
5711
5712 static int
5713 negate_data_op (unsigned long * instruction,
5714                 unsigned long   value)
5715 {
5716   int op, new_inst;
5717   unsigned long negated, inverted;
5718
5719   negated = validate_immediate (-value);
5720   inverted = validate_immediate (~value);
5721
5722   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5723   switch (op)
5724     {
5725       /* First negates.  */
5726     case OPCODE_SUB:             /* ADD <-> SUB  */
5727       new_inst = OPCODE_ADD;
5728       value = negated;
5729       break;
5730
5731     case OPCODE_ADD:
5732       new_inst = OPCODE_SUB;
5733       value = negated;
5734       break;
5735
5736     case OPCODE_CMP:             /* CMP <-> CMN  */
5737       new_inst = OPCODE_CMN;
5738       value = negated;
5739       break;
5740
5741     case OPCODE_CMN:
5742       new_inst = OPCODE_CMP;
5743       value = negated;
5744       break;
5745
5746       /* Now Inverted ops.  */
5747     case OPCODE_MOV:             /* MOV <-> MVN  */
5748       new_inst = OPCODE_MVN;
5749       value = inverted;
5750       break;
5751
5752     case OPCODE_MVN:
5753       new_inst = OPCODE_MOV;
5754       value = inverted;
5755       break;
5756
5757     case OPCODE_AND:             /* AND <-> BIC  */
5758       new_inst = OPCODE_BIC;
5759       value = inverted;
5760       break;
5761
5762     case OPCODE_BIC:
5763       new_inst = OPCODE_AND;
5764       value = inverted;
5765       break;
5766
5767     case OPCODE_ADC:              /* ADC <-> SBC  */
5768       new_inst = OPCODE_SBC;
5769       value = inverted;
5770       break;
5771
5772     case OPCODE_SBC:
5773       new_inst = OPCODE_ADC;
5774       value = inverted;
5775       break;
5776
5777       /* We cannot do anything.  */
5778     default:
5779       return FAIL;
5780     }
5781
5782   if (value == (unsigned) FAIL)
5783     return FAIL;
5784
5785   *instruction &= OPCODE_MASK;
5786   *instruction |= new_inst << DATA_OP_SHIFT;
5787   return value;
5788 }
5789
5790 static int
5791 data_op2 (char ** str)
5792 {
5793   int value;
5794   expressionS expr;
5795
5796   skip_whitespace (* str);
5797
5798   if (reg_required_here (str, 0) != FAIL)
5799     {
5800       if (skip_past_comma (str) == SUCCESS)
5801         /* Shift operation on register.  */
5802         return decode_shift (str, NO_SHIFT_RESTRICT);
5803
5804       return SUCCESS;
5805     }
5806   else
5807     {
5808       /* Immediate expression.  */
5809       if (is_immediate_prefix (**str))
5810         {
5811           (*str)++;
5812           inst.error = NULL;
5813
5814           if (my_get_expression (&inst.reloc.exp, str))
5815             return FAIL;
5816
5817           if (inst.reloc.exp.X_add_symbol)
5818             {
5819               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5820               inst.reloc.pc_rel = 0;
5821             }
5822           else
5823             {
5824               if (skip_past_comma (str) == SUCCESS)
5825                 {
5826                   /* #x, y -- ie explicit rotation by Y.  */
5827                   if (my_get_expression (&expr, str))
5828                     return FAIL;
5829
5830                   if (expr.X_op != O_constant)
5831                     {
5832                       inst.error = _("constant expression expected");
5833                       return FAIL;
5834                     }
5835
5836                   /* Rotate must be a multiple of 2.  */
5837                   if (((unsigned) expr.X_add_number) > 30
5838                       || (expr.X_add_number & 1) != 0
5839                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
5840                     {
5841                       inst.error = _("invalid constant");
5842                       return FAIL;
5843                     }
5844                   inst.instruction |= INST_IMMEDIATE;
5845                   inst.instruction |= inst.reloc.exp.X_add_number;
5846                   inst.instruction |= expr.X_add_number << 7;
5847                   return SUCCESS;
5848                 }
5849
5850               /* Implicit rotation, select a suitable one.  */
5851               value = validate_immediate (inst.reloc.exp.X_add_number);
5852
5853               if (value == FAIL)
5854                 {
5855                   /* Can't be done.  Perhaps the code reads something like
5856                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
5857                   if ((value = negate_data_op (&inst.instruction,
5858                                                inst.reloc.exp.X_add_number))
5859                       == FAIL)
5860                     {
5861                       inst.error = _("invalid constant");
5862                       return FAIL;
5863                     }
5864                 }
5865
5866               inst.instruction |= value;
5867             }
5868
5869           inst.instruction |= INST_IMMEDIATE;
5870           return SUCCESS;
5871         }
5872
5873       (*str)++;
5874       inst.error = _("register or shift expression expected");
5875       return FAIL;
5876     }
5877 }
5878
5879 static int
5880 fp_op2 (char ** str)
5881 {
5882   skip_whitespace (* str);
5883
5884   if (fp_reg_required_here (str, 0) != FAIL)
5885     return SUCCESS;
5886   else
5887     {
5888       /* Immediate expression.  */
5889       if (*((*str)++) == '#')
5890         {
5891           int i;
5892
5893           inst.error = NULL;
5894
5895           skip_whitespace (* str);
5896
5897           /* First try and match exact strings, this is to guarantee
5898              that some formats will work even for cross assembly.  */
5899
5900           for (i = 0; fp_const[i]; i++)
5901             {
5902               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
5903                 {
5904                   char *start = *str;
5905
5906                   *str += strlen (fp_const[i]);
5907                   if (is_end_of_line[(unsigned char) **str])
5908                     {
5909                       inst.instruction |= i + 8;
5910                       return SUCCESS;
5911                     }
5912                   *str = start;
5913                 }
5914             }
5915
5916           /* Just because we didn't get a match doesn't mean that the
5917              constant isn't valid, just that it is in a format that we
5918              don't automatically recognize.  Try parsing it with
5919              the standard expression routines.  */
5920           if ((i = my_get_float_expression (str)) >= 0)
5921             {
5922               inst.instruction |= i + 8;
5923               return SUCCESS;
5924             }
5925
5926           inst.error = _("invalid floating point immediate expression");
5927           return FAIL;
5928         }
5929       inst.error =
5930         _("floating point register or immediate expression expected");
5931       return FAIL;
5932     }
5933 }
5934
5935 static void
5936 do_arit (char * str)
5937 {
5938   skip_whitespace (str);
5939
5940   if (reg_required_here (&str, 12) == FAIL
5941       || skip_past_comma (&str) == FAIL
5942       || reg_required_here (&str, 16) == FAIL
5943       || skip_past_comma (&str) == FAIL
5944       || data_op2 (&str) == FAIL)
5945     {
5946       if (!inst.error)
5947         inst.error = BAD_ARGS;
5948       return;
5949     }
5950
5951   end_of_line (str);
5952 }
5953
5954 static void
5955 do_adr (char * str)
5956 {
5957   /* This is a pseudo-op of the form "adr rd, label" to be converted
5958      into a relative address of the form "add rd, pc, #label-.-8".  */
5959   skip_whitespace (str);
5960
5961   if (reg_required_here (&str, 12) == FAIL
5962       || skip_past_comma (&str) == FAIL
5963       || my_get_expression (&inst.reloc.exp, &str))
5964     {
5965       if (!inst.error)
5966         inst.error = BAD_ARGS;
5967       return;
5968     }
5969
5970   /* Frag hacking will turn this into a sub instruction if the offset turns
5971      out to be negative.  */
5972   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5973 #ifndef TE_WINCE
5974   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
5975 #endif
5976   inst.reloc.pc_rel = 1;
5977
5978   end_of_line (str);
5979 }
5980
5981 static void
5982 do_adrl (char * str)
5983 {
5984   /* This is a pseudo-op of the form "adrl rd, label" to be converted
5985      into a relative address of the form:
5986      add rd, pc, #low(label-.-8)"
5987      add rd, rd, #high(label-.-8)"  */
5988
5989   skip_whitespace (str);
5990
5991   if (reg_required_here (&str, 12) == FAIL
5992       || skip_past_comma (&str) == FAIL
5993       || my_get_expression (&inst.reloc.exp, &str))
5994     {
5995       if (!inst.error)
5996         inst.error = BAD_ARGS;
5997
5998       return;
5999     }
6000
6001   end_of_line (str);
6002   /* Frag hacking will turn this into a sub instruction if the offset turns
6003      out to be negative.  */
6004   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6005 #ifndef TE_WINCE
6006   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
6007 #endif
6008   inst.reloc.pc_rel            = 1;
6009   inst.size                    = INSN_SIZE * 2;
6010 }
6011
6012 static void
6013 do_cmp (char * str)
6014 {
6015   skip_whitespace (str);
6016
6017   if (reg_required_here (&str, 16) == FAIL)
6018     {
6019       if (!inst.error)
6020         inst.error = BAD_ARGS;
6021       return;
6022     }
6023
6024   if (skip_past_comma (&str) == FAIL
6025       || data_op2 (&str) == FAIL)
6026     {
6027       if (!inst.error)
6028         inst.error = BAD_ARGS;
6029       return;
6030     }
6031
6032   end_of_line (str);
6033 }
6034
6035 static void
6036 do_mov (char * str)
6037 {
6038   skip_whitespace (str);
6039
6040   if (reg_required_here (&str, 12) == FAIL)
6041     {
6042       if (!inst.error)
6043         inst.error = BAD_ARGS;
6044       return;
6045     }
6046
6047   if (skip_past_comma (&str) == FAIL
6048       || data_op2 (&str) == FAIL)
6049     {
6050       if (!inst.error)
6051         inst.error = BAD_ARGS;
6052       return;
6053     }
6054
6055   end_of_line (str);
6056 }
6057
6058 static void
6059 do_ldst (char * str)
6060 {
6061   int pre_inc = 0;
6062   int conflict_reg;
6063   int value;
6064
6065   skip_whitespace (str);
6066
6067   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6068     {
6069       if (!inst.error)
6070         inst.error = BAD_ARGS;
6071       return;
6072     }
6073
6074   if (skip_past_comma (&str) == FAIL)
6075     {
6076       inst.error = _("address expected");
6077       return;
6078     }
6079
6080   if (*str == '[')
6081     {
6082       int reg;
6083
6084       str++;
6085
6086       skip_whitespace (str);
6087
6088       if ((reg = reg_required_here (&str, 16)) == FAIL)
6089         return;
6090
6091       /* Conflicts can occur on stores as well as loads.  */
6092       conflict_reg = (conflict_reg == reg);
6093
6094       skip_whitespace (str);
6095
6096       if (*str == ']')
6097         {
6098           str ++;
6099
6100           if (skip_past_comma (&str) == SUCCESS)
6101             {
6102               /* [Rn],... (post inc)  */
6103               if (ldst_extend (&str) == FAIL)
6104                 return;
6105               if (conflict_reg)
6106                 as_warn (_("%s register same as write-back base"),
6107                          ((inst.instruction & LOAD_BIT)
6108                           ? _("destination") : _("source")));
6109             }
6110           else
6111             {
6112               /* [Rn]  */
6113               skip_whitespace (str);
6114
6115               if (*str == '!')
6116                 {
6117                   if (conflict_reg)
6118                     as_warn (_("%s register same as write-back base"),
6119                              ((inst.instruction & LOAD_BIT)
6120                               ? _("destination") : _("source")));
6121                   str++;
6122                   inst.instruction |= WRITE_BACK;
6123                 }
6124
6125               inst.instruction |= INDEX_UP;
6126               pre_inc = 1;
6127             }
6128         }
6129       else
6130         {
6131           /* [Rn,...]  */
6132           if (skip_past_comma (&str) == FAIL)
6133             {
6134               inst.error = _("pre-indexed expression expected");
6135               return;
6136             }
6137
6138           pre_inc = 1;
6139           if (ldst_extend (&str) == FAIL)
6140             return;
6141
6142           skip_whitespace (str);
6143
6144           if (*str++ != ']')
6145             {
6146               inst.error = _("missing ]");
6147               return;
6148             }
6149
6150           skip_whitespace (str);
6151
6152           if (*str == '!')
6153             {
6154               if (conflict_reg)
6155                 as_warn (_("%s register same as write-back base"),
6156                          ((inst.instruction & LOAD_BIT)
6157                           ? _("destination") : _("source")));
6158               str++;
6159               inst.instruction |= WRITE_BACK;
6160             }
6161         }
6162     }
6163   else if (*str == '=')
6164     {
6165       if ((inst.instruction & LOAD_BIT) == 0)
6166         {
6167           inst.error = _("invalid pseudo operation");
6168           return;
6169         }
6170
6171       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6172       str++;
6173
6174       skip_whitespace (str);
6175
6176       if (my_get_expression (&inst.reloc.exp, &str))
6177         return;
6178
6179       if (inst.reloc.exp.X_op != O_constant
6180           && inst.reloc.exp.X_op != O_symbol)
6181         {
6182           inst.error = _("constant expression expected");
6183           return;
6184         }
6185
6186       if (inst.reloc.exp.X_op == O_constant)
6187         {
6188           value = validate_immediate (inst.reloc.exp.X_add_number);
6189
6190           if (value != FAIL)
6191             {
6192               /* This can be done with a mov instruction.  */
6193               inst.instruction &= LITERAL_MASK;
6194               inst.instruction |= (INST_IMMEDIATE
6195                                    | (OPCODE_MOV << DATA_OP_SHIFT));
6196               inst.instruction |= value & 0xfff;
6197               end_of_line (str);
6198               return;
6199             }
6200
6201           value = validate_immediate (~inst.reloc.exp.X_add_number);
6202
6203           if (value != FAIL)
6204             {
6205               /* This can be done with a mvn instruction.  */
6206               inst.instruction &= LITERAL_MASK;
6207               inst.instruction |= (INST_IMMEDIATE
6208                                    | (OPCODE_MVN << DATA_OP_SHIFT));
6209               inst.instruction |= value & 0xfff;
6210               end_of_line (str);
6211               return;
6212             }
6213         }
6214
6215       /* Insert into literal pool.  */
6216       if (add_to_lit_pool () == FAIL)
6217         {
6218           if (!inst.error)
6219             inst.error = _("literal pool insertion failed");
6220           return;
6221         }
6222
6223       /* Change the instruction exp to point to the pool.  */
6224       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6225       inst.reloc.pc_rel = 1;
6226       inst.instruction |= (REG_PC << 16);
6227       pre_inc = 1;
6228     }
6229   else
6230     {
6231       if (my_get_expression (&inst.reloc.exp, &str))
6232         return;
6233
6234       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6235 #ifndef TE_WINCE
6236       /* PC rel adjust.  */
6237       inst.reloc.exp.X_add_number -= 8;
6238 #endif
6239       inst.reloc.pc_rel = 1;
6240       inst.instruction |= (REG_PC << 16);
6241       pre_inc = 1;
6242     }
6243
6244   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6245   end_of_line (str);
6246 }
6247
6248 static void
6249 do_ldstt (char * str)
6250 {
6251   int conflict_reg;
6252
6253   skip_whitespace (str);
6254
6255   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6256     {
6257       if (!inst.error)
6258         inst.error = BAD_ARGS;
6259       return;
6260     }
6261
6262   if (skip_past_comma (& str) == FAIL)
6263     {
6264       inst.error = _("address expected");
6265       return;
6266     }
6267
6268   if (*str == '[')
6269     {
6270       int reg;
6271
6272       str++;
6273
6274       skip_whitespace (str);
6275
6276       if ((reg = reg_required_here (&str, 16)) == FAIL)
6277         return;
6278
6279       /* ldrt/strt always use post-indexed addressing, so if the base is
6280          the same as Rd, we warn.  */
6281       if (conflict_reg == reg)
6282         as_warn (_("%s register same as write-back base"),
6283                  ((inst.instruction & LOAD_BIT)
6284                   ? _("destination") : _("source")));
6285
6286       skip_whitespace (str);
6287
6288       if (*str == ']')
6289         {
6290           str ++;
6291
6292           if (skip_past_comma (&str) == SUCCESS)
6293             {
6294               /* [Rn],... (post inc)  */
6295               if (ldst_extend (&str) == FAIL)
6296                 return;
6297             }
6298           else
6299             {
6300               /* [Rn]  */
6301               skip_whitespace (str);
6302
6303               /* Skip a write-back '!'.  */
6304               if (*str == '!')
6305                 str++;
6306
6307               inst.instruction |= INDEX_UP;
6308             }
6309         }
6310       else
6311         {
6312           inst.error = _("post-indexed expression expected");
6313           return;
6314         }
6315     }
6316   else
6317     {
6318       inst.error = _("post-indexed expression expected");
6319       return;
6320     }
6321
6322   end_of_line (str);
6323 }
6324
6325 /* Halfword and signed-byte load/store operations.  */
6326
6327 static void
6328 do_ldstv4 (char * str)
6329 {
6330   int pre_inc = 0;
6331   int conflict_reg;
6332   int value;
6333
6334   skip_whitespace (str);
6335
6336   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6337     {
6338       if (!inst.error)
6339         inst.error = BAD_ARGS;
6340       return;
6341     }
6342
6343   if (skip_past_comma (& str) == FAIL)
6344     {
6345       inst.error = _("address expected");
6346       return;
6347     }
6348
6349   if (*str == '[')
6350     {
6351       int reg;
6352
6353       str++;
6354
6355       skip_whitespace (str);
6356
6357       if ((reg = reg_required_here (&str, 16)) == FAIL)
6358         return;
6359
6360       /* Conflicts can occur on stores as well as loads.  */
6361       conflict_reg = (conflict_reg == reg);
6362
6363       skip_whitespace (str);
6364
6365       if (*str == ']')
6366         {
6367           str ++;
6368
6369           if (skip_past_comma (&str) == SUCCESS)
6370             {
6371               /* [Rn],... (post inc)  */
6372               if (ldst_extend_v4 (&str) == FAIL)
6373                 return;
6374               if (conflict_reg)
6375                 as_warn (_("%s register same as write-back base"),
6376                          ((inst.instruction & LOAD_BIT)
6377                           ? _("destination") : _("source")));
6378             }
6379           else
6380             {
6381               /* [Rn]  */
6382               inst.instruction |= HWOFFSET_IMM;
6383
6384               skip_whitespace (str);
6385
6386               if (*str == '!')
6387                 {
6388                   if (conflict_reg)
6389                     as_warn (_("%s register same as write-back base"),
6390                              ((inst.instruction & LOAD_BIT)
6391                               ? _("destination") : _("source")));
6392                   str++;
6393                   inst.instruction |= WRITE_BACK;
6394                 }
6395
6396               inst.instruction |= INDEX_UP;
6397               pre_inc = 1;
6398             }
6399         }
6400       else
6401         {
6402           /* [Rn,...]  */
6403           if (skip_past_comma (&str) == FAIL)
6404             {
6405               inst.error = _("pre-indexed expression expected");
6406               return;
6407             }
6408
6409           pre_inc = 1;
6410           if (ldst_extend_v4 (&str) == FAIL)
6411             return;
6412
6413           skip_whitespace (str);
6414
6415           if (*str++ != ']')
6416             {
6417               inst.error = _("missing ]");
6418               return;
6419             }
6420
6421           skip_whitespace (str);
6422
6423           if (*str == '!')
6424             {
6425               if (conflict_reg)
6426                 as_warn (_("%s register same as write-back base"),
6427                          ((inst.instruction & LOAD_BIT)
6428                           ? _("destination") : _("source")));
6429               str++;
6430               inst.instruction |= WRITE_BACK;
6431             }
6432         }
6433     }
6434   else if (*str == '=')
6435     {
6436       if ((inst.instruction & LOAD_BIT) == 0)
6437         {
6438           inst.error = _("invalid pseudo operation");
6439           return;
6440         }
6441
6442       /* XXX Does this work correctly for half-word/byte ops?  */
6443       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6444       str++;
6445
6446       skip_whitespace (str);
6447
6448       if (my_get_expression (&inst.reloc.exp, &str))
6449         return;
6450
6451       if (inst.reloc.exp.X_op != O_constant
6452           && inst.reloc.exp.X_op != O_symbol)
6453         {
6454           inst.error = _("constant expression expected");
6455           return;
6456         }
6457
6458       if (inst.reloc.exp.X_op == O_constant)
6459         {
6460           value = validate_immediate (inst.reloc.exp.X_add_number);
6461
6462           if (value != FAIL)
6463             {
6464               /* This can be done with a mov instruction.  */
6465               inst.instruction &= LITERAL_MASK;
6466               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6467               inst.instruction |= value & 0xfff;
6468               end_of_line (str);
6469               return;
6470             }
6471
6472           value = validate_immediate (~ inst.reloc.exp.X_add_number);
6473
6474           if (value != FAIL)
6475             {
6476               /* This can be done with a mvn instruction.  */
6477               inst.instruction &= LITERAL_MASK;
6478               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6479               inst.instruction |= value & 0xfff;
6480               end_of_line (str);
6481               return;
6482             }
6483         }
6484
6485       /* Insert into literal pool.  */
6486       if (add_to_lit_pool () == FAIL)
6487         {
6488           if (!inst.error)
6489             inst.error = _("literal pool insertion failed");
6490           return;
6491         }
6492
6493       /* Change the instruction exp to point to the pool.  */
6494       inst.instruction |= HWOFFSET_IMM;
6495       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6496       inst.reloc.pc_rel = 1;
6497       inst.instruction |= (REG_PC << 16);
6498       pre_inc = 1;
6499     }
6500   else
6501     {
6502       if (my_get_expression (&inst.reloc.exp, &str))
6503         return;
6504
6505       inst.instruction |= HWOFFSET_IMM;
6506       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6507 #ifndef TE_WINCE
6508       /* PC rel adjust.  */
6509       inst.reloc.exp.X_add_number -= 8;
6510 #endif
6511       inst.reloc.pc_rel = 1;
6512       inst.instruction |= (REG_PC << 16);
6513       pre_inc = 1;
6514     }
6515
6516   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6517   end_of_line (str);
6518 }
6519
6520 static long
6521 reg_list (char ** strp)
6522 {
6523   char * str = * strp;
6524   long   range = 0;
6525   int    another_range;
6526
6527   /* We come back here if we get ranges concatenated by '+' or '|'.  */
6528   do
6529     {
6530       another_range = 0;
6531
6532       if (*str == '{')
6533         {
6534           int in_range = 0;
6535           int cur_reg = -1;
6536
6537           str++;
6538           do
6539             {
6540               int reg;
6541
6542               skip_whitespace (str);
6543
6544               if ((reg = reg_required_here (& str, -1)) == FAIL)
6545                 return FAIL;
6546
6547               if (in_range)
6548                 {
6549                   int i;
6550
6551                   if (reg <= cur_reg)
6552                     {
6553                       inst.error = _("bad range in register list");
6554                       return FAIL;
6555                     }
6556
6557                   for (i = cur_reg + 1; i < reg; i++)
6558                     {
6559                       if (range & (1 << i))
6560                         as_tsktsk
6561                           (_("Warning: duplicated register (r%d) in register list"),
6562                            i);
6563                       else
6564                         range |= 1 << i;
6565                     }
6566                   in_range = 0;
6567                 }
6568
6569               if (range & (1 << reg))
6570                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6571                            reg);
6572               else if (reg <= cur_reg)
6573                 as_tsktsk (_("Warning: register range not in ascending order"));
6574
6575               range |= 1 << reg;
6576               cur_reg = reg;
6577             }
6578           while (skip_past_comma (&str) != FAIL
6579                  || (in_range = 1, *str++ == '-'));
6580           str--;
6581           skip_whitespace (str);
6582
6583           if (*str++ != '}')
6584             {
6585               inst.error = _("missing `}'");
6586               return FAIL;
6587             }
6588         }
6589       else
6590         {
6591           expressionS expr;
6592
6593           if (my_get_expression (&expr, &str))
6594             return FAIL;
6595
6596           if (expr.X_op == O_constant)
6597             {
6598               if (expr.X_add_number
6599                   != (expr.X_add_number & 0x0000ffff))
6600                 {
6601                   inst.error = _("invalid register mask");
6602                   return FAIL;
6603                 }
6604
6605               if ((range & expr.X_add_number) != 0)
6606                 {
6607                   int regno = range & expr.X_add_number;
6608
6609                   regno &= -regno;
6610                   regno = (1 << regno) - 1;
6611                   as_tsktsk
6612                     (_("Warning: duplicated register (r%d) in register list"),
6613                      regno);
6614                 }
6615
6616               range |= expr.X_add_number;
6617             }
6618           else
6619             {
6620               if (inst.reloc.type != 0)
6621                 {
6622                   inst.error = _("expression too complex");
6623                   return FAIL;
6624                 }
6625
6626               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6627               inst.reloc.type = BFD_RELOC_ARM_MULTI;
6628               inst.reloc.pc_rel = 0;
6629             }
6630         }
6631
6632       skip_whitespace (str);
6633
6634       if (*str == '|' || *str == '+')
6635         {
6636           str++;
6637           another_range = 1;
6638         }
6639     }
6640   while (another_range);
6641
6642   *strp = str;
6643   return range;
6644 }
6645
6646 static void
6647 do_ldmstm (char * str)
6648 {
6649   int base_reg;
6650   long range;
6651
6652   skip_whitespace (str);
6653
6654   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6655     return;
6656
6657   if (base_reg == REG_PC)
6658     {
6659       inst.error = _("r15 not allowed as base register");
6660       return;
6661     }
6662
6663   skip_whitespace (str);
6664
6665   if (*str == '!')
6666     {
6667       inst.instruction |= WRITE_BACK;
6668       str++;
6669     }
6670
6671   if (skip_past_comma (&str) == FAIL
6672       || (range = reg_list (&str)) == FAIL)
6673     {
6674       if (! inst.error)
6675         inst.error = BAD_ARGS;
6676       return;
6677     }
6678
6679   if (*str == '^')
6680     {
6681       str++;
6682       inst.instruction |= LDM_TYPE_2_OR_3;
6683     }
6684
6685   if (inst.instruction & WRITE_BACK)
6686     {
6687       /* Check for unpredictable uses of writeback.  */
6688       if (inst.instruction & LOAD_BIT)
6689         {
6690           /* Not allowed in LDM type 2.  */
6691           if ((inst.instruction & LDM_TYPE_2_OR_3)
6692               && ((range & (1 << REG_PC)) == 0))
6693             as_warn (_("writeback of base register is UNPREDICTABLE"));
6694           /* Only allowed if base reg not in list for other types.  */
6695           else if (range & (1 << base_reg))
6696             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
6697         }
6698       else /* STM.  */
6699         {
6700           /* Not allowed for type 2.  */
6701           if (inst.instruction & LDM_TYPE_2_OR_3)
6702             as_warn (_("writeback of base register is UNPREDICTABLE"));
6703           /* Only allowed if base reg not in list, or first in list.  */
6704           else if ((range & (1 << base_reg))
6705                    && (range & ((1 << base_reg) - 1)))
6706             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
6707         }
6708     }
6709
6710   inst.instruction |= range;
6711   end_of_line (str);
6712 }
6713
6714 static void
6715 do_smi (char * str)
6716 {
6717   skip_whitespace (str);
6718
6719   /* Allow optional leading '#'.  */
6720   if (is_immediate_prefix (*str))
6721     str++;
6722
6723   if (my_get_expression (& inst.reloc.exp, & str))
6724     return;
6725
6726   inst.reloc.type = BFD_RELOC_ARM_SMI;
6727   inst.reloc.pc_rel = 0;
6728   end_of_line (str);
6729 }
6730
6731 static void
6732 do_swi (char * str)
6733 {
6734   skip_whitespace (str);
6735
6736   /* Allow optional leading '#'.  */
6737   if (is_immediate_prefix (*str))
6738     str++;
6739
6740   if (my_get_expression (& inst.reloc.exp, & str))
6741     return;
6742
6743   inst.reloc.type = BFD_RELOC_ARM_SWI;
6744   inst.reloc.pc_rel = 0;
6745   end_of_line (str);
6746 }
6747
6748 static void
6749 do_swap (char * str)
6750 {
6751   int reg;
6752
6753   skip_whitespace (str);
6754
6755   if ((reg = reg_required_here (&str, 12)) == FAIL)
6756     return;
6757
6758   if (reg == REG_PC)
6759     {
6760       inst.error = _("r15 not allowed in swap");
6761       return;
6762     }
6763
6764   if (skip_past_comma (&str) == FAIL
6765       || (reg = reg_required_here (&str, 0)) == FAIL)
6766     {
6767       if (!inst.error)
6768         inst.error = BAD_ARGS;
6769       return;
6770     }
6771
6772   if (reg == REG_PC)
6773     {
6774       inst.error = _("r15 not allowed in swap");
6775       return;
6776     }
6777
6778   if (skip_past_comma (&str) == FAIL
6779       || *str++ != '[')
6780     {
6781       inst.error = BAD_ARGS;
6782       return;
6783     }
6784
6785   skip_whitespace (str);
6786
6787   if ((reg = reg_required_here (&str, 16)) == FAIL)
6788     return;
6789
6790   if (reg == REG_PC)
6791     {
6792       inst.error = BAD_PC;
6793       return;
6794     }
6795
6796   skip_whitespace (str);
6797
6798   if (*str++ != ']')
6799     {
6800       inst.error = _("missing ]");
6801       return;
6802     }
6803
6804   end_of_line (str);
6805 }
6806
6807 static void
6808 do_branch (char * str)
6809 {
6810   if (my_get_expression (&inst.reloc.exp, &str))
6811     return;
6812
6813 #ifdef OBJ_ELF
6814   {
6815     char * save_in;
6816
6817     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
6818        required for the instruction.  */
6819
6820     /* arm_parse_reloc () works on input_line_pointer.
6821        We actually want to parse the operands to the branch instruction
6822        passed in 'str'.  Save the input pointer and restore it later.  */
6823     save_in = input_line_pointer;
6824     input_line_pointer = str;
6825     if (inst.reloc.exp.X_op == O_symbol
6826         && *str == '('
6827         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
6828       {
6829         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
6830         inst.reloc.pc_rel = 0;
6831         /* Modify str to point to after parsed operands, otherwise
6832            end_of_line() will complain about the (PLT) left in str.  */
6833         str = input_line_pointer;
6834       }
6835     else
6836       {
6837         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6838         inst.reloc.pc_rel = 1;
6839       }
6840     input_line_pointer = save_in;
6841   }
6842 #else
6843   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6844   inst.reloc.pc_rel = 1;
6845 #endif /* OBJ_ELF  */
6846
6847   end_of_line (str);
6848 }
6849
6850 static void
6851 do_cdp (char * str)
6852 {
6853   /* Co-processor data operation.
6854      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
6855   skip_whitespace (str);
6856
6857   if (co_proc_number (&str) == FAIL)
6858     {
6859       if (!inst.error)
6860         inst.error = BAD_ARGS;
6861       return;
6862     }
6863
6864   if (skip_past_comma (&str) == FAIL
6865       || cp_opc_expr (&str, 20,4) == FAIL)
6866     {
6867       if (!inst.error)
6868         inst.error = BAD_ARGS;
6869       return;
6870     }
6871
6872   if (skip_past_comma (&str) == FAIL
6873       || cp_reg_required_here (&str, 12) == FAIL)
6874     {
6875       if (!inst.error)
6876         inst.error = BAD_ARGS;
6877       return;
6878     }
6879
6880   if (skip_past_comma (&str) == FAIL
6881       || cp_reg_required_here (&str, 16) == FAIL)
6882     {
6883       if (!inst.error)
6884         inst.error = BAD_ARGS;
6885       return;
6886     }
6887
6888   if (skip_past_comma (&str) == FAIL
6889       || cp_reg_required_here (&str, 0) == FAIL)
6890     {
6891       if (!inst.error)
6892         inst.error = BAD_ARGS;
6893       return;
6894     }
6895
6896   if (skip_past_comma (&str) == SUCCESS)
6897     {
6898       if (cp_opc_expr (&str, 5, 3) == FAIL)
6899         {
6900           if (!inst.error)
6901             inst.error = BAD_ARGS;
6902           return;
6903         }
6904     }
6905
6906   end_of_line (str);
6907 }
6908
6909 static void
6910 do_lstc (char * str)
6911 {
6912   /* Co-processor register load/store.
6913      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
6914
6915   skip_whitespace (str);
6916
6917   if (co_proc_number (&str) == FAIL)
6918     {
6919       if (!inst.error)
6920         inst.error = BAD_ARGS;
6921       return;
6922     }
6923
6924   if (skip_past_comma (&str) == FAIL
6925       || cp_reg_required_here (&str, 12) == FAIL)
6926     {
6927       if (!inst.error)
6928         inst.error = BAD_ARGS;
6929       return;
6930     }
6931
6932   if (skip_past_comma (&str) == FAIL
6933       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6934     {
6935       if (! inst.error)
6936         inst.error = BAD_ARGS;
6937       return;
6938     }
6939
6940   end_of_line (str);
6941 }
6942
6943 static void
6944 do_co_reg (char * str)
6945 {
6946   /* Co-processor register transfer.
6947      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
6948
6949   skip_whitespace (str);
6950
6951   if (co_proc_number (&str) == FAIL)
6952     {
6953       if (!inst.error)
6954         inst.error = BAD_ARGS;
6955       return;
6956     }
6957
6958   if (skip_past_comma (&str) == FAIL
6959       || cp_opc_expr (&str, 21, 3) == FAIL)
6960     {
6961       if (!inst.error)
6962         inst.error = BAD_ARGS;
6963       return;
6964     }
6965
6966   if (skip_past_comma (&str) == FAIL
6967       || reg_required_here (&str, 12) == FAIL)
6968     {
6969       if (!inst.error)
6970         inst.error = BAD_ARGS;
6971       return;
6972     }
6973
6974   if (skip_past_comma (&str) == FAIL
6975       || cp_reg_required_here (&str, 16) == FAIL)
6976     {
6977       if (!inst.error)
6978         inst.error = BAD_ARGS;
6979       return;
6980     }
6981
6982   if (skip_past_comma (&str) == FAIL
6983       || cp_reg_required_here (&str, 0) == FAIL)
6984     {
6985       if (!inst.error)
6986         inst.error = BAD_ARGS;
6987       return;
6988     }
6989
6990   if (skip_past_comma (&str) == SUCCESS)
6991     {
6992       if (cp_opc_expr (&str, 5, 3) == FAIL)
6993         {
6994           if (!inst.error)
6995             inst.error = BAD_ARGS;
6996           return;
6997         }
6998     }
6999
7000   end_of_line (str);
7001 }
7002
7003 static void
7004 do_fpa_ctrl (char * str)
7005 {
7006   /* FP control registers.
7007      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
7008
7009   skip_whitespace (str);
7010
7011   if (reg_required_here (&str, 12) == FAIL)
7012     {
7013       if (!inst.error)
7014         inst.error = BAD_ARGS;
7015       return;
7016     }
7017
7018   end_of_line (str);
7019 }
7020
7021 static void
7022 do_fpa_ldst (char * str)
7023 {
7024   skip_whitespace (str);
7025
7026   if (fp_reg_required_here (&str, 12) == FAIL)
7027     {
7028       if (!inst.error)
7029         inst.error = BAD_ARGS;
7030       return;
7031     }
7032
7033   if (skip_past_comma (&str) == FAIL
7034       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7035     {
7036       if (!inst.error)
7037         inst.error = BAD_ARGS;
7038       return;
7039     }
7040
7041   end_of_line (str);
7042 }
7043
7044 static void
7045 do_fpa_ldmstm (char * str)
7046 {
7047   int num_regs;
7048
7049   skip_whitespace (str);
7050
7051   if (fp_reg_required_here (&str, 12) == FAIL)
7052     {
7053       if (! inst.error)
7054         inst.error = BAD_ARGS;
7055       return;
7056     }
7057
7058   /* Get Number of registers to transfer.  */
7059   if (skip_past_comma (&str) == FAIL
7060       || my_get_expression (&inst.reloc.exp, &str))
7061     {
7062       if (! inst.error)
7063         inst.error = _("constant expression expected");
7064       return;
7065     }
7066
7067   if (inst.reloc.exp.X_op != O_constant)
7068     {
7069       inst.error = _("constant value required for number of registers");
7070       return;
7071     }
7072
7073   num_regs = inst.reloc.exp.X_add_number;
7074
7075   if (num_regs < 1 || num_regs > 4)
7076     {
7077       inst.error = _("number of registers must be in the range [1:4]");
7078       return;
7079     }
7080
7081   switch (num_regs)
7082     {
7083     case 1:
7084       inst.instruction |= CP_T_X;
7085       break;
7086     case 2:
7087       inst.instruction |= CP_T_Y;
7088       break;
7089     case 3:
7090       inst.instruction |= CP_T_Y | CP_T_X;
7091       break;
7092     case 4:
7093       break;
7094     default:
7095       abort ();
7096     }
7097
7098   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
7099     {
7100       int reg;
7101       int write_back;
7102       int offset;
7103
7104       /* The instruction specified "ea" or "fd", so we can only accept
7105          [Rn]{!}.  The instruction does not really support stacking or
7106          unstacking, so we have to emulate these by setting appropriate
7107          bits and offsets.  */
7108       if (skip_past_comma (&str) == FAIL
7109           || *str != '[')
7110         {
7111           if (! inst.error)
7112             inst.error = BAD_ARGS;
7113           return;
7114         }
7115
7116       str++;
7117       skip_whitespace (str);
7118
7119       if ((reg = reg_required_here (&str, 16)) == FAIL)
7120         return;
7121
7122       skip_whitespace (str);
7123
7124       if (*str != ']')
7125         {
7126           inst.error = BAD_ARGS;
7127           return;
7128         }
7129
7130       str++;
7131       if (*str == '!')
7132         {
7133           write_back = 1;
7134           str++;
7135           if (reg == REG_PC)
7136             {
7137               inst.error =
7138                 _("r15 not allowed as base register with write-back");
7139               return;
7140             }
7141         }
7142       else
7143         write_back = 0;
7144
7145       if (inst.instruction & CP_T_Pre)
7146         {
7147           /* Pre-decrement.  */
7148           offset = 3 * num_regs;
7149           if (write_back)
7150             inst.instruction |= CP_T_WB;
7151         }
7152       else
7153         {
7154           /* Post-increment.  */
7155           if (write_back)
7156             {
7157               inst.instruction |= CP_T_WB;
7158               offset = 3 * num_regs;
7159             }
7160           else
7161             {
7162               /* No write-back, so convert this into a standard pre-increment
7163                  instruction -- aesthetically more pleasing.  */
7164               inst.instruction |= CP_T_Pre | CP_T_UD;
7165               offset = 0;
7166             }
7167         }
7168
7169       inst.instruction |= offset;
7170     }
7171   else if (skip_past_comma (&str) == FAIL
7172            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7173     {
7174       if (! inst.error)
7175         inst.error = BAD_ARGS;
7176       return;
7177     }
7178
7179   end_of_line (str);
7180 }
7181
7182 static void
7183 do_fpa_dyadic (char * str)
7184 {
7185   skip_whitespace (str);
7186
7187   if (fp_reg_required_here (&str, 12) == FAIL)
7188     {
7189       if (! inst.error)
7190         inst.error = BAD_ARGS;
7191       return;
7192     }
7193
7194   if (skip_past_comma (&str) == FAIL
7195       || fp_reg_required_here (&str, 16) == FAIL)
7196     {
7197       if (! inst.error)
7198         inst.error = BAD_ARGS;
7199       return;
7200     }
7201
7202   if (skip_past_comma (&str) == FAIL
7203       || fp_op2 (&str) == FAIL)
7204     {
7205       if (! inst.error)
7206         inst.error = BAD_ARGS;
7207       return;
7208     }
7209
7210   end_of_line (str);
7211 }
7212
7213 static void
7214 do_fpa_monadic (char * str)
7215 {
7216   skip_whitespace (str);
7217
7218   if (fp_reg_required_here (&str, 12) == FAIL)
7219     {
7220       if (! inst.error)
7221         inst.error = BAD_ARGS;
7222       return;
7223     }
7224
7225   if (skip_past_comma (&str) == FAIL
7226       || fp_op2 (&str) == FAIL)
7227     {
7228       if (! inst.error)
7229         inst.error = BAD_ARGS;
7230       return;
7231     }
7232
7233   end_of_line (str);
7234 }
7235
7236 static void
7237 do_fpa_cmp (char * str)
7238 {
7239   skip_whitespace (str);
7240
7241   if (fp_reg_required_here (&str, 16) == FAIL)
7242     {
7243       if (! inst.error)
7244         inst.error = BAD_ARGS;
7245       return;
7246     }
7247
7248   if (skip_past_comma (&str) == FAIL
7249       || fp_op2 (&str) == FAIL)
7250     {
7251       if (! inst.error)
7252         inst.error = BAD_ARGS;
7253       return;
7254     }
7255
7256   end_of_line (str);
7257 }
7258
7259 static void
7260 do_fpa_from_reg (char * str)
7261 {
7262   skip_whitespace (str);
7263
7264   if (fp_reg_required_here (&str, 16) == FAIL)
7265     {
7266       if (! inst.error)
7267         inst.error = BAD_ARGS;
7268       return;
7269     }
7270
7271   if (skip_past_comma (&str) == FAIL
7272       || reg_required_here (&str, 12) == FAIL)
7273     {
7274       if (! inst.error)
7275         inst.error = BAD_ARGS;
7276       return;
7277     }
7278
7279   end_of_line (str);
7280 }
7281
7282 static void
7283 do_fpa_to_reg (char * str)
7284 {
7285   skip_whitespace (str);
7286
7287   if (reg_required_here (&str, 12) == FAIL)
7288     return;
7289
7290   if (skip_past_comma (&str) == FAIL
7291       || fp_reg_required_here (&str, 0) == FAIL)
7292     {
7293       if (! inst.error)
7294         inst.error = BAD_ARGS;
7295       return;
7296     }
7297
7298   end_of_line (str);
7299 }
7300
7301 /* Encode a VFP SP register number.  */
7302
7303 static void
7304 vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
7305 {
7306   switch (pos)
7307     {
7308     case VFP_REG_Sd:
7309       inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7310       break;
7311
7312     case VFP_REG_Sn:
7313       inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7314       break;
7315
7316     case VFP_REG_Sm:
7317       inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7318       break;
7319
7320     default:
7321       abort ();
7322     }
7323 }
7324
7325 static int
7326 vfp_sp_reg_required_here (char ** str,
7327                           enum vfp_sp_reg_pos pos)
7328 {
7329   int    reg;
7330   char * start = *str;
7331
7332   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7333     {
7334       vfp_sp_encode_reg (reg, pos);
7335       return reg;
7336     }
7337
7338   /* In the few cases where we might be able to accept something else
7339      this error can be overridden.  */
7340   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7341
7342   /* Restore the start point.  */
7343   *str = start;
7344   return FAIL;
7345 }
7346
7347 static int
7348 vfp_dp_reg_required_here (char ** str,
7349                           enum vfp_dp_reg_pos pos)
7350 {
7351   int    reg;
7352   char * start = *str;
7353
7354   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7355     {
7356       switch (pos)
7357         {
7358         case VFP_REG_Dd:
7359           inst.instruction |= reg << 12;
7360           break;
7361
7362         case VFP_REG_Dn:
7363           inst.instruction |= reg << 16;
7364           break;
7365
7366         case VFP_REG_Dm:
7367           inst.instruction |= reg << 0;
7368           break;
7369
7370         default:
7371           abort ();
7372         }
7373       return reg;
7374     }
7375
7376   /* In the few cases where we might be able to accept something else
7377      this error can be overridden.  */
7378   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7379
7380   /* Restore the start point.  */
7381   *str = start;
7382   return FAIL;
7383 }
7384
7385 static void
7386 do_vfp_sp_monadic (char * str)
7387 {
7388   skip_whitespace (str);
7389
7390   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7391     return;
7392
7393   if (skip_past_comma (&str) == FAIL
7394       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7395     {
7396       if (! inst.error)
7397         inst.error = BAD_ARGS;
7398       return;
7399     }
7400
7401   end_of_line (str);
7402 }
7403
7404 static void
7405 do_vfp_dp_monadic (char * str)
7406 {
7407   skip_whitespace (str);
7408
7409   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7410     return;
7411
7412   if (skip_past_comma (&str) == FAIL
7413       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7414     {
7415       if (! inst.error)
7416         inst.error = BAD_ARGS;
7417       return;
7418     }
7419
7420   end_of_line (str);
7421 }
7422
7423 static void
7424 do_vfp_sp_dyadic (char * str)
7425 {
7426   skip_whitespace (str);
7427
7428   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7429     return;
7430
7431   if (skip_past_comma (&str) == FAIL
7432       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7433       || skip_past_comma (&str) == FAIL
7434       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7435     {
7436       if (! inst.error)
7437         inst.error = BAD_ARGS;
7438       return;
7439     }
7440
7441   end_of_line (str);
7442 }
7443
7444 static void
7445 do_vfp_dp_dyadic (char * str)
7446 {
7447   skip_whitespace (str);
7448
7449   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7450     return;
7451
7452   if (skip_past_comma (&str) == FAIL
7453       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7454       || skip_past_comma (&str) == FAIL
7455       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7456     {
7457       if (! inst.error)
7458         inst.error = BAD_ARGS;
7459       return;
7460     }
7461
7462   end_of_line (str);
7463 }
7464
7465 static void
7466 do_vfp_reg_from_sp (char * str)
7467 {
7468   skip_whitespace (str);
7469
7470   if (reg_required_here (&str, 12) == FAIL)
7471     return;
7472
7473   if (skip_past_comma (&str) == FAIL
7474       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7475     {
7476       if (! inst.error)
7477         inst.error = BAD_ARGS;
7478       return;
7479     }
7480
7481   end_of_line (str);
7482 }
7483
7484 /* Parse a VFP register list.  If the string is invalid return FAIL.
7485    Otherwise return the number of registers, and set PBASE to the first
7486    register.  Double precision registers are matched if DP is nonzero.  */
7487
7488 static int
7489 vfp_parse_reg_list (char **str, int *pbase, int dp)
7490 {
7491   int base_reg;
7492   int new_base;
7493   int regtype;
7494   int max_regs;
7495   int count = 0;
7496   int warned = 0;
7497   unsigned long mask = 0;
7498   int i;
7499
7500   if (**str != '{')
7501     return FAIL;
7502
7503   (*str)++;
7504   skip_whitespace (*str);
7505
7506   if (dp)
7507     {
7508       regtype = REG_TYPE_DN;
7509       max_regs = 16;
7510     }
7511   else
7512     {
7513       regtype = REG_TYPE_SN;
7514       max_regs = 32;
7515     }
7516
7517   base_reg = max_regs;
7518
7519   do
7520     {
7521       new_base = arm_reg_parse (str, all_reg_maps[regtype].htab);
7522       if (new_base == FAIL)
7523         {
7524           inst.error = _(all_reg_maps[regtype].expected);
7525           return FAIL;
7526         }
7527
7528       if (new_base < base_reg)
7529         base_reg = new_base;
7530
7531       if (mask & (1 << new_base))
7532         {
7533           inst.error = _("invalid register list");
7534           return FAIL;
7535         }
7536
7537       if ((mask >> new_base) != 0 && ! warned)
7538         {
7539           as_tsktsk (_("register list not in ascending order"));
7540           warned = 1;
7541         }
7542
7543       mask |= 1 << new_base;
7544       count++;
7545
7546       skip_whitespace (*str);
7547
7548       if (**str == '-') /* We have the start of a range expression */
7549         {
7550           int high_range;
7551
7552           (*str)++;
7553
7554           if ((high_range
7555                = arm_reg_parse (str, all_reg_maps[regtype].htab))
7556               == FAIL)
7557             {
7558               inst.error = _(all_reg_maps[regtype].expected);
7559               return FAIL;
7560             }
7561
7562           if (high_range <= new_base)
7563             {
7564               inst.error = _("register range not in ascending order");
7565               return FAIL;
7566             }
7567
7568           for (new_base++; new_base <= high_range; new_base++)
7569             {
7570               if (mask & (1 << new_base))
7571                 {
7572                   inst.error = _("invalid register list");
7573                   return FAIL;
7574                 }
7575
7576               mask |= 1 << new_base;
7577               count++;
7578             }
7579         }
7580     }
7581   while (skip_past_comma (str) != FAIL);
7582
7583   (*str)++;
7584
7585   /* Sanity check -- should have raised a parse error above.  */
7586   if (count == 0 || count > max_regs)
7587     abort ();
7588
7589   *pbase = base_reg;
7590
7591   /* Final test -- the registers must be consecutive.  */
7592   mask >>= base_reg;
7593   for (i = 0; i < count; i++)
7594     {
7595       if ((mask & (1u << i)) == 0)
7596         {
7597           inst.error = _("non-contiguous register range");
7598           return FAIL;
7599         }
7600     }
7601
7602   return count;
7603 }
7604
7605 static void
7606 do_vfp_reg2_from_sp2 (char * str)
7607 {
7608   int reg;
7609
7610   skip_whitespace (str);
7611
7612   if (reg_required_here (&str, 12) == FAIL
7613       || skip_past_comma (&str) == FAIL
7614       || reg_required_here (&str, 16) == FAIL
7615       || skip_past_comma (&str) == FAIL)
7616     {
7617       if (! inst.error)
7618         inst.error = BAD_ARGS;
7619       return;
7620     }
7621
7622   /* We require exactly two consecutive SP registers.  */
7623   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7624     {
7625       if (! inst.error)
7626         inst.error = _("only two consecutive VFP SP registers allowed here");
7627     }
7628   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7629
7630   end_of_line (str);
7631 }
7632
7633 static void
7634 do_vfp_sp_from_reg (char * str)
7635 {
7636   skip_whitespace (str);
7637
7638   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7639     return;
7640
7641   if (skip_past_comma (&str) == FAIL
7642       || reg_required_here (&str, 12) == FAIL)
7643     {
7644       if (! inst.error)
7645         inst.error = BAD_ARGS;
7646       return;
7647     }
7648
7649   end_of_line (str);
7650 }
7651
7652 static void
7653 do_vfp_sp2_from_reg2 (char * str)
7654 {
7655   int reg;
7656
7657   skip_whitespace (str);
7658
7659   /* We require exactly two consecutive SP registers.  */
7660   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7661     {
7662       if (! inst.error)
7663         inst.error = _("only two consecutive VFP SP registers allowed here");
7664     }
7665   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7666
7667   if (skip_past_comma (&str) == FAIL
7668       || reg_required_here (&str, 12) == FAIL
7669       || skip_past_comma (&str) == FAIL
7670       || reg_required_here (&str, 16) == FAIL)
7671     {
7672       if (! inst.error)
7673         inst.error = BAD_ARGS;
7674       return;
7675     }
7676
7677   end_of_line (str);
7678 }
7679
7680 static void
7681 do_vfp_reg_from_dp (char * str)
7682 {
7683   skip_whitespace (str);
7684
7685   if (reg_required_here (&str, 12) == FAIL)
7686     return;
7687
7688   if (skip_past_comma (&str) == FAIL
7689       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7690     {
7691       if (! inst.error)
7692         inst.error = BAD_ARGS;
7693       return;
7694     }
7695
7696   end_of_line (str);
7697 }
7698
7699 static void
7700 do_vfp_reg2_from_dp (char * str)
7701 {
7702   skip_whitespace (str);
7703
7704   if (reg_required_here (&str, 12) == FAIL)
7705     return;
7706
7707   if (skip_past_comma (&str) == FAIL
7708       || reg_required_here (&str, 16) == FAIL
7709       || skip_past_comma (&str) == FAIL
7710       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7711     {
7712       if (! inst.error)
7713         inst.error = BAD_ARGS;
7714       return;
7715     }
7716
7717   end_of_line (str);
7718 }
7719
7720 static void
7721 do_vfp_dp_from_reg (char * str)
7722 {
7723   skip_whitespace (str);
7724
7725   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7726     return;
7727
7728   if (skip_past_comma (&str) == FAIL
7729       || reg_required_here (&str, 12) == FAIL)
7730     {
7731       if (! inst.error)
7732         inst.error = BAD_ARGS;
7733       return;
7734     }
7735
7736   end_of_line (str);
7737 }
7738
7739 static void
7740 do_vfp_dp_from_reg2 (char * str)
7741 {
7742   skip_whitespace (str);
7743
7744   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7745     return;
7746
7747   if (skip_past_comma (&str) == FAIL
7748       || reg_required_here (&str, 12) == FAIL
7749       || skip_past_comma (&str) == FAIL
7750       || reg_required_here (&str, 16) == FAIL)
7751     {
7752       if (! inst.error)
7753         inst.error = BAD_ARGS;
7754       return;
7755     }
7756
7757   end_of_line (str);
7758 }
7759
7760 static const struct vfp_reg *
7761 vfp_psr_parse (char ** str)
7762 {
7763   char *start = *str;
7764   char  c;
7765   char *p;
7766   const struct vfp_reg *vreg;
7767
7768   p = start;
7769
7770   /* Find the end of the current token.  */
7771   do
7772     {
7773       c = *p++;
7774     }
7775   while (ISALPHA (c));
7776
7777   /* Mark it.  */
7778   *--p = 0;
7779
7780   for (vreg = vfp_regs + 0;
7781        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
7782        vreg++)
7783     {
7784       if (streq (start, vreg->name))
7785         {
7786           *p = c;
7787           *str = p;
7788           return vreg;
7789         }
7790     }
7791
7792   *p = c;
7793   return NULL;
7794 }
7795
7796 static int
7797 vfp_psr_required_here (char ** str)
7798 {
7799   char *start = *str;
7800   const struct vfp_reg *vreg;
7801
7802   vreg = vfp_psr_parse (str);
7803
7804   if (vreg)
7805     {
7806       inst.instruction |= vreg->regno;
7807       return SUCCESS;
7808     }
7809
7810   inst.error = _("VFP system register expected");
7811
7812   *str = start;
7813   return FAIL;
7814 }
7815
7816 static void
7817 do_vfp_reg_from_ctrl (char * str)
7818 {
7819   skip_whitespace (str);
7820
7821   if (reg_required_here (&str, 12) == FAIL)
7822     return;
7823
7824   if (skip_past_comma (&str) == FAIL
7825       || vfp_psr_required_here (&str) == FAIL)
7826     {
7827       if (! inst.error)
7828         inst.error = BAD_ARGS;
7829       return;
7830     }
7831
7832   end_of_line (str);
7833 }
7834
7835 static void
7836 do_vfp_ctrl_from_reg (char * str)
7837 {
7838   skip_whitespace (str);
7839
7840   if (vfp_psr_required_here (&str) == FAIL)
7841     return;
7842
7843   if (skip_past_comma (&str) == FAIL
7844       || reg_required_here (&str, 12) == FAIL)
7845     {
7846       if (! inst.error)
7847         inst.error = BAD_ARGS;
7848       return;
7849     }
7850
7851   end_of_line (str);
7852 }
7853
7854 static void
7855 do_vfp_sp_ldst (char * str)
7856 {
7857   skip_whitespace (str);
7858
7859   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7860     {
7861       if (!inst.error)
7862         inst.error = BAD_ARGS;
7863       return;
7864     }
7865
7866   if (skip_past_comma (&str) == FAIL
7867       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7868     {
7869       if (!inst.error)
7870         inst.error = BAD_ARGS;
7871       return;
7872     }
7873
7874   end_of_line (str);
7875 }
7876
7877 static void
7878 do_vfp_dp_ldst (char * str)
7879 {
7880   skip_whitespace (str);
7881
7882   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7883     {
7884       if (!inst.error)
7885         inst.error = BAD_ARGS;
7886       return;
7887     }
7888
7889   if (skip_past_comma (&str) == FAIL
7890       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7891     {
7892       if (!inst.error)
7893         inst.error = BAD_ARGS;
7894       return;
7895     }
7896
7897   end_of_line (str);
7898 }
7899
7900
7901 static void
7902 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7903 {
7904   int count;
7905   int reg;
7906
7907   skip_whitespace (str);
7908
7909   if (reg_required_here (&str, 16) == FAIL)
7910     return;
7911
7912   skip_whitespace (str);
7913
7914   if (*str == '!')
7915     {
7916       inst.instruction |= WRITE_BACK;
7917       str++;
7918     }
7919   else if (ldstm_type != VFP_LDSTMIA)
7920     {
7921       inst.error = _("this addressing mode requires base-register writeback");
7922       return;
7923     }
7924
7925   if (skip_past_comma (&str) == FAIL
7926       || (count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
7927     {
7928       if (!inst.error)
7929         inst.error = BAD_ARGS;
7930       return;
7931     }
7932   vfp_sp_encode_reg (reg, VFP_REG_Sd);
7933
7934   inst.instruction |= count;
7935   end_of_line (str);
7936 }
7937
7938 static void
7939 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7940 {
7941   int count;
7942   int reg;
7943
7944   skip_whitespace (str);
7945
7946   if (reg_required_here (&str, 16) == FAIL)
7947     return;
7948
7949   skip_whitespace (str);
7950
7951   if (*str == '!')
7952     {
7953       inst.instruction |= WRITE_BACK;
7954       str++;
7955     }
7956   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7957     {
7958       inst.error = _("this addressing mode requires base-register writeback");
7959       return;
7960     }
7961
7962   if (skip_past_comma (&str) == FAIL
7963       || (count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
7964     {
7965       if (!inst.error)
7966         inst.error = BAD_ARGS;
7967       return;
7968     }
7969
7970   count <<= 1;
7971   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7972     count += 1;
7973
7974   inst.instruction |= (reg << 12) | count;
7975   end_of_line (str);
7976 }
7977
7978 static void
7979 do_vfp_sp_ldstmia (char * str)
7980 {
7981   vfp_sp_ldstm (str, VFP_LDSTMIA);
7982 }
7983
7984 static void
7985 do_vfp_sp_ldstmdb (char * str)
7986 {
7987   vfp_sp_ldstm (str, VFP_LDSTMDB);
7988 }
7989
7990 static void
7991 do_vfp_dp_ldstmia (char * str)
7992 {
7993   vfp_dp_ldstm (str, VFP_LDSTMIA);
7994 }
7995
7996 static void
7997 do_vfp_dp_ldstmdb (char * str)
7998 {
7999   vfp_dp_ldstm (str, VFP_LDSTMDB);
8000 }
8001
8002 static void
8003 do_vfp_xp_ldstmia (char *str)
8004 {
8005   vfp_dp_ldstm (str, VFP_LDSTMIAX);
8006 }
8007
8008 static void
8009 do_vfp_xp_ldstmdb (char * str)
8010 {
8011   vfp_dp_ldstm (str, VFP_LDSTMDBX);
8012 }
8013
8014 static void
8015 do_vfp_sp_compare_z (char * str)
8016 {
8017   skip_whitespace (str);
8018
8019   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8020     {
8021       if (!inst.error)
8022         inst.error = BAD_ARGS;
8023       return;
8024     }
8025
8026   end_of_line (str);
8027 }
8028
8029 static void
8030 do_vfp_dp_compare_z (char * str)
8031 {
8032   skip_whitespace (str);
8033
8034   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8035     {
8036       if (!inst.error)
8037         inst.error = BAD_ARGS;
8038       return;
8039     }
8040
8041   end_of_line (str);
8042 }
8043
8044 static void
8045 do_vfp_dp_sp_cvt (char * str)
8046 {
8047   skip_whitespace (str);
8048
8049   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8050     return;
8051
8052   if (skip_past_comma (&str) == FAIL
8053       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8054     {
8055       if (! inst.error)
8056         inst.error = BAD_ARGS;
8057       return;
8058     }
8059
8060   end_of_line (str);
8061 }
8062
8063 static void
8064 do_vfp_sp_dp_cvt (char * str)
8065 {
8066   skip_whitespace (str);
8067
8068   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8069     return;
8070
8071   if (skip_past_comma (&str) == FAIL
8072       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8073     {
8074       if (! inst.error)
8075         inst.error = BAD_ARGS;
8076       return;
8077     }
8078
8079   end_of_line (str);
8080 }
8081
8082 /* Thumb specific routines.  */
8083
8084 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8085    was SUB.  */
8086
8087 static void
8088 thumb_add_sub (char * str, int subtract)
8089 {
8090   int Rd, Rs, Rn = FAIL;
8091
8092   skip_whitespace (str);
8093
8094   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8095       || skip_past_comma (&str) == FAIL)
8096     {
8097       if (! inst.error)
8098         inst.error = BAD_ARGS;
8099       return;
8100     }
8101
8102   if (is_immediate_prefix (*str))
8103     {
8104       Rs = Rd;
8105       str++;
8106       if (my_get_expression (&inst.reloc.exp, &str))
8107         return;
8108     }
8109   else
8110     {
8111       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8112         return;
8113
8114       if (skip_past_comma (&str) == FAIL)
8115         {
8116           /* Two operand format, shuffle the registers
8117              and pretend there are 3.  */
8118           Rn = Rs;
8119           Rs = Rd;
8120         }
8121       else if (is_immediate_prefix (*str))
8122         {
8123           str++;
8124           if (my_get_expression (&inst.reloc.exp, &str))
8125             return;
8126         }
8127       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8128         return;
8129     }
8130
8131   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8132      for the latter case, EXPR contains the immediate that was found.  */
8133   if (Rn != FAIL)
8134     {
8135       /* All register format.  */
8136       if (Rd > 7 || Rs > 7 || Rn > 7)
8137         {
8138           if (Rs != Rd)
8139             {
8140               inst.error = _("dest and source1 must be the same register");
8141               return;
8142             }
8143
8144           /* Can't do this for SUB.  */
8145           if (subtract)
8146             {
8147               inst.error = _("subtract valid only on lo regs");
8148               return;
8149             }
8150
8151           inst.instruction = (T_OPCODE_ADD_HI
8152                               | (Rd > 7 ? THUMB_H1 : 0)
8153                               | (Rn > 7 ? THUMB_H2 : 0));
8154           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8155         }
8156       else
8157         {
8158           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8159           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8160         }
8161     }
8162   else
8163     {
8164       /* Immediate expression, now things start to get nasty.  */
8165
8166       /* First deal with HI regs, only very restricted cases allowed:
8167          Adjusting SP, and using PC or SP to get an address.  */
8168       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8169           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8170         {
8171           inst.error = _("invalid Hi register with immediate");
8172           return;
8173         }
8174
8175       if (inst.reloc.exp.X_op != O_constant)
8176         {
8177           /* Value isn't known yet, all we can do is store all the fragments
8178              we know about in the instruction and let the reloc hacking
8179              work it all out.  */
8180           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8181           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8182         }
8183       else
8184         {
8185           int offset = inst.reloc.exp.X_add_number;
8186
8187           if (subtract)
8188             offset = - offset;
8189
8190           if (offset < 0)
8191             {
8192               offset = - offset;
8193               subtract = 1;
8194
8195               /* Quick check, in case offset is MIN_INT.  */
8196               if (offset < 0)
8197                 {
8198                   inst.error = _("immediate value out of range");
8199                   return;
8200                 }
8201             }
8202           /* Note - you cannot convert a subtract of 0 into an
8203              add of 0 because the carry flag is set differently.  */
8204           else if (offset > 0)
8205             subtract = 0;
8206
8207           if (Rd == REG_SP)
8208             {
8209               if (offset & ~0x1fc)
8210                 {
8211                   inst.error = _("invalid immediate value for stack adjust");
8212                   return;
8213                 }
8214               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8215               inst.instruction |= offset >> 2;
8216             }
8217           else if (Rs == REG_PC || Rs == REG_SP)
8218             {
8219               if (subtract
8220                   || (offset & ~0x3fc))
8221                 {
8222                   inst.error = _("invalid immediate for address calculation");
8223                   return;
8224                 }
8225               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8226                                   : T_OPCODE_ADD_SP);
8227               inst.instruction |= (Rd << 8) | (offset >> 2);
8228             }
8229           else if (Rs == Rd)
8230             {
8231               if (offset & ~0xff)
8232                 {
8233                   inst.error = _("immediate value out of range");
8234                   return;
8235                 }
8236               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8237               inst.instruction |= (Rd << 8) | offset;
8238             }
8239           else
8240             {
8241               if (offset & ~0x7)
8242                 {
8243                   inst.error = _("immediate value out of range");
8244                   return;
8245                 }
8246               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8247               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8248             }
8249         }
8250     }
8251
8252   end_of_line (str);
8253 }
8254
8255 static void
8256 thumb_shift (char * str, int shift)
8257 {
8258   int Rd, Rs, Rn = FAIL;
8259
8260   skip_whitespace (str);
8261
8262   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8263       || skip_past_comma (&str) == FAIL)
8264     {
8265       if (! inst.error)
8266         inst.error = BAD_ARGS;
8267       return;
8268     }
8269
8270   if (is_immediate_prefix (*str))
8271     {
8272       /* Two operand immediate format, set Rs to Rd.  */
8273       Rs = Rd;
8274       str ++;
8275       if (my_get_expression (&inst.reloc.exp, &str))
8276         return;
8277     }
8278   else
8279     {
8280       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8281         return;
8282
8283       if (skip_past_comma (&str) == FAIL)
8284         {
8285           /* Two operand format, shuffle the registers
8286              and pretend there are 3.  */
8287           Rn = Rs;
8288           Rs = Rd;
8289         }
8290       else if (is_immediate_prefix (*str))
8291         {
8292           str++;
8293           if (my_get_expression (&inst.reloc.exp, &str))
8294             return;
8295         }
8296       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8297         return;
8298     }
8299
8300   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8301      for the latter case, EXPR contains the immediate that was found.  */
8302
8303   if (Rn != FAIL)
8304     {
8305       if (Rs != Rd)
8306         {
8307           inst.error = _("source1 and dest must be same register");
8308           return;
8309         }
8310
8311       switch (shift)
8312         {
8313         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8314         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8315         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8316         }
8317
8318       inst.instruction |= Rd | (Rn << 3);
8319     }
8320   else
8321     {
8322       switch (shift)
8323         {
8324         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8325         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8326         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8327         }
8328
8329       if (inst.reloc.exp.X_op != O_constant)
8330         {
8331           /* Value isn't known yet, create a dummy reloc and let reloc
8332              hacking fix it up.  */
8333           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8334         }
8335       else
8336         {
8337           unsigned shift_value = inst.reloc.exp.X_add_number;
8338
8339           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8340             {
8341               inst.error = _("invalid immediate for shift");
8342               return;
8343             }
8344
8345           /* Shifts of zero are handled by converting to LSL.  */
8346           if (shift_value == 0)
8347             inst.instruction = T_OPCODE_LSL_I;
8348
8349           /* Shifts of 32 are encoded as a shift of zero.  */
8350           if (shift_value == 32)
8351             shift_value = 0;
8352
8353           inst.instruction |= shift_value << 6;
8354         }
8355
8356       inst.instruction |= Rd | (Rs << 3);
8357     }
8358
8359   end_of_line (str);
8360 }
8361
8362 static void
8363 thumb_load_store (char * str, int load_store, int size)
8364 {
8365   int Rd, Rb, Ro = FAIL;
8366
8367   skip_whitespace (str);
8368
8369   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8370       || skip_past_comma (&str) == FAIL)
8371     {
8372       if (! inst.error)
8373         inst.error = BAD_ARGS;
8374       return;
8375     }
8376
8377   if (*str == '[')
8378     {
8379       str++;
8380       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8381         return;
8382
8383       if (skip_past_comma (&str) != FAIL)
8384         {
8385           if (is_immediate_prefix (*str))
8386             {
8387               str++;
8388               if (my_get_expression (&inst.reloc.exp, &str))
8389                 return;
8390             }
8391           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8392             return;
8393         }
8394       else
8395         {
8396           inst.reloc.exp.X_op = O_constant;
8397           inst.reloc.exp.X_add_number = 0;
8398         }
8399
8400       if (*str != ']')
8401         {
8402           inst.error = _("expected ']'");
8403           return;
8404         }
8405       str++;
8406     }
8407   else if (*str == '=')
8408     {
8409       if (load_store != THUMB_LOAD)
8410         {
8411           inst.error = _("invalid pseudo operation");
8412           return;
8413         }
8414
8415       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
8416       str++;
8417
8418       skip_whitespace (str);
8419
8420       if (my_get_expression (& inst.reloc.exp, & str))
8421         return;
8422
8423       end_of_line (str);
8424
8425       if (   inst.reloc.exp.X_op != O_constant
8426           && inst.reloc.exp.X_op != O_symbol)
8427         {
8428           inst.error = "Constant expression expected";
8429           return;
8430         }
8431
8432       if (inst.reloc.exp.X_op == O_constant
8433           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8434         {
8435           /* This can be done with a mov instruction.  */
8436
8437           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
8438           inst.instruction |= inst.reloc.exp.X_add_number;
8439           return;
8440         }
8441
8442       /* Insert into literal pool.  */
8443       if (add_to_lit_pool () == FAIL)
8444         {
8445           if (!inst.error)
8446             inst.error = "literal pool insertion failed";
8447           return;
8448         }
8449
8450       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
8451       inst.reloc.pc_rel = 1;
8452       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
8453       /* Adjust ARM pipeline offset to Thumb.  */
8454       inst.reloc.exp.X_add_number += 4;
8455
8456       return;
8457     }
8458   else
8459     {
8460       if (my_get_expression (&inst.reloc.exp, &str))
8461         return;
8462
8463       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8464       inst.reloc.pc_rel = 1;
8465       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
8466       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8467       end_of_line (str);
8468       return;
8469     }
8470
8471   if (Rb == REG_PC || Rb == REG_SP)
8472     {
8473       if (size != THUMB_WORD)
8474         {
8475           inst.error = _("byte or halfword not valid for base register");
8476           return;
8477         }
8478       else if (Rb == REG_PC && load_store != THUMB_LOAD)
8479         {
8480           inst.error = _("r15 based store not allowed");
8481           return;
8482         }
8483       else if (Ro != FAIL)
8484         {
8485           inst.error = _("invalid base register for register offset");
8486           return;
8487         }
8488
8489       if (Rb == REG_PC)
8490         inst.instruction = T_OPCODE_LDR_PC;
8491       else if (load_store == THUMB_LOAD)
8492         inst.instruction = T_OPCODE_LDR_SP;
8493       else
8494         inst.instruction = T_OPCODE_STR_SP;
8495
8496       inst.instruction |= Rd << 8;
8497       if (inst.reloc.exp.X_op == O_constant)
8498         {
8499           unsigned offset = inst.reloc.exp.X_add_number;
8500
8501           if (offset & ~0x3fc)
8502             {
8503               inst.error = _("invalid offset");
8504               return;
8505             }
8506
8507           inst.instruction |= offset >> 2;
8508         }
8509       else
8510         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8511     }
8512   else if (Rb > 7)
8513     {
8514       inst.error = _("invalid base register in load/store");
8515       return;
8516     }
8517   else if (Ro == FAIL)
8518     {
8519       /* Immediate offset.  */
8520       if (size == THUMB_WORD)
8521         inst.instruction = (load_store == THUMB_LOAD
8522                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8523       else if (size == THUMB_HALFWORD)
8524         inst.instruction = (load_store == THUMB_LOAD
8525                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8526       else
8527         inst.instruction = (load_store == THUMB_LOAD
8528                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8529
8530       inst.instruction |= Rd | (Rb << 3);
8531
8532       if (inst.reloc.exp.X_op == O_constant)
8533         {
8534           unsigned offset = inst.reloc.exp.X_add_number;
8535
8536           if (offset & ~(0x1f << size))
8537             {
8538               inst.error = _("invalid offset");
8539               return;
8540             }
8541           inst.instruction |= (offset >> size) << 6;
8542         }
8543       else
8544         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8545     }
8546   else
8547     {
8548       /* Register offset.  */
8549       if (size == THUMB_WORD)
8550         inst.instruction = (load_store == THUMB_LOAD
8551                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8552       else if (size == THUMB_HALFWORD)
8553         inst.instruction = (load_store == THUMB_LOAD
8554                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8555       else
8556         inst.instruction = (load_store == THUMB_LOAD
8557                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8558
8559       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8560     }
8561
8562   end_of_line (str);
8563 }
8564
8565 /* A register must be given at this point.
8566
8567    Shift is the place to put it in inst.instruction.
8568
8569    Restores input start point on err.
8570    Returns the reg#, or FAIL.  */
8571
8572 static int
8573 mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
8574 {
8575   int   reg;
8576   char *start = *str;
8577
8578   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8579     {
8580       if (shift >= 0)
8581         inst.instruction |= reg << shift;
8582
8583       return reg;
8584     }
8585
8586   /* Restore the start point.  */
8587   *str = start;
8588
8589   /* Try generic coprocessor name if applicable.  */
8590   if (regtype == REG_TYPE_MVF ||
8591       regtype == REG_TYPE_MVD ||
8592       regtype == REG_TYPE_MVFX ||
8593       regtype == REG_TYPE_MVDX)
8594     {
8595       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
8596         {
8597           if (shift >= 0)
8598             inst.instruction |= reg << shift;
8599
8600           return reg;
8601         }
8602
8603       /* Restore the start point.  */
8604       *str = start;
8605     }
8606
8607   /* In the few cases where we might be able to accept something else
8608      this error can be overridden.  */
8609   inst.error = _(all_reg_maps[regtype].expected);
8610
8611   return FAIL;
8612 }
8613
8614 /* Cirrus Maverick Instructions.  */
8615
8616 /* Isnsn like "foo X,Y".  */
8617
8618 static void
8619 do_mav_binops (char * str,
8620                int mode,
8621                enum arm_reg_type reg0,
8622                enum arm_reg_type reg1)
8623 {
8624   int shift0, shift1;
8625
8626   shift0 = mode & 0xff;
8627   shift1 = (mode >> 8) & 0xff;
8628
8629   skip_whitespace (str);
8630
8631   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8632       || skip_past_comma (&str) == FAIL
8633       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8634     {
8635       if (!inst.error)
8636         inst.error = BAD_ARGS;
8637     }
8638   else
8639     end_of_line (str);
8640 }
8641
8642 /* Isnsn like "foo X,Y,Z".  */
8643
8644 static void
8645 do_mav_triple (char * str,
8646                int mode,
8647                enum arm_reg_type reg0,
8648                enum arm_reg_type reg1,
8649                enum arm_reg_type reg2)
8650 {
8651   int shift0, shift1, shift2;
8652
8653   shift0 = mode & 0xff;
8654   shift1 = (mode >> 8) & 0xff;
8655   shift2 = (mode >> 16) & 0xff;
8656
8657   skip_whitespace (str);
8658
8659   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8660       || skip_past_comma (&str) == FAIL
8661       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8662       || skip_past_comma (&str) == FAIL
8663       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8664     {
8665       if (!inst.error)
8666         inst.error = BAD_ARGS;
8667     }
8668   else
8669     end_of_line (str);
8670 }
8671
8672 /* Wrapper functions.  */
8673
8674 static void
8675 do_mav_binops_1a (char * str)
8676 {
8677   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8678 }
8679
8680 static void
8681 do_mav_binops_1b (char * str)
8682 {
8683   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
8684 }
8685
8686 static void
8687 do_mav_binops_1c (char * str)
8688 {
8689   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8690 }
8691
8692 static void
8693 do_mav_binops_1d (char * str)
8694 {
8695   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8696 }
8697
8698 static void
8699 do_mav_binops_1e (char * str)
8700 {
8701   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8702 }
8703
8704 static void
8705 do_mav_binops_1f (char * str)
8706 {
8707   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8708 }
8709
8710 static void
8711 do_mav_binops_1g (char * str)
8712 {
8713   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8714 }
8715
8716 static void
8717 do_mav_binops_1h (char * str)
8718 {
8719   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8720 }
8721
8722 static void
8723 do_mav_binops_1i (char * str)
8724 {
8725   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8726 }
8727
8728 static void
8729 do_mav_binops_1j (char * str)
8730 {
8731   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8732 }
8733
8734 static void
8735 do_mav_binops_1k (char * str)
8736 {
8737   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8738 }
8739
8740 static void
8741 do_mav_binops_1l (char * str)
8742 {
8743   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8744 }
8745
8746 static void
8747 do_mav_binops_1m (char * str)
8748 {
8749   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8750 }
8751
8752 static void
8753 do_mav_binops_1n (char * str)
8754 {
8755   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8756 }
8757
8758 static void
8759 do_mav_binops_1o (char * str)
8760 {
8761   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8762 }
8763
8764 static void
8765 do_mav_binops_2a (char * str)
8766 {
8767   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8768 }
8769
8770 static void
8771 do_mav_binops_2b (char * str)
8772 {
8773   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8774 }
8775
8776 static void
8777 do_mav_binops_2c (char * str)
8778 {
8779   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8780 }
8781
8782 static void
8783 do_mav_binops_3a (char * str)
8784 {
8785   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8786 }
8787
8788 static void
8789 do_mav_binops_3b (char * str)
8790 {
8791   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8792 }
8793
8794 static void
8795 do_mav_binops_3c (char * str)
8796 {
8797   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8798 }
8799
8800 static void
8801 do_mav_binops_3d (char * str)
8802 {
8803   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8804 }
8805
8806 static void
8807 do_mav_triple_4a (char * str)
8808 {
8809   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8810 }
8811
8812 static void
8813 do_mav_triple_4b (char * str)
8814 {
8815   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8816 }
8817
8818 static void
8819 do_mav_triple_5a (char * str)
8820 {
8821   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8822 }
8823
8824 static void
8825 do_mav_triple_5b (char * str)
8826 {
8827   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8828 }
8829
8830 static void
8831 do_mav_triple_5c (char * str)
8832 {
8833   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8834 }
8835
8836 static void
8837 do_mav_triple_5d (char * str)
8838 {
8839   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8840 }
8841
8842 static void
8843 do_mav_triple_5e (char * str)
8844 {
8845   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8846 }
8847
8848 static void
8849 do_mav_triple_5f (char * str)
8850 {
8851   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8852 }
8853
8854 static void
8855 do_mav_triple_5g (char * str)
8856 {
8857   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8858 }
8859
8860 static void
8861 do_mav_triple_5h (char * str)
8862 {
8863   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8864 }
8865
8866 /* Isnsn like "foo W,X,Y,Z".
8867     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
8868
8869 static void
8870 do_mav_quad (char * str,
8871              int mode,
8872              enum arm_reg_type reg0,
8873              enum arm_reg_type reg1,
8874              enum arm_reg_type reg2,
8875              enum arm_reg_type reg3)
8876 {
8877   int shift0, shift1, shift2, shift3;
8878
8879   shift0= mode & 0xff;
8880   shift1 = (mode >> 8) & 0xff;
8881   shift2 = (mode >> 16) & 0xff;
8882   shift3 = (mode >> 24) & 0xff;
8883
8884   skip_whitespace (str);
8885
8886   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8887       || skip_past_comma (&str) == FAIL
8888       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8889       || skip_past_comma (&str) == FAIL
8890       || mav_reg_required_here (&str, shift2, reg2) == FAIL
8891       || skip_past_comma (&str) == FAIL
8892       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
8893     {
8894       if (!inst.error)
8895         inst.error = BAD_ARGS;
8896     }
8897   else
8898     end_of_line (str);
8899 }
8900
8901 static void
8902 do_mav_quad_6a (char * str)
8903 {
8904   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8905                REG_TYPE_MVFX);
8906 }
8907
8908 static void
8909 do_mav_quad_6b (char * str)
8910 {
8911   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8912                REG_TYPE_MVFX);
8913 }
8914
8915 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
8916 static void
8917 do_mav_dspsc_1 (char * str)
8918 {
8919   skip_whitespace (str);
8920
8921   /* cfmvsc32.  */
8922   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8923       || skip_past_comma (&str) == FAIL
8924       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
8925     {
8926       if (!inst.error)
8927         inst.error = BAD_ARGS;
8928
8929       return;
8930     }
8931
8932   end_of_line (str);
8933 }
8934
8935 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
8936 static void
8937 do_mav_dspsc_2 (char * str)
8938 {
8939   skip_whitespace (str);
8940
8941   /* cfmv32sc.  */
8942   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
8943       || skip_past_comma (&str) == FAIL
8944       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8945     {
8946       if (!inst.error)
8947         inst.error = BAD_ARGS;
8948
8949       return;
8950     }
8951
8952   end_of_line (str);
8953 }
8954
8955 /* Maverick shift immediate instructions.
8956    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8957    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
8958
8959 static void
8960 do_mav_shift (char * str,
8961               enum arm_reg_type reg0,
8962               enum arm_reg_type reg1)
8963 {
8964   int error;
8965   int imm, neg = 0;
8966
8967   skip_whitespace (str);
8968
8969   error = 0;
8970
8971   if (mav_reg_required_here (&str, 12, reg0) == FAIL
8972       || skip_past_comma (&str) == FAIL
8973       || mav_reg_required_here (&str, 16, reg1) == FAIL
8974       || skip_past_comma  (&str) == FAIL)
8975     {
8976       if (!inst.error)
8977         inst.error = BAD_ARGS;
8978       return;
8979     }
8980
8981   /* Calculate the immediate operand.
8982      The operand is a 7bit signed number.  */
8983   skip_whitespace (str);
8984
8985   if (*str == '#')
8986     ++str;
8987
8988   if (!ISDIGIT (*str) && *str != '-')
8989     {
8990       inst.error = _("expecting immediate, 7bit operand");
8991       return;
8992     }
8993
8994   if (*str == '-')
8995     {
8996       neg = 1;
8997       ++str;
8998     }
8999
9000   for (imm = 0; *str && ISDIGIT (*str); ++str)
9001     imm = imm * 10 + *str - '0';
9002
9003   if (imm > 64)
9004     {
9005       inst.error = _("immediate out of range");
9006       return;
9007     }
9008
9009   /* Make negative imm's into 7bit signed numbers.  */
9010   if (neg)
9011     {
9012       imm = -imm;
9013       imm &= 0x0000007f;
9014     }
9015
9016   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9017      Bits 5-7 of the insn should have bits 4-6 of the immediate.
9018      Bit 4 should be 0.  */
9019   imm = (imm & 0xf) | ((imm & 0x70) << 1);
9020
9021   inst.instruction |= imm;
9022   end_of_line (str);
9023 }
9024
9025 static void
9026 do_mav_shift_1 (char * str)
9027 {
9028   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9029 }
9030
9031 static void
9032 do_mav_shift_2 (char * str)
9033 {
9034   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9035 }
9036
9037 static int
9038 mav_parse_offset (char ** str, int * negative)
9039 {
9040   char * p = *str;
9041   int offset;
9042
9043   *negative = 0;
9044
9045   skip_whitespace (p);
9046
9047   if (*p == '#')
9048     ++p;
9049
9050   if (*p == '-')
9051     {
9052       *negative = 1;
9053       ++p;
9054     }
9055
9056   if (!ISDIGIT (*p))
9057     {
9058       inst.error = _("offset expected");
9059       return 0;
9060     }
9061
9062   for (offset = 0; *p && ISDIGIT (*p); ++p)
9063     offset = offset * 10 + *p - '0';
9064
9065   if (offset > 0x3fc)
9066     {
9067       inst.error = _("offset out of range");
9068       return 0;
9069     }
9070   if (offset & 0x3)
9071     {
9072       inst.error = _("offset not a multiple of 4");
9073       return 0;
9074     }
9075
9076   *str = p;
9077
9078   return *negative ? -offset : offset;
9079 }
9080
9081 /* Maverick load/store instructions.
9082   <insn><cond> CRd,[Rn,<offset>]{!}.
9083   <insn><cond> CRd,[Rn],<offset>.  */
9084
9085 static void
9086 do_mav_ldst (char * str, enum arm_reg_type reg0)
9087 {
9088   int offset, negative;
9089
9090   skip_whitespace (str);
9091
9092   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9093       || skip_past_comma (&str) == FAIL
9094       || *str++ != '['
9095       || reg_required_here (&str, 16) == FAIL)
9096     goto fail_ldst;
9097
9098   if (skip_past_comma (&str) == SUCCESS)
9099     {
9100       /* You are here: "<offset>]{!}".  */
9101       inst.instruction |= PRE_INDEX;
9102
9103       offset = mav_parse_offset (&str, &negative);
9104
9105       if (inst.error)
9106         return;
9107
9108       if (*str++ != ']')
9109         {
9110           inst.error = _("missing ]");
9111           return;
9112         }
9113
9114       if (*str == '!')
9115         {
9116           inst.instruction |= WRITE_BACK;
9117           ++str;
9118         }
9119     }
9120   else
9121     {
9122       /* You are here: "], <offset>".  */
9123       if (*str++ != ']')
9124         {
9125           inst.error = _("missing ]");
9126           return;
9127         }
9128
9129       if (skip_past_comma (&str) == FAIL
9130           || (offset = mav_parse_offset (&str, &negative), inst.error))
9131         goto fail_ldst;
9132
9133       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
9134     }
9135
9136   if (negative)
9137     offset = -offset;
9138   else
9139     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
9140
9141   inst.instruction |= offset >> 2;
9142   end_of_line (str);
9143   return;
9144
9145 fail_ldst:
9146   if (!inst.error)
9147      inst.error = BAD_ARGS;
9148 }
9149
9150 static void
9151 do_mav_ldst_1 (char * str)
9152 {
9153   do_mav_ldst (str, REG_TYPE_MVF);
9154 }
9155
9156 static void
9157 do_mav_ldst_2 (char * str)
9158 {
9159   do_mav_ldst (str, REG_TYPE_MVD);
9160 }
9161
9162 static void
9163 do_mav_ldst_3 (char * str)
9164 {
9165   do_mav_ldst (str, REG_TYPE_MVFX);
9166 }
9167
9168 static void
9169 do_mav_ldst_4 (char * str)
9170 {
9171   do_mav_ldst (str, REG_TYPE_MVDX);
9172 }
9173
9174 static void
9175 do_t_nop (char * str)
9176 {
9177   /* Do nothing.  */
9178   end_of_line (str);
9179 }
9180
9181 /* Handle the Format 4 instructions that do not have equivalents in other
9182    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9183    BIC and MVN.  */
9184
9185 static void
9186 do_t_arit (char * str)
9187 {
9188   int Rd, Rs, Rn;
9189
9190   skip_whitespace (str);
9191
9192   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9193       || skip_past_comma (&str) == FAIL
9194       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9195     {
9196       inst.error = BAD_ARGS;
9197       return;
9198     }
9199
9200   if (skip_past_comma (&str) != FAIL)
9201     {
9202       /* Three operand format not allowed for TST, CMN, NEG and MVN.
9203          (It isn't allowed for CMP either, but that isn't handled by this
9204          function.)  */
9205       if (inst.instruction == T_OPCODE_TST
9206           || inst.instruction == T_OPCODE_CMN
9207           || inst.instruction == T_OPCODE_NEG
9208           || inst.instruction == T_OPCODE_MVN)
9209         {
9210           inst.error = BAD_ARGS;
9211           return;
9212         }
9213
9214       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9215         return;
9216
9217       if (Rs != Rd)
9218         {
9219           inst.error = _("dest and source1 must be the same register");
9220           return;
9221         }
9222       Rs = Rn;
9223     }
9224
9225   if (inst.instruction == T_OPCODE_MUL
9226       && Rs == Rd)
9227     as_tsktsk (_("Rs and Rd must be different in MUL"));
9228
9229   inst.instruction |= Rd | (Rs << 3);
9230   end_of_line (str);
9231 }
9232
9233 static void
9234 do_t_add (char * str)
9235 {
9236   thumb_add_sub (str, 0);
9237 }
9238
9239 static void
9240 do_t_asr (char * str)
9241 {
9242   thumb_shift (str, THUMB_ASR);
9243 }
9244
9245 static void
9246 do_t_branch9 (char * str)
9247 {
9248   if (my_get_expression (&inst.reloc.exp, &str))
9249     return;
9250   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9251   inst.reloc.pc_rel = 1;
9252   end_of_line (str);
9253 }
9254
9255 static void
9256 do_t_branch12 (char * str)
9257 {
9258   if (my_get_expression (&inst.reloc.exp, &str))
9259     return;
9260   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9261   inst.reloc.pc_rel = 1;
9262   end_of_line (str);
9263 }
9264
9265 /* Find the real, Thumb encoded start of a Thumb function.  */
9266
9267 static symbolS *
9268 find_real_start (symbolS * symbolP)
9269 {
9270   char *       real_start;
9271   const char * name = S_GET_NAME (symbolP);
9272   symbolS *    new_target;
9273
9274   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
9275 #define STUB_NAME ".real_start_of"
9276
9277   if (name == NULL)
9278     abort ();
9279
9280   /* Names that start with '.' are local labels, not function entry points.
9281      The compiler may generate BL instructions to these labels because it
9282      needs to perform a branch to a far away location.  */
9283   if (name[0] == '.')
9284     return symbolP;
9285
9286   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9287   sprintf (real_start, "%s%s", STUB_NAME, name);
9288
9289   new_target = symbol_find (real_start);
9290
9291   if (new_target == NULL)
9292     {
9293       as_warn ("Failed to find real start of function: %s\n", name);
9294       new_target = symbolP;
9295     }
9296
9297   free (real_start);
9298
9299   return new_target;
9300 }
9301
9302 static void
9303 do_t_branch23 (char * str)
9304 {
9305   if (my_get_expression (& inst.reloc.exp, & str))
9306     return;
9307
9308   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
9309   inst.reloc.pc_rel = 1;
9310   end_of_line (str);
9311
9312   /* If the destination of the branch is a defined symbol which does not have
9313      the THUMB_FUNC attribute, then we must be calling a function which has
9314      the (interfacearm) attribute.  We look for the Thumb entry point to that
9315      function and change the branch to refer to that function instead.  */
9316   if (   inst.reloc.exp.X_op == O_symbol
9317       && inst.reloc.exp.X_add_symbol != NULL
9318       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9319       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9320     inst.reloc.exp.X_add_symbol =
9321       find_real_start (inst.reloc.exp.X_add_symbol);
9322 }
9323
9324 static void
9325 do_t_bx (char * str)
9326 {
9327   int reg;
9328
9329   skip_whitespace (str);
9330
9331   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9332     return;
9333
9334   /* This sets THUMB_H2 from the top bit of reg.  */
9335   inst.instruction |= reg << 3;
9336
9337   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
9338      should cause the alignment to be checked once it is known.  This is
9339      because BX PC only works if the instruction is word aligned.  */
9340
9341   end_of_line (str);
9342 }
9343
9344 static void
9345 do_t_compare (char * str)
9346 {
9347   thumb_mov_compare (str, THUMB_COMPARE);
9348 }
9349
9350 static void
9351 do_t_ldmstm (char * str)
9352 {
9353   int Rb;
9354   long range;
9355
9356   skip_whitespace (str);
9357
9358   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9359     return;
9360
9361   if (*str != '!')
9362     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9363   else
9364     str++;
9365
9366   if (skip_past_comma (&str) == FAIL
9367       || (range = reg_list (&str)) == FAIL)
9368     {
9369       if (! inst.error)
9370         inst.error = BAD_ARGS;
9371       return;
9372     }
9373
9374   if (inst.reloc.type != BFD_RELOC_UNUSED)
9375     {
9376       /* This really doesn't seem worth it.  */
9377       inst.reloc.type = BFD_RELOC_UNUSED;
9378       inst.error = _("expression too complex");
9379       return;
9380     }
9381
9382   if (range & ~0xff)
9383     {
9384       inst.error = _("only lo-regs valid in load/store multiple");
9385       return;
9386     }
9387
9388   inst.instruction |= (Rb << 8) | range;
9389   end_of_line (str);
9390 }
9391
9392 static void
9393 do_t_ldr (char * str)
9394 {
9395   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9396 }
9397
9398 static void
9399 do_t_ldrb (char * str)
9400 {
9401   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9402 }
9403
9404 static void
9405 do_t_ldrh (char * str)
9406 {
9407   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9408 }
9409
9410 static void
9411 do_t_lds (char * str)
9412 {
9413   int Rd, Rb, Ro;
9414
9415   skip_whitespace (str);
9416
9417   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9418       || skip_past_comma (&str) == FAIL
9419       || *str++ != '['
9420       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9421       || skip_past_comma (&str) == FAIL
9422       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9423       || *str++ != ']')
9424     {
9425       if (! inst.error)
9426         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9427       return;
9428     }
9429
9430   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9431   end_of_line (str);
9432 }
9433
9434 static void
9435 do_t_lsl (char * str)
9436 {
9437   thumb_shift (str, THUMB_LSL);
9438 }
9439
9440 static void
9441 do_t_lsr (char * str)
9442 {
9443   thumb_shift (str, THUMB_LSR);
9444 }
9445
9446 static void
9447 do_t_mov (char * str)
9448 {
9449   thumb_mov_compare (str, THUMB_MOVE);
9450 }
9451
9452 static void
9453 do_t_push_pop (char * str)
9454 {
9455   long range;
9456
9457   skip_whitespace (str);
9458
9459   if ((range = reg_list (&str)) == FAIL)
9460     {
9461       if (! inst.error)
9462         inst.error = BAD_ARGS;
9463       return;
9464     }
9465
9466   if (inst.reloc.type != BFD_RELOC_UNUSED)
9467     {
9468       /* This really doesn't seem worth it.  */
9469       inst.reloc.type = BFD_RELOC_UNUSED;
9470       inst.error = _("expression too complex");
9471       return;
9472     }
9473
9474   if (range & ~0xff)
9475     {
9476       if ((inst.instruction == T_OPCODE_PUSH
9477            && (range & ~0xff) == 1 << REG_LR)
9478           || (inst.instruction == T_OPCODE_POP
9479               && (range & ~0xff) == 1 << REG_PC))
9480         {
9481           inst.instruction |= THUMB_PP_PC_LR;
9482           range &= 0xff;
9483         }
9484       else
9485         {
9486           inst.error = _("invalid register list to push/pop instruction");
9487           return;
9488         }
9489     }
9490
9491   inst.instruction |= range;
9492   end_of_line (str);
9493 }
9494
9495 static void
9496 do_t_str (char * str)
9497 {
9498   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9499 }
9500
9501 static void
9502 do_t_strb (char * str)
9503 {
9504   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9505 }
9506
9507 static void
9508 do_t_strh (char * str)
9509 {
9510   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9511 }
9512
9513 static void
9514 do_t_sub (char * str)
9515 {
9516   thumb_add_sub (str, 1);
9517 }
9518
9519 static void
9520 do_t_swi (char * str)
9521 {
9522   skip_whitespace (str);
9523
9524   if (my_get_expression (&inst.reloc.exp, &str))
9525     return;
9526
9527   inst.reloc.type = BFD_RELOC_ARM_SWI;
9528   end_of_line (str);
9529 }
9530
9531 static void
9532 do_t_adr (char * str)
9533 {
9534   int reg;
9535
9536   /* This is a pseudo-op of the form "adr rd, label" to be converted
9537      into a relative address of the form "add rd, pc, #label-.-4".  */
9538   skip_whitespace (str);
9539
9540   /* Store Rd in temporary location inside instruction.  */
9541   if ((reg = reg_required_here (&str, 4)) == FAIL
9542       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
9543       || skip_past_comma (&str) == FAIL
9544       || my_get_expression (&inst.reloc.exp, &str))
9545     {
9546       if (!inst.error)
9547         inst.error = BAD_ARGS;
9548       return;
9549     }
9550
9551   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9552   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
9553   inst.reloc.pc_rel = 1;
9554   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
9555
9556   end_of_line (str);
9557 }
9558
9559 static void
9560 insert_reg (const struct reg_entry * r,
9561             struct hash_control * htab)
9562 {
9563   int    len  = strlen (r->name) + 2;
9564   char * buf  = xmalloc (len);
9565   char * buf2 = xmalloc (len);
9566   int    i    = 0;
9567
9568 #ifdef REGISTER_PREFIX
9569   buf[i++] = REGISTER_PREFIX;
9570 #endif
9571
9572   strcpy (buf + i, r->name);
9573
9574   for (i = 0; buf[i]; i++)
9575     buf2[i] = TOUPPER (buf[i]);
9576
9577   buf2[i] = '\0';
9578
9579   hash_insert (htab, buf,  (PTR) r);
9580   hash_insert (htab, buf2, (PTR) r);
9581 }
9582
9583 static void
9584 build_reg_hsh (struct reg_map * map)
9585 {
9586   const struct reg_entry *r;
9587
9588   if ((map->htab = hash_new ()) == NULL)
9589     as_fatal (_("virtual memory exhausted"));
9590
9591   for (r = map->names; r->name != NULL; r++)
9592     insert_reg (r, map->htab);
9593 }
9594
9595 static void
9596 insert_reg_alias (char * str,
9597                   int regnum,
9598                   struct hash_control *htab)
9599 {
9600   const char * error;
9601   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
9602   const char * name = xmalloc (strlen (str) + 1);
9603
9604   strcpy ((char *) name, str);
9605
9606   new->name = name;
9607   new->number = regnum;
9608   new->builtin = FALSE;
9609
9610   error = hash_insert (htab, name, (PTR) new);
9611   if (error)
9612     {
9613       as_bad (_("failed to create an alias for %s, reason: %s"),
9614             str, error);
9615       free ((char *) name);
9616       free (new);
9617     }
9618 }
9619
9620 /* Look for the .req directive.  This is of the form:
9621
9622         new_register_name .req existing_register_name
9623
9624    If we find one, or if it looks sufficiently like one that we want to
9625    handle any error here, return non-zero.  Otherwise return zero.  */
9626
9627 static int
9628 create_register_alias (char * newname, char * p)
9629 {
9630   char * q;
9631   char c;
9632
9633   q = p;
9634   skip_whitespace (q);
9635
9636   c = *p;
9637   *p = '\0';
9638
9639   if (*q && !strncmp (q, ".req ", 5))
9640     {
9641       char *copy_of_str;
9642       char *r;
9643
9644 #ifndef IGNORE_OPCODE_CASE
9645       newname = original_case_string;
9646 #endif
9647       copy_of_str = newname;
9648
9649       q += 4;
9650       skip_whitespace (q);
9651
9652       for (r = q; *r != '\0'; r++)
9653         if (*r == ' ')
9654           break;
9655
9656       if (r != q)
9657         {
9658           enum arm_reg_type new_type, old_type;
9659           int old_regno;
9660           char d = *r;
9661
9662           *r = '\0';
9663           old_type = arm_reg_parse_any (q);
9664           *r = d;
9665
9666           new_type = arm_reg_parse_any (newname);
9667
9668           if (new_type == REG_TYPE_MAX)
9669             {
9670               if (old_type != REG_TYPE_MAX)
9671                 {
9672                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9673                   insert_reg_alias (newname, old_regno,
9674                                     all_reg_maps[old_type].htab);
9675                 }
9676               else
9677                 as_warn (_("register '%s' does not exist\n"), q);
9678             }
9679           else if (old_type == REG_TYPE_MAX)
9680             {
9681               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9682                        copy_of_str, q);
9683             }
9684           else
9685             {
9686               /* Do not warn about redefinitions to the same alias.  */
9687               if (new_type != old_type
9688                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9689                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9690                 as_warn (_("ignoring redefinition of register alias '%s'"),
9691                          copy_of_str);
9692
9693             }
9694         }
9695       else
9696         as_warn (_("ignoring incomplete .req pseuso op"));
9697
9698       *p = c;
9699       return 1;
9700     }
9701
9702   *p = c;
9703   return 0;
9704 }
9705
9706 static void
9707 set_constant_flonums (void)
9708 {
9709   int i;
9710
9711   for (i = 0; i < NUM_FLOAT_VALS; i++)
9712     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9713       abort ();
9714 }
9715
9716 \f
9717 static const struct asm_opcode insns[] =
9718 {
9719   /* Core ARM Instructions.  */
9720   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
9721   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
9722   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
9723   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
9724   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
9725   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
9726   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
9727   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
9728   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
9729   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
9730   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
9731   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
9732   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
9733   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
9734   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
9735   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
9736   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
9737   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
9738   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
9739   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
9740
9741   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9742   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9743   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
9744   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9745   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9746   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
9747   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9748   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9749   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
9750   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9751   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9752   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
9753
9754   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
9755   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
9756   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
9757   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
9758
9759   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
9760   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
9761   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
9762   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
9763   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
9764   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
9765   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
9766   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
9767
9768   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9769   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9770   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9771   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9772   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9773   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9774   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9775   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9776
9777   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9778   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9779   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9780   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9781   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9782   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9783   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9784   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9785
9786   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
9787 #ifdef TE_WINCE
9788   /* XXX This is the wrong place to do this.  Think multi-arch.  */
9789   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
9790   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
9791 #else
9792   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
9793   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
9794 #endif
9795
9796   /* Pseudo ops.  */
9797   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
9798   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
9799   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_nop},
9800
9801   /* ARM 2 multiplies.  */
9802   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
9803   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
9804   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
9805   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
9806
9807   /* Generic coprocessor instructions.  */
9808   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
9809   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
9810   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
9811   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
9812   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
9813   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
9814   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
9815
9816   /* ARM 3 - swp instructions.  */
9817   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
9818   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
9819
9820   /* ARM 6 Status register instructions.  */
9821   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
9822   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
9823   /* ScottB: our code uses     0xe128f000 for msr.
9824      NickC:  but this is wrong because the bits 16 through 19 are
9825              handled by the PSR_xxx defines above.  */
9826
9827   /* ARM 7M long multiplies.  */
9828   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
9829   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
9830   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
9831   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
9832   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
9833   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
9834   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
9835   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
9836
9837   /* ARM Architecture 4.  */
9838   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9839   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
9840   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
9841   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9842
9843   /* ARM Architecture 4T.  */
9844   /* Note: bx (and blx) are required on V5, even if the processor does
9845      not support Thumb.  */
9846   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
9847
9848   /*  ARM Architecture 5T.  */
9849   /* Note: blx has 2 variants, so the .value is set dynamically.
9850      Only one of the variants has conditional execution.  */
9851   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
9852   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
9853   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
9854   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
9855   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
9856   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
9857   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
9858   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
9859   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
9860   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
9861
9862   /*  ARM Architecture 5TExP.  */
9863   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
9864   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
9865   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9866   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
9867
9868   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
9869   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9870
9871   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
9872   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
9873   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
9874   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
9875
9876   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
9877   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9878   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
9879   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9880
9881   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9882   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9883
9884   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
9885   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
9886   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
9887   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
9888
9889   /*  ARM Architecture 5TE.  */
9890   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
9891   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
9892   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
9893
9894   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9895   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9896
9897   /*  ARM Architecture 5TEJ.  */
9898   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
9899
9900   /*  ARM V6.  */
9901   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
9902   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
9903   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
9904   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
9905   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
9906   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
9907   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
9908   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
9909   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
9910   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
9911   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
9912   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
9913   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
9914   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
9915   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
9916   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
9917   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
9918   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
9919   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
9920   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
9921   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
9922   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
9923   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
9924   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
9925   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
9926   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
9927   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
9928   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
9929   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
9930   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
9931   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
9932   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
9933   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
9934   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
9935   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
9936   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
9937   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
9938   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
9939   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
9940   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
9941   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
9942   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
9943   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
9944   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
9945   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
9946   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
9947   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
9948   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9949   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9950   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9951   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9952   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9953   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9954   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9955   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9956   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
9957   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
9958   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
9959   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
9960   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
9961   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
9962   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
9963   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
9964   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
9965   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
9966   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
9967   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
9968   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
9969   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
9970   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
9971   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
9972   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
9973   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
9974   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
9975   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
9976   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
9977   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
9978   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
9979   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
9980   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
9981   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
9982   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
9983   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
9984   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
9985   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
9986   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
9987   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
9988   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
9989   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
9990   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
9991   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
9992   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
9993   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
9994   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
9995   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
9996   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
9997   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
9998   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
9999   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
10000
10001   /*  ARM V6K.  */
10002   { "clrex",     0xf57ff01f, 0,  ARM_EXT_V6K,      do_empty},
10003   { "ldrexb",    0xe1d00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10004   { "ldrexd",    0xe1b00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10005   { "ldrexh",    0xe1f00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10006   { "sev",       0xe320f004, 3,  ARM_EXT_V6K,      do_empty},
10007   { "strexb",    0xe1c00f90, 6,  ARM_EXT_V6K,      do_strex},
10008   { "strexd",    0xe1a00f90, 6,  ARM_EXT_V6K,      do_strex},
10009   { "strexh",    0xe1e00f90, 6,  ARM_EXT_V6K,      do_strex},
10010   { "wfe",       0xe320f002, 3,  ARM_EXT_V6K,      do_empty},
10011   { "wfi",       0xe320f003, 3,  ARM_EXT_V6K,      do_empty},
10012   { "yield",     0xe320f001, 5,  ARM_EXT_V6K,      do_empty},
10013
10014   /*  ARM V6Z.  */
10015   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
10016
10017   /* Core FPA instruction set (V1).  */
10018   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10019   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10020   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10021   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10022
10023   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10024   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10025   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10026   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10027
10028   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10029   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10030   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10031   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10032
10033   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10034   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10035   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10036   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10037   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10038   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10039   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10040   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10041   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10042   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10043   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10044   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10045
10046   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10047   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10048   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10049   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10050   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10051   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10052   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10053   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10054   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10055   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10056   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10057   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10058
10059   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10060   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10061   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10062   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10063   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10064   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10065   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10066   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10067   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10068   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10069   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10070   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10071
10072   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10073   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10074   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10075   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10076   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10077   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10078   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10079   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10080   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10081   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10082   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10083   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10084
10085   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10086   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10087   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10088   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10089   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10090   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10091   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10092   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10093   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10094   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10095   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10096   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10097
10098   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10099   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10100   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10101   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10102   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10103   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10104   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10105   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10106   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10107   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10108   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10109   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10110
10111   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10112   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10113   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10114   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10115   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10116   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10117   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10118   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10119   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10120   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10121   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10122   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10123
10124   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10125   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10126   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10127   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10128   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10129   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10130   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10131   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10132   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10133   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10134   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10135   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10136
10137   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10138   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10139   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10140   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10141   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10142   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10143   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10144   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10145   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10146   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10147   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10148   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10149
10150   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10151   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10152   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10153   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10154   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10155   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10156   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10157   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10158   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10159   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10160   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10161   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10162
10163   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10164   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10165   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10166   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10167   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10168   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10169   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10170   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10171   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10172   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10173   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10174   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10175
10176   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10177   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10178   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10179   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10180   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10181   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10182   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10183   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10184   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10185   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10186   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10187   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10188
10189   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10190   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10191   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10192   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10193   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10194   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10195   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10196   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10197   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10198   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10199   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10200   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10201
10202   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10203   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10204   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10205   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10206   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10207   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10208   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10209   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10210   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10211   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10212   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10213   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10214
10215   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10216   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10217   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10218   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10219   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10220   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10221   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10222   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10223   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10224   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10225   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10226   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10227
10228   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10229   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10230   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10231   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10232   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10233   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10234   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10235   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10236   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10237   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10238   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10239   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10240
10241   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10242   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10243   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10244   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10245   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10246   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10247   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10248   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10249   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10250   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10251   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10252   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10253
10254   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10255   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10256   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10257   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10258   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10259   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10260   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10261   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10262   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10263   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10264   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10265   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10266
10267   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10268   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10269   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10270   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10271   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10272   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10273   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10274   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10275   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10276   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10277   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10278   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10279
10280   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10281   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10282   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10283   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10284   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10285   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10286   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10287   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10288   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10289   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10290   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10291   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10292
10293   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10294   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10295   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10296   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10297   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10298   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10299   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10300   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10301   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10302   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10303   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10304   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10305
10306   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10307   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10308   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10309   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10310   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10311   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10312   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10313   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10314   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10315   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10316   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10317   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10318
10319   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10320   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10321   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10322   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10323   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10324   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10325   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10326   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10327   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10328   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10329   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10330   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10331
10332   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10333   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10334   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10335   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10336   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10337   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10338   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10339   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10340   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10341   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10342   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10343   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10344
10345   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10346   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10347   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10348   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10349   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10350   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10351   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10352   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10353   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10354   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10355   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10356   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10357
10358   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10359   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10360   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10361   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10362   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10363   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10364   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10365   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10366   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10367   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10368   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10369   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10370
10371   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10372   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10373   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10374   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10375   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10376   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10377   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10378   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10379   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10380   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10381   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10382   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10383
10384   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10385   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10386   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10387   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10388   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10389   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10390   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10391   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10392   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10393   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10394   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10395   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10396
10397   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10398   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10399   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10400   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10401   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10402   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10403   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10404   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10405   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10406   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10407   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10408   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10409
10410   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10411   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10412   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10413   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10414   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
10415      not be an optional suffix, but part of the instruction.  To be
10416      compatible, we accept either.  */
10417   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10418   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10419
10420   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10421   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10422   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10423   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10424   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10425   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10426   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10427   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10428   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10429   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10430   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10431   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10432
10433   /* The implementation of the FIX instruction is broken on some
10434      assemblers, in that it accepts a precision specifier as well as a
10435      rounding specifier, despite the fact that this is meaningless.
10436      To be more compatible, we accept it as well, though of course it
10437      does not set any bits.  */
10438   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10439   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10440   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10441   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10442   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10443   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10444   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10445   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10446   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10447   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10448   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10449   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10450   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10451
10452   /* Instructions that were new with the real FPA, call them V2.  */
10453   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10454   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10455   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10456   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10457   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10458   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10459
10460   /* VFP V1xD (single precision).  */
10461   /* Moves and type conversions.  */
10462   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10463   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
10464   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
10465   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
10466   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10467   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10468   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10469   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10470   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10471   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10472   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
10473   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
10474
10475   /* Memory operations.  */
10476   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10477   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10478   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10479   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10480   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10481   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10482   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10483   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10484   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10485   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10486   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10487   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10488   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10489   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10490   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10491   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10492   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10493   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10494
10495   /* Monadic operations.  */
10496   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10497   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10498   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10499
10500   /* Dyadic operations.  */
10501   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10502   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10503   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10504   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10505   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10506   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10507   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10508   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10509   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10510
10511   /* Comparisons.  */
10512   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10513   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10514   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10515   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10516
10517   /* VFP V1 (Double precision).  */
10518   /* Moves and type conversions.  */
10519   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10520   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10521   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10522   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10523   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10524   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10525   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10526   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10527   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10528   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10529   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10530   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10531   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10532
10533   /* Memory operations.  */
10534   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10535   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10536   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10537   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10538   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10539   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10540   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10541   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10542   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10543   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10544
10545   /* Monadic operations.  */
10546   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10547   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10548   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10549
10550   /* Dyadic operations.  */
10551   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10552   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10553   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10554   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10555   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10556   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10557   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10558   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10559   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10560
10561   /* Comparisons.  */
10562   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10563   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10564   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10565   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10566
10567   /* VFP V2.  */
10568   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
10569   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
10570   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
10571   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
10572
10573   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
10574   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
10575   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10576   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10577   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10578   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10579   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10580   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
10581   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
10582
10583   /* Intel Wireless MMX technology instructions.  */
10584   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10585   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10586   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10587   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10588   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10589   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10590   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10591   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10592   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10593   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10594   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10595   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10596   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10597   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10598   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10599   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10600   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10601   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10602   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
10603   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
10604   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10605   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10606   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10607   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10608   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10609   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10610   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10611   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10612   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10613   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
10614   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
10615   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10616   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10617   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10618   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10619   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10620   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10621   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10622   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10623   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10624   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10625   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10626   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10627   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10628   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10629   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10630   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
10631   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10632   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10633   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10634   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10635   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10636   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10637   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10638   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10639   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10640   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10641   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10642   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10643   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10644   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10645   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10646   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10647   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10648   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10649   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10650   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10651   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10652   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10653   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10654   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10655   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10656   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10657   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10658   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10659   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10660   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10661   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10662   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10663   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10664   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10665   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10666   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10667   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10668   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10669   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10670   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10671   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10672   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
10673   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10674   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10675   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10676   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10677   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10678   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10679   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10680   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10681   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10682   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10683   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10684   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10685   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10686   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10687   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10688   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10689   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10690   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10691   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10692   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10693   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10694   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
10695   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10696   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10697   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10698   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10699   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10700   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10701   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10702   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10703   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10704   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10705   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10706   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10707   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10708   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10709   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10710   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10711   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10712   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10713   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10714   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10715   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10716   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10717   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10718   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10719   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10720   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10721   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10722   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10723   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10724   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10725   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10726   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10727   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10728   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10729   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10730   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10731   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10732   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10733   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10734   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10735   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10736   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10737   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10738   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10739   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10740   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10741   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10742   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10743   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10744   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10745   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
10746
10747   /* Cirrus Maverick instructions.  */
10748   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10749   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10750   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10751   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10752   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10753   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10754   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10755   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10756   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
10757   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
10758   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10759   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10760   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10761   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10762   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10763   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10764   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10765   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10766   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10767   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10768   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10769   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10770   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10771   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10772   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10773   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10774   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
10775   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
10776   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
10777   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
10778   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10779   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10780   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
10781   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
10782   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
10783   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
10784   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
10785   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
10786   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
10787   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
10788   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
10789   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
10790   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
10791   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
10792   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
10793   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
10794   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
10795   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
10796   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
10797   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
10798   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10799   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10800   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10801   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10802   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10803   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10804   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10805   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10806   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10807   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10808   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10809   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10810   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10811   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10812   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10813   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10814   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10815   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10816   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10817   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10818   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10819   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10820   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10821   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10822   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10823   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10824 };
10825
10826 /* Iterate over the base tables to create the instruction patterns.  */
10827
10828 static void
10829 build_arm_ops_hsh (void)
10830 {
10831   unsigned int i;
10832   unsigned int j;
10833   static struct obstack insn_obstack;
10834
10835   obstack_begin (&insn_obstack, 4000);
10836
10837   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10838     {
10839       const struct asm_opcode *insn = insns + i;
10840
10841       if (insn->cond_offset != 0)
10842         {
10843           /* Insn supports conditional execution.  Build the varaints
10844              and insert them in the hash table.  */
10845           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10846             {
10847               unsigned len = strlen (insn->template);
10848               struct asm_opcode *new;
10849               char *template;
10850
10851               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10852               /* All condition codes are two characters.  */
10853               template = obstack_alloc (&insn_obstack, len + 3);
10854
10855               strncpy (template, insn->template, insn->cond_offset);
10856               strcpy (template + insn->cond_offset, conds[j].template);
10857               if (len > insn->cond_offset)
10858                 strcpy (template + insn->cond_offset + 2,
10859                         insn->template + insn->cond_offset);
10860               new->template = template;
10861               new->cond_offset = 0;
10862               new->variant = insn->variant;
10863               new->parms = insn->parms;
10864               new->value = (insn->value & ~COND_MASK) | conds[j].value;
10865
10866               hash_insert (arm_ops_hsh, new->template, (PTR) new);
10867             }
10868         }
10869       /* Finally, insert the unconditional insn in the table directly;
10870          no need to build a copy.  */
10871       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10872     }
10873 }
10874
10875 \f
10876 static const struct thumb_opcode tinsns[] =
10877 {
10878   /* Thumb v1 (ARMv4T).  */
10879   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
10880   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
10881   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
10882   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
10883   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
10884   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
10885   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
10886   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10887   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10888   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10889   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10890   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10891   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
10892   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
10893   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
10894   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
10895   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
10896   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
10897   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
10898   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
10899   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
10900   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
10901   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
10902   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
10903   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
10904   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
10905   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
10906   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
10907   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
10908   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
10909   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
10910   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
10911   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
10912   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10913   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10914   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10915   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10916   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
10917   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
10918   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
10919   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
10920   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
10921   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
10922   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
10923   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
10924   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
10925   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
10926   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
10927   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
10928   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
10929   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
10930   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
10931   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
10932   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
10933   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
10934   /* Pseudo ops:  */
10935   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
10936   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
10937   /* Thumb v2 (ARMv5T).  */
10938   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
10939   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
10940
10941   /* ARM V6.  */
10942   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
10943   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
10944   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
10945   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
10946   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
10947   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
10948   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
10949   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
10950   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
10951   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
10952   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
10953 };
10954
10955 void
10956 md_begin (void)
10957 {
10958   unsigned mach;
10959   unsigned int i;
10960
10961   if (   (arm_ops_hsh = hash_new ()) == NULL
10962       || (arm_tops_hsh = hash_new ()) == NULL
10963       || (arm_cond_hsh = hash_new ()) == NULL
10964       || (arm_shift_hsh = hash_new ()) == NULL
10965       || (arm_psr_hsh = hash_new ()) == NULL)
10966     as_fatal (_("virtual memory exhausted"));
10967
10968   build_arm_ops_hsh ();
10969   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
10970     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
10971   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
10972     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
10973   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
10974     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
10975   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
10976     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
10977
10978   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10979     build_reg_hsh (all_reg_maps + i);
10980
10981   set_constant_flonums ();
10982
10983   /* Set the cpu variant based on the command-line options.  We prefer
10984      -mcpu= over -march= if both are set (as for GCC); and we prefer
10985      -mfpu= over any other way of setting the floating point unit.
10986      Use of legacy options with new options are faulted.  */
10987   if (legacy_cpu != -1)
10988     {
10989       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
10990         as_bad (_("use of old and new-style options to set CPU type"));
10991
10992       mcpu_cpu_opt = legacy_cpu;
10993     }
10994   else if (mcpu_cpu_opt == -1)
10995     mcpu_cpu_opt = march_cpu_opt;
10996
10997   if (legacy_fpu != -1)
10998     {
10999       if (mfpu_opt != -1)
11000         as_bad (_("use of old and new-style options to set FPU type"));
11001
11002       mfpu_opt = legacy_fpu;
11003     }
11004   else if (mfpu_opt == -1)
11005     {
11006 #if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) 
11007       /* Some environments specify a default FPU.  If they don't, infer it
11008          from the processor.  */
11009       if (mcpu_fpu_opt != -1)
11010         mfpu_opt = mcpu_fpu_opt;
11011       else
11012         mfpu_opt = march_fpu_opt;
11013 #else
11014       mfpu_opt = FPU_DEFAULT;
11015 #endif
11016     }
11017
11018   if (mfpu_opt == -1)
11019     {
11020       if (mcpu_cpu_opt == -1)
11021         mfpu_opt = FPU_DEFAULT;
11022       else if (mcpu_cpu_opt & ARM_EXT_V5)
11023         mfpu_opt = FPU_ARCH_VFP_V2;
11024       else
11025         mfpu_opt = FPU_ARCH_FPA;
11026     }
11027
11028   if (mcpu_cpu_opt == -1)
11029     mcpu_cpu_opt = CPU_DEFAULT;
11030
11031   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11032
11033 #if defined OBJ_COFF || defined OBJ_ELF
11034   {
11035     unsigned int flags = 0;
11036
11037 #if defined OBJ_ELF
11038     flags = meabi_flags;
11039
11040     switch (meabi_flags)
11041       {
11042       case EF_ARM_EABI_UNKNOWN:
11043 #endif
11044         /* Set the flags in the private structure.  */
11045         if (uses_apcs_26)      flags |= F_APCS26;
11046         if (support_interwork) flags |= F_INTERWORK;
11047         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11048         if (pic_code)          flags |= F_PIC;
11049         if ((cpu_variant & FPU_ANY) == FPU_NONE
11050              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11051           flags |= F_SOFT_FLOAT;
11052
11053         switch (mfloat_abi_opt)
11054           {
11055           case ARM_FLOAT_ABI_SOFT:
11056           case ARM_FLOAT_ABI_SOFTFP:
11057             flags |= F_SOFT_FLOAT;
11058             break;
11059
11060           case ARM_FLOAT_ABI_HARD:
11061             if (flags & F_SOFT_FLOAT)
11062               as_bad (_("hard-float conflicts with specified fpu"));
11063             break;
11064           }
11065
11066         /* Using VFP conventions (even if soft-float).  */
11067         if (cpu_variant & FPU_VFP_EXT_NONE)
11068           flags |= F_VFP_FLOAT;
11069
11070 #if defined OBJ_ELF
11071         if (cpu_variant & FPU_ARCH_MAVERICK)
11072             flags |= EF_ARM_MAVERICK_FLOAT;
11073         break;
11074
11075       case EF_ARM_EABI_VER4:
11076         /* No additional flags to set.  */
11077         break;
11078
11079       default:
11080         abort ();
11081       }
11082 #endif
11083     bfd_set_private_flags (stdoutput, flags);
11084
11085     /* We have run out flags in the COFF header to encode the
11086        status of ATPCS support, so instead we create a dummy,
11087        empty, debug section called .arm.atpcs.  */
11088     if (atpcs)
11089       {
11090         asection * sec;
11091
11092         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11093
11094         if (sec != NULL)
11095           {
11096             bfd_set_section_flags
11097               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11098             bfd_set_section_size (stdoutput, sec, 0);
11099             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11100           }
11101       }
11102   }
11103 #endif
11104
11105   /* Record the CPU type as well.  */
11106   switch (cpu_variant & ARM_CPU_MASK)
11107     {
11108     case ARM_2:
11109       mach = bfd_mach_arm_2;
11110       break;
11111
11112     case ARM_3:                 /* Also ARM_250.  */
11113       mach = bfd_mach_arm_2a;
11114       break;
11115
11116     case ARM_6:                 /* Also ARM_7.  */
11117       mach = bfd_mach_arm_3;
11118       break;
11119
11120     default:
11121       mach = bfd_mach_arm_unknown;
11122       break;
11123     }
11124
11125   /* Catch special cases.  */
11126   if (cpu_variant & ARM_CEXT_IWMMXT)
11127     mach = bfd_mach_arm_iWMMXt;
11128   else if (cpu_variant & ARM_CEXT_XSCALE)
11129     mach = bfd_mach_arm_XScale;
11130   else if (cpu_variant & ARM_CEXT_MAVERICK)
11131     mach = bfd_mach_arm_ep9312;
11132   else if (cpu_variant & ARM_EXT_V5E)
11133     mach = bfd_mach_arm_5TE;
11134   else if (cpu_variant & ARM_EXT_V5)
11135     {
11136       if (cpu_variant & ARM_EXT_V4T)
11137         mach = bfd_mach_arm_5T;
11138       else
11139         mach = bfd_mach_arm_5;
11140     }
11141   else if (cpu_variant & ARM_EXT_V4)
11142     {
11143       if (cpu_variant & ARM_EXT_V4T)
11144         mach = bfd_mach_arm_4T;
11145       else
11146         mach = bfd_mach_arm_4;
11147     }
11148   else if (cpu_variant & ARM_EXT_V3M)
11149     mach = bfd_mach_arm_3M;
11150
11151   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11152 }
11153
11154 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11155    for use in the a.out file, and stores them in the array pointed to by buf.
11156    This knows about the endian-ness of the target machine and does
11157    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11158    2 (short) and 4 (long)  Floating numbers are put out as a series of
11159    LITTLENUMS (shorts, here at least).  */
11160
11161 void
11162 md_number_to_chars (char * buf, valueT val, int n)
11163 {
11164   if (target_big_endian)
11165     number_to_chars_bigendian (buf, val, n);
11166   else
11167     number_to_chars_littleendian (buf, val, n);
11168 }
11169
11170 static valueT
11171 md_chars_to_number (char * buf, int n)
11172 {
11173   valueT result = 0;
11174   unsigned char * where = (unsigned char *) buf;
11175
11176   if (target_big_endian)
11177     {
11178       while (n--)
11179         {
11180           result <<= 8;
11181           result |= (*where++ & 255);
11182         }
11183     }
11184   else
11185     {
11186       while (n--)
11187         {
11188           result <<= 8;
11189           result |= (where[n] & 255);
11190         }
11191     }
11192
11193   return result;
11194 }
11195
11196 /* Turn a string in input_line_pointer into a floating point constant
11197    of type TYPE, and store the appropriate bytes in *LITP.  The number
11198    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11199    returned, or NULL on OK.
11200
11201    Note that fp constants aren't represent in the normal way on the ARM.
11202    In big endian mode, things are as expected.  However, in little endian
11203    mode fp constants are big-endian word-wise, and little-endian byte-wise
11204    within the words.  For example, (double) 1.1 in big endian mode is
11205    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11206    the byte sequence 99 99 f1 3f 9a 99 99 99.
11207
11208    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11209
11210 char *
11211 md_atof (int type, char * litP, int * sizeP)
11212 {
11213   int prec;
11214   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11215   char *t;
11216   int i;
11217
11218   switch (type)
11219     {
11220     case 'f':
11221     case 'F':
11222     case 's':
11223     case 'S':
11224       prec = 2;
11225       break;
11226
11227     case 'd':
11228     case 'D':
11229     case 'r':
11230     case 'R':
11231       prec = 4;
11232       break;
11233
11234     case 'x':
11235     case 'X':
11236       prec = 6;
11237       break;
11238
11239     case 'p':
11240     case 'P':
11241       prec = 6;
11242       break;
11243
11244     default:
11245       *sizeP = 0;
11246       return _("bad call to MD_ATOF()");
11247     }
11248
11249   t = atof_ieee (input_line_pointer, type, words);
11250   if (t)
11251     input_line_pointer = t;
11252   *sizeP = prec * 2;
11253
11254   if (target_big_endian)
11255     {
11256       for (i = 0; i < prec; i++)
11257         {
11258           md_number_to_chars (litP, (valueT) words[i], 2);
11259           litP += 2;
11260         }
11261     }
11262   else
11263     {
11264       if (cpu_variant & FPU_ARCH_VFP)
11265         for (i = prec - 1; i >= 0; i--)
11266           {
11267             md_number_to_chars (litP, (valueT) words[i], 2);
11268             litP += 2;
11269           }
11270       else
11271         /* For a 4 byte float the order of elements in `words' is 1 0.
11272            For an 8 byte float the order is 1 0 3 2.  */
11273         for (i = 0; i < prec; i += 2)
11274           {
11275             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11276             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11277             litP += 4;
11278           }
11279     }
11280
11281   return 0;
11282 }
11283
11284 /* The knowledge of the PC's pipeline offset is built into the insns
11285    themselves.  */
11286
11287 long
11288 md_pcrel_from (fixS * fixP)
11289 {
11290   if (fixP->fx_addsy
11291       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11292       && fixP->fx_subsy == NULL)
11293     return 0;
11294
11295   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11296     {
11297       /* PC relative addressing on the Thumb is slightly odd
11298          as the bottom two bits of the PC are forced to zero
11299          for the calculation.  */
11300       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11301     }
11302
11303 #ifdef TE_WINCE
11304   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11305      so we un-adjust here to compensate for the accommodation.  */
11306   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11307 #else
11308   return fixP->fx_where + fixP->fx_frag->fr_address;
11309 #endif
11310 }
11311
11312 /* Round up a section size to the appropriate boundary.  */
11313
11314 valueT
11315 md_section_align (segT   segment ATTRIBUTE_UNUSED,
11316                   valueT size)
11317 {
11318 #ifdef OBJ_ELF
11319   return size;
11320 #else
11321   /* Round all sects to multiple of 4.  */
11322   return (size + 3) & ~3;
11323 #endif
11324 }
11325
11326 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
11327    Otherwise we have no need to default values of symbols.  */
11328
11329 symbolS *
11330 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
11331 {
11332 #ifdef OBJ_ELF
11333   if (name[0] == '_' && name[1] == 'G'
11334       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
11335     {
11336       if (!GOT_symbol)
11337         {
11338           if (symbol_find (name))
11339             as_bad ("GOT already in the symbol table");
11340
11341           GOT_symbol = symbol_new (name, undefined_section,
11342                                    (valueT) 0, & zero_address_frag);
11343         }
11344
11345       return GOT_symbol;
11346     }
11347 #endif
11348
11349   return 0;
11350 }
11351
11352 void
11353 md_apply_fix3 (fixS *   fixP,
11354                valueT * valP,
11355                segT     seg)
11356 {
11357   offsetT        value = * valP;
11358   offsetT        newval;
11359   unsigned int   newimm;
11360   unsigned long  temp;
11361   int            sign;
11362   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
11363   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
11364
11365   assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
11366
11367   /* Note whether this will delete the relocation.  */
11368   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11369     fixP->fx_done = 1;
11370
11371   /* If this symbol is in a different section then we need to leave it for
11372      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
11373      so we have to undo it's effects here.  */
11374   if (fixP->fx_pcrel)
11375     {
11376       if (fixP->fx_addsy != NULL
11377           && S_IS_DEFINED (fixP->fx_addsy)
11378           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11379         value += md_pcrel_from (fixP);
11380     }
11381
11382   /* Remember value for emit_reloc.  */
11383   fixP->fx_addnumber = value;
11384
11385   switch (fixP->fx_r_type)
11386     {
11387     case BFD_RELOC_NONE:
11388       /* This will need to go in the object file.  */
11389       fixP->fx_done = 0;
11390       break;
11391   
11392     case BFD_RELOC_ARM_IMMEDIATE:
11393       /* We claim that this fixup has been processed here,
11394          even if in fact we generate an error because we do
11395          not have a reloc for it, so tc_gen_reloc will reject it.  */
11396       fixP->fx_done = 1;
11397
11398       if (fixP->fx_addsy
11399           && ! S_IS_DEFINED (fixP->fx_addsy))
11400         {
11401           as_bad_where (fixP->fx_file, fixP->fx_line,
11402                         _("undefined symbol %s used as an immediate value"),
11403                         S_GET_NAME (fixP->fx_addsy));
11404           break;
11405         }
11406
11407       newimm = validate_immediate (value);
11408       temp = md_chars_to_number (buf, INSN_SIZE);
11409
11410       /* If the instruction will fail, see if we can fix things up by
11411          changing the opcode.  */
11412       if (newimm == (unsigned int) FAIL
11413           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11414         {
11415           as_bad_where (fixP->fx_file, fixP->fx_line,
11416                         _("invalid constant (%lx) after fixup"),
11417                         (unsigned long) value);
11418           break;
11419         }
11420
11421       newimm |= (temp & 0xfffff000);
11422       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11423       break;
11424
11425     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11426       {
11427         unsigned int highpart = 0;
11428         unsigned int newinsn  = 0xe1a00000; /* nop.  */
11429
11430         newimm = validate_immediate (value);
11431         temp = md_chars_to_number (buf, INSN_SIZE);
11432
11433         /* If the instruction will fail, see if we can fix things up by
11434            changing the opcode.  */
11435         if (newimm == (unsigned int) FAIL
11436             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11437           {
11438             /* No ?  OK - try using two ADD instructions to generate
11439                the value.  */
11440             newimm = validate_immediate_twopart (value, & highpart);
11441
11442             /* Yes - then make sure that the second instruction is
11443                also an add.  */
11444             if (newimm != (unsigned int) FAIL)
11445               newinsn = temp;
11446             /* Still No ?  Try using a negated value.  */
11447             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11448               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11449             /* Otherwise - give up.  */
11450             else
11451               {
11452                 as_bad_where (fixP->fx_file, fixP->fx_line,
11453                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11454                               (long) value);
11455                 break;
11456               }
11457
11458             /* Replace the first operand in the 2nd instruction (which
11459                is the PC) with the destination register.  We have
11460                already added in the PC in the first instruction and we
11461                do not want to do it again.  */
11462             newinsn &= ~ 0xf0000;
11463             newinsn |= ((newinsn & 0x0f000) << 4);
11464           }
11465
11466         newimm |= (temp & 0xfffff000);
11467         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11468
11469         highpart |= (newinsn & 0xfffff000);
11470         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11471       }
11472       break;
11473
11474     case BFD_RELOC_ARM_OFFSET_IMM:
11475       sign = value >= 0;
11476
11477       if (value < 0)
11478         value = - value;
11479
11480       if (validate_offset_imm (value, 0) == FAIL)
11481         {
11482           as_bad_where (fixP->fx_file, fixP->fx_line,
11483                         _("bad immediate value for offset (%ld)"),
11484                         (long) value);
11485           break;
11486         }
11487
11488       newval = md_chars_to_number (buf, INSN_SIZE);
11489       newval &= 0xff7ff000;
11490       newval |= value | (sign ? INDEX_UP : 0);
11491       md_number_to_chars (buf, newval, INSN_SIZE);
11492       break;
11493
11494     case BFD_RELOC_ARM_OFFSET_IMM8:
11495     case BFD_RELOC_ARM_HWLITERAL:
11496       sign = value >= 0;
11497
11498       if (value < 0)
11499         value = - value;
11500
11501       if (validate_offset_imm (value, 1) == FAIL)
11502         {
11503           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11504             as_bad_where (fixP->fx_file, fixP->fx_line,
11505                           _("invalid literal constant: pool needs to be closer"));
11506           else
11507             as_bad (_("bad immediate value for half-word offset (%ld)"),
11508                     (long) value);
11509           break;
11510         }
11511
11512       newval = md_chars_to_number (buf, INSN_SIZE);
11513       newval &= 0xff7ff0f0;
11514       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11515       md_number_to_chars (buf, newval, INSN_SIZE);
11516       break;
11517
11518     case BFD_RELOC_ARM_LITERAL:
11519       sign = value >= 0;
11520
11521       if (value < 0)
11522         value = - value;
11523
11524       if (validate_offset_imm (value, 0) == FAIL)
11525         {
11526           as_bad_where (fixP->fx_file, fixP->fx_line,
11527                         _("invalid literal constant: pool needs to be closer"));
11528           break;
11529         }
11530
11531       newval = md_chars_to_number (buf, INSN_SIZE);
11532       newval &= 0xff7ff000;
11533       newval |= value | (sign ? INDEX_UP : 0);
11534       md_number_to_chars (buf, newval, INSN_SIZE);
11535       break;
11536
11537     case BFD_RELOC_ARM_SHIFT_IMM:
11538       newval = md_chars_to_number (buf, INSN_SIZE);
11539       if (((unsigned long) value) > 32
11540           || (value == 32
11541               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11542         {
11543           as_bad_where (fixP->fx_file, fixP->fx_line,
11544                         _("shift expression is too large"));
11545           break;
11546         }
11547
11548       if (value == 0)
11549         /* Shifts of zero must be done as lsl.  */
11550         newval &= ~0x60;
11551       else if (value == 32)
11552         value = 0;
11553       newval &= 0xfffff07f;
11554       newval |= (value & 0x1f) << 7;
11555       md_number_to_chars (buf, newval, INSN_SIZE);
11556       break;
11557
11558     case BFD_RELOC_ARM_SMI:
11559       if (((unsigned long) value) > 0xffff)
11560         as_bad_where (fixP->fx_file, fixP->fx_line,
11561                       _("invalid smi expression"));
11562       newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0;
11563       newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11564       md_number_to_chars (buf, newval, INSN_SIZE);
11565       break;
11566
11567     case BFD_RELOC_ARM_SWI:
11568       if (arm_data->thumb_mode)
11569         {
11570           if (((unsigned long) value) > 0xff)
11571             as_bad_where (fixP->fx_file, fixP->fx_line,
11572                           _("invalid swi expression"));
11573           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11574           newval |= value;
11575           md_number_to_chars (buf, newval, THUMB_SIZE);
11576         }
11577       else
11578         {
11579           if (((unsigned long) value) > 0x00ffffff)
11580             as_bad_where (fixP->fx_file, fixP->fx_line,
11581                           _("invalid swi expression"));
11582           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11583           newval |= value;
11584           md_number_to_chars (buf, newval, INSN_SIZE);
11585         }
11586       break;
11587
11588     case BFD_RELOC_ARM_MULTI:
11589       if (((unsigned long) value) > 0xffff)
11590         as_bad_where (fixP->fx_file, fixP->fx_line,
11591                       _("invalid expression in load/store multiple"));
11592       newval = value | md_chars_to_number (buf, INSN_SIZE);
11593       md_number_to_chars (buf, newval, INSN_SIZE);
11594       break;
11595
11596     case BFD_RELOC_ARM_PCREL_BRANCH:
11597       newval = md_chars_to_number (buf, INSN_SIZE);
11598
11599       /* Sign-extend a 24-bit number.  */
11600 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11601
11602 #ifdef OBJ_ELF
11603       value = fixP->fx_offset;
11604 #endif
11605
11606       /* We are going to store value (shifted right by two) in the
11607          instruction, in a 24 bit, signed field.  Thus we need to check
11608          that none of the top 8 bits of the shifted value (top 7 bits of
11609          the unshifted, unsigned value) are set, or that they are all set.  */
11610       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
11611           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
11612         {
11613 #ifdef OBJ_ELF
11614           /* Normally we would be stuck at this point, since we cannot store
11615              the absolute address that is the destination of the branch in the
11616              24 bits of the branch instruction.  If however, we happen to know
11617              that the destination of the branch is in the same section as the
11618              branch instruction itself, then we can compute the relocation for
11619              ourselves and not have to bother the linker with it.
11620
11621              FIXME: The test for OBJ_ELF is only here because I have not
11622              worked out how to do this for OBJ_COFF.  */
11623           if (fixP->fx_addsy != NULL
11624               && S_IS_DEFINED (fixP->fx_addsy)
11625               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
11626             {
11627               /* Get pc relative value to go into the branch.  */
11628               value = * valP;
11629
11630               /* Permit a backward branch provided that enough bits
11631                  are set.  Allow a forwards branch, provided that
11632                  enough bits are clear.  */
11633               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
11634                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
11635                 fixP->fx_done = 1;
11636             }
11637
11638           if (! fixP->fx_done)
11639 #endif
11640             as_bad_where (fixP->fx_file, fixP->fx_line,
11641                           _("GAS can't handle same-section branch dest >= 0x04000000"));
11642         }
11643
11644       value >>= 2;
11645       value += SEXT24 (newval);
11646
11647       if (    (value & ~ ((offsetT) 0xffffff)) != 0
11648           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
11649         as_bad_where (fixP->fx_file, fixP->fx_line,
11650                       _("out of range branch"));
11651
11652       if (seg->use_rela_p && !fixP->fx_done)
11653         {
11654           /* Must unshift the value before storing it in the addend.  */
11655           value <<= 2;
11656 #ifdef OBJ_ELF
11657           fixP->fx_offset = value;
11658 #endif
11659           fixP->fx_addnumber = value;
11660           newval = newval & 0xff000000;
11661         }
11662       else
11663           newval = (value & 0x00ffffff) | (newval & 0xff000000);
11664       md_number_to_chars (buf, newval, INSN_SIZE);
11665       break;
11666
11667     case BFD_RELOC_ARM_PCREL_BLX:
11668       {
11669         offsetT hbit;
11670         newval = md_chars_to_number (buf, INSN_SIZE);
11671
11672 #ifdef OBJ_ELF
11673         value = fixP->fx_offset;
11674 #endif
11675         hbit   = (value >> 1) & 1;
11676         value  = (value >> 2) & 0x00ffffff;
11677         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
11678
11679         if (seg->use_rela_p && !fixP->fx_done)
11680           {
11681             /* Must sign-extend and unshift the value before storing
11682                it in the addend.  */
11683             value = SEXT24 (value);
11684             value = (value << 2) | hbit;
11685 #ifdef OBJ_ELF
11686             fixP->fx_offset = value;
11687 #endif
11688             fixP->fx_addnumber = value;
11689             newval = newval & 0xfe000000;
11690           }
11691         else
11692           newval = value | (newval & 0xfe000000) | (hbit << 24);
11693         md_number_to_chars (buf, newval, INSN_SIZE);
11694       }
11695       break;
11696
11697     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
11698       newval = md_chars_to_number (buf, THUMB_SIZE);
11699       {
11700         addressT diff = (newval & 0xff) << 1;
11701         if (diff & 0x100)
11702           diff |= ~0xff;
11703
11704         value += diff;
11705         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
11706           as_bad_where (fixP->fx_file, fixP->fx_line,
11707                         _("branch out of range"));
11708         if (seg->use_rela_p && !fixP->fx_done)
11709           {
11710 #ifdef OBJ_ELF
11711             fixP->fx_offset = value;
11712 #endif
11713             fixP->fx_addnumber = value;
11714             newval = newval & 0xff00;
11715           }
11716         else
11717           newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
11718       }
11719       md_number_to_chars (buf, newval, THUMB_SIZE);
11720       break;
11721
11722     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
11723       newval = md_chars_to_number (buf, THUMB_SIZE);
11724       {
11725         addressT diff = (newval & 0x7ff) << 1;
11726         if (diff & 0x800)
11727           diff |= ~0x7ff;
11728
11729         value += diff;
11730         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
11731           as_bad_where (fixP->fx_file, fixP->fx_line,
11732                         _("branch out of range"));
11733         if (seg->use_rela_p && !fixP->fx_done)
11734           {
11735 #ifdef OBJ_ELF
11736             fixP->fx_offset = value;
11737 #endif
11738             fixP->fx_addnumber = value;
11739             newval = newval & 0xf800;
11740           }
11741         else
11742           newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
11743       }
11744       md_number_to_chars (buf, newval, THUMB_SIZE);
11745       break;
11746
11747     case BFD_RELOC_THUMB_PCREL_BLX:
11748     case BFD_RELOC_THUMB_PCREL_BRANCH23:
11749       {
11750         offsetT newval2;
11751         addressT diff;
11752
11753         newval  = md_chars_to_number (buf, THUMB_SIZE);
11754         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11755         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
11756         if (diff & 0x400000)
11757           diff |= ~0x3fffff;
11758 #ifdef OBJ_ELF
11759         value = fixP->fx_offset;
11760 #endif
11761         value += diff;
11762
11763         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
11764           as_bad_where (fixP->fx_file, fixP->fx_line,
11765                         _("branch with link out of range"));
11766
11767         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
11768           /* For a BLX instruction, make sure that the relocation is rounded up
11769              to a word boundary.  This follows the semantics of the instruction
11770              which specifies that bit 1 of the target address will come from bit
11771              1 of the base address.  */
11772           value = (value + 1) & ~ 1;
11773
11774         if (seg->use_rela_p && !fixP->fx_done)
11775           {
11776 #ifdef OBJ_ELF
11777             fixP->fx_offset = value;
11778 #endif
11779             fixP->fx_addnumber = value;
11780             newval = newval & 0xf800;
11781             newval2 = newval2 & 0xf800;
11782           }
11783         else
11784           {
11785             newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
11786             newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
11787           }
11788         md_number_to_chars (buf, newval, THUMB_SIZE);
11789         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11790       }
11791       break;
11792
11793     case BFD_RELOC_8:
11794       if (seg->use_rela_p && !fixP->fx_done)
11795         break;
11796       if (fixP->fx_done || fixP->fx_pcrel)
11797         md_number_to_chars (buf, value, 1);
11798 #ifdef OBJ_ELF
11799       else
11800         {
11801           value = fixP->fx_offset;
11802           md_number_to_chars (buf, value, 1);
11803         }
11804 #endif
11805       break;
11806
11807     case BFD_RELOC_16:
11808       if (seg->use_rela_p && !fixP->fx_done)
11809         break;
11810       if (fixP->fx_done || fixP->fx_pcrel)
11811         md_number_to_chars (buf, value, 2);
11812 #ifdef OBJ_ELF
11813       else
11814         {
11815           value = fixP->fx_offset;
11816           md_number_to_chars (buf, value, 2);
11817         }
11818 #endif
11819       break;
11820
11821 #ifdef OBJ_ELF
11822     case BFD_RELOC_ARM_GOT32:
11823     case BFD_RELOC_ARM_GOTOFF:
11824     case BFD_RELOC_ARM_TARGET2:
11825       if (seg->use_rela_p && !fixP->fx_done)
11826         break;
11827       md_number_to_chars (buf, 0, 4);
11828       break;
11829 #endif
11830
11831     case BFD_RELOC_RVA:
11832     case BFD_RELOC_32:
11833     case BFD_RELOC_ARM_TARGET1:
11834     case BFD_RELOC_ARM_ROSEGREL32:
11835     case BFD_RELOC_ARM_SBREL32:
11836     case BFD_RELOC_32_PCREL:
11837       if (seg->use_rela_p && !fixP->fx_done)
11838         break;
11839       if (fixP->fx_done || fixP->fx_pcrel)
11840         md_number_to_chars (buf, value, 4);
11841 #ifdef OBJ_ELF
11842       else
11843         {
11844           value = fixP->fx_offset;
11845           md_number_to_chars (buf, value, 4);
11846         }
11847 #endif
11848       break;
11849
11850 #ifdef OBJ_ELF
11851     case BFD_RELOC_ARM_PREL31:
11852       if (fixP->fx_done || fixP->fx_pcrel)
11853         {
11854           newval = md_chars_to_number (buf, 4) & 0x80000000;
11855           if ((value ^ (value >> 1)) & 0x40000000)
11856             {
11857               as_bad_where (fixP->fx_file, fixP->fx_line,
11858                             _("rel31 relocation overflow"));
11859             }
11860           newval |= value & 0x7fffffff;
11861           md_number_to_chars (buf, newval, 4);
11862         }
11863       break;
11864
11865     case BFD_RELOC_ARM_PLT32:
11866       /* It appears the instruction is fully prepared at this point.  */
11867       break;
11868 #endif
11869
11870     case BFD_RELOC_ARM_CP_OFF_IMM:
11871       sign = value >= 0;
11872       if (value < -1023 || value > 1023 || (value & 3))
11873         as_bad_where (fixP->fx_file, fixP->fx_line,
11874                       _("illegal value for co-processor offset"));
11875       if (value < 0)
11876         value = -value;
11877       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11878       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11879       md_number_to_chars (buf, newval, INSN_SIZE);
11880       break;
11881
11882     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11883       sign = value >= 0;
11884       if (value < -255 || value > 255)
11885         as_bad_where (fixP->fx_file, fixP->fx_line,
11886                       _("Illegal value for co-processor offset"));
11887       if (value < 0)
11888         value = -value;
11889       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11890       newval |= value | (sign ?  INDEX_UP : 0);
11891       md_number_to_chars (buf, newval , INSN_SIZE);
11892       break;
11893
11894     case BFD_RELOC_ARM_THUMB_OFFSET:
11895       newval = md_chars_to_number (buf, THUMB_SIZE);
11896       /* Exactly what ranges, and where the offset is inserted depends
11897          on the type of instruction, we can establish this from the
11898          top 4 bits.  */
11899       switch (newval >> 12)
11900         {
11901         case 4: /* PC load.  */
11902           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11903              forced to zero for these loads, so we will need to round
11904              up the offset if the instruction address is not word
11905              aligned (since the final address produced must be, and
11906              we can only describe word-aligned immediate offsets).  */
11907
11908           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11909             as_bad_where (fixP->fx_file, fixP->fx_line,
11910                           _("invalid offset, target not word aligned (0x%08X)"),
11911                           (unsigned int) (fixP->fx_frag->fr_address
11912                                           + fixP->fx_where + value));
11913
11914           if ((value + 2) & ~0x3fe)
11915             as_bad_where (fixP->fx_file, fixP->fx_line,
11916                           _("invalid offset, value too big (0x%08lX)"),
11917                           (long) value);
11918
11919           /* Round up, since pc will be rounded down.  */
11920           newval |= (value + 2) >> 2;
11921           break;
11922
11923         case 9: /* SP load/store.  */
11924           if (value & ~0x3fc)
11925             as_bad_where (fixP->fx_file, fixP->fx_line,
11926                           _("invalid offset, value too big (0x%08lX)"),
11927                           (long) value);
11928           newval |= value >> 2;
11929           break;
11930
11931         case 6: /* Word load/store.  */
11932           if (value & ~0x7c)
11933             as_bad_where (fixP->fx_file, fixP->fx_line,
11934                           _("invalid offset, value too big (0x%08lX)"),
11935                           (long) value);
11936           newval |= value << 4; /* 6 - 2.  */
11937           break;
11938
11939         case 7: /* Byte load/store.  */
11940           if (value & ~0x1f)
11941             as_bad_where (fixP->fx_file, fixP->fx_line,
11942                           _("invalid offset, value too big (0x%08lX)"),
11943                           (long) value);
11944           newval |= value << 6;
11945           break;
11946
11947         case 8: /* Halfword load/store.  */
11948           if (value & ~0x3e)
11949             as_bad_where (fixP->fx_file, fixP->fx_line,
11950                           _("invalid offset, value too big (0x%08lX)"),
11951                           (long) value);
11952           newval |= value << 5; /* 6 - 1.  */
11953           break;
11954
11955         default:
11956           as_bad_where (fixP->fx_file, fixP->fx_line,
11957                         "Unable to process relocation for thumb opcode: %lx",
11958                         (unsigned long) newval);
11959           break;
11960         }
11961       md_number_to_chars (buf, newval, THUMB_SIZE);
11962       break;
11963
11964     case BFD_RELOC_ARM_THUMB_ADD:
11965       /* This is a complicated relocation, since we use it for all of
11966          the following immediate relocations:
11967
11968             3bit ADD/SUB
11969             8bit ADD/SUB
11970             9bit ADD/SUB SP word-aligned
11971            10bit ADD PC/SP word-aligned
11972
11973          The type of instruction being processed is encoded in the
11974          instruction field:
11975
11976            0x8000  SUB
11977            0x00F0  Rd
11978            0x000F  Rs
11979       */
11980       newval = md_chars_to_number (buf, THUMB_SIZE);
11981       {
11982         int rd = (newval >> 4) & 0xf;
11983         int rs = newval & 0xf;
11984         int subtract = newval & 0x8000;
11985
11986         if (rd == REG_SP)
11987           {
11988             if (value & ~0x1fc)
11989               as_bad_where (fixP->fx_file, fixP->fx_line,
11990                             _("invalid immediate for stack address calculation"));
11991             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11992             newval |= value >> 2;
11993           }
11994         else if (rs == REG_PC || rs == REG_SP)
11995           {
11996             if (subtract ||
11997                 value & ~0x3fc)
11998               as_bad_where (fixP->fx_file, fixP->fx_line,
11999                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12000                             (unsigned long) value);
12001             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12002             newval |= rd << 8;
12003             newval |= value >> 2;
12004           }
12005         else if (rs == rd)
12006           {
12007             if (value & ~0xff)
12008               as_bad_where (fixP->fx_file, fixP->fx_line,
12009                             _("invalid 8bit immediate"));
12010             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12011             newval |= (rd << 8) | value;
12012           }
12013         else
12014           {
12015             if (value & ~0x7)
12016               as_bad_where (fixP->fx_file, fixP->fx_line,
12017                             _("invalid 3bit immediate"));
12018             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12019             newval |= rd | (rs << 3) | (value << 6);
12020           }
12021       }
12022       md_number_to_chars (buf, newval, THUMB_SIZE);
12023       break;
12024
12025     case BFD_RELOC_ARM_THUMB_IMM:
12026       newval = md_chars_to_number (buf, THUMB_SIZE);
12027       switch (newval >> 11)
12028         {
12029         case 0x04: /* 8bit immediate MOV.  */
12030         case 0x05: /* 8bit immediate CMP.  */
12031           if (value < 0 || value > 255)
12032             as_bad_where (fixP->fx_file, fixP->fx_line,
12033                           _("invalid immediate: %ld is too large"),
12034                           (long) value);
12035           newval |= value;
12036           break;
12037
12038         default:
12039           abort ();
12040         }
12041       md_number_to_chars (buf, newval, THUMB_SIZE);
12042       break;
12043
12044     case BFD_RELOC_ARM_THUMB_SHIFT:
12045       /* 5bit shift value (0..31).  */
12046       if (value < 0 || value > 31)
12047         as_bad_where (fixP->fx_file, fixP->fx_line,
12048                       _("illegal Thumb shift value: %ld"), (long) value);
12049       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12050       newval |= value << 6;
12051       md_number_to_chars (buf, newval, THUMB_SIZE);
12052       break;
12053
12054     case BFD_RELOC_VTABLE_INHERIT:
12055     case BFD_RELOC_VTABLE_ENTRY:
12056       fixP->fx_done = 0;
12057       return;
12058
12059     case BFD_RELOC_UNUSED:
12060     default:
12061       as_bad_where (fixP->fx_file, fixP->fx_line,
12062                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12063     }
12064 }
12065
12066 /* Translate internal representation of relocation info to BFD target
12067    format.  */
12068
12069 arelent *
12070 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
12071               fixS *     fixp)
12072 {
12073   arelent * reloc;
12074   bfd_reloc_code_real_type code;
12075
12076   reloc = xmalloc (sizeof (arelent));
12077
12078   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
12079   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12080   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12081
12082   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12083 #ifndef OBJ_ELF
12084   if (fixp->fx_pcrel == 0)
12085     reloc->addend = fixp->fx_offset;
12086   else
12087     reloc->addend = fixp->fx_offset = reloc->address;
12088 #else  /* OBJ_ELF */
12089   reloc->addend = fixp->fx_offset;
12090 #endif
12091
12092   switch (fixp->fx_r_type)
12093     {
12094     case BFD_RELOC_8:
12095       if (fixp->fx_pcrel)
12096         {
12097           code = BFD_RELOC_8_PCREL;
12098           break;
12099         }
12100
12101     case BFD_RELOC_16:
12102       if (fixp->fx_pcrel)
12103         {
12104           code = BFD_RELOC_16_PCREL;
12105           break;
12106         }
12107
12108     case BFD_RELOC_32:
12109       if (fixp->fx_pcrel)
12110         {
12111           code = BFD_RELOC_32_PCREL;
12112           break;
12113         }
12114
12115     case BFD_RELOC_NONE:
12116     case BFD_RELOC_ARM_PCREL_BRANCH:
12117     case BFD_RELOC_ARM_PCREL_BLX:
12118     case BFD_RELOC_RVA:
12119     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12120     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12121     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12122     case BFD_RELOC_THUMB_PCREL_BLX:
12123     case BFD_RELOC_VTABLE_ENTRY:
12124     case BFD_RELOC_VTABLE_INHERIT:
12125       code = fixp->fx_r_type;
12126       break;
12127
12128     case BFD_RELOC_ARM_LITERAL:
12129     case BFD_RELOC_ARM_HWLITERAL:
12130       /* If this is called then the a literal has
12131          been referenced across a section boundary.  */
12132       as_bad_where (fixp->fx_file, fixp->fx_line,
12133                     _("literal referenced across section boundary"));
12134       return NULL;
12135
12136 #ifdef OBJ_ELF
12137     case BFD_RELOC_ARM_GOT32:
12138     case BFD_RELOC_ARM_GOTOFF:
12139     case BFD_RELOC_ARM_PLT32:
12140     case BFD_RELOC_ARM_TARGET1:
12141     case BFD_RELOC_ARM_ROSEGREL32:
12142     case BFD_RELOC_ARM_SBREL32:
12143     case BFD_RELOC_ARM_PREL31:
12144     case BFD_RELOC_ARM_TARGET2:
12145       code = fixp->fx_r_type;
12146       break;
12147 #endif
12148
12149     case BFD_RELOC_ARM_IMMEDIATE:
12150       as_bad_where (fixp->fx_file, fixp->fx_line,
12151                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12152       return NULL;
12153
12154     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12155       as_bad_where (fixp->fx_file, fixp->fx_line,
12156                     _("ADRL used for a symbol not defined in the same file"));
12157       return NULL;
12158
12159     case BFD_RELOC_ARM_OFFSET_IMM:
12160       if (fixp->fx_addsy != NULL
12161           && !S_IS_DEFINED (fixp->fx_addsy)
12162           && S_IS_LOCAL (fixp->fx_addsy))
12163         {
12164           as_bad_where (fixp->fx_file, fixp->fx_line,
12165                         _("undefined local label `%s'"),
12166                         S_GET_NAME (fixp->fx_addsy));
12167           return NULL;
12168         }
12169
12170       as_bad_where (fixp->fx_file, fixp->fx_line,
12171                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12172       return NULL;
12173
12174     default:
12175       {
12176         char * type;
12177
12178         switch (fixp->fx_r_type)
12179           {
12180           case BFD_RELOC_NONE:             type = "NONE";         break;
12181           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12182           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12183           case BFD_RELOC_ARM_SMI:          type = "SMI";          break;
12184           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12185           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12186           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12187           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12188           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12189           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12190           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12191           default:                         type = _("<unknown>"); break;
12192           }
12193         as_bad_where (fixp->fx_file, fixp->fx_line,
12194                       _("cannot represent %s relocation in this object file format"),
12195                       type);
12196         return NULL;
12197       }
12198     }
12199
12200 #ifdef OBJ_ELF
12201   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12202       && GOT_symbol
12203       && fixp->fx_addsy == GOT_symbol)
12204     {
12205       code = BFD_RELOC_ARM_GOTPC;
12206       reloc->addend = fixp->fx_offset = reloc->address;
12207     }
12208 #endif
12209
12210   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12211
12212   if (reloc->howto == NULL)
12213     {
12214       as_bad_where (fixp->fx_file, fixp->fx_line,
12215                     _("cannot represent %s relocation in this object file format"),
12216                     bfd_get_reloc_code_name (code));
12217       return NULL;
12218     }
12219
12220   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12221      vtable entry to be used in the relocation's section offset.  */
12222   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12223     reloc->address = fixp->fx_offset;
12224
12225   return reloc;
12226 }
12227
12228 int
12229 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
12230                                segT    segtype ATTRIBUTE_UNUSED)
12231 {
12232   as_fatal (_("md_estimate_size_before_relax\n"));
12233   return 1;
12234 }
12235
12236 /* We need to be able to fix up arbitrary expressions in some statements.
12237    This is so that we can handle symbols that are an arbitrary distance from
12238    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12239    which returns part of an address in a form which will be valid for
12240    a data instruction.  We do this by pushing the expression into a symbol
12241    in the expr_section, and creating a fix for that.  */
12242
12243 static void
12244 fix_new_arm (fragS *       frag,
12245              int           where,
12246              short int     size,
12247              expressionS * exp,
12248              int           pc_rel,
12249              int           reloc)
12250 {
12251   fixS *           new_fix;
12252   arm_fix_data *   arm_data;
12253
12254   switch (exp->X_op)
12255     {
12256     case O_constant:
12257     case O_symbol:
12258     case O_add:
12259     case O_subtract:
12260       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12261       break;
12262
12263     default:
12264       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12265                          pc_rel, reloc);
12266       break;
12267     }
12268
12269   /* Mark whether the fix is to a THUMB instruction, or an ARM
12270      instruction.  */
12271   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
12272   new_fix->tc_fix_data = (PTR) arm_data;
12273   arm_data->thumb_mode = thumb_mode;
12274 }
12275
12276 static void
12277 output_inst (const char * str)
12278 {
12279   char * to = NULL;
12280
12281   if (inst.error)
12282     {
12283       as_bad ("%s -- `%s'", inst.error, str);
12284       return;
12285     }
12286
12287   to = frag_more (inst.size);
12288
12289   if (thumb_mode && (inst.size > THUMB_SIZE))
12290     {
12291       assert (inst.size == (2 * THUMB_SIZE));
12292       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12293       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12294     }
12295   else if (inst.size > INSN_SIZE)
12296     {
12297       assert (inst.size == (2 * INSN_SIZE));
12298       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12299       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12300     }
12301   else
12302     md_number_to_chars (to, inst.instruction, inst.size);
12303
12304   if (inst.reloc.type != BFD_RELOC_UNUSED)
12305     fix_new_arm (frag_now, to - frag_now->fr_literal,
12306                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12307                  inst.reloc.type);
12308
12309 #ifdef OBJ_ELF
12310   dwarf2_emit_insn (inst.size);
12311 #endif
12312 }
12313
12314 void
12315 md_assemble (char * str)
12316 {
12317   char  c;
12318   char *p;
12319   char *start;
12320
12321   /* Align the previous label if needed.  */
12322   if (last_label_seen != NULL)
12323     {
12324       symbol_set_frag (last_label_seen, frag_now);
12325       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12326       S_SET_SEGMENT (last_label_seen, now_seg);
12327     }
12328
12329   memset (&inst, '\0', sizeof (inst));
12330   inst.reloc.type = BFD_RELOC_UNUSED;
12331
12332   skip_whitespace (str);
12333
12334   /* Scan up to the end of the op-code, which must end in white space or
12335      end of string.  */
12336   for (start = p = str; *p != '\0'; p++)
12337     if (*p == ' ')
12338       break;
12339
12340   if (p == str)
12341     {
12342       as_bad (_("no operator -- statement `%s'\n"), str);
12343       return;
12344     }
12345
12346   if (thumb_mode)
12347     {
12348       const struct thumb_opcode * opcode;
12349
12350       c = *p;
12351       *p = '\0';
12352       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12353       *p = c;
12354
12355       if (opcode)
12356         {
12357           /* Check that this instruction is supported for this CPU.  */
12358           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12359             {
12360               as_bad (_("selected processor does not support `%s'"), str);
12361               return;
12362             }
12363
12364           mapping_state (MAP_THUMB);
12365           inst.instruction = opcode->value;
12366           inst.size = opcode->size;
12367           opcode->parms (p);
12368           output_inst (str);
12369           return;
12370         }
12371     }
12372   else
12373     {
12374       const struct asm_opcode * opcode;
12375
12376       c = *p;
12377       *p = '\0';
12378       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12379       *p = c;
12380
12381       if (opcode)
12382         {
12383           /* Check that this instruction is supported for this CPU.  */
12384           if ((opcode->variant & cpu_variant) == 0)
12385             {
12386               as_bad (_("selected processor does not support `%s'"), str);
12387               return;
12388             }
12389
12390           mapping_state (MAP_ARM);
12391           inst.instruction = opcode->value;
12392           inst.size = INSN_SIZE;
12393           opcode->parms (p);
12394           output_inst (str);
12395           return;
12396         }
12397     }
12398
12399   /* It wasn't an instruction, but it might be a register alias of the form
12400      alias .req reg.  */
12401   if (create_register_alias (str, p))
12402     return;
12403
12404   as_bad (_("bad instruction `%s'"), start);
12405 }
12406
12407 /* md_parse_option
12408       Invocation line includes a switch not recognized by the base assembler.
12409       See if it's a processor-specific option.
12410
12411       This routine is somewhat complicated by the need for backwards
12412       compatibility (since older releases of gcc can't be changed).
12413       The new options try to make the interface as compatible as
12414       possible with GCC.
12415
12416       New options (supported) are:
12417
12418               -mcpu=<cpu name>           Assemble for selected processor
12419               -march=<architecture name> Assemble for selected architecture
12420               -mfpu=<fpu architecture>   Assemble for selected FPU.
12421               -EB/-mbig-endian           Big-endian
12422               -EL/-mlittle-endian        Little-endian
12423               -k                         Generate PIC code
12424               -mthumb                    Start in Thumb mode
12425               -mthumb-interwork          Code supports ARM/Thumb interworking
12426
12427       For now we will also provide support for:
12428
12429               -mapcs-32                  32-bit Program counter
12430               -mapcs-26                  26-bit Program counter
12431               -macps-float               Floats passed in FP registers
12432               -mapcs-reentrant           Reentrant code
12433               -matpcs
12434       (sometime these will probably be replaced with -mapcs=<list of options>
12435       and -matpcs=<list of options>)
12436
12437       The remaining options are only supported for back-wards compatibility.
12438       Cpu variants, the arm part is optional:
12439               -m[arm]1                Currently not supported.
12440               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
12441               -m[arm]3                Arm 3 processor
12442               -m[arm]6[xx],           Arm 6 processors
12443               -m[arm]7[xx][t][[d]m]   Arm 7 processors
12444               -m[arm]8[10]            Arm 8 processors
12445               -m[arm]9[20][tdmi]      Arm 9 processors
12446               -mstrongarm[110[0]]     StrongARM processors
12447               -mxscale                XScale processors
12448               -m[arm]v[2345[t[e]]]    Arm architectures
12449               -mall                   All (except the ARM1)
12450       FP variants:
12451               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
12452               -mfpe-old               (No float load/store multiples)
12453               -mvfpxd                 VFP Single precision
12454               -mvfp                   All VFP
12455               -mno-fpu                Disable all floating point instructions
12456
12457       The following CPU names are recognized:
12458               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12459               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12460               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12461               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12462               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12463               arm10t arm10e, arm1020t, arm1020e, arm10200e,
12464               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
12465
12466       */
12467
12468 const char * md_shortopts = "m:k";
12469
12470 #ifdef ARM_BI_ENDIAN
12471 #define OPTION_EB (OPTION_MD_BASE + 0)
12472 #define OPTION_EL (OPTION_MD_BASE + 1)
12473 #else
12474 #if TARGET_BYTES_BIG_ENDIAN
12475 #define OPTION_EB (OPTION_MD_BASE + 0)
12476 #else
12477 #define OPTION_EL (OPTION_MD_BASE + 1)
12478 #endif
12479 #endif
12480
12481 struct option md_longopts[] =
12482 {
12483 #ifdef OPTION_EB
12484   {"EB", no_argument, NULL, OPTION_EB},
12485 #endif
12486 #ifdef OPTION_EL
12487   {"EL", no_argument, NULL, OPTION_EL},
12488 #endif
12489   {NULL, no_argument, NULL, 0}
12490 };
12491
12492 size_t md_longopts_size = sizeof (md_longopts);
12493
12494 struct arm_option_table
12495 {
12496   char *option;         /* Option name to match.  */
12497   char *help;           /* Help information.  */
12498   int  *var;            /* Variable to change.  */
12499   int   value;          /* What to change it to.  */
12500   char *deprecated;     /* If non-null, print this message.  */
12501 };
12502
12503 struct arm_option_table arm_opts[] =
12504 {
12505   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
12506   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
12507   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12508    &support_interwork, 1, NULL},
12509   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12510   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12511   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12512    1, NULL},
12513   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12514   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12515   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12516   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
12517    NULL},
12518
12519   /* These are recognized by the assembler, but have no affect on code.  */
12520   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12521   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12522
12523   /* DON'T add any new processors to this list -- we want the whole list
12524      to go away...  Add them to the processors table instead.  */
12525   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12526   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12527   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12528   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12529   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12530   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12531   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12532   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12533   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12534   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12535   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12536   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12537   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12538   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12539   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12540   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12541   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12542   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12543   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12544   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12545   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12546   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12547   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12548   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12549   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12550   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12551   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12552   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12553   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12554   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12555   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12556   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12557   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12558   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12559   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12560   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12561   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12562   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12563   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12564   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12565   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12566   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12567   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12568   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12569   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12570   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12571   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12572   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12573   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12574   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12575   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12576   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12577   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12578   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12579   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12580   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12581   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12582   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12583   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12584   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12585   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12586   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12587   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12588   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12589   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12590   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12591   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12592   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12593   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
12594   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12595    N_("use -mcpu=strongarm110")},
12596   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12597    N_("use -mcpu=strongarm1100")},
12598   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12599    N_("use -mcpu=strongarm1110")},
12600   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12601   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12602   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
12603
12604   /* Architecture variants -- don't add any more to this list either.  */
12605   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12606   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12607   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12608   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12609   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12610   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12611   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12612   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12613   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12614   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12615   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12616   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12617   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12618   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12619   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12620   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12621   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12622   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12623
12624   /* Floating point variants -- don't add any more to this list either.  */
12625   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12626   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12627   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12628   {"mno-fpu",  NULL, &legacy_fpu, 0,
12629    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
12630
12631   {NULL, NULL, NULL, 0, NULL}
12632 };
12633
12634 struct arm_cpu_option_table
12635 {
12636   char *name;
12637   int   value;
12638   /* For some CPUs we assume an FPU unless the user explicitly sets
12639      -mfpu=...  */
12640   int   default_fpu;
12641 };
12642
12643 /* This list should, at a minimum, contain all the cpu names
12644    recognized by GCC.  */
12645 static struct arm_cpu_option_table arm_cpus[] =
12646 {
12647   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12648   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
12649   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
12650   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12651   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
12652   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12653   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12654   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12655   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12656   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12657   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12658   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
12659   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12660   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12661   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12662   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
12663   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12664   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12665   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12666   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12667   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12668   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12669   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12670   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12671   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12672   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12673   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12674   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
12675   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
12676   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12677   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
12678   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
12679   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
12680   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
12681   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
12682   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
12683   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12684   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12685   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
12686   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12687   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12688   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12689   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12690   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12691   /* For V5 or later processors we default to using VFP; but the user
12692      should really set the FPU type explicitly.  */
12693   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12694   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12695   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12696   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12697   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12698   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12699   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12700   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12701   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12702   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12703   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12704   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12705   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12706   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12707   {"arm1026ejs",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12708   {"arm1026ej-s",       ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12709   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
12710   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
12711   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12712   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12713   {"mpcore",            ARM_ARCH_V6K,    FPU_ARCH_VFP_V2},
12714   {"mpcorenovfp",       ARM_ARCH_V6K,    FPU_NONE},
12715   {"arm1176jz-s",       ARM_ARCH_V6ZK,   FPU_NONE},
12716   {"arm1176jzf-s",      ARM_ARCH_V6ZK,   FPU_ARCH_VFP_V2},
12717   /* ??? XSCALE is really an architecture.  */
12718   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12719   /* ??? iwmmxt is not a processor.  */
12720   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
12721   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12722   /* Maverick */
12723   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
12724   {NULL, 0, 0}
12725 };
12726
12727 struct arm_arch_option_table
12728 {
12729   char *name;
12730   int   value;
12731   int   default_fpu;
12732 };
12733
12734 /* This list should, at a minimum, contain all the architecture names
12735    recognized by GCC.  */
12736 static struct arm_arch_option_table arm_archs[] =
12737 {
12738   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12739   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
12740   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
12741   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12742   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12743   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12744   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12745   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
12746   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
12747   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12748   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
12749   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
12750   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
12751   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
12752   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
12753   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
12754   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
12755   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
12756   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
12757   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
12758   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
12759   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
12760   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
12761   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
12762   {NULL, 0, 0}
12763 };
12764
12765 /* ISA extensions in the co-processor space.  */
12766 struct arm_arch_extension_table
12767 {
12768   char *name;
12769   int value;
12770 };
12771
12772 static struct arm_arch_extension_table arm_extensions[] =
12773 {
12774   {"maverick",          ARM_CEXT_MAVERICK},
12775   {"xscale",            ARM_CEXT_XSCALE},
12776   {"iwmmxt",            ARM_CEXT_IWMMXT},
12777   {NULL,                0}
12778 };
12779
12780 struct arm_fpu_option_table
12781 {
12782   char *name;
12783   int   value;
12784 };
12785
12786 /* This list should, at a minimum, contain all the fpu names
12787    recognized by GCC.  */
12788 static struct arm_fpu_option_table arm_fpus[] =
12789 {
12790   {"softfpa",           FPU_NONE},
12791   {"fpe",               FPU_ARCH_FPE},
12792   {"fpe2",              FPU_ARCH_FPE},
12793   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
12794   {"fpa",               FPU_ARCH_FPA},
12795   {"fpa10",             FPU_ARCH_FPA},
12796   {"fpa11",             FPU_ARCH_FPA},
12797   {"arm7500fe",         FPU_ARCH_FPA},
12798   {"softvfp",           FPU_ARCH_VFP},
12799   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
12800   {"vfp",               FPU_ARCH_VFP_V2},
12801   {"vfp9",              FPU_ARCH_VFP_V2},
12802   {"vfp10",             FPU_ARCH_VFP_V2},
12803   {"vfp10-r0",          FPU_ARCH_VFP_V1},
12804   {"vfpxd",             FPU_ARCH_VFP_V1xD},
12805   {"arm1020t",          FPU_ARCH_VFP_V1},
12806   {"arm1020e",          FPU_ARCH_VFP_V2},
12807   {"arm1136jfs",        FPU_ARCH_VFP_V2},
12808   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
12809   {"maverick",          FPU_ARCH_MAVERICK},
12810   {NULL, 0}
12811 };
12812
12813 struct arm_float_abi_option_table
12814 {
12815   char *name;
12816   int value;
12817 };
12818
12819 static struct arm_float_abi_option_table arm_float_abis[] =
12820 {
12821   {"hard",      ARM_FLOAT_ABI_HARD},
12822   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
12823   {"soft",      ARM_FLOAT_ABI_SOFT},
12824   {NULL, 0}
12825 };
12826
12827 struct arm_eabi_option_table
12828 {
12829   char *name;
12830   unsigned int value;
12831 };
12832
12833 #ifdef OBJ_ELF
12834 /* We only know how to output GNU and ver 4 (AAELF) formats.  */
12835 static struct arm_eabi_option_table arm_eabis[] =
12836 {
12837   {"gnu",       EF_ARM_EABI_UNKNOWN},
12838   {"4",         EF_ARM_EABI_VER4},
12839   {NULL, 0}
12840 };
12841 #endif
12842
12843 struct arm_long_option_table
12844 {
12845   char * option;                /* Substring to match.  */
12846   char * help;                  /* Help information.  */
12847   int (* func) (char * subopt); /* Function to decode sub-option.  */
12848   char * deprecated;            /* If non-null, print this message.  */
12849 };
12850
12851 static int
12852 arm_parse_extension (char * str, int * opt_p)
12853 {
12854   while (str != NULL && *str != 0)
12855     {
12856       struct arm_arch_extension_table * opt;
12857       char * ext;
12858       int optlen;
12859
12860       if (*str != '+')
12861         {
12862           as_bad (_("invalid architectural extension"));
12863           return 0;
12864         }
12865
12866       str++;
12867       ext = strchr (str, '+');
12868
12869       if (ext != NULL)
12870         optlen = ext - str;
12871       else
12872         optlen = strlen (str);
12873
12874       if (optlen == 0)
12875         {
12876           as_bad (_("missing architectural extension"));
12877           return 0;
12878         }
12879
12880       for (opt = arm_extensions; opt->name != NULL; opt++)
12881         if (strncmp (opt->name, str, optlen) == 0)
12882           {
12883             *opt_p |= opt->value;
12884             break;
12885           }
12886
12887       if (opt->name == NULL)
12888         {
12889           as_bad (_("unknown architectural extnsion `%s'"), str);
12890           return 0;
12891         }
12892
12893       str = ext;
12894     };
12895
12896   return 1;
12897 }
12898
12899 static int
12900 arm_parse_cpu (char * str)
12901 {
12902   struct arm_cpu_option_table * opt;
12903   char * ext = strchr (str, '+');
12904   int optlen;
12905
12906   if (ext != NULL)
12907     optlen = ext - str;
12908   else
12909     optlen = strlen (str);
12910
12911   if (optlen == 0)
12912     {
12913       as_bad (_("missing cpu name `%s'"), str);
12914       return 0;
12915     }
12916
12917   for (opt = arm_cpus; opt->name != NULL; opt++)
12918     if (strncmp (opt->name, str, optlen) == 0)
12919       {
12920         mcpu_cpu_opt = opt->value;
12921         mcpu_fpu_opt = opt->default_fpu;
12922
12923         if (ext != NULL)
12924           return arm_parse_extension (ext, &mcpu_cpu_opt);
12925
12926         return 1;
12927       }
12928
12929   as_bad (_("unknown cpu `%s'"), str);
12930   return 0;
12931 }
12932
12933 static int
12934 arm_parse_arch (char * str)
12935 {
12936   struct arm_arch_option_table *opt;
12937   char *ext = strchr (str, '+');
12938   int optlen;
12939
12940   if (ext != NULL)
12941     optlen = ext - str;
12942   else
12943     optlen = strlen (str);
12944
12945   if (optlen == 0)
12946     {
12947       as_bad (_("missing architecture name `%s'"), str);
12948       return 0;
12949     }
12950
12951
12952   for (opt = arm_archs; opt->name != NULL; opt++)
12953     if (streq (opt->name, str))
12954       {
12955         march_cpu_opt = opt->value;
12956         march_fpu_opt = opt->default_fpu;
12957
12958         if (ext != NULL)
12959           return arm_parse_extension (ext, &march_cpu_opt);
12960
12961         return 1;
12962       }
12963
12964   as_bad (_("unknown architecture `%s'\n"), str);
12965   return 0;
12966 }
12967
12968 static int
12969 arm_parse_fpu (char * str)
12970 {
12971   struct arm_fpu_option_table * opt;
12972
12973   for (opt = arm_fpus; opt->name != NULL; opt++)
12974     if (streq (opt->name, str))
12975       {
12976         mfpu_opt = opt->value;
12977         return 1;
12978       }
12979
12980   as_bad (_("unknown floating point format `%s'\n"), str);
12981   return 0;
12982 }
12983
12984 static int
12985 arm_parse_float_abi (char * str)
12986 {
12987   struct arm_float_abi_option_table * opt;
12988
12989   for (opt = arm_float_abis; opt->name != NULL; opt++)
12990     if (streq (opt->name, str))
12991       {
12992         mfloat_abi_opt = opt->value;
12993         return 1;
12994       }
12995
12996   as_bad (_("unknown floating point abi `%s'\n"), str);
12997   return 0;
12998 }
12999
13000 #ifdef OBJ_ELF
13001 static int
13002 arm_parse_eabi (char * str)
13003 {
13004   struct arm_eabi_option_table *opt;
13005
13006   for (opt = arm_eabis; opt->name != NULL; opt++)
13007     if (streq (opt->name, str))
13008       {
13009         meabi_flags = opt->value;
13010         return 1;
13011       }
13012   as_bad (_("unknown EABI `%s'\n"), str);
13013   return 0;
13014 }
13015 #endif
13016
13017 struct arm_long_option_table arm_long_opts[] =
13018 {
13019   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13020    arm_parse_cpu, NULL},
13021   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13022    arm_parse_arch, NULL},
13023   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13024    arm_parse_fpu, NULL},
13025   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13026    arm_parse_float_abi, NULL},
13027 #ifdef OBJ_ELF
13028   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13029    arm_parse_eabi, NULL},
13030 #endif
13031   {NULL, NULL, 0, NULL}
13032 };
13033
13034 int
13035 md_parse_option (int c, char * arg)
13036 {
13037   struct arm_option_table *opt;
13038   struct arm_long_option_table *lopt;
13039
13040   switch (c)
13041     {
13042 #ifdef OPTION_EB
13043     case OPTION_EB:
13044       target_big_endian = 1;
13045       break;
13046 #endif
13047
13048 #ifdef OPTION_EL
13049     case OPTION_EL:
13050       target_big_endian = 0;
13051       break;
13052 #endif
13053
13054     case 'a':
13055       /* Listing option.  Just ignore these, we don't support additional
13056          ones.  */
13057       return 0;
13058
13059     default:
13060       for (opt = arm_opts; opt->option != NULL; opt++)
13061         {
13062           if (c == opt->option[0]
13063               && ((arg == NULL && opt->option[1] == 0)
13064                   || streq (arg, opt->option + 1)))
13065             {
13066 #if WARN_DEPRECATED
13067               /* If the option is deprecated, tell the user.  */
13068               if (opt->deprecated != NULL)
13069                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13070                            arg ? arg : "", _(opt->deprecated));
13071 #endif
13072
13073               if (opt->var != NULL)
13074                 *opt->var = opt->value;
13075
13076               return 1;
13077             }
13078         }
13079
13080       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13081         {
13082           /* These options are expected to have an argument.  */
13083           if (c == lopt->option[0]
13084               && arg != NULL
13085               && strncmp (arg, lopt->option + 1,
13086                           strlen (lopt->option + 1)) == 0)
13087             {
13088 #if WARN_DEPRECATED
13089               /* If the option is deprecated, tell the user.  */
13090               if (lopt->deprecated != NULL)
13091                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13092                            _(lopt->deprecated));
13093 #endif
13094
13095               /* Call the sup-option parser.  */
13096               return lopt->func (arg + strlen (lopt->option) - 1);
13097             }
13098         }
13099
13100       return 0;
13101     }
13102
13103   return 1;
13104 }
13105
13106 void
13107 md_show_usage (FILE * fp)
13108 {
13109   struct arm_option_table *opt;
13110   struct arm_long_option_table *lopt;
13111
13112   fprintf (fp, _(" ARM-specific assembler options:\n"));
13113
13114   for (opt = arm_opts; opt->option != NULL; opt++)
13115     if (opt->help != NULL)
13116       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13117
13118   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13119     if (lopt->help != NULL)
13120       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13121
13122 #ifdef OPTION_EB
13123   fprintf (fp, _("\
13124   -EB                     assemble code for a big-endian cpu\n"));
13125 #endif
13126
13127 #ifdef OPTION_EL
13128   fprintf (fp, _("\
13129   -EL                     assemble code for a little-endian cpu\n"));
13130 #endif
13131 }
13132
13133 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13134
13135 void
13136 cons_fix_new_arm (fragS *       frag,
13137                   int           where,
13138                   int           size,
13139                   expressionS * exp)
13140 {
13141   bfd_reloc_code_real_type type;
13142   int pcrel = 0;
13143
13144   /* Pick a reloc.
13145      FIXME: @@ Should look at CPU word size.  */
13146   switch (size)
13147     {
13148     case 1:
13149       type = BFD_RELOC_8;
13150       break;
13151     case 2:
13152       type = BFD_RELOC_16;
13153       break;
13154     case 4:
13155     default:
13156       type = BFD_RELOC_32;
13157       break;
13158     case 8:
13159       type = BFD_RELOC_64;
13160       break;
13161     }
13162
13163   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13164 }
13165
13166 /* A good place to do this, although this was probably not intended
13167    for this kind of use.  We need to dump the literal pool before
13168    references are made to a null symbol pointer.  */
13169
13170 void
13171 arm_cleanup (void)
13172 {
13173   literal_pool * pool;
13174
13175   for (pool = list_of_pools; pool; pool = pool->next)
13176     {
13177       /* Put it at the end of the relevent section.  */
13178       subseg_set (pool->section, pool->sub_section);
13179 #ifdef OBJ_ELF
13180       arm_elf_change_section ();
13181 #endif
13182       s_ltorg (0);
13183     }
13184 }
13185
13186 void
13187 arm_start_line_hook (void)
13188 {
13189   last_label_seen = NULL;
13190 }
13191
13192 void
13193 arm_frob_label (symbolS * sym)
13194 {
13195   last_label_seen = sym;
13196
13197   ARM_SET_THUMB (sym, thumb_mode);
13198
13199 #if defined OBJ_COFF || defined OBJ_ELF
13200   ARM_SET_INTERWORK (sym, support_interwork);
13201 #endif
13202
13203   /* Note - do not allow local symbols (.Lxxx) to be labeled
13204      as Thumb functions.  This is because these labels, whilst
13205      they exist inside Thumb code, are not the entry points for
13206      possible ARM->Thumb calls.  Also, these labels can be used
13207      as part of a computed goto or switch statement.  eg gcc
13208      can generate code that looks like this:
13209
13210                 ldr  r2, [pc, .Laaa]
13211                 lsl  r3, r3, #2
13212                 ldr  r2, [r3, r2]
13213                 mov  pc, r2
13214
13215        .Lbbb:  .word .Lxxx
13216        .Lccc:  .word .Lyyy
13217        ..etc...
13218        .Laaa:   .word Lbbb
13219
13220      The first instruction loads the address of the jump table.
13221      The second instruction converts a table index into a byte offset.
13222      The third instruction gets the jump address out of the table.
13223      The fourth instruction performs the jump.
13224
13225      If the address stored at .Laaa is that of a symbol which has the
13226      Thumb_Func bit set, then the linker will arrange for this address
13227      to have the bottom bit set, which in turn would mean that the
13228      address computation performed by the third instruction would end
13229      up with the bottom bit set.  Since the ARM is capable of unaligned
13230      word loads, the instruction would then load the incorrect address
13231      out of the jump table, and chaos would ensue.  */
13232   if (label_is_thumb_function_name
13233       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13234       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13235     {
13236       /* When the address of a Thumb function is taken the bottom
13237          bit of that address should be set.  This will allow
13238          interworking between Arm and Thumb functions to work
13239          correctly.  */
13240
13241       THUMB_SET_FUNC (sym, 1);
13242
13243       label_is_thumb_function_name = FALSE;
13244     }
13245 }
13246
13247 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13248    ARM ones.  */
13249
13250 void
13251 arm_adjust_symtab (void)
13252 {
13253 #ifdef OBJ_COFF
13254   symbolS * sym;
13255
13256   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13257     {
13258       if (ARM_IS_THUMB (sym))
13259         {
13260           if (THUMB_IS_FUNC (sym))
13261             {
13262               /* Mark the symbol as a Thumb function.  */
13263               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13264                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13265                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13266
13267               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13268                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13269               else
13270                 as_bad (_("%s: unexpected function type: %d"),
13271                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13272             }
13273           else switch (S_GET_STORAGE_CLASS (sym))
13274             {
13275             case C_EXT:
13276               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13277               break;
13278             case C_STAT:
13279               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13280               break;
13281             case C_LABEL:
13282               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13283               break;
13284             default:
13285               /* Do nothing.  */
13286               break;
13287             }
13288         }
13289
13290       if (ARM_IS_INTERWORK (sym))
13291         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13292     }
13293 #endif
13294 #ifdef OBJ_ELF
13295   symbolS * sym;
13296   char      bind;
13297
13298   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13299     {
13300       if (ARM_IS_THUMB (sym))
13301         {
13302           elf_symbol_type * elf_sym;
13303
13304           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13305           bind = ELF_ST_BIND (elf_sym);
13306
13307           /* If it's a .thumb_func, declare it as so,
13308              otherwise tag label as .code 16.  */
13309           if (THUMB_IS_FUNC (sym))
13310             elf_sym->internal_elf_sym.st_info =
13311               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13312           else
13313             elf_sym->internal_elf_sym.st_info =
13314               ELF_ST_INFO (bind, STT_ARM_16BIT);
13315         }
13316     }
13317 #endif
13318 }
13319
13320 int
13321 arm_data_in_code (void)
13322 {
13323   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13324     {
13325       *input_line_pointer = '/';
13326       input_line_pointer += 5;
13327       *input_line_pointer = 0;
13328       return 1;
13329     }
13330
13331   return 0;
13332 }
13333
13334 char *
13335 arm_canonicalize_symbol_name (char * name)
13336 {
13337   int len;
13338
13339   if (thumb_mode && (len = strlen (name)) > 5
13340       && streq (name + len - 5, "/data"))
13341     *(name + len - 5) = 0;
13342
13343   return name;
13344 }
13345
13346 #if defined OBJ_COFF || defined OBJ_ELF
13347 void
13348 arm_validate_fix (fixS * fixP)
13349 {
13350   /* If the destination of the branch is a defined symbol which does not have
13351      the THUMB_FUNC attribute, then we must be calling a function which has
13352      the (interfacearm) attribute.  We look for the Thumb entry point to that
13353      function and change the branch to refer to that function instead.  */
13354   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13355       && fixP->fx_addsy != NULL
13356       && S_IS_DEFINED (fixP->fx_addsy)
13357       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13358     {
13359       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13360     }
13361 }
13362 #endif
13363
13364 int
13365 arm_force_relocation (struct fix * fixp)
13366 {
13367 #if defined (OBJ_COFF) && defined (TE_PE)
13368   if (fixp->fx_r_type == BFD_RELOC_RVA)
13369     return 1;
13370 #endif
13371 #ifdef OBJ_ELF
13372   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13373       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13374       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13375       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13376     return 1;
13377 #endif
13378
13379   /* Resolve these relocations even if the symbol is extern or weak.  */
13380   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13381       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13382       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13383     return 0;
13384
13385   return generic_force_reloc (fixp);
13386 }
13387
13388 #ifdef OBJ_COFF
13389 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13390    local labels from being added to the output symbol table when they
13391    are used with the ADRL pseudo op.  The ADRL relocation should always
13392    be resolved before the binbary is emitted, so it is safe to say that
13393    it is adjustable.  */
13394
13395 bfd_boolean
13396 arm_fix_adjustable (fixS * fixP)
13397 {
13398   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13399     return 1;
13400   return 0;
13401 }
13402 #endif
13403
13404 #ifdef OBJ_ELF
13405 /* Relocations against Thumb function names must be left unadjusted,
13406    so that the linker can use this information to correctly set the
13407    bottom bit of their addresses.  The MIPS version of this function
13408    also prevents relocations that are mips-16 specific, but I do not
13409    know why it does this.
13410
13411    FIXME:
13412    There is one other problem that ought to be addressed here, but
13413    which currently is not:  Taking the address of a label (rather
13414    than a function) and then later jumping to that address.  Such
13415    addresses also ought to have their bottom bit set (assuming that
13416    they reside in Thumb code), but at the moment they will not.  */
13417
13418 bfd_boolean
13419 arm_fix_adjustable (fixS * fixP)
13420 {
13421   if (fixP->fx_addsy == NULL)
13422     return 1;
13423
13424   if (THUMB_IS_FUNC (fixP->fx_addsy)
13425       && fixP->fx_subsy == NULL)
13426     return 0;
13427
13428   /* We need the symbol name for the VTABLE entries.  */
13429   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
13430       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
13431     return 0;
13432
13433   /* Don't allow symbols to be discarded on GOT related relocs.  */
13434   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
13435       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
13436       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
13437       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
13438     return 0;
13439
13440   return 1;
13441 }
13442
13443 const char *
13444 elf32_arm_target_format (void)
13445 {
13446 #ifdef TE_SYMBIAN
13447   return (target_big_endian
13448           ? "elf32-bigarm-symbian"
13449           : "elf32-littlearm-symbian");
13450 #elif defined (TE_VXWORKS)
13451   return (target_big_endian
13452           ? "elf32-bigarm-vxworks"
13453           : "elf32-littlearm-vxworks");
13454 #else
13455   if (target_big_endian)
13456     return "elf32-bigarm";
13457   else
13458     return "elf32-littlearm";
13459 #endif
13460 }
13461
13462 void
13463 armelf_frob_symbol (symbolS * symp,
13464                     int *     puntp)
13465 {
13466   elf_frob_symbol (symp, puntp);
13467 }
13468
13469 static void
13470 s_arm_elf_cons (int nbytes)
13471 {
13472   expressionS exp;
13473
13474 #ifdef md_flush_pending_output
13475   md_flush_pending_output ();
13476 #endif
13477
13478   if (is_it_end_of_statement ())
13479     {
13480       demand_empty_rest_of_line ();
13481       return;
13482     }
13483
13484 #ifdef md_cons_align
13485   md_cons_align (nbytes);
13486 #endif
13487
13488   mapping_state (MAP_DATA);
13489   do
13490     {
13491       bfd_reloc_code_real_type reloc;
13492
13493       expression (& exp);
13494
13495       if (exp.X_op == O_symbol
13496           && * input_line_pointer == '('
13497           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
13498         {
13499           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13500           int size = bfd_get_reloc_size (howto);
13501
13502           if (size > nbytes)
13503             as_bad ("%s relocations do not fit in %d bytes",
13504                     howto->name, nbytes);
13505           else
13506             {
13507               char *p = frag_more ((int) nbytes);
13508               int offset = nbytes - size;
13509
13510               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13511                            &exp, 0, reloc);
13512             }
13513         }
13514       else
13515         emit_expr (&exp, (unsigned int) nbytes);
13516     }
13517   while (*input_line_pointer++ == ',');
13518
13519   /* Put terminator back into stream.  */
13520   input_line_pointer --;
13521   demand_empty_rest_of_line ();
13522 }
13523
13524
13525 /* Parse a .rel31 directive.  */
13526
13527 static void
13528 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
13529 {
13530   expressionS exp;
13531   char *p;
13532   valueT highbit;
13533
13534   SKIP_WHITESPACE ();
13535
13536   highbit = 0;
13537   if (*input_line_pointer == '1')
13538     highbit = 0x80000000;
13539   else if (*input_line_pointer != '0')
13540     as_bad (_("expected 0 or 1"));
13541
13542   input_line_pointer++;
13543   SKIP_WHITESPACE ();
13544   if (*input_line_pointer != ',')
13545     as_bad (_("missing comma"));
13546   input_line_pointer++;
13547
13548 #ifdef md_flush_pending_output
13549   md_flush_pending_output ();
13550 #endif
13551
13552 #ifdef md_cons_align
13553   md_cons_align (4);
13554 #endif
13555
13556   mapping_state (MAP_DATA);
13557
13558   expression (&exp);
13559
13560   p = frag_more (4);
13561   md_number_to_chars (p, highbit, 4);
13562   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
13563                BFD_RELOC_ARM_PREL31);
13564
13565   demand_empty_rest_of_line ();
13566 }
13567 \f
13568 /* Code to deal with unwinding tables.  */
13569
13570 static void add_unwind_adjustsp (offsetT);
13571
13572 /* Switch to section NAME and create section if necessary.  It's
13573    rather ugly that we have to manipulate input_line_pointer but I
13574    don't see any other way to accomplish the same thing without
13575    changing obj-elf.c (which may be the Right Thing, in the end).
13576    Copied from tc-ia64.c.  */
13577
13578 static void
13579 set_section (char *name)
13580 {
13581   char *saved_input_line_pointer;
13582
13583   saved_input_line_pointer = input_line_pointer;
13584   input_line_pointer = name;
13585   obj_elf_section (0);
13586   input_line_pointer = saved_input_line_pointer;
13587 }
13588
13589 /* Cenerate and deferred unwind frame offset.  */
13590
13591 static void
13592 flush_pending_unwind (void)
13593 {
13594   offsetT offset;
13595
13596   offset = unwind.pending_offset;
13597   unwind.pending_offset = 0;
13598   if (offset != 0)
13599     add_unwind_adjustsp (offset);
13600 }
13601
13602 /* Add an opcode to this list for this function.  Two-byte opcodes should
13603    be passed as op[0] << 8 | op[1].  The list of opcodes is built in reverse
13604    order.  */
13605
13606 static void
13607 add_unwind_opcode (valueT op, int length)
13608 {
13609   /* Add any deferred stack adjustment.  */
13610   if (unwind.pending_offset)
13611     flush_pending_unwind ();
13612
13613   unwind.sp_restored = 0;
13614
13615   if (unwind.opcode_count + length > unwind.opcode_alloc)
13616     {
13617       unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
13618       if (unwind.opcodes)
13619         unwind.opcodes = xrealloc (unwind.opcodes,
13620                                    unwind.opcode_alloc);
13621       else
13622         unwind.opcodes = xmalloc (unwind.opcode_alloc);
13623     }
13624   while (length > 0)
13625     {
13626       length--;
13627       unwind.opcodes[unwind.opcode_count] = op & 0xff;
13628       op >>= 8;
13629       unwind.opcode_count++;
13630     }
13631 }
13632
13633 /* Add unwind opcodes to adjust the stack pointer.  */
13634
13635 static void
13636 add_unwind_adjustsp (offsetT offset)
13637 {
13638   valueT op;
13639
13640   if (offset > 0x200)
13641     {
13642       /* We need at most 5 bytes to hold a 32-bit value in a uleb128.  */
13643       char bytes[5];
13644       int n;
13645       valueT o;
13646
13647       /* Long form: 0xb2, uleb128.  */
13648       /* This might not fit in a word so add the individual bytes,
13649          remembering the list is built in reverse order.  */
13650       o = (valueT) ((offset - 0x204) >> 2);
13651       if (o == 0)
13652         add_unwind_opcode (0, 1);
13653
13654       /* Calculate the uleb128 encoding of the offset.  */
13655       n = 0;
13656       while (o)
13657         {
13658           bytes[n] = o & 0x7f;
13659           o >>= 7;
13660           if (o)
13661             bytes[n] |= 0x80;
13662           n++;
13663         }
13664       /* Add the insn.  */
13665       for (; n; n--)
13666         add_unwind_opcode (bytes[n - 1], 1);
13667       add_unwind_opcode (0xb2, 1);
13668     }
13669   else if (offset > 0x100)
13670     {
13671       /* Two short opcodes.  */
13672       add_unwind_opcode (0x3f, 1);
13673       op = (offset - 0x104) >> 2;
13674       add_unwind_opcode (op, 1);
13675     }
13676   else if (offset > 0)
13677     {
13678       /* Short opcode.  */
13679       op = (offset - 4) >> 2;
13680       add_unwind_opcode (op, 1);
13681     }
13682   else if (offset < 0)
13683     {
13684       offset = -offset;
13685       while (offset > 0x100)
13686         {
13687           add_unwind_opcode (0x7f, 1);
13688           offset -= 0x100;
13689         }
13690       op = ((offset - 4) >> 2) | 0x40;
13691       add_unwind_opcode (op, 1);
13692     }
13693 }
13694
13695 /* Finish the list of unwind opcodes for this function.  */
13696 static void
13697 finish_unwind_opcodes (void)
13698 {
13699   valueT op;
13700
13701   if (unwind.fp_used)
13702     {
13703       /* Adjust sp as neccessary.  */
13704       unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
13705       flush_pending_unwind ();
13706
13707       /* After restoring sp from the frame pointer.  */
13708       op = 0x90 | unwind.fp_reg;
13709       add_unwind_opcode (op, 1);
13710     }
13711   else
13712     flush_pending_unwind ();
13713 }
13714
13715
13716 /* Start an exception table entry.  If idx is nonzero this is an index table
13717    entry.  */
13718
13719 static void
13720 start_unwind_section (const segT text_seg, int idx)
13721 {
13722   const char * text_name;
13723   const char * prefix;
13724   const char * prefix_once;
13725   size_t prefix_len;
13726   size_t text_len;
13727   char * sec_name;
13728   size_t sec_name_len;
13729
13730   if (idx)
13731     {
13732       prefix = ELF_STRING_ARM_unwind;
13733       prefix_once = ELF_STRING_ARM_unwind_once;
13734     }
13735   else
13736     {
13737       prefix = ELF_STRING_ARM_unwind_info;
13738       prefix_once = ELF_STRING_ARM_unwind_info_once;
13739     }
13740
13741   text_name = segment_name (text_seg);
13742   if (streq (text_name, ".text"))
13743     text_name = "";
13744
13745   if (strncmp (text_name, ".gnu.linkonce.t.",
13746                strlen (".gnu.linkonce.t.")) == 0)
13747     {
13748       prefix = prefix_once;
13749       text_name += strlen (".gnu.linkonce.t.");
13750     }
13751
13752   prefix_len = strlen (prefix);
13753   text_len = strlen (text_name);
13754   sec_name_len = prefix_len + text_len;
13755   sec_name = alloca (sec_name_len + 1);
13756   memcpy (sec_name, prefix, prefix_len);
13757   memcpy (sec_name + prefix_len, text_name, text_len);
13758   sec_name[prefix_len + text_len] = '\0';
13759
13760   /* Handle COMDAT group.  */
13761   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
13762     {
13763       char *section;
13764       size_t len, group_name_len;
13765       const char *group_name = elf_group_name (text_seg);
13766
13767       if (group_name == NULL)
13768         {
13769           as_bad ("Group section `%s' has no group signature",
13770                   segment_name (text_seg));
13771           ignore_rest_of_line ();
13772           return;
13773         }
13774       /* We have to construct a fake section directive.  */
13775       group_name_len = strlen (group_name);
13776       if (idx)
13777         prefix_len = 13;
13778       else
13779         prefix_len = 16;
13780
13781       len = (sec_name_len
13782              + prefix_len             /* ,"aG",%sectiontype,  */
13783              + group_name_len         /* ,group_name  */
13784              + 7);                    /* ,comdat  */
13785
13786       section = alloca (len + 1);
13787       memcpy (section, sec_name, sec_name_len);
13788       if (idx)
13789           memcpy (section + sec_name_len, ",\"aG\",%exidx,", 13);
13790       else
13791           memcpy (section + sec_name_len, ",\"aG\",%progbits,", 16);
13792       memcpy (section + sec_name_len + prefix_len, group_name, group_name_len);
13793       memcpy (section + len - 7, ",comdat", 7);
13794       section [len] = '\0';
13795       set_section (section);
13796     }
13797   else
13798     {
13799       set_section (sec_name);
13800       bfd_set_section_flags (stdoutput, now_seg,
13801                              SEC_LOAD | SEC_ALLOC | SEC_READONLY);
13802     }
13803
13804   /* Set the setion link for index tables.  */
13805   if (idx)
13806     elf_linked_to_section (now_seg) = text_seg;
13807 }
13808
13809
13810 /* Start an unwind table entry.  HAVE_DATA is nonzero if we have additional
13811    personality routine data.  Returns zero, or the index table value for
13812    and inline entry.  */
13813
13814 static valueT
13815 create_unwind_entry (int have_data)
13816 {
13817   int size;
13818   addressT where;
13819   unsigned char *ptr;
13820   /* The current word of data.  */
13821   valueT data;
13822   /* The number of bytes left in this word.  */
13823   int n;
13824
13825   finish_unwind_opcodes ();
13826
13827   /* Remember the current text section.  */
13828   unwind.saved_seg = now_seg;
13829   unwind.saved_subseg = now_subseg;
13830
13831   start_unwind_section (now_seg, 0);
13832
13833   if (unwind.personality_routine == NULL)
13834     {
13835       if (unwind.personality_index == -2)
13836         {
13837           if (have_data)
13838             as_bad (_("handerdata in cantunwind frame"));
13839           return 1; /* EXIDX_CANTUNWIND.  */
13840         }
13841
13842       /* Use a default personality routine if none is specified.  */
13843       if (unwind.personality_index == -1)
13844         {
13845           if (unwind.opcode_count > 3)
13846             unwind.personality_index = 1;
13847           else
13848             unwind.personality_index = 0;
13849         }
13850
13851       /* Space for the personality routine entry.  */
13852       if (unwind.personality_index == 0)
13853         {
13854           if (unwind.opcode_count > 3)
13855             as_bad (_("too many unwind opcodes for personality routine 0"));
13856
13857           if (!have_data)
13858             {
13859               /* All the data is inline in the index table.  */
13860               data = 0x80;
13861               n = 3;
13862               while (unwind.opcode_count > 0)
13863                 {
13864                   unwind.opcode_count--;
13865                   data = (data << 8) | unwind.opcodes[unwind.opcode_count];
13866                   n--;
13867                 }
13868
13869               /* Pad with "finish" opcodes.  */
13870               while (n--)
13871                 data = (data << 8) | 0xb0;
13872
13873               return data;
13874             }
13875           size = 0;
13876         }
13877       else
13878         /* We get two opcodes "free" in the first word.  */
13879         size = unwind.opcode_count - 2;
13880     }
13881   else
13882     /* An extra byte is required for the opcode count.  */
13883     size = unwind.opcode_count + 1;
13884
13885   size = (size + 3) >> 2;
13886   if (size > 0xff)
13887     as_bad (_("too many unwind opcodes"));
13888
13889   frag_align (2, 0, 0);
13890   record_alignment (now_seg, 2);
13891   unwind.table_entry = expr_build_dot ();
13892
13893   /* Allocate the table entry.  */
13894   ptr = frag_more ((size << 2) + 4);
13895   where = frag_now_fix () - ((size << 2) + 4);
13896
13897   switch (unwind.personality_index)
13898     {
13899     case -1:
13900       /* ??? Should this be a PLT generating relocation?  */
13901       /* Custom personality routine.  */
13902       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
13903                BFD_RELOC_ARM_PREL31);
13904
13905       /* Indicate dependency to linker.  */
13906         {
13907           char *name = "__aeabi_unwind_cpp_pr0";
13908           symbolS *pr = symbol_find_or_make (name);
13909           fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
13910         }
13911
13912       where += 4;
13913       ptr += 4;
13914
13915       /* Set the first byte to the number of additional words.  */
13916       data = size - 1;
13917       n = 3;
13918       break;
13919
13920     /* ABI defined personality routines.  */
13921     case 0:
13922       /* Three opcodes bytes are packed into the first word.  */
13923       data = 0x80;
13924       n = 3;
13925       goto emit_reloc;
13926
13927     case 1:
13928     case 2:
13929       /* The size and first two opcode bytes go in the first word.  */
13930       data = ((0x80 + unwind.personality_index) << 8) | size;
13931       n = 2;
13932       goto emit_reloc;
13933
13934     emit_reloc:
13935       {
13936         /* Indicate dependency to linker.  */
13937         char *name[] = { "__aeabi_unwind_cpp_pr0",
13938                          "__aeabi_unwind_cpp_pr1",
13939                          "__aeabi_unwind_cpp_pr2" };
13940         symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
13941         fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
13942       }
13943       break;
13944
13945     default:
13946       /* Should never happen.  */
13947       abort ();
13948     }
13949
13950   /* Pack the opcodes into words (MSB first), reversing the list at the same
13951      time.  */
13952   while (unwind.opcode_count > 0)
13953     {
13954       if (n == 0)
13955         {
13956           md_number_to_chars (ptr, data, 4);
13957           ptr += 4;
13958           n = 4;
13959           data = 0;
13960         }
13961       unwind.opcode_count--;
13962       n--;
13963       data = (data << 8) | unwind.opcodes[unwind.opcode_count];
13964     }
13965
13966   /* Finish off the last word.  */
13967   if (n < 4)
13968     {
13969       /* Pad with "finish" opcodes.  */
13970       while (n--)
13971         data = (data << 8) | 0xb0;
13972
13973       md_number_to_chars (ptr, data, 4);
13974     }
13975
13976   if (!have_data)
13977     {
13978       /* Add an empty descriptor if there is no user-specified data.   */
13979       ptr = frag_more (4);
13980       md_number_to_chars (ptr, 0, 4);
13981     }
13982
13983   return 0;
13984 }
13985
13986
13987 /* Parse an unwind_fnstart directive.  Simply records the current location.  */
13988
13989 static void
13990 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
13991 {
13992   demand_empty_rest_of_line ();
13993   /* Mark the start of the function.  */
13994   unwind.proc_start = expr_build_dot ();
13995
13996   /* Reset the rest of the unwind info.  */
13997   unwind.opcode_count = 0;
13998   unwind.table_entry = NULL;
13999   unwind.personality_routine = NULL;
14000   unwind.personality_index = -1;
14001   unwind.frame_size = 0;
14002   unwind.fp_offset = 0;
14003   unwind.fp_reg = 13;
14004   unwind.fp_used = 0;
14005   unwind.sp_restored = 0;
14006 }
14007
14008
14009 /* Parse a handlerdata directive.  Creates the exception handling table entry
14010    for the function.  */
14011
14012 static void
14013 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
14014 {
14015   demand_empty_rest_of_line ();
14016   if (unwind.table_entry)
14017     as_bad (_("dupicate .handlerdata directive"));
14018
14019   create_unwind_entry (1);
14020 }
14021
14022 /* Parse an unwind_fnend directive.  Generates the index table entry.  */
14023
14024 static void
14025 s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
14026 {
14027   long where;
14028   unsigned char *ptr;
14029   valueT val;
14030
14031   demand_empty_rest_of_line ();
14032
14033   /* Add eh table entry.  */
14034   if (unwind.table_entry == NULL)
14035     val = create_unwind_entry (0);
14036   else
14037     val = 0;
14038
14039   /* Add index table entry.  This is two words.  */
14040   start_unwind_section (unwind.saved_seg, 1);
14041   frag_align (2, 0, 0);
14042   record_alignment (now_seg, 2);
14043
14044   ptr = frag_more (8);
14045   where = frag_now_fix () - 8;
14046
14047   /* Self relative offset of the function start.  */
14048   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
14049            BFD_RELOC_ARM_PREL31);
14050
14051   if (val)
14052     /* Inline exception table entry.  */
14053     md_number_to_chars (ptr + 4, val, 4);
14054   else
14055     /* Self relative offset of the table entry.  */
14056     fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
14057              BFD_RELOC_ARM_PREL31);
14058
14059   /* Restore the original section.  */
14060   subseg_set (unwind.saved_seg, unwind.saved_subseg);
14061 }
14062
14063
14064 /* Parse an unwind_cantunwind directive.  */
14065
14066 static void
14067 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
14068 {
14069   demand_empty_rest_of_line ();
14070   if (unwind.personality_routine || unwind.personality_index != -1)
14071     as_bad (_("personality routine specified for cantunwind frame"));
14072
14073   unwind.personality_index = -2;
14074 }
14075
14076
14077 /* Parse a personalityindex directive.  */
14078
14079 static void
14080 s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
14081 {
14082   expressionS exp;
14083
14084   if (unwind.personality_routine || unwind.personality_index != -1)
14085     as_bad (_("duplicate .personalityindex directive"));
14086
14087   SKIP_WHITESPACE ();
14088
14089   expression (&exp);
14090
14091   if (exp.X_op != O_constant
14092       || exp.X_add_number < 0 || exp.X_add_number > 15)
14093     {
14094       as_bad (_("bad personality routine number"));
14095       ignore_rest_of_line ();
14096       return;
14097     }
14098
14099   unwind.personality_index = exp.X_add_number;
14100
14101   demand_empty_rest_of_line ();
14102 }
14103
14104
14105 /* Parse a personality directive.  */
14106
14107 static void
14108 s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
14109 {
14110   char *name, *p, c;
14111
14112   if (unwind.personality_routine || unwind.personality_index != -1)
14113     as_bad (_("duplicate .personality directive"));
14114
14115   SKIP_WHITESPACE ();
14116   name = input_line_pointer;
14117   c = get_symbol_end ();
14118   p = input_line_pointer;
14119   unwind.personality_routine = symbol_find_or_make (name);
14120   *p = c;
14121   SKIP_WHITESPACE ();
14122   demand_empty_rest_of_line ();
14123 }
14124
14125
14126 /* Parse a directive saving core registers.  */
14127
14128 static void
14129 s_arm_unwind_save_core (void)
14130 {
14131   valueT op;
14132   long range;
14133   int n;
14134
14135   SKIP_WHITESPACE ();
14136   range = reg_list (&input_line_pointer);
14137   if (range == FAIL)
14138     {
14139       as_bad (_("expected register list"));
14140       ignore_rest_of_line ();
14141       return;
14142     }
14143
14144   demand_empty_rest_of_line ();
14145
14146   /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
14147      into .unwind_save {..., sp...}.  We aren't bothered about the value of
14148      ip because it is clobbered by calls.  */
14149   if (unwind.sp_restored && unwind.fp_reg == 12
14150       && (range & 0x3000) == 0x1000)
14151     {
14152       unwind.opcode_count--;
14153       unwind.sp_restored = 0;
14154       range = (range | 0x2000) & ~0x1000;
14155       unwind.pending_offset = 0;
14156     }
14157
14158   /* See if we can use the short opcodes.  These pop a block of upto 8
14159      registers starting with r4, plus maybe r14.  */
14160   for (n = 0; n < 8; n++)
14161     {
14162       /* Break at the first non-saved register.  */
14163       if ((range & (1 << (n + 4))) == 0)
14164         break;
14165     }
14166   /* See if there are any other bits set.  */
14167   if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
14168     {
14169       /* Use the long form.  */
14170       op = 0x8000 | ((range >> 4) & 0xfff);
14171       add_unwind_opcode (op, 2);
14172     }
14173   else
14174     {
14175       /* Use the short form.  */
14176       if (range & 0x4000)
14177         op = 0xa8; /* Pop r14.  */
14178       else
14179         op = 0xa0; /* Do not pop r14.  */
14180       op |= (n - 1);
14181       add_unwind_opcode (op, 1);
14182     }
14183
14184   /* Pop r0-r3.  */
14185   if (range & 0xf)
14186     {
14187       op = 0xb100 | (range & 0xf);
14188       add_unwind_opcode (op, 2);
14189     }
14190
14191   /* Record the number of bytes pushed.  */
14192   for (n = 0; n < 16; n++)
14193     {
14194       if (range & (1 << n))
14195         unwind.frame_size += 4;
14196     }
14197 }
14198
14199
14200 /* Parse a directive saving FPA registers.  */
14201
14202 static void
14203 s_arm_unwind_save_fpa (int reg)
14204 {
14205   expressionS exp;
14206   int num_regs;
14207   valueT op;
14208
14209   /* Get Number of registers to transfer.  */
14210   if (skip_past_comma (&input_line_pointer) != FAIL)
14211     expression (&exp);
14212   else
14213     exp.X_op = O_illegal;
14214
14215   if (exp.X_op != O_constant)
14216     {
14217       as_bad (_("expected , <constant>"));
14218       ignore_rest_of_line ();
14219       return;
14220     }
14221
14222   num_regs = exp.X_add_number;
14223
14224   if (num_regs < 1 || num_regs > 4)
14225     {
14226       as_bad (_("number of registers must be in the range [1:4]"));
14227       ignore_rest_of_line ();
14228       return;
14229     }
14230
14231   demand_empty_rest_of_line ();
14232
14233   if (reg == 4)
14234     {
14235       /* Short form.  */
14236       op = 0xb4 | (num_regs - 1);
14237       add_unwind_opcode (op, 1);
14238     }
14239   else
14240     {
14241       /* Long form.  */
14242       op = 0xc800 | (reg << 4) | (num_regs - 1);
14243       add_unwind_opcode (op, 2);
14244     }
14245   unwind.frame_size += num_regs * 12;
14246 }
14247
14248
14249 /* Parse a directive saving VFP registers.  */
14250
14251 static void
14252 s_arm_unwind_save_vfp (void)
14253 {
14254   int count;
14255   int reg;
14256   valueT op;
14257
14258   count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
14259   if (count == FAIL)
14260     {
14261       as_bad (_("expected register list"));
14262       ignore_rest_of_line ();
14263       return;
14264     }
14265
14266   demand_empty_rest_of_line ();
14267
14268   if (reg == 8)
14269     {
14270       /* Short form.  */
14271       op = 0xb8 | (count - 1);
14272       add_unwind_opcode (op, 1);
14273     }
14274   else
14275     {
14276       /* Long form.  */
14277       op = 0xb300 | (reg << 4) | (count - 1);
14278       add_unwind_opcode (op, 2);
14279     }
14280   unwind.frame_size += count * 8 + 4;
14281 }
14282
14283
14284 /* Parse a directive saving iWMMXt registers.  */
14285
14286 static void
14287 s_arm_unwind_save_wmmx (void)
14288 {
14289   int reg;
14290   int hi_reg;
14291   int i;
14292   unsigned wcg_mask;
14293   unsigned wr_mask;
14294   valueT op;
14295
14296   if (*input_line_pointer == '{')
14297     input_line_pointer++;
14298
14299   wcg_mask = 0;
14300   wr_mask = 0;
14301   do
14302     {
14303       reg = arm_reg_parse (&input_line_pointer,
14304                            all_reg_maps[REG_TYPE_IWMMXT].htab);
14305
14306       if (wr_register (reg))
14307         {
14308           i = reg & ~WR_PREFIX;
14309           if (wr_mask >> i)
14310             as_tsktsk (_("register list not in ascending order"));
14311           wr_mask |= 1 << i;
14312         }
14313       else if (wcg_register (reg))
14314         {
14315           i = (reg & ~WC_PREFIX) - 8;
14316           if (wcg_mask >> i)
14317             as_tsktsk (_("register list not in ascending order"));
14318           wcg_mask |= 1 << i;
14319         }
14320       else
14321         {
14322           as_bad (_("expected wr or wcgr"));
14323           goto error;
14324         }
14325
14326       SKIP_WHITESPACE ();
14327       if (*input_line_pointer == '-')
14328         {
14329           hi_reg = arm_reg_parse (&input_line_pointer,
14330                                   all_reg_maps[REG_TYPE_IWMMXT].htab);
14331           if (wr_register (reg) && wr_register (hi_reg))
14332             {
14333               for (; reg < hi_reg; reg++)
14334                 wr_mask |= 1 << (reg & ~WR_PREFIX);
14335             }
14336           else if (wcg_register (reg) && wcg_register (hi_reg))
14337             {
14338               for (; reg < hi_reg; reg++)
14339                 wcg_mask |= 1 << ((reg & ~WC_PREFIX) - 8);
14340             }
14341           else
14342             {
14343               as_bad (_("bad register range"));
14344               goto error;
14345             }
14346         }
14347     }
14348   while (skip_past_comma (&input_line_pointer) != FAIL);
14349
14350   SKIP_WHITESPACE ();
14351   if (*input_line_pointer == '}')
14352     input_line_pointer++;
14353
14354   demand_empty_rest_of_line ();
14355
14356   if (wr_mask && wcg_mask)
14357     {
14358       as_bad (_("inconsistent register types"));
14359       goto error;
14360     }
14361
14362   /* Generate any deferred opcodes becuuse we're going to be looking at
14363      the list.  */
14364   flush_pending_unwind ();
14365
14366   if (wcg_mask)
14367     {
14368       for (i = 0; i < 16; i++)
14369         {
14370           if (wcg_mask & (1 << i))
14371             unwind.frame_size += 4;
14372         }
14373       op = 0xc700 | wcg_mask;
14374       add_unwind_opcode (op, 2);
14375     }
14376   else
14377     {
14378       for (i = 0; i < 16; i++)
14379         {
14380           if (wr_mask & (1 << i))
14381             unwind.frame_size += 8;
14382         }
14383       /* Attempt to combine with a previous opcode.  We do this because gcc
14384          likes to output separate unwind directives for a single block of
14385          registers.  */
14386       if (unwind.opcode_count > 0)
14387         {
14388           i = unwind.opcodes[unwind.opcode_count - 1];
14389           if ((i & 0xf8) == 0xc0)
14390             {
14391               i &= 7;
14392               /* Only merge if the blocks are contiguous.  */
14393               if (i < 6)
14394                 {
14395                   if ((wr_mask & 0xfe00) == (1 << 9))
14396                     {
14397                       wr_mask |= ((1 << (i + 11)) - 1) & 0xfc00;
14398                       unwind.opcode_count--;
14399                     }
14400                 }
14401               else if (i == 6 && unwind.opcode_count >= 2)
14402                 {
14403                   i = unwind.opcodes[unwind.opcode_count - 2];
14404                   reg = i >> 4;
14405                   i &= 0xf;
14406
14407                   op = 0xffff << (reg - 1);
14408                   if (reg > 0
14409                       || ((wr_mask & op) == (1u << (reg - 1))))
14410                     {
14411                       op = (1 << (reg + i + 1)) - 1;
14412                       op &= ~((1 << reg) - 1);
14413                       wr_mask |= op;
14414                       unwind.opcode_count -= 2;
14415                     }
14416                 }
14417             }
14418         }
14419
14420       hi_reg = 15;
14421       /* We want to generate opcodes in the order the registers have been
14422          saved, ie. descending order.  */
14423       for (reg = 15; reg >= -1; reg--)
14424         {
14425           /* Save registers in blocks.  */
14426           if (reg < 0
14427               || !(wr_mask & (1 << reg)))
14428             {
14429               /* We found an unsaved reg.  Generate opcodes to save the
14430                  preceeding block.  */
14431               if (reg != hi_reg)
14432                 {
14433                   if (reg == 9)
14434                     {
14435                       /* Short form.  */
14436                       op = 0xc0 | (hi_reg - 10);
14437                       add_unwind_opcode (op, 1);
14438                     }
14439                   else
14440                     {
14441                       /* Long form.  */
14442                       op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
14443                       add_unwind_opcode (op, 2);
14444                     }
14445                 }
14446               hi_reg = reg - 1;
14447             }
14448         }
14449     }
14450   return;
14451 error:
14452   ignore_rest_of_line ();
14453 }
14454
14455
14456 /* Parse an unwind_save directive.  */
14457
14458 static void
14459 s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
14460 {
14461   char *saved_ptr;
14462   int reg;
14463
14464   /* Figure out what sort of save we have.  */
14465   SKIP_WHITESPACE ();
14466   saved_ptr = input_line_pointer;
14467
14468   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_FN].htab);
14469   if (reg != FAIL)
14470     {
14471       s_arm_unwind_save_fpa (reg);
14472       return;
14473     }
14474
14475   if (*input_line_pointer == '{')
14476     input_line_pointer++;
14477
14478   SKIP_WHITESPACE ();
14479
14480   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_RN].htab);
14481   if (reg != FAIL)
14482     {
14483       input_line_pointer = saved_ptr;
14484       s_arm_unwind_save_core ();
14485       return;
14486     }
14487
14488   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_DN].htab);
14489   if (reg != FAIL)
14490     {
14491       input_line_pointer = saved_ptr;
14492       s_arm_unwind_save_vfp ();
14493       return;
14494     }
14495
14496   reg = arm_reg_parse (&input_line_pointer,
14497                        all_reg_maps[REG_TYPE_IWMMXT].htab);
14498   if (reg != FAIL)
14499     {
14500       input_line_pointer = saved_ptr;
14501       s_arm_unwind_save_wmmx ();
14502       return;
14503     }
14504
14505   /* TODO: Maverick registers.  */
14506   as_bad (_("unrecognised register"));
14507 }
14508
14509
14510 /* Parse an unwind_movsp directive.  */
14511
14512 static void
14513 s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
14514 {
14515   int reg;
14516   valueT op;
14517
14518   SKIP_WHITESPACE ();
14519   reg = reg_required_here (&input_line_pointer, -1);
14520   if (reg == FAIL)
14521     {
14522       as_bad (_("ARM register expected"));
14523       ignore_rest_of_line ();
14524       return;
14525     }
14526
14527   if (reg == 13 || reg == 15)
14528     {
14529       as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
14530       ignore_rest_of_line ();
14531       return;
14532     }
14533
14534   if (unwind.fp_reg != 13)
14535     as_bad (_("unexpected .unwind_movsp directive"));
14536
14537   /* Generate opcode to restore the value.  */
14538   op = 0x90 | reg;
14539   add_unwind_opcode (op, 1);
14540
14541   /* Record the information for later.  */
14542   unwind.fp_reg = reg;
14543   unwind.fp_offset = unwind.frame_size;
14544   unwind.sp_restored = 1;
14545   demand_empty_rest_of_line ();
14546 }
14547
14548
14549 /* Parse #<number>.  */
14550
14551 static int
14552 require_hashconst (int * val)
14553 {
14554   expressionS exp;
14555
14556   SKIP_WHITESPACE ();
14557   if (*input_line_pointer == '#')
14558     {
14559       input_line_pointer++;
14560       expression (&exp);
14561     }
14562   else
14563     exp.X_op = O_illegal;
14564
14565   if (exp.X_op != O_constant)
14566     {
14567       as_bad (_("expected #constant"));
14568       ignore_rest_of_line ();
14569       return FAIL;
14570     }
14571   *val = exp.X_add_number;
14572   return SUCCESS;
14573 }
14574
14575 /* Parse an unwind_pad directive.  */
14576
14577 static void
14578 s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
14579 {
14580   int offset;
14581
14582   if (require_hashconst (&offset) == FAIL)
14583     return;
14584
14585   if (offset & 3)
14586     {
14587       as_bad (_("stack increment must be multiple of 4"));
14588       ignore_rest_of_line ();
14589       return;
14590     }
14591
14592   /* Don't generate any opcodes, just record the details for later.  */
14593   unwind.frame_size += offset;
14594   unwind.pending_offset += offset;
14595
14596   demand_empty_rest_of_line ();
14597 }
14598
14599 /* Parse an unwind_setfp directive.  */
14600
14601 static void
14602 s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
14603 {
14604   int sp_reg;
14605   int fp_reg;
14606   int offset;
14607
14608   fp_reg = reg_required_here (&input_line_pointer, -1);
14609   if (skip_past_comma (&input_line_pointer) == FAIL)
14610     sp_reg = FAIL;
14611   else
14612     sp_reg = reg_required_here (&input_line_pointer, -1);
14613
14614   if (fp_reg == FAIL || sp_reg == FAIL)
14615     {
14616       as_bad (_("expected <reg>, <reg>"));
14617       ignore_rest_of_line ();
14618       return;
14619     }
14620
14621   /* Optonal constant.  */
14622   if (skip_past_comma (&input_line_pointer) != FAIL)
14623     {
14624       if (require_hashconst (&offset) == FAIL)
14625         return;
14626     }
14627   else
14628     offset = 0;
14629
14630   demand_empty_rest_of_line ();
14631
14632   if (sp_reg != 13 && sp_reg != unwind.fp_reg)
14633     {
14634       as_bad (_("register must be either sp or set by a previous"
14635                 "unwind_movsp directive"));
14636       return;
14637     }
14638
14639   /* Don't generate any opcodes, just record the information for later.  */
14640   unwind.fp_reg = fp_reg;
14641   unwind.fp_used = 1;
14642   if (sp_reg == 13)
14643     unwind.fp_offset = unwind.frame_size - offset;
14644   else
14645     unwind.fp_offset -= offset;
14646 }
14647
14648 /* Parse an unwind_raw directive.  */
14649
14650 static void
14651 s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
14652 {
14653   expressionS exp;
14654   /* This is an arbitary limit.  */
14655   unsigned char op[16];
14656   int count;
14657
14658   SKIP_WHITESPACE ();
14659   expression (&exp);
14660   if (exp.X_op == O_constant
14661       && skip_past_comma (&input_line_pointer) != FAIL)
14662     {
14663       unwind.frame_size += exp.X_add_number;
14664       expression (&exp);
14665     }
14666   else
14667     exp.X_op = O_illegal;
14668
14669   if (exp.X_op != O_constant)
14670     {
14671       as_bad (_("expected <offset>, <opcode>"));
14672       ignore_rest_of_line ();
14673       return;
14674     }
14675
14676   count = 0;
14677
14678   /* Parse the opcode.  */
14679   for (;;)
14680     {
14681       if (count >= 16)
14682         {
14683           as_bad (_("unwind opcode too long"));
14684           ignore_rest_of_line ();
14685         }
14686       if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
14687         {
14688           as_bad (_("invalid unwind opcode"));
14689           ignore_rest_of_line ();
14690           return;
14691         }
14692       op[count++] = exp.X_add_number;
14693
14694       /* Parse the next byte.  */
14695       if (skip_past_comma (&input_line_pointer) == FAIL)
14696         break;
14697
14698       expression (&exp);
14699     }
14700
14701   /* Add the opcode bytes in reverse order.  */
14702   while (count--)
14703     add_unwind_opcode (op[count], 1);
14704
14705   demand_empty_rest_of_line ();
14706 }
14707
14708 #endif /* OBJ_ELF */
14709
14710 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14711    of an rs_align_code fragment.  */
14712
14713 void
14714 arm_handle_align (fragS * fragP)
14715 {
14716   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14717   static char const thumb_noop[2] = { 0xc0, 0x46 };
14718   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14719   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14720
14721   int bytes, fix, noop_size;
14722   char * p;
14723   const char * noop;
14724
14725   if (fragP->fr_type != rs_align_code)
14726     return;
14727
14728   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14729   p = fragP->fr_literal + fragP->fr_fix;
14730   fix = 0;
14731
14732   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14733     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14734
14735   if (fragP->tc_frag_data)
14736     {
14737       if (target_big_endian)
14738         noop = thumb_bigend_noop;
14739       else
14740         noop = thumb_noop;
14741       noop_size = sizeof (thumb_noop);
14742     }
14743   else
14744     {
14745       if (target_big_endian)
14746         noop = arm_bigend_noop;
14747       else
14748         noop = arm_noop;
14749       noop_size = sizeof (arm_noop);
14750     }
14751
14752   if (bytes & (noop_size - 1))
14753     {
14754       fix = bytes & (noop_size - 1);
14755       memset (p, 0, fix);
14756       p += fix;
14757       bytes -= fix;
14758     }
14759
14760   while (bytes >= noop_size)
14761     {
14762       memcpy (p, noop, noop_size);
14763       p += noop_size;
14764       bytes -= noop_size;
14765       fix += noop_size;
14766     }
14767
14768   fragP->fr_fix += fix;
14769   fragP->fr_var = noop_size;
14770 }
14771
14772 /* Called from md_do_align.  Used to create an alignment
14773    frag in a code section.  */
14774
14775 void
14776 arm_frag_align_code (int n, int max)
14777 {
14778   char * p;
14779
14780   /* We assume that there will never be a requirement
14781      to support alignments greater than 32 bytes.  */
14782   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14783     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14784
14785   p = frag_var (rs_align_code,
14786                 MAX_MEM_FOR_RS_ALIGN_CODE,
14787                 1,
14788                 (relax_substateT) max,
14789                 (symbolS *) NULL,
14790                 (offsetT) n,
14791                 (char *) NULL);
14792   *p = 0;
14793 }
14794
14795 /* Perform target specific initialisation of a frag.  */
14796
14797 void
14798 arm_init_frag (fragS * fragP)
14799 {
14800   /* Record whether this frag is in an ARM or a THUMB area.  */
14801   fragP->tc_frag_data = thumb_mode;
14802 }
14803
14804 #ifdef OBJ_ELF
14805
14806 /* Convert REGNAME to a DWARF-2 register number.  */
14807
14808 int
14809 tc_arm_regname_to_dw2regnum (const char *regname)
14810 {
14811   unsigned int i;
14812
14813   for (i = 0; rn_table[i].name; i++)
14814     if (streq (regname, rn_table[i].name))
14815       return rn_table[i].number;
14816
14817   return -1;
14818 }
14819
14820 /* Initialize the DWARF-2 unwind information for this procedure.  */
14821
14822 void
14823 tc_arm_frame_initial_instructions (void)
14824 {
14825   cfi_add_CFA_def_cfa (REG_SP, 0);
14826 }
14827 #endif
14828
14829 /* This table describes all the machine specific pseudo-ops the assembler
14830    has to support.  The fields are:
14831      pseudo-op name without dot
14832      function to call to execute this pseudo-op
14833      Integer arg to pass to the function.  */
14834
14835 const pseudo_typeS md_pseudo_table[] =
14836 {
14837   /* Never called because '.req' does not start a line.  */
14838   { "req",         s_req,         0 },
14839   { "unreq",       s_unreq,       0 },
14840   { "bss",         s_bss,         0 },
14841   { "align",       s_align,       0 },
14842   { "arm",         s_arm,         0 },
14843   { "thumb",       s_thumb,       0 },
14844   { "code",        s_code,        0 },
14845   { "force_thumb", s_force_thumb, 0 },
14846   { "thumb_func",  s_thumb_func,  0 },
14847   { "thumb_set",   s_thumb_set,   0 },
14848   { "even",        s_even,        0 },
14849   { "ltorg",       s_ltorg,       0 },
14850   { "pool",        s_ltorg,       0 },
14851 #ifdef OBJ_ELF
14852   { "word",        s_arm_elf_cons, 4 },
14853   { "long",        s_arm_elf_cons, 4 },
14854   { "rel31",       s_arm_rel31,   0 },
14855   { "fnstart",          s_arm_unwind_fnstart,   0 },
14856   { "fnend",            s_arm_unwind_fnend,     0 },
14857   { "cantunwind",       s_arm_unwind_cantunwind, 0 },
14858   { "personality",      s_arm_unwind_personality, 0 },
14859   { "personalityindex", s_arm_unwind_personalityindex, 0 },
14860   { "handlerdata",      s_arm_unwind_handlerdata, 0 },
14861   { "save",             s_arm_unwind_save,      0 },
14862   { "movsp",            s_arm_unwind_movsp,     0 },
14863   { "pad",              s_arm_unwind_pad,       0 },
14864   { "setfp",            s_arm_unwind_setfp,     0 },
14865   { "unwind_raw",       s_arm_unwind_raw,       0 },
14866 #else
14867   { "word",        cons, 4},
14868 #endif
14869   { "extend",      float_cons, 'x' },
14870   { "ldouble",     float_cons, 'x' },
14871   { "packed",      float_cons, 'p' },
14872   { 0, 0, 0 }
14873 };