* config/tc-arm.c (do_mla): Rename to do_mlas, take second
[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_mlas (char * str, bfd_boolean is_mls)
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   /* This restriction does not apply to mls (nor to mla in v6, but
2850      that's hard to detect at present).  */
2851   if (rm == rd && !is_mls)
2852     as_tsktsk (_("rd and rm should be different in mla"));
2853
2854   if (skip_past_comma (&str) == FAIL
2855       || (rd = reg_required_here (&str, 8)) == FAIL
2856       || skip_past_comma (&str) == FAIL
2857       || (rm = reg_required_here (&str, 12)) == FAIL)
2858     {
2859       inst.error = BAD_ARGS;
2860       return;
2861     }
2862
2863   if (rd == REG_PC || rm == REG_PC)
2864     {
2865       inst.error = BAD_PC;
2866       return;
2867     }
2868
2869   end_of_line (str);
2870 }
2871
2872 static void
2873 do_mla (char *str)
2874 {
2875   do_mlas (str, FALSE);
2876 }
2877
2878 static void
2879 do_mls (char *str)
2880 {
2881   do_mlas (str, TRUE);
2882 }
2883
2884 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2885    Advances *str to the next non-alphanumeric.
2886    Returns 0, or else FAIL (in which case sets inst.error).
2887
2888   (In a future XScale, there may be accumulators other than zero.
2889   At that time this routine and its callers can be upgraded to suit.)  */
2890
2891 static int
2892 accum0_required_here (char ** str)
2893 {
2894   static char buff [128];       /* Note the address is taken.  Hence, static.  */
2895   char * p = * str;
2896   char   c;
2897   int result = 0;               /* The accum number.  */
2898
2899   skip_whitespace (p);
2900
2901   *str = p;                     /* Advance caller's string pointer too.  */
2902   c = *p++;
2903   while (ISALNUM (c))
2904     c = *p++;
2905
2906   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
2907
2908   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2909     {
2910       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2911       inst.error = buff;
2912       result = FAIL;
2913     }
2914
2915   *p = c;                       /* Unzap.  */
2916   *str = p;                     /* Caller's string pointer to after match.  */
2917   return result;
2918 }
2919
2920 static int
2921 ldst_extend_v4 (char ** str)
2922 {
2923   int add = INDEX_UP;
2924
2925   switch (**str)
2926     {
2927     case '#':
2928     case '$':
2929       (*str)++;
2930       if (my_get_expression (& inst.reloc.exp, str))
2931         return FAIL;
2932
2933       if (inst.reloc.exp.X_op == O_constant)
2934         {
2935           int value = inst.reloc.exp.X_add_number;
2936
2937           if (value < -255 || value > 255)
2938             {
2939               inst.error = _("address offset too large");
2940               return FAIL;
2941             }
2942
2943           if (value < 0)
2944             {
2945               value = -value;
2946               add = 0;
2947             }
2948
2949           /* Halfword and signextension instructions have the
2950              immediate value split across bits 11..8 and bits 3..0.  */
2951           inst.instruction |= (add | HWOFFSET_IMM
2952                                | ((value >> 4) << 8) | (value & 0xF));
2953         }
2954       else
2955         {
2956           inst.instruction |= HWOFFSET_IMM;
2957           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2958           inst.reloc.pc_rel = 0;
2959         }
2960       return SUCCESS;
2961
2962     case '-':
2963       add = 0;
2964       /* Fall through.  */
2965
2966     case '+':
2967       (*str)++;
2968       /* Fall through.  */
2969
2970     default:
2971       if (reg_required_here (str, 0) == FAIL)
2972         return FAIL;
2973
2974       inst.instruction |= add;
2975       return SUCCESS;
2976     }
2977 }
2978
2979 /* Expects **str -> after a comma. May be leading blanks.
2980    Advances *str, recognizing a load  mode, and setting inst.instruction.
2981    Returns rn, or else FAIL (in which case may set inst.error
2982    and not advance str)
2983
2984    Note: doesn't know Rd, so no err checks that require such knowledge.  */
2985
2986 static int
2987 ld_mode_required_here (char ** string)
2988 {
2989   char * str = * string;
2990   int    rn;
2991   int    pre_inc = 0;
2992
2993   skip_whitespace (str);
2994
2995   if (* str == '[')
2996     {
2997       str++;
2998
2999       skip_whitespace (str);
3000
3001       if ((rn = reg_required_here (& str, 16)) == FAIL)
3002         return FAIL;
3003
3004       skip_whitespace (str);
3005
3006       if (* str == ']')
3007         {
3008           str ++;
3009
3010           if (skip_past_comma (& str) == SUCCESS)
3011             {
3012               /* [Rn],... (post inc) */
3013               if (ldst_extend_v4 (&str) == FAIL)
3014                 return FAIL;
3015             }
3016           else        /* [Rn] */
3017             {
3018               skip_whitespace (str);
3019
3020               if (* str == '!')
3021                 {
3022                   str ++;
3023                   inst.instruction |= WRITE_BACK;
3024                 }
3025
3026               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3027               pre_inc = 1;
3028             }
3029         }
3030       else        /* [Rn,...] */
3031         {
3032           if (skip_past_comma (& str) == FAIL)
3033             {
3034               inst.error = _("pre-indexed expression expected");
3035               return FAIL;
3036             }
3037
3038           pre_inc = 1;
3039
3040           if (ldst_extend_v4 (&str) == FAIL)
3041             return FAIL;
3042
3043           skip_whitespace (str);
3044
3045           if (* str ++ != ']')
3046             {
3047               inst.error = _("missing ]");
3048               return FAIL;
3049             }
3050
3051           skip_whitespace (str);
3052
3053           if (* str == '!')
3054             {
3055               str ++;
3056               inst.instruction |= WRITE_BACK;
3057             }
3058         }
3059     }
3060   else if (* str == '=')        /* ldr's "r,=label" syntax */
3061     /* We should never reach here, because <text> = <expression> is
3062        caught gas/read.c read_a_source_file() as a .set operation.  */
3063     return FAIL;
3064   else                          /* PC +- 8 bit immediate offset.  */
3065     {
3066       if (my_get_expression (& inst.reloc.exp, & str))
3067         return FAIL;
3068
3069       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3070       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3071       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3072       inst.reloc.pc_rel            = 1;
3073       inst.instruction            |= (REG_PC << 16);
3074
3075       rn = REG_PC;
3076       pre_inc = 1;
3077     }
3078
3079   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3080   * string = str;
3081
3082   return rn;
3083 }
3084
3085 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3086    SMLAxy{cond} Rd,Rm,Rs,Rn
3087    SMLAWy{cond} Rd,Rm,Rs,Rn
3088    Error if any register is R15.  */
3089
3090 static void
3091 do_smla (char * str)
3092 {
3093   int rd, rm, rs, rn;
3094
3095   skip_whitespace (str);
3096
3097   if ((rd = reg_required_here (& str, 16)) == FAIL
3098       || skip_past_comma (& str) == FAIL
3099       || (rm = reg_required_here (& str, 0)) == FAIL
3100       || skip_past_comma (& str) == FAIL
3101       || (rs = reg_required_here (& str, 8)) == FAIL
3102       || skip_past_comma (& str) == FAIL
3103       || (rn = reg_required_here (& str, 12)) == FAIL)
3104     inst.error = BAD_ARGS;
3105
3106   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3107     inst.error = BAD_PC;
3108
3109   else
3110     end_of_line (str);
3111 }
3112
3113 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3114    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3115    Error if any register is R15.
3116    Warning if Rdlo == Rdhi.  */
3117
3118 static void
3119 do_smlal (char * str)
3120 {
3121   int rdlo, rdhi, rm, rs;
3122
3123   skip_whitespace (str);
3124
3125   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3126       || skip_past_comma (& str) == FAIL
3127       || (rdhi = reg_required_here (& str, 16)) == FAIL
3128       || skip_past_comma (& str) == FAIL
3129       || (rm = reg_required_here (& str, 0)) == FAIL
3130       || skip_past_comma (& str) == FAIL
3131       || (rs = reg_required_here (& str, 8)) == FAIL)
3132     {
3133       inst.error = BAD_ARGS;
3134       return;
3135     }
3136
3137   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3138     {
3139       inst.error = BAD_PC;
3140       return;
3141     }
3142
3143   if (rdlo == rdhi)
3144     as_tsktsk (_("rdhi and rdlo must be different"));
3145
3146   end_of_line (str);
3147 }
3148
3149 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3150    SMULxy{cond} Rd,Rm,Rs
3151    Error if any register is R15.  */
3152
3153 static void
3154 do_smul (char * str)
3155 {
3156   int rd, rm, rs;
3157
3158   skip_whitespace (str);
3159
3160   if ((rd = reg_required_here (& str, 16)) == FAIL
3161       || skip_past_comma (& str) == FAIL
3162       || (rm = reg_required_here (& str, 0)) == FAIL
3163       || skip_past_comma (& str) == FAIL
3164       || (rs = reg_required_here (& str, 8)) == FAIL)
3165     inst.error = BAD_ARGS;
3166
3167   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3168     inst.error = BAD_PC;
3169
3170   else
3171     end_of_line (str);
3172 }
3173
3174 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3175    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3176    Error if any register is R15.  */
3177
3178 static void
3179 do_qadd (char * str)
3180 {
3181   int rd, rm, rn;
3182
3183   skip_whitespace (str);
3184
3185   if ((rd = reg_required_here (& str, 12)) == FAIL
3186       || skip_past_comma (& str) == FAIL
3187       || (rm = reg_required_here (& str, 0)) == FAIL
3188       || skip_past_comma (& str) == FAIL
3189       || (rn = reg_required_here (& str, 16)) == FAIL)
3190     inst.error = BAD_ARGS;
3191
3192   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3193     inst.error = BAD_PC;
3194
3195   else
3196     end_of_line (str);
3197 }
3198
3199 /* ARM V5E (el Segundo)
3200    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3201    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3202
3203    These are equivalent to the XScale instructions MAR and MRA,
3204    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3205
3206    Result unpredicatable if Rd or Rn is R15.  */
3207
3208 static void
3209 do_co_reg2c (char * str)
3210 {
3211   int rd, rn;
3212
3213   skip_whitespace (str);
3214
3215   if (co_proc_number (& str) == FAIL)
3216     {
3217       if (!inst.error)
3218         inst.error = BAD_ARGS;
3219       return;
3220     }
3221
3222   if (skip_past_comma (& str) == FAIL
3223       || cp_opc_expr (& str, 4, 4) == FAIL)
3224     {
3225       if (!inst.error)
3226         inst.error = BAD_ARGS;
3227       return;
3228     }
3229
3230   if (skip_past_comma (& str) == FAIL
3231       || (rd = reg_required_here (& str, 12)) == FAIL)
3232     {
3233       if (!inst.error)
3234         inst.error = BAD_ARGS;
3235       return;
3236     }
3237
3238   if (skip_past_comma (& str) == FAIL
3239       || (rn = reg_required_here (& str, 16)) == FAIL)
3240     {
3241       if (!inst.error)
3242         inst.error = BAD_ARGS;
3243       return;
3244     }
3245
3246   /* Unpredictable result if rd or rn is R15.  */
3247   if (rd == REG_PC || rn == REG_PC)
3248     as_tsktsk
3249       (_("Warning: instruction unpredictable when using r15"));
3250
3251   if (skip_past_comma (& str) == FAIL
3252       || cp_reg_required_here (& str, 0) == FAIL)
3253     {
3254       if (!inst.error)
3255         inst.error = BAD_ARGS;
3256       return;
3257     }
3258
3259   end_of_line (str);
3260 }
3261
3262 /* ARM V5 count-leading-zeroes instruction (argument parse)
3263      CLZ{<cond>} <Rd>, <Rm>
3264      Condition defaults to COND_ALWAYS.
3265      Error if Rd or Rm are R15.  */
3266
3267 static void
3268 do_clz (char * str)
3269 {
3270   int rd, rm;
3271
3272   skip_whitespace (str);
3273
3274   if (((rd = reg_required_here (& str, 12)) == FAIL)
3275       || (skip_past_comma (& str) == FAIL)
3276       || ((rm = reg_required_here (& str, 0)) == FAIL))
3277     inst.error = BAD_ARGS;
3278
3279   else if (rd == REG_PC || rm == REG_PC )
3280     inst.error = BAD_PC;
3281
3282   else
3283     end_of_line (str);
3284 }
3285
3286 /* ARM V5 (argument parse)
3287      LDC2{L} <coproc>, <CRd>, <addressing mode>
3288      STC2{L} <coproc>, <CRd>, <addressing mode>
3289      Instruction is not conditional, and has 0xf in the condition field.
3290      Otherwise, it's the same as LDC/STC.  */
3291
3292 static void
3293 do_lstc2 (char * str)
3294 {
3295   skip_whitespace (str);
3296
3297   if (co_proc_number (& str) == FAIL)
3298     {
3299       if (!inst.error)
3300         inst.error = BAD_ARGS;
3301     }
3302   else if (skip_past_comma (& str) == FAIL
3303            || cp_reg_required_here (& str, 12) == FAIL)
3304     {
3305       if (!inst.error)
3306         inst.error = BAD_ARGS;
3307     }
3308   else if (skip_past_comma (& str) == FAIL
3309            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3310     {
3311       if (! inst.error)
3312         inst.error = BAD_ARGS;
3313     }
3314   else
3315     end_of_line (str);
3316 }
3317
3318 /* ARM V5 (argument parse)
3319      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3320      Instruction is not conditional, and has 0xf in the condition field.
3321      Otherwise, it's the same as CDP.  */
3322
3323 static void
3324 do_cdp2 (char * str)
3325 {
3326   skip_whitespace (str);
3327
3328   if (co_proc_number (& str) == FAIL)
3329     {
3330       if (!inst.error)
3331         inst.error = BAD_ARGS;
3332       return;
3333     }
3334
3335   if (skip_past_comma (& str) == FAIL
3336       || cp_opc_expr (& str, 20,4) == FAIL)
3337     {
3338       if (!inst.error)
3339         inst.error = BAD_ARGS;
3340       return;
3341     }
3342
3343   if (skip_past_comma (& str) == FAIL
3344       || cp_reg_required_here (& str, 12) == FAIL)
3345     {
3346       if (!inst.error)
3347         inst.error = BAD_ARGS;
3348       return;
3349     }
3350
3351   if (skip_past_comma (& str) == FAIL
3352       || cp_reg_required_here (& str, 16) == FAIL)
3353     {
3354       if (!inst.error)
3355         inst.error = BAD_ARGS;
3356       return;
3357     }
3358
3359   if (skip_past_comma (& str) == FAIL
3360       || cp_reg_required_here (& str, 0) == FAIL)
3361     {
3362       if (!inst.error)
3363         inst.error = BAD_ARGS;
3364       return;
3365     }
3366
3367   if (skip_past_comma (& str) == SUCCESS)
3368     {
3369       if (cp_opc_expr (& str, 5, 3) == FAIL)
3370         {
3371           if (!inst.error)
3372             inst.error = BAD_ARGS;
3373           return;
3374         }
3375     }
3376
3377   end_of_line (str);
3378 }
3379
3380 /* ARM V5 (argument parse)
3381      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3382      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3383      Instruction is not conditional, and has 0xf in the condition field.
3384      Otherwise, it's the same as MCR/MRC.  */
3385
3386 static void
3387 do_co_reg2 (char * str)
3388 {
3389   skip_whitespace (str);
3390
3391   if (co_proc_number (& str) == FAIL)
3392     {
3393       if (!inst.error)
3394         inst.error = BAD_ARGS;
3395       return;
3396     }
3397
3398   if (skip_past_comma (& str) == FAIL
3399       || cp_opc_expr (& str, 21, 3) == FAIL)
3400     {
3401       if (!inst.error)
3402         inst.error = BAD_ARGS;
3403       return;
3404     }
3405
3406   if (skip_past_comma (& str) == FAIL
3407       || reg_required_here (& str, 12) == FAIL)
3408     {
3409       if (!inst.error)
3410         inst.error = BAD_ARGS;
3411       return;
3412     }
3413
3414   if (skip_past_comma (& str) == FAIL
3415       || cp_reg_required_here (& str, 16) == FAIL)
3416     {
3417       if (!inst.error)
3418         inst.error = BAD_ARGS;
3419       return;
3420     }
3421
3422   if (skip_past_comma (& str) == FAIL
3423       || cp_reg_required_here (& str, 0) == FAIL)
3424     {
3425       if (!inst.error)
3426         inst.error = BAD_ARGS;
3427       return;
3428     }
3429
3430   if (skip_past_comma (& str) == SUCCESS)
3431     {
3432       if (cp_opc_expr (& str, 5, 3) == FAIL)
3433         {
3434           if (!inst.error)
3435             inst.error = BAD_ARGS;
3436           return;
3437         }
3438     }
3439
3440   end_of_line (str);
3441 }
3442
3443 static void
3444 do_bx (char * str)
3445 {
3446   int reg;
3447
3448   skip_whitespace (str);
3449
3450   if ((reg = reg_required_here (&str, 0)) == FAIL)
3451     {
3452       inst.error = BAD_ARGS;
3453       return;
3454     }
3455
3456   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
3457   if (reg == REG_PC)
3458     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
3459
3460   end_of_line (str);
3461 }
3462
3463 /* ARM v5TEJ.  Jump to Jazelle code.  */
3464
3465 static void
3466 do_bxj (char * str)
3467 {
3468   int reg;
3469
3470   skip_whitespace (str);
3471
3472   if ((reg = reg_required_here (&str, 0)) == FAIL)
3473     {
3474       inst.error = BAD_ARGS;
3475       return;
3476     }
3477
3478   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3479   if (reg == REG_PC)
3480     as_tsktsk (_("use of r15 in bxj is not really useful"));
3481
3482   end_of_line (str);
3483 }
3484
3485 /* ARM V6 umaal (argument parse).  */
3486
3487 static void
3488 do_umaal (char * str)
3489 {
3490   int rdlo, rdhi, rm, rs;
3491
3492   skip_whitespace (str);
3493   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3494       || skip_past_comma (& str) == FAIL
3495       || (rdhi = reg_required_here (& str, 16)) == FAIL
3496       || skip_past_comma (& str) == FAIL
3497       || (rm = reg_required_here (& str, 0)) == FAIL
3498       || skip_past_comma (& str) == FAIL
3499       || (rs = reg_required_here (& str, 8)) == FAIL)
3500     {
3501       inst.error = BAD_ARGS;
3502       return;
3503     }
3504
3505   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3506     {
3507       inst.error = BAD_PC;
3508       return;
3509     }
3510
3511   end_of_line (str);
3512 }
3513
3514 /* ARM V6 strex (argument parse).  */
3515
3516 static void
3517 do_strex (char * str)
3518 {
3519   int rd, rm, rn;
3520
3521   /* Parse Rd, Rm,.  */
3522   skip_whitespace (str);
3523   if ((rd = reg_required_here (& str, 12)) == FAIL
3524       || skip_past_comma (& str) == FAIL
3525       || (rm = reg_required_here (& str, 0)) == FAIL
3526       || skip_past_comma (& str) == FAIL)
3527     {
3528       inst.error = BAD_ARGS;
3529       return;
3530     }
3531   if (rd == REG_PC || rm == REG_PC)
3532     {
3533       inst.error = BAD_PC;
3534       return;
3535     }
3536   if (rd == rm)
3537     {
3538       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3539       return;
3540     }
3541
3542   /* Skip past '['.  */
3543   if ((strlen (str) >= 1)
3544       && strncmp (str, "[", 1) == 0)
3545     str += 1;
3546
3547   skip_whitespace (str);
3548
3549   /* Parse Rn.  */
3550   if ((rn = reg_required_here (& str, 16)) == FAIL)
3551     {
3552       inst.error = BAD_ARGS;
3553       return;
3554     }
3555   else if (rn == REG_PC)
3556     {
3557       inst.error = BAD_PC;
3558       return;
3559     }
3560   if (rd == rn)
3561     {
3562       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3563       return;
3564     }
3565   skip_whitespace (str);
3566
3567   /* Skip past ']'.  */
3568   if ((strlen (str) >= 1)
3569       && strncmp (str, "]", 1) == 0)
3570     str += 1;
3571
3572   end_of_line (str);
3573 }
3574
3575 /* KIND indicates what kind of shifts are accepted.  */
3576
3577 static int
3578 decode_shift (char ** str, int kind)
3579 {
3580   const struct asm_shift_name * shift;
3581   char * p;
3582   char   c;
3583
3584   skip_whitespace (* str);
3585
3586   for (p = * str; ISALPHA (* p); p ++)
3587     ;
3588
3589   if (p == * str)
3590     {
3591       inst.error = _("shift expression expected");
3592       return FAIL;
3593     }
3594
3595   c = * p;
3596   * p = '\0';
3597   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3598   * p = c;
3599
3600   if (shift == NULL)
3601     {
3602       inst.error = _("shift expression expected");
3603       return FAIL;
3604     }
3605
3606   assert (shift->properties->index == shift_properties[shift->properties->index].index);
3607
3608   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
3609       && shift->properties->index != SHIFT_LSL
3610       && shift->properties->index != SHIFT_ASR)
3611     {
3612       inst.error = _("'LSL' or 'ASR' required");
3613       return FAIL;
3614     }
3615   else if (kind == SHIFT_LSL_IMMEDIATE
3616            && shift->properties->index != SHIFT_LSL)
3617     {
3618       inst.error = _("'LSL' required");
3619       return FAIL;
3620     }
3621   else if (kind == SHIFT_ASR_IMMEDIATE
3622            && shift->properties->index != SHIFT_ASR)
3623     {
3624       inst.error = _("'ASR' required");
3625       return FAIL;
3626     }
3627
3628   if (shift->properties->index == SHIFT_RRX)
3629     {
3630       * str = p;
3631       inst.instruction |= shift->properties->bit_field;
3632       return SUCCESS;
3633     }
3634
3635   skip_whitespace (p);
3636
3637   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
3638     {
3639       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3640       * str = p;
3641       return SUCCESS;
3642     }
3643   else if (! is_immediate_prefix (* p))
3644     {
3645       inst.error = (NO_SHIFT_RESTRICT
3646                     ? _("shift requires register or #expression")
3647                     : _("shift requires #expression"));
3648       * str = p;
3649       return FAIL;
3650     }
3651
3652   inst.error = NULL;
3653   p ++;
3654
3655   if (my_get_expression (& inst.reloc.exp, & p))
3656     return FAIL;
3657
3658   /* Validate some simple #expressions.  */
3659   if (inst.reloc.exp.X_op == O_constant)
3660     {
3661       unsigned num = inst.reloc.exp.X_add_number;
3662
3663       /* Reject operations greater than 32.  */
3664       if (num > 32
3665           /* Reject a shift of 0 unless the mode allows it.  */
3666           || (num == 0 && shift->properties->allows_0 == 0)
3667           /* Reject a shift of 32 unless the mode allows it.  */
3668           || (num == 32 && shift->properties->allows_32 == 0)
3669           )
3670         {
3671           /* As a special case we allow a shift of zero for
3672              modes that do not support it to be recoded as an
3673              logical shift left of zero (ie nothing).  We warn
3674              about this though.  */
3675           if (num == 0)
3676             {
3677               as_warn (_("shift of 0 ignored."));
3678               shift = & shift_names[0];
3679               assert (shift->properties->index == SHIFT_LSL);
3680             }
3681           else
3682             {
3683               inst.error = _("invalid immediate shift");
3684               return FAIL;
3685             }
3686         }
3687
3688       /* Shifts of 32 are encoded as 0, for those shifts that
3689          support it.  */
3690       if (num == 32)
3691         num = 0;
3692
3693       inst.instruction |= (num << 7) | shift->properties->bit_field;
3694     }
3695   else
3696     {
3697       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
3698       inst.reloc.pc_rel = 0;
3699       inst.instruction |= shift->properties->bit_field;
3700     }
3701
3702   * str = p;
3703   return SUCCESS;
3704 }
3705
3706 static void
3707 do_sat (char ** str, int bias)
3708 {
3709   int rd, rm;
3710   expressionS expr;
3711
3712   skip_whitespace (*str);
3713
3714   /* Parse <Rd>, field.  */
3715   if ((rd = reg_required_here (str, 12)) == FAIL
3716       || skip_past_comma (str) == FAIL)
3717     {
3718       inst.error = BAD_ARGS;
3719       return;
3720     }
3721   if (rd == REG_PC)
3722     {
3723       inst.error = BAD_PC;
3724       return;
3725     }
3726
3727   /* Parse #<immed>,  field.  */
3728   if (is_immediate_prefix (**str))
3729     (*str)++;
3730   else
3731     {
3732       inst.error = _("immediate expression expected");
3733       return;
3734     }
3735   if (my_get_expression (&expr, str))
3736     {
3737       inst.error = _("bad expression");
3738       return;
3739     }
3740   if (expr.X_op != O_constant)
3741     {
3742       inst.error = _("constant expression expected");
3743       return;
3744     }
3745   if (expr.X_add_number + bias < 0
3746       || expr.X_add_number + bias > 31)
3747     {
3748       inst.error = _("immediate value out of range");
3749       return;
3750     }
3751   inst.instruction |= (expr.X_add_number + bias) << 16;
3752   if (skip_past_comma (str) == FAIL)
3753     {
3754       inst.error = BAD_ARGS;
3755       return;
3756     }
3757
3758   /* Parse <Rm> field.  */
3759   if ((rm = reg_required_here (str, 0)) == FAIL)
3760     {
3761       inst.error = BAD_ARGS;
3762       return;
3763     }
3764   if (rm == REG_PC)
3765     {
3766       inst.error = BAD_PC;
3767       return;
3768     }
3769
3770   if (skip_past_comma (str) == SUCCESS)
3771     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
3772 }
3773
3774 /* ARM V6 ssat (argument parse).  */
3775
3776 static void
3777 do_ssat (char * str)
3778 {
3779   do_sat (&str, /*bias=*/-1);
3780   end_of_line (str);
3781 }
3782
3783 /* ARM V6 usat (argument parse).  */
3784
3785 static void
3786 do_usat (char * str)
3787 {
3788   do_sat (&str, /*bias=*/0);
3789   end_of_line (str);
3790 }
3791
3792 static void
3793 do_sat16 (char ** str, int bias)
3794 {
3795   int rd, rm;
3796   expressionS expr;
3797
3798   skip_whitespace (*str);
3799
3800   /* Parse the <Rd> field.  */
3801   if ((rd = reg_required_here (str, 12)) == FAIL
3802       || skip_past_comma (str) == FAIL)
3803     {
3804       inst.error = BAD_ARGS;
3805       return;
3806     }
3807   if (rd == REG_PC)
3808     {
3809       inst.error = BAD_PC;
3810       return;
3811     }
3812
3813   /* Parse #<immed>, field.  */
3814   if (is_immediate_prefix (**str))
3815     (*str)++;
3816   else
3817     {
3818       inst.error = _("immediate expression expected");
3819       return;
3820     }
3821   if (my_get_expression (&expr, str))
3822     {
3823       inst.error = _("bad expression");
3824       return;
3825     }
3826   if (expr.X_op != O_constant)
3827     {
3828       inst.error = _("constant expression expected");
3829       return;
3830     }
3831   if (expr.X_add_number + bias < 0
3832       || expr.X_add_number + bias > 15)
3833     {
3834       inst.error = _("immediate value out of range");
3835       return;
3836     }
3837   inst.instruction |= (expr.X_add_number + bias) << 16;
3838   if (skip_past_comma (str) == FAIL)
3839     {
3840       inst.error = BAD_ARGS;
3841       return;
3842     }
3843
3844   /* Parse <Rm> field.  */
3845   if ((rm = reg_required_here (str, 0)) == FAIL)
3846     {
3847       inst.error = BAD_ARGS;
3848       return;
3849     }
3850   if (rm == REG_PC)
3851     {
3852       inst.error = BAD_PC;
3853       return;
3854     }
3855 }
3856
3857 /* ARM V6 ssat16 (argument parse).  */
3858
3859 static void
3860 do_ssat16 (char * str)
3861 {
3862   do_sat16 (&str, /*bias=*/-1);
3863   end_of_line (str);
3864 }
3865
3866 static void
3867 do_usat16 (char * str)
3868 {
3869   do_sat16 (&str, /*bias=*/0);
3870   end_of_line (str);
3871 }
3872
3873 static void
3874 do_cps_mode (char ** str)
3875 {
3876   expressionS expr;
3877
3878   skip_whitespace (*str);
3879
3880   if (! is_immediate_prefix (**str))
3881     {
3882       inst.error = _("immediate expression expected");
3883       return;
3884     }
3885
3886   (*str)++; /* Strip off the immediate signifier.  */
3887   if (my_get_expression (&expr, str))
3888     {
3889       inst.error = _("bad expression");
3890       return;
3891     }
3892
3893   if (expr.X_op != O_constant)
3894     {
3895       inst.error = _("constant expression expected");
3896       return;
3897     }
3898
3899   /* The mode is a 5 bit field.  Valid values are 0-31.  */
3900   if (((unsigned) expr.X_add_number) > 31
3901       || (inst.reloc.exp.X_add_number) < 0)
3902     {
3903       inst.error = _("invalid constant");
3904       return;
3905     }
3906
3907   inst.instruction |= expr.X_add_number;
3908 }
3909
3910 /* ARM V6 srs (argument parse).  */
3911
3912 static void
3913 do_srs (char * str)
3914 {
3915   char *exclam;
3916   skip_whitespace (str);
3917   exclam = strchr (str, '!');
3918   if (exclam)
3919     *exclam = '\0';
3920   do_cps_mode (&str);
3921   if (exclam)
3922     *exclam = '!';
3923   if (*str == '!')
3924     {
3925       inst.instruction |= WRITE_BACK;
3926       str++;
3927     }
3928   end_of_line (str);
3929 }
3930
3931 /* ARM V6 SMMUL (argument parse).  */
3932
3933 static void
3934 do_smmul (char * str)
3935 {
3936   int rd, rm, rs;
3937
3938   skip_whitespace (str);
3939   if ((rd = reg_required_here (&str, 16)) == FAIL
3940       || skip_past_comma (&str) == FAIL
3941       || (rm = reg_required_here (&str, 0)) == FAIL
3942       || skip_past_comma (&str) == FAIL
3943       || (rs = reg_required_here (&str, 8)) == FAIL)
3944     {
3945       inst.error = BAD_ARGS;
3946       return;
3947     }
3948
3949   if (   rd == REG_PC
3950       || rm == REG_PC
3951       || rs == REG_PC)
3952     {
3953       inst.error = BAD_PC;
3954       return;
3955     }
3956
3957   end_of_line (str);
3958 }
3959
3960 /* ARM V6 SMLALD (argument parse).  */
3961
3962 static void
3963 do_smlald (char * str)
3964 {
3965   int rdlo, rdhi, rm, rs;
3966
3967   skip_whitespace (str);
3968   if ((rdlo = reg_required_here (&str, 12)) == FAIL
3969       || skip_past_comma (&str) == FAIL
3970       || (rdhi = reg_required_here (&str, 16)) == FAIL
3971       || skip_past_comma (&str) == FAIL
3972       || (rm = reg_required_here (&str, 0)) == FAIL
3973       || skip_past_comma (&str) == FAIL
3974       || (rs = reg_required_here (&str, 8)) == FAIL)
3975     {
3976       inst.error = BAD_ARGS;
3977       return;
3978     }
3979
3980   if (   rdlo == REG_PC
3981       || rdhi == REG_PC
3982       || rm == REG_PC
3983       || rs == REG_PC)
3984     {
3985       inst.error = BAD_PC;
3986       return;
3987     }
3988
3989   end_of_line (str);
3990 }
3991
3992 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
3993    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
3994
3995 static void
3996 do_smlad (char * str)
3997 {
3998   int rd, rm, rs, rn;
3999
4000   skip_whitespace (str);
4001   if ((rd = reg_required_here (&str, 16)) == FAIL
4002       || skip_past_comma (&str) == FAIL
4003       || (rm = reg_required_here (&str, 0)) == FAIL
4004       || skip_past_comma (&str) == FAIL
4005       || (rs = reg_required_here (&str, 8)) == FAIL
4006       || skip_past_comma (&str) == FAIL
4007       || (rn = reg_required_here (&str, 12)) == FAIL)
4008     {
4009       inst.error = BAD_ARGS;
4010       return;
4011     }
4012
4013   if (   rd == REG_PC
4014       || rn == REG_PC
4015       || rs == REG_PC
4016       || rm == REG_PC)
4017     {
4018       inst.error = BAD_PC;
4019       return;
4020     }
4021
4022   end_of_line (str);
4023 }
4024
4025 /* Returns true if the endian-specifier indicates big-endianness.  */
4026
4027 static int
4028 do_endian_specifier (char * str)
4029 {
4030   int big_endian = 0;
4031
4032   skip_whitespace (str);
4033   if (strlen (str) < 2)
4034     inst.error = _("missing endian specifier");
4035   else if (strncasecmp (str, "BE", 2) == 0)
4036     {
4037       str += 2;
4038       big_endian = 1;
4039     }
4040   else if (strncasecmp (str, "LE", 2) == 0)
4041     str += 2;
4042   else
4043     inst.error = _("valid endian specifiers are be or le");
4044
4045   end_of_line (str);
4046
4047   return big_endian;
4048 }
4049
4050 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
4051    preserving the other bits.
4052
4053    setend <endian_specifier>, where <endian_specifier> is either
4054    BE or LE.  */
4055
4056 static void
4057 do_setend (char * str)
4058 {
4059   if (do_endian_specifier (str))
4060     inst.instruction |= 0x200;
4061 }
4062
4063 /* ARM V6 SXTH.
4064
4065    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
4066    Condition defaults to COND_ALWAYS.
4067    Error if any register uses R15.  */
4068
4069 static void
4070 do_sxth (char * str)
4071 {
4072   int rd, rm;
4073   expressionS expr;
4074   int rotation_clear_mask = 0xfffff3ff;
4075   int rotation_eight_mask = 0x00000400;
4076   int rotation_sixteen_mask = 0x00000800;
4077   int rotation_twenty_four_mask = 0x00000c00;
4078
4079   skip_whitespace (str);
4080   if ((rd = reg_required_here (&str, 12)) == FAIL
4081       || skip_past_comma (&str) == FAIL
4082       || (rm = reg_required_here (&str, 0)) == FAIL)
4083     {
4084       inst.error = BAD_ARGS;
4085       return;
4086     }
4087
4088   else if (rd == REG_PC || rm == REG_PC)
4089     {
4090       inst.error = BAD_PC;
4091       return;
4092     }
4093
4094   /* Zero out the rotation field.  */
4095   inst.instruction &= rotation_clear_mask;
4096
4097   /* Check for lack of optional rotation field.  */
4098   if (skip_past_comma (&str) == FAIL)
4099     {
4100       end_of_line (str);
4101       return;
4102     }
4103
4104   /* Move past 'ROR'.  */
4105   skip_whitespace (str);
4106   if (strncasecmp (str, "ROR", 3) == 0)
4107     str += 3;
4108   else
4109     {
4110       inst.error = _("missing rotation field after comma");
4111       return;
4112     }
4113
4114   /* Get the immediate constant.  */
4115   skip_whitespace (str);
4116   if (is_immediate_prefix (* str))
4117     str++;
4118   else
4119     {
4120       inst.error = _("immediate expression expected");
4121       return;
4122     }
4123
4124   if (my_get_expression (&expr, &str))
4125     {
4126       inst.error = _("bad expression");
4127       return;
4128     }
4129
4130   if (expr.X_op != O_constant)
4131     {
4132       inst.error = _("constant expression expected");
4133       return;
4134     }
4135
4136   switch (expr.X_add_number)
4137     {
4138     case 0:
4139       /* Rotation field has already been zeroed.  */
4140       break;
4141     case 8:
4142       inst.instruction |= rotation_eight_mask;
4143       break;
4144
4145     case 16:
4146       inst.instruction |= rotation_sixteen_mask;
4147       break;
4148
4149     case 24:
4150       inst.instruction |= rotation_twenty_four_mask;
4151       break;
4152
4153     default:
4154       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4155       break;
4156     }
4157
4158   end_of_line (str);
4159 }
4160
4161 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
4162    extends it to 32-bits, and adds the result to a value in another
4163    register.  You can specify a rotation by 0, 8, 16, or 24 bits
4164    before extracting the 16-bit value.
4165    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
4166    Condition defaults to COND_ALWAYS.
4167    Error if any register uses R15.  */
4168
4169 static void
4170 do_sxtah (char * str)
4171 {
4172   int rd, rn, rm;
4173   expressionS expr;
4174   int rotation_clear_mask = 0xfffff3ff;
4175   int rotation_eight_mask = 0x00000400;
4176   int rotation_sixteen_mask = 0x00000800;
4177   int rotation_twenty_four_mask = 0x00000c00;
4178
4179   skip_whitespace (str);
4180   if ((rd = reg_required_here (&str, 12)) == FAIL
4181       || skip_past_comma (&str) == FAIL
4182       || (rn = reg_required_here (&str, 16)) == FAIL
4183       || skip_past_comma (&str) == FAIL
4184       || (rm = reg_required_here (&str, 0)) == FAIL)
4185     {
4186       inst.error = BAD_ARGS;
4187       return;
4188     }
4189
4190   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4191     {
4192       inst.error = BAD_PC;
4193       return;
4194     }
4195
4196   /* Zero out the rotation field.  */
4197   inst.instruction &= rotation_clear_mask;
4198
4199   /* Check for lack of optional rotation field.  */
4200   if (skip_past_comma (&str) == FAIL)
4201     {
4202       end_of_line (str);
4203       return;
4204     }
4205
4206   /* Move past 'ROR'.  */
4207   skip_whitespace (str);
4208   if (strncasecmp (str, "ROR", 3) == 0)
4209     str += 3;
4210   else
4211     {
4212       inst.error = _("missing rotation field after comma");
4213       return;
4214     }
4215
4216   /* Get the immediate constant.  */
4217   skip_whitespace (str);
4218   if (is_immediate_prefix (* str))
4219     str++;
4220   else
4221     {
4222       inst.error = _("immediate expression expected");
4223       return;
4224     }
4225
4226   if (my_get_expression (&expr, &str))
4227     {
4228       inst.error = _("bad expression");
4229       return;
4230     }
4231
4232   if (expr.X_op != O_constant)
4233     {
4234       inst.error = _("constant expression expected");
4235       return;
4236     }
4237
4238   switch (expr.X_add_number)
4239     {
4240     case 0:
4241       /* Rotation field has already been zeroed.  */
4242       break;
4243
4244     case 8:
4245       inst.instruction |= rotation_eight_mask;
4246       break;
4247
4248     case 16:
4249       inst.instruction |= rotation_sixteen_mask;
4250       break;
4251
4252     case 24:
4253       inst.instruction |= rotation_twenty_four_mask;
4254       break;
4255
4256     default:
4257       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4258       break;
4259     }
4260
4261   end_of_line (str);
4262 }
4263
4264
4265 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
4266    word at the specified address and the following word
4267    respectively.
4268    Unconditionally executed.
4269    Error if Rn is R15.  */
4270
4271 static void
4272 do_rfe (char * str)
4273 {
4274   int rn;
4275
4276   skip_whitespace (str);
4277
4278   if ((rn = reg_required_here (&str, 16)) == FAIL)
4279     return;
4280
4281   if (rn == REG_PC)
4282     {
4283       inst.error = BAD_PC;
4284       return;
4285     }
4286
4287   skip_whitespace (str);
4288
4289   if (*str == '!')
4290     {
4291       inst.instruction |= WRITE_BACK;
4292       str++;
4293     }
4294   end_of_line (str);
4295 }
4296
4297 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
4298    register (argument parse).
4299    REV{<cond>} Rd, Rm.
4300    Condition defaults to COND_ALWAYS.
4301    Error if Rd or Rm are R15.  */
4302
4303 static void
4304 do_rev (char * str)
4305 {
4306   int rd, rm;
4307
4308   skip_whitespace (str);
4309
4310   if ((rd = reg_required_here (&str, 12)) == FAIL
4311       || skip_past_comma (&str) == FAIL
4312       || (rm = reg_required_here (&str, 0)) == FAIL)
4313     inst.error = BAD_ARGS;
4314
4315   else if (rd == REG_PC || rm == REG_PC)
4316     inst.error = BAD_PC;
4317
4318   else
4319     end_of_line (str);
4320 }
4321
4322 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
4323    QADD16{<cond>} <Rd>, <Rn>, <Rm>
4324    Condition defaults to COND_ALWAYS.
4325    Error if Rd, Rn or Rm are R15.  */
4326
4327 static void
4328 do_qadd16 (char * str)
4329 {
4330   int rd, rm, rn;
4331
4332   skip_whitespace (str);
4333
4334   if ((rd = reg_required_here (&str, 12)) == FAIL
4335       || skip_past_comma (&str) == FAIL
4336       || (rn = reg_required_here (&str, 16)) == FAIL
4337       || skip_past_comma (&str) == FAIL
4338       || (rm = reg_required_here (&str, 0)) == FAIL)
4339     inst.error = BAD_ARGS;
4340
4341   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4342     inst.error = BAD_PC;
4343
4344   else
4345     end_of_line (str);
4346 }
4347
4348 static void
4349 do_pkh_core (char * str, int shift)
4350 {
4351   int rd, rn, rm;
4352
4353   skip_whitespace (str);
4354   if (((rd = reg_required_here (&str, 12)) == FAIL)
4355       || (skip_past_comma (&str) == FAIL)
4356       || ((rn = reg_required_here (&str, 16)) == FAIL)
4357       || (skip_past_comma (&str) == FAIL)
4358       || ((rm = reg_required_here (&str, 0)) == FAIL))
4359     {
4360       inst.error = BAD_ARGS;
4361       return;
4362     }
4363
4364   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4365     {
4366       inst.error = BAD_PC;
4367       return;
4368     }
4369
4370   /* Check for optional shift immediate constant.  */
4371   if (skip_past_comma (&str) == FAIL)
4372     {
4373       if (shift == SHIFT_ASR_IMMEDIATE)
4374         {
4375           /* If the shift specifier is ommited, turn the instruction
4376              into pkhbt rd, rm, rn.  First, switch the instruction
4377              code, and clear the rn and rm fields.  */
4378           inst.instruction &= 0xfff0f010;
4379           /* Now, re-encode the registers.  */
4380           inst.instruction |= (rm << 16) | rn;
4381         }
4382       return;
4383     }
4384
4385   decode_shift (&str, shift);
4386 }
4387
4388 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
4389    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
4390    Condition defaults to COND_ALWAYS.
4391    Error if Rd, Rn or Rm are R15.  */
4392
4393 static void
4394 do_pkhbt (char * str)
4395 {
4396   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
4397 }
4398
4399 /* ARM V6 PKHTB (Argument Parse).  */
4400
4401 static void
4402 do_pkhtb (char * str)
4403 {
4404   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
4405 }
4406
4407 /* ARM V6 Load Register Exclusive instruction (argument parse).
4408    LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
4409    Condition defaults to COND_ALWAYS.
4410    Error if Rd or Rn are R15.
4411    See ARMARMv6 A4.1.27: LDREX.  */
4412
4413 static void
4414 do_ldrex (char * str)
4415 {
4416   int rd, rn;
4417
4418   skip_whitespace (str);
4419
4420   /* Parse Rd.  */
4421   if (((rd = reg_required_here (&str, 12)) == FAIL)
4422       || (skip_past_comma (&str) == FAIL))
4423     {
4424       inst.error = BAD_ARGS;
4425       return;
4426     }
4427   else if (rd == REG_PC)
4428     {
4429       inst.error = BAD_PC;
4430       return;
4431     }
4432   skip_whitespace (str);
4433
4434   /* Skip past '['.  */
4435   if ((strlen (str) >= 1)
4436       &&strncmp (str, "[", 1) == 0)
4437     str += 1;
4438   skip_whitespace (str);
4439
4440   /* Parse Rn.  */
4441   if ((rn = reg_required_here (&str, 16)) == FAIL)
4442     {
4443       inst.error = BAD_ARGS;
4444       return;
4445     }
4446   else if (rn == REG_PC)
4447     {
4448       inst.error = BAD_PC;
4449       return;
4450     }
4451   skip_whitespace (str);
4452
4453   /* Skip past ']'.  */
4454   if ((strlen (str) >= 1)
4455       && strncmp (str, "]", 1) == 0)
4456     str += 1;
4457
4458   end_of_line (str);
4459 }
4460
4461 /* ARM V6 change processor state instruction (argument parse)
4462       CPS, CPSIE, CSPID .  */
4463
4464 static void
4465 do_cps (char * str)
4466 {
4467   do_cps_mode (&str);
4468   end_of_line (str);
4469 }
4470
4471 static void
4472 do_cps_flags (char ** str, int thumb_p)
4473 {
4474   struct cps_flag
4475   {
4476     char character;
4477     unsigned long arm_value;
4478     unsigned long thumb_value;
4479   };
4480   static struct cps_flag flag_table[] =
4481   {
4482     {'a', 0x100, 0x4 },
4483     {'i', 0x080, 0x2 },
4484     {'f', 0x040, 0x1 }
4485   };
4486
4487   int saw_a_flag = 0;
4488
4489   skip_whitespace (*str);
4490
4491   /* Get the a, f and i flags.  */
4492   while (**str && **str != ',')
4493     {
4494       struct cps_flag *p;
4495       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
4496
4497       for (p = flag_table; p < q; ++p)
4498         if (strncasecmp (*str, &p->character, 1) == 0)
4499           {
4500             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
4501             saw_a_flag = 1;
4502             break;
4503           }
4504       if (p == q)
4505         {
4506           inst.error = _("unrecognized flag");
4507           return;
4508         }
4509       (*str)++;
4510     }
4511
4512   if (!saw_a_flag)
4513     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
4514 }
4515
4516 static void
4517 do_cpsi (char * str)
4518 {
4519   do_cps_flags (&str, /*thumb_p=*/0);
4520
4521   if (skip_past_comma (&str) == SUCCESS)
4522     {
4523       skip_whitespace (str);
4524       do_cps_mode (&str);
4525     }
4526   end_of_line (str);
4527 }
4528
4529 /* ARM V6T2 bitfield manipulation instructions.  */
4530
4531 static int
4532 five_bit_unsigned_immediate (char **str)
4533 {
4534   expressionS expr;
4535
4536   skip_whitespace (*str);
4537   if (!is_immediate_prefix (**str))
4538     {
4539       inst.error = _("immediate expression expected");
4540       return -1;
4541     }
4542   (*str)++;
4543   if (my_get_expression (&expr, str))
4544     {
4545       inst.error = _("bad expression");
4546       return -1;
4547     }
4548   if (expr.X_op != O_constant)
4549     {
4550       inst.error = _("constant expression expected");
4551       return -1;
4552     }
4553   if (expr.X_add_number < 0 || expr.X_add_number > 32)
4554     {
4555       inst.error = _("immediate value out of range");
4556       return -1;
4557     }
4558   
4559   return expr.X_add_number;
4560 }
4561
4562 static void
4563 bfci_lsb_and_width (char *str)
4564 {
4565   int lsb, width;
4566
4567   if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
4568     return;
4569
4570   if (skip_past_comma (&str) == FAIL)
4571     {
4572       inst.error = BAD_ARGS;
4573       return;
4574     }
4575   if ((width = five_bit_unsigned_immediate (&str)) == -1)
4576     return;
4577
4578   end_of_line (str);
4579
4580   if (width == 0 || lsb == 32)
4581     {
4582       inst.error = _("immediate value out of range");
4583       return;
4584     }
4585   else if (width + lsb > 32)
4586     {
4587       inst.error = _("bit-field extends past end of register");
4588       return;
4589     }
4590
4591   /* Convert to LSB/MSB and write to register.  */
4592   inst.instruction |= lsb << 7;
4593   inst.instruction |= (width + lsb - 1) << 16;
4594 }
4595
4596 static void
4597 do_bfc (char *str)
4598 {
4599   int rd;
4600
4601   /* Rd.  */
4602   skip_whitespace (str);
4603   if (((rd = reg_required_here (&str, 12)) == FAIL)
4604       || (skip_past_comma (&str) == FAIL))
4605     {
4606       inst.error = BAD_ARGS;
4607       return;
4608     }
4609   else if (rd == REG_PC)
4610     {
4611       inst.error = BAD_PC;
4612       return;
4613     }
4614
4615   bfci_lsb_and_width (str);
4616 }
4617
4618 static void
4619 do_bfi (char *str)
4620 {
4621   int rd, rm;
4622
4623   /* Rd.  */
4624   skip_whitespace (str);
4625   if (((rd = reg_required_here (&str, 12)) == FAIL)
4626       || (skip_past_comma (&str) == FAIL))
4627     {
4628       inst.error = BAD_ARGS;
4629       return;
4630     }
4631   else if (rd == REG_PC)
4632     {
4633       inst.error = BAD_PC;
4634       return;
4635     }
4636
4637   /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
4638   skip_whitespace (str);
4639   if (is_immediate_prefix (*str))
4640     {
4641       expressionS expr;
4642       str++;
4643       if (my_get_expression (&expr, &str))
4644         {
4645           inst.error = _("bad expression");
4646           return;
4647         }
4648       if (expr.X_op != O_constant)
4649         {
4650           inst.error = _("constant expression expected");
4651           return;
4652         }
4653       if (expr.X_add_number != 0)
4654         {
4655           inst.error = _("immediate value out of range");
4656           return;
4657         }
4658       inst.instruction |= 0x0000000f;  /* Rm = PC -> bfc, not bfi.  */
4659     }
4660   else
4661     {
4662       if ((rm = reg_required_here (&str, 0)) == FAIL)
4663         {
4664           inst.error = BAD_ARGS;
4665           return;
4666         }
4667       else if (rm == REG_PC)
4668         {
4669           inst.error = BAD_PC;
4670           return;
4671         }
4672     }
4673   if (skip_past_comma (&str) == FAIL)
4674     {
4675       inst.error = BAD_ARGS;
4676       return;
4677     }
4678
4679   bfci_lsb_and_width (str);
4680 }
4681
4682 static void
4683 do_bfx (char *str)
4684 {
4685   int lsb, width;
4686
4687   /* Rd.  */
4688   skip_whitespace (str);
4689   if (reg_required_here (&str, 12) == FAIL
4690       || skip_past_comma (&str) == FAIL)
4691     {
4692       inst.error = BAD_ARGS;
4693       return;
4694     }
4695
4696   /* Rm.  */
4697   skip_whitespace (str);
4698   if (reg_required_here (&str, 0) == FAIL
4699       || skip_past_comma (&str) == FAIL)
4700     {
4701       inst.error = BAD_ARGS;
4702       return;
4703     }
4704
4705   if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
4706     return;
4707
4708   if (skip_past_comma (&str) == FAIL)
4709     {
4710       inst.error = BAD_ARGS;
4711       return;
4712     }
4713   if ((width = five_bit_unsigned_immediate (&str)) == -1)
4714     return;
4715
4716   end_of_line (str);
4717
4718   if (width == 0 || lsb == 32)
4719     {
4720       inst.error = _("immediate value out of range");
4721       return;
4722     }
4723   else if (width + lsb > 32)
4724     {
4725       inst.error = _("bit-field extends past end of register");
4726       return;
4727     }
4728
4729   inst.instruction |= lsb << 7;
4730   inst.instruction |= (width - 1) << 16;
4731 }
4732
4733 static void
4734 do_rbit (char *str)
4735 {
4736   /* Rd.  */
4737   skip_whitespace (str);
4738   if (reg_required_here (&str, 12) == FAIL
4739       || skip_past_comma (&str) == FAIL)
4740     {
4741       inst.error = BAD_ARGS;
4742       return;
4743     }
4744
4745   /* Rm.  */
4746   skip_whitespace (str);
4747   if (reg_required_here (&str, 0) == FAIL)
4748     {
4749       inst.error = BAD_ARGS;
4750       return;
4751     }
4752
4753   end_of_line (str);
4754 }
4755
4756 /* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>.  */
4757 static void
4758 do_mov16 (char *str)
4759 {
4760   int rd;
4761   expressionS expr;
4762
4763   /* Rd.  */
4764   skip_whitespace (str);
4765   if (((rd = reg_required_here (&str, 12)) == FAIL)
4766       || (skip_past_comma (&str) == FAIL))
4767     {
4768       inst.error = BAD_ARGS;
4769       return;
4770     }
4771   else if (rd == REG_PC)
4772     {
4773       inst.error = BAD_PC;
4774       return;
4775     }
4776
4777   /* Imm16.  */
4778   skip_whitespace (str);
4779   if (!is_immediate_prefix (*str))
4780     {
4781       inst.error = _("immediate expression expected");
4782       return;
4783     }
4784   str++;
4785   if (my_get_expression (&expr, &str))
4786     {
4787       inst.error = _("bad expression");
4788       return;
4789     }
4790   if (expr.X_op != O_constant)
4791     {
4792       inst.error = _("constant expression expected");
4793       return;
4794     }
4795   if (expr.X_add_number < 0 || expr.X_add_number > 65535)
4796     {
4797       inst.error = _("immediate value out of range");
4798       return;
4799     }
4800
4801   end_of_line (str);
4802
4803   /* The value is in two pieces: 0:11, 16:19.  */
4804   inst.instruction |= (expr.X_add_number & 0x00000fff);
4805   inst.instruction |= (expr.X_add_number & 0x0000f000) << 4;
4806 }
4807   
4808
4809 /* THUMB V5 breakpoint instruction (argument parse)
4810         BKPT <immed_8>.  */
4811
4812 static void
4813 do_t_bkpt (char * str)
4814 {
4815   expressionS expr;
4816   unsigned long number;
4817
4818   skip_whitespace (str);
4819
4820   /* Allow optional leading '#'.  */
4821   if (is_immediate_prefix (*str))
4822     str ++;
4823
4824   memset (& expr, '\0', sizeof (expr));
4825   if (my_get_expression (& expr, & str)
4826       || (expr.X_op != O_constant
4827           /* As a convenience we allow 'bkpt' without an operand.  */
4828           && expr.X_op != O_absent))
4829     {
4830       inst.error = _("bad expression");
4831       return;
4832     }
4833
4834   number = expr.X_add_number;
4835
4836   /* Check it fits an 8 bit unsigned.  */
4837   if (number != (number & 0xff))
4838     {
4839       inst.error = _("immediate value out of range");
4840       return;
4841     }
4842
4843   inst.instruction |= number;
4844
4845   end_of_line (str);
4846 }
4847
4848 #ifdef OBJ_ELF
4849 static bfd_reloc_code_real_type
4850 arm_parse_reloc (void)
4851 {
4852   char         id [16];
4853   char *       ip;
4854   unsigned int i;
4855   static struct
4856   {
4857     char * str;
4858     int    len;
4859     bfd_reloc_code_real_type reloc;
4860   }
4861   reloc_map[] =
4862   {
4863 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
4864     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
4865     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
4866     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
4867        branch instructions generated by GCC for PLT relocs.  */
4868     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
4869     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
4870     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
4871     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
4872     { NULL, 0,         BFD_RELOC_UNUSED }
4873 #undef MAP
4874   };
4875
4876   for (i = 0, ip = input_line_pointer;
4877        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
4878        i++, ip++)
4879     id[i] = TOLOWER (*ip);
4880
4881   for (i = 0; reloc_map[i].str; i++)
4882     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
4883       break;
4884
4885   input_line_pointer += reloc_map[i].len;
4886
4887   return reloc_map[i].reloc;
4888 }
4889 #endif
4890
4891 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4892    Expects inst.instruction is set for BLX(1).
4893    Note: this is cloned from do_branch, and the reloc changed to be a
4894         new one that can cope with setting one extra bit (the H bit).  */
4895
4896 static void
4897 do_branch25 (char * str)
4898 {
4899   if (my_get_expression (& inst.reloc.exp, & str))
4900     return;
4901
4902 #ifdef OBJ_ELF
4903   {
4904     char * save_in;
4905
4906     /* ScottB: February 5, 1998 */
4907     /* Check to see of PLT32 reloc required for the instruction.  */
4908
4909     /* arm_parse_reloc() works on input_line_pointer.
4910        We actually want to parse the operands to the branch instruction
4911        passed in 'str'.  Save the input pointer and restore it later.  */
4912     save_in = input_line_pointer;
4913     input_line_pointer = str;
4914
4915     if (inst.reloc.exp.X_op == O_symbol
4916         && *str == '('
4917         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4918       {
4919         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
4920         inst.reloc.pc_rel = 0;
4921         /* Modify str to point to after parsed operands, otherwise
4922            end_of_line() will complain about the (PLT) left in str.  */
4923         str = input_line_pointer;
4924       }
4925     else
4926       {
4927         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4928         inst.reloc.pc_rel = 1;
4929       }
4930
4931     input_line_pointer = save_in;
4932   }
4933 #else
4934   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4935   inst.reloc.pc_rel = 1;
4936 #endif /* OBJ_ELF */
4937
4938   end_of_line (str);
4939 }
4940
4941 /* ARM V5 branch-link-exchange instruction (argument parse)
4942      BLX <target_addr>          ie BLX(1)
4943      BLX{<condition>} <Rm>      ie BLX(2)
4944    Unfortunately, there are two different opcodes for this mnemonic.
4945    So, the insns[].value is not used, and the code here zaps values
4946         into inst.instruction.
4947    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4948
4949 static void
4950 do_blx (char * str)
4951 {
4952   char * mystr = str;
4953   int rm;
4954
4955   skip_whitespace (mystr);
4956   rm = reg_required_here (& mystr, 0);
4957
4958   /* The above may set inst.error.  Ignore his opinion.  */
4959   inst.error = 0;
4960
4961   if (rm != FAIL)
4962     {
4963       /* Arg is a register.
4964          Use the condition code our caller put in inst.instruction.
4965          Pass ourselves off as a BX with a funny opcode.  */
4966       inst.instruction |= 0x012fff30;
4967       do_bx (str);
4968     }
4969   else
4970     {
4971       /* This must be is BLX <target address>, no condition allowed.  */
4972       if (inst.instruction != COND_ALWAYS)
4973         {
4974           inst.error = BAD_COND;
4975           return;
4976         }
4977
4978       inst.instruction = 0xfafffffe;
4979
4980       /* Process like a B/BL, but with a different reloc.
4981          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4982       do_branch25 (str);
4983     }
4984 }
4985
4986 /* ARM V5 Thumb BLX (argument parse)
4987         BLX <target_addr>       which is BLX(1)
4988         BLX <Rm>                which is BLX(2)
4989    Unfortunately, there are two different opcodes for this mnemonic.
4990    So, the tinsns[].value is not used, and the code here zaps values
4991         into inst.instruction.  */
4992
4993 static void
4994 do_t_blx (char * str)
4995 {
4996   char * mystr = str;
4997   int rm;
4998
4999   skip_whitespace (mystr);
5000   inst.instruction = 0x4780;
5001
5002   /* Note that this call is to the ARM register recognizer.  BLX(2)
5003      uses the ARM register space, not the Thumb one, so a call to
5004      thumb_reg() would be wrong.  */
5005   rm = reg_required_here (& mystr, 3);
5006   inst.error = 0;
5007
5008   if (rm != FAIL)
5009     {
5010       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5011       inst.size = 2;
5012     }
5013   else
5014     {
5015       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5016       inst.instruction = 0xf7ffeffe;
5017       inst.size = 4;
5018
5019       if (my_get_expression (& inst.reloc.exp, & mystr))
5020         return;
5021
5022       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5023       inst.reloc.pc_rel = 1;
5024     }
5025
5026   end_of_line (mystr);
5027 }
5028
5029 /* ARM V5 breakpoint instruction (argument parse)
5030      BKPT <16 bit unsigned immediate>
5031      Instruction is not conditional.
5032         The bit pattern given in insns[] has the COND_ALWAYS condition,
5033         and it is an error if the caller tried to override that.  */
5034
5035 static void
5036 do_bkpt (char * str)
5037 {
5038   expressionS expr;
5039   unsigned long number;
5040
5041   skip_whitespace (str);
5042
5043   /* Allow optional leading '#'.  */
5044   if (is_immediate_prefix (* str))
5045     str++;
5046
5047   memset (& expr, '\0', sizeof (expr));
5048
5049   if (my_get_expression (& expr, & str)
5050       || (expr.X_op != O_constant
5051           /* As a convenience we allow 'bkpt' without an operand.  */
5052           && expr.X_op != O_absent))
5053     {
5054       inst.error = _("bad expression");
5055       return;
5056     }
5057
5058   number = expr.X_add_number;
5059
5060   /* Check it fits a 16 bit unsigned.  */
5061   if (number != (number & 0xffff))
5062     {
5063       inst.error = _("immediate value out of range");
5064       return;
5065     }
5066
5067   /* Top 12 of 16 bits to bits 19:8.  */
5068   inst.instruction |= (number & 0xfff0) << 4;
5069
5070   /* Bottom 4 of 16 bits to bits 3:0.  */
5071   inst.instruction |= number & 0xf;
5072
5073   end_of_line (str);
5074 }
5075
5076 /* THUMB CPS instruction (argument parse).  */
5077
5078 static void
5079 do_t_cps (char * str)
5080 {
5081   do_cps_flags (&str, /*thumb_p=*/1);
5082   end_of_line (str);
5083 }
5084
5085 /* Parse and validate that a register is of the right form, this saves
5086    repeated checking of this information in many similar cases.
5087    Unlike the 32-bit case we do not insert the register into the opcode
5088    here, since the position is often unknown until the full instruction
5089    has been parsed.  */
5090
5091 static int
5092 thumb_reg (char ** strp, int hi_lo)
5093 {
5094   int reg;
5095
5096   if ((reg = reg_required_here (strp, -1)) == FAIL)
5097     return FAIL;
5098
5099   switch (hi_lo)
5100     {
5101     case THUMB_REG_LO:
5102       if (reg > 7)
5103         {
5104           inst.error = _("lo register required");
5105           return FAIL;
5106         }
5107       break;
5108
5109     case THUMB_REG_HI:
5110       if (reg < 8)
5111         {
5112           inst.error = _("hi register required");
5113           return FAIL;
5114         }
5115       break;
5116
5117     default:
5118       break;
5119     }
5120
5121   return reg;
5122 }
5123
5124 static void
5125 thumb_mov_compare (char * str, int move)
5126 {
5127   int Rd, Rs = FAIL;
5128
5129   skip_whitespace (str);
5130
5131   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5132       || skip_past_comma (&str) == FAIL)
5133     {
5134       if (! inst.error)
5135         inst.error = BAD_ARGS;
5136       return;
5137     }
5138
5139   if (move != THUMB_CPY && is_immediate_prefix (*str))
5140     {
5141       str++;
5142       if (my_get_expression (&inst.reloc.exp, &str))
5143         return;
5144     }
5145   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5146     return;
5147
5148   if (Rs != FAIL)
5149     {
5150       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
5151         {
5152           if (move == THUMB_MOVE)
5153             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5154                since a MOV instruction produces unpredictable results.  */
5155             inst.instruction = T_OPCODE_ADD_I3;
5156           else
5157             inst.instruction = T_OPCODE_CMP_LR;
5158           inst.instruction |= Rd | (Rs << 3);
5159         }
5160       else
5161         {
5162           if (move == THUMB_MOVE)
5163             inst.instruction = T_OPCODE_MOV_HR;
5164           else if (move != THUMB_CPY)
5165             inst.instruction = T_OPCODE_CMP_HR;
5166
5167           if (Rd > 7)
5168             inst.instruction |= THUMB_H1;
5169
5170           if (Rs > 7)
5171             inst.instruction |= THUMB_H2;
5172
5173           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
5174         }
5175     }
5176   else
5177     {
5178       if (Rd > 7)
5179         {
5180           inst.error = _("only lo regs allowed with immediate");
5181           return;
5182         }
5183
5184       if (move == THUMB_MOVE)
5185         inst.instruction = T_OPCODE_MOV_I8;
5186       else
5187         inst.instruction = T_OPCODE_CMP_I8;
5188
5189       inst.instruction |= Rd << 8;
5190
5191       if (inst.reloc.exp.X_op != O_constant)
5192         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
5193       else
5194         {
5195           unsigned value = inst.reloc.exp.X_add_number;
5196
5197           if (value > 255)
5198             {
5199               inst.error = _("invalid immediate");
5200               return;
5201             }
5202
5203           inst.instruction |= value;
5204         }
5205     }
5206
5207   end_of_line (str);
5208 }
5209
5210 /* THUMB CPY instruction (argument parse).  */
5211
5212 static void
5213 do_t_cpy (char * str)
5214 {
5215   thumb_mov_compare (str, THUMB_CPY);
5216 }
5217
5218 /* THUMB SETEND instruction (argument parse).  */
5219
5220 static void
5221 do_t_setend (char * str)
5222 {
5223   if (do_endian_specifier (str))
5224     inst.instruction |= 0x8;
5225 }
5226
5227 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
5228
5229 static unsigned long
5230 check_iwmmxt_insn (char * str,
5231                    enum iwmmxt_insn_type insn_type,
5232                    int immediate_size)
5233 {
5234   int reg = 0;
5235   const char *  inst_error;
5236   expressionS expr;
5237   unsigned long number;
5238
5239   inst_error = inst.error;
5240   if (!inst.error)
5241     inst.error = BAD_ARGS;
5242   skip_whitespace (str);
5243
5244   switch (insn_type)
5245     {
5246     case check_rd:
5247       if ((reg = reg_required_here (&str, 12)) == FAIL)
5248         return FAIL;
5249       break;
5250
5251     case check_wr:
5252        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
5253          return FAIL;
5254        break;
5255
5256     case check_wrwr:
5257       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5258            || skip_past_comma (&str) == FAIL
5259            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5260         return FAIL;
5261       break;
5262
5263     case check_wrwrwr:
5264       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5265            || skip_past_comma (&str) == FAIL
5266            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5267            || skip_past_comma (&str) == FAIL
5268            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5269         return FAIL;
5270       break;
5271
5272     case check_wrwrwcg:
5273       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5274            || skip_past_comma (&str) == FAIL
5275            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5276            || skip_past_comma (&str) == FAIL
5277            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
5278         return FAIL;
5279       break;
5280
5281     case check_tbcst:
5282       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5283            || skip_past_comma (&str) == FAIL
5284            || reg_required_here (&str, 12) == FAIL))
5285         return FAIL;
5286       break;
5287
5288     case check_tmovmsk:
5289       if ((reg_required_here (&str, 12) == FAIL
5290            || skip_past_comma (&str) == FAIL
5291            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5292         return FAIL;
5293       break;
5294
5295     case check_tmia:
5296       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5297            || skip_past_comma (&str) == FAIL
5298            || reg_required_here (&str, 0) == FAIL
5299            || skip_past_comma (&str) == FAIL
5300            || reg_required_here (&str, 12) == FAIL))
5301         return FAIL;
5302       break;
5303
5304     case check_tmcrr:
5305       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5306            || skip_past_comma (&str) == FAIL
5307            || reg_required_here (&str, 12) == FAIL
5308            || skip_past_comma (&str) == FAIL
5309            || reg_required_here (&str, 16) == FAIL))
5310         return FAIL;
5311       break;
5312
5313     case check_tmrrc:
5314       if ((reg_required_here (&str, 12) == FAIL
5315            || skip_past_comma (&str) == FAIL
5316            || reg_required_here (&str, 16) == FAIL
5317            || skip_past_comma (&str) == FAIL
5318            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5319         return FAIL;
5320       break;
5321
5322     case check_tmcr:
5323       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5324            || skip_past_comma (&str) == FAIL
5325            || reg_required_here (&str, 12) == FAIL))
5326         return FAIL;
5327       break;
5328
5329     case check_tmrc:
5330       if ((reg_required_here (&str, 12) == FAIL
5331            || skip_past_comma (&str) == FAIL
5332            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5333         return FAIL;
5334       break;
5335
5336     case check_tinsr:
5337       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5338            || skip_past_comma (&str) == FAIL
5339            || reg_required_here (&str, 12) == FAIL
5340            || skip_past_comma (&str) == FAIL))
5341         return FAIL;
5342       break;
5343
5344     case check_textrc:
5345       if ((reg_required_here (&str, 12) == FAIL
5346            || skip_past_comma (&str) == FAIL))
5347         return FAIL;
5348       break;
5349
5350     case check_waligni:
5351       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5352            || skip_past_comma (&str) == FAIL
5353            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5354            || skip_past_comma (&str) == FAIL
5355            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5356            || skip_past_comma (&str) == FAIL))
5357         return FAIL;
5358       break;
5359
5360     case check_textrm:
5361       if ((reg_required_here (&str, 12) == FAIL
5362            || skip_past_comma (&str) == FAIL
5363            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5364            || skip_past_comma (&str) == FAIL))
5365         return FAIL;
5366       break;
5367
5368     case check_wshufh:
5369       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5370            || skip_past_comma (&str) == FAIL
5371            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5372            || skip_past_comma (&str) == FAIL))
5373         return FAIL;
5374       break;
5375     }
5376
5377   if (immediate_size == 0)
5378     {
5379       end_of_line (str);
5380       inst.error = inst_error;
5381       return reg;
5382     }
5383   else
5384     {
5385       skip_whitespace (str);
5386
5387       /* Allow optional leading '#'.  */
5388       if (is_immediate_prefix (* str))
5389         str++;
5390
5391       memset (& expr, '\0', sizeof (expr));
5392
5393       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5394         {
5395           inst.error = _("bad or missing expression");
5396           return FAIL;
5397         }
5398
5399       number = expr.X_add_number;
5400
5401       if (number != (number & immediate_size))
5402         {
5403           inst.error = _("immediate value out of range");
5404           return FAIL;
5405         }
5406       end_of_line (str);
5407       inst.error = inst_error;
5408       return number;
5409     }
5410 }
5411
5412 static void
5413 do_iwmmxt_byte_addr (char * str)
5414 {
5415   int op = (inst.instruction & 0x300) >> 8;
5416   int reg;
5417
5418   inst.instruction &= ~0x300;
5419   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5420
5421   skip_whitespace (str);
5422
5423   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5424       || skip_past_comma (& str) == FAIL
5425       || cp_byte_address_required_here (&str) == FAIL)
5426     {
5427       if (! inst.error)
5428         inst.error = BAD_ARGS;
5429     }
5430   else
5431     end_of_line (str);
5432
5433   if (wc_register (reg))
5434     {
5435       as_bad (_("non-word size not supported with control register"));
5436       inst.instruction |=  0xf0000100;
5437       inst.instruction &= ~0x00400000;
5438     }
5439 }
5440
5441 static void
5442 do_iwmmxt_tandc (char * str)
5443 {
5444   int reg;
5445
5446   reg = check_iwmmxt_insn (str, check_rd, 0);
5447
5448   if (reg != REG_PC && !inst.error)
5449     inst.error = _("only r15 allowed here");
5450 }
5451
5452 static void
5453 do_iwmmxt_tbcst (char * str)
5454 {
5455   check_iwmmxt_insn (str, check_tbcst, 0);
5456 }
5457
5458 static void
5459 do_iwmmxt_textrc (char * str)
5460 {
5461   unsigned long number;
5462
5463   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5464     return;
5465
5466   inst.instruction |= number & 0x7;
5467 }
5468
5469 static void
5470 do_iwmmxt_textrm (char * str)
5471 {
5472   unsigned long number;
5473
5474   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5475     return;
5476
5477   inst.instruction |= number & 0x7;
5478 }
5479
5480 static void
5481 do_iwmmxt_tinsr (char * str)
5482 {
5483   unsigned long number;
5484
5485   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5486     return;
5487
5488   inst.instruction |= number & 0x7;
5489 }
5490
5491 static void
5492 do_iwmmxt_tmcr (char * str)
5493 {
5494   check_iwmmxt_insn (str, check_tmcr, 0);
5495 }
5496
5497 static void
5498 do_iwmmxt_tmcrr (char * str)
5499 {
5500   check_iwmmxt_insn (str, check_tmcrr, 0);
5501 }
5502
5503 static void
5504 do_iwmmxt_tmia (char * str)
5505 {
5506   check_iwmmxt_insn (str, check_tmia, 0);
5507 }
5508
5509 static void
5510 do_iwmmxt_tmovmsk (char * str)
5511 {
5512   check_iwmmxt_insn (str, check_tmovmsk, 0);
5513 }
5514
5515 static void
5516 do_iwmmxt_tmrc (char * str)
5517 {
5518   check_iwmmxt_insn (str, check_tmrc, 0);
5519 }
5520
5521 static void
5522 do_iwmmxt_tmrrc (char * str)
5523 {
5524   check_iwmmxt_insn (str, check_tmrrc, 0);
5525 }
5526
5527 static void
5528 do_iwmmxt_torc (char * str)
5529 {
5530   check_iwmmxt_insn (str, check_rd, 0);
5531 }
5532
5533 static void
5534 do_iwmmxt_waligni (char * str)
5535 {
5536   unsigned long number;
5537
5538   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5539     return;
5540
5541   inst.instruction |= ((number & 0x7) << 20);
5542 }
5543
5544 static void
5545 do_iwmmxt_wmov (char * str)
5546 {
5547   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5548     return;
5549
5550   inst.instruction |= ((inst.instruction >> 16) & 0xf);
5551 }
5552
5553 static void
5554 do_iwmmxt_word_addr (char * str)
5555 {
5556   int op = (inst.instruction & 0x300) >> 8;
5557   int reg;
5558
5559   inst.instruction &= ~0x300;
5560   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5561
5562   skip_whitespace (str);
5563
5564   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5565       || skip_past_comma (& str) == FAIL
5566       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5567     {
5568       if (! inst.error)
5569         inst.error = BAD_ARGS;
5570     }
5571   else
5572     end_of_line (str);
5573
5574   if (wc_register (reg))
5575     {
5576       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5577         as_bad (_("conditional execution not supported with control register"));
5578       if (op != 2)
5579         as_bad (_("non-word size not supported with control register"));
5580       inst.instruction |=  0xf0000100;
5581       inst.instruction &= ~0x00400000;
5582     }
5583 }
5584
5585 static void
5586 do_iwmmxt_wrwr (char * str)
5587 {
5588   check_iwmmxt_insn (str, check_wrwr, 0);
5589 }
5590
5591 static void
5592 do_iwmmxt_wrwrwcg (char * str)
5593 {
5594   check_iwmmxt_insn (str, check_wrwrwcg, 0);
5595 }
5596
5597 static void
5598 do_iwmmxt_wrwrwr (char * str)
5599 {
5600   check_iwmmxt_insn (str, check_wrwrwr, 0);
5601 }
5602
5603 static void
5604 do_iwmmxt_wshufh (char * str)
5605 {
5606   unsigned long number;
5607
5608   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5609     return;
5610
5611   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5612 }
5613
5614 static void
5615 do_iwmmxt_wzero (char * str)
5616 {
5617   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5618     return;
5619
5620   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5621 }
5622
5623 /* Xscale multiply-accumulate (argument parse)
5624      MIAcc   acc0,Rm,Rs
5625      MIAPHcc acc0,Rm,Rs
5626      MIAxycc acc0,Rm,Rs.  */
5627
5628 static void
5629 do_xsc_mia (char * str)
5630 {
5631   int rs;
5632   int rm;
5633
5634   if (accum0_required_here (& str) == FAIL)
5635     inst.error = ERR_NO_ACCUM;
5636
5637   else if (skip_past_comma (& str) == FAIL
5638            || (rm = reg_required_here (& str, 0)) == FAIL)
5639     inst.error = BAD_ARGS;
5640
5641   else if (skip_past_comma (& str) == FAIL
5642            || (rs = reg_required_here (& str, 12)) == FAIL)
5643     inst.error = BAD_ARGS;
5644
5645   /* inst.instruction has now been zapped with both rm and rs.  */
5646   else if (rm == REG_PC || rs == REG_PC)
5647     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
5648
5649   else
5650     end_of_line (str);
5651 }
5652
5653 /* Xscale move-accumulator-register (argument parse)
5654
5655      MARcc   acc0,RdLo,RdHi.  */
5656
5657 static void
5658 do_xsc_mar (char * str)
5659 {
5660   int rdlo, rdhi;
5661
5662   if (accum0_required_here (& str) == FAIL)
5663     inst.error = ERR_NO_ACCUM;
5664
5665   else if (skip_past_comma (& str) == FAIL
5666            || (rdlo = reg_required_here (& str, 12)) == FAIL)
5667     inst.error = BAD_ARGS;
5668
5669   else if (skip_past_comma (& str) == FAIL
5670            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5671     inst.error = BAD_ARGS;
5672
5673   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5674   else if (rdlo == REG_PC || rdhi == REG_PC)
5675     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5676
5677   else
5678     end_of_line (str);
5679 }
5680
5681 /* Xscale move-register-accumulator (argument parse)
5682
5683      MRAcc   RdLo,RdHi,acc0.  */
5684
5685 static void
5686 do_xsc_mra (char * str)
5687 {
5688   int rdlo;
5689   int rdhi;
5690
5691   skip_whitespace (str);
5692
5693   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5694     inst.error = BAD_ARGS;
5695
5696   else if (skip_past_comma (& str) == FAIL
5697            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5698     inst.error = BAD_ARGS;
5699
5700   else if  (skip_past_comma (& str) == FAIL
5701             || accum0_required_here (& str) == FAIL)
5702     inst.error = ERR_NO_ACCUM;
5703
5704   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5705   else if (rdlo == rdhi)
5706     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
5707
5708   else if (rdlo == REG_PC || rdhi == REG_PC)
5709     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5710   else
5711     end_of_line (str);
5712 }
5713
5714 static int
5715 ldst_extend (char ** str)
5716 {
5717   int add = INDEX_UP;
5718
5719   switch (**str)
5720     {
5721     case '#':
5722     case '$':
5723       (*str)++;
5724       if (my_get_expression (& inst.reloc.exp, str))
5725         return FAIL;
5726
5727       if (inst.reloc.exp.X_op == O_constant)
5728         {
5729           int value = inst.reloc.exp.X_add_number;
5730
5731           if (value < -4095 || value > 4095)
5732             {
5733               inst.error = _("address offset too large");
5734               return FAIL;
5735             }
5736
5737           if (value < 0)
5738             {
5739               value = -value;
5740               add = 0;
5741             }
5742
5743           inst.instruction |= add | value;
5744         }
5745       else
5746         {
5747           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5748           inst.reloc.pc_rel = 0;
5749         }
5750       return SUCCESS;
5751
5752     case '-':
5753       add = 0;
5754       /* Fall through.  */
5755
5756     case '+':
5757       (*str)++;
5758       /* Fall through.  */
5759
5760     default:
5761       if (reg_required_here (str, 0) == FAIL)
5762         return FAIL;
5763
5764       inst.instruction |= add | OFFSET_REG;
5765       if (skip_past_comma (str) == SUCCESS)
5766         return decode_shift (str, SHIFT_IMMEDIATE);
5767
5768       return SUCCESS;
5769     }
5770 }
5771
5772 /* ARMv5TE: Preload-Cache
5773
5774     PLD <addr_mode>
5775
5776   Syntactically, like LDR with B=1, W=0, L=1.  */
5777
5778 static void
5779 do_pld (char * str)
5780 {
5781   int rd;
5782
5783   skip_whitespace (str);
5784
5785   if (* str != '[')
5786     {
5787       inst.error = _("'[' expected after PLD mnemonic");
5788       return;
5789     }
5790
5791   ++str;
5792   skip_whitespace (str);
5793
5794   if ((rd = reg_required_here (& str, 16)) == FAIL)
5795     return;
5796
5797   skip_whitespace (str);
5798
5799   if (*str == ']')
5800     {
5801       /* [Rn], ... ?  */
5802       ++str;
5803       skip_whitespace (str);
5804
5805       /* Post-indexed addressing is not allowed with PLD.  */
5806       if (skip_past_comma (&str) == SUCCESS)
5807         {
5808           inst.error
5809             = _("post-indexed expression used in preload instruction");
5810           return;
5811         }
5812       else if (*str == '!') /* [Rn]! */
5813         {
5814           inst.error = _("writeback used in preload instruction");
5815           ++str;
5816         }
5817       else /* [Rn] */
5818         inst.instruction |= INDEX_UP | PRE_INDEX;
5819     }
5820   else /* [Rn, ...] */
5821     {
5822       if (skip_past_comma (& str) == FAIL)
5823         {
5824           inst.error = _("pre-indexed expression expected");
5825           return;
5826         }
5827
5828       if (ldst_extend (&str) == FAIL)
5829         return;
5830
5831       skip_whitespace (str);
5832
5833       if (* str != ']')
5834         {
5835           inst.error = _("missing ]");
5836           return;
5837         }
5838
5839       ++ str;
5840       skip_whitespace (str);
5841
5842       if (* str == '!') /* [Rn]! */
5843         {
5844           inst.error = _("writeback used in preload instruction");
5845           ++ str;
5846         }
5847
5848       inst.instruction |= PRE_INDEX;
5849     }
5850
5851   end_of_line (str);
5852 }
5853
5854 /* ARMv5TE load-consecutive (argument parse)
5855    Mode is like LDRH.
5856
5857      LDRccD R, mode
5858      STRccD R, mode.  */
5859
5860 static void
5861 do_ldrd (char * str)
5862 {
5863   int rd;
5864   int rn;
5865
5866   skip_whitespace (str);
5867
5868   if ((rd = reg_required_here (& str, 12)) == FAIL)
5869     {
5870       inst.error = BAD_ARGS;
5871       return;
5872     }
5873
5874   if (skip_past_comma (& str) == FAIL
5875       || (rn = ld_mode_required_here (& str)) == FAIL)
5876     {
5877       if (!inst.error)
5878         inst.error = BAD_ARGS;
5879       return;
5880     }
5881
5882   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
5883   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
5884     {
5885       inst.error = _("destination register must be even");
5886       return;
5887     }
5888
5889   if (rd == REG_LR)
5890     {
5891       inst.error = _("r14 not allowed here");
5892       return;
5893     }
5894
5895   if (((rd == rn) || (rd + 1 == rn))
5896       && ((inst.instruction & WRITE_BACK)
5897           || (!(inst.instruction & PRE_INDEX))))
5898     as_warn (_("pre/post-indexing used when modified address register is destination"));
5899
5900   /* For an index-register load, the index register must not overlap the
5901      destination (even if not write-back).  */
5902   if ((inst.instruction & V4_STR_BIT) == 0
5903       && (inst.instruction & HWOFFSET_IMM) == 0)
5904     {
5905       int rm = inst.instruction & 0x0000000f;
5906
5907       if (rm == rd || (rm == rd + 1))
5908         as_warn (_("ldrd destination registers must not overlap index register"));
5909     }
5910
5911   end_of_line (str);
5912 }
5913
5914 /* Returns the index into fp_values of a floating point number,
5915    or -1 if not in the table.  */
5916
5917 static int
5918 my_get_float_expression (char ** str)
5919 {
5920   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5921   char *         save_in;
5922   expressionS    exp;
5923   int            i;
5924   int            j;
5925
5926   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5927
5928   /* Look for a raw floating point number.  */
5929   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5930       && is_end_of_line[(unsigned char) *save_in])
5931     {
5932       for (i = 0; i < NUM_FLOAT_VALS; i++)
5933         {
5934           for (j = 0; j < MAX_LITTLENUMS; j++)
5935             {
5936               if (words[j] != fp_values[i][j])
5937                 break;
5938             }
5939
5940           if (j == MAX_LITTLENUMS)
5941             {
5942               *str = save_in;
5943               return i;
5944             }
5945         }
5946     }
5947
5948   /* Try and parse a more complex expression, this will probably fail
5949      unless the code uses a floating point prefix (eg "0f").  */
5950   save_in = input_line_pointer;
5951   input_line_pointer = *str;
5952   if (expression (&exp) == absolute_section
5953       && exp.X_op == O_big
5954       && exp.X_add_number < 0)
5955     {
5956       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5957          Ditto for 15.  */
5958       if (gen_to_words (words, 5, (long) 15) == 0)
5959         {
5960           for (i = 0; i < NUM_FLOAT_VALS; i++)
5961             {
5962               for (j = 0; j < MAX_LITTLENUMS; j++)
5963                 {
5964                   if (words[j] != fp_values[i][j])
5965                     break;
5966                 }
5967
5968               if (j == MAX_LITTLENUMS)
5969                 {
5970                   *str = input_line_pointer;
5971                   input_line_pointer = save_in;
5972                   return i;
5973                 }
5974             }
5975         }
5976     }
5977
5978   *str = input_line_pointer;
5979   input_line_pointer = save_in;
5980   return -1;
5981 }
5982
5983 /* We handle all bad expressions here, so that we can report the faulty
5984    instruction in the error message.  */
5985 void
5986 md_operand (expressionS * expr)
5987 {
5988   if (in_my_get_expression)
5989     {
5990       expr->X_op = O_illegal;
5991       if (inst.error == NULL)
5992         inst.error = _("bad expression");
5993     }
5994 }
5995
5996 /* Do those data_ops which can take a negative immediate constant
5997    by altering the instruction.  A bit of a hack really.
5998         MOV <-> MVN
5999         AND <-> BIC
6000         ADC <-> SBC
6001         by inverting the second operand, and
6002         ADD <-> SUB
6003         CMP <-> CMN
6004         by negating the second operand.  */
6005
6006 static int
6007 negate_data_op (unsigned long * instruction,
6008                 unsigned long   value)
6009 {
6010   int op, new_inst;
6011   unsigned long negated, inverted;
6012
6013   negated = validate_immediate (-value);
6014   inverted = validate_immediate (~value);
6015
6016   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
6017   switch (op)
6018     {
6019       /* First negates.  */
6020     case OPCODE_SUB:             /* ADD <-> SUB  */
6021       new_inst = OPCODE_ADD;
6022       value = negated;
6023       break;
6024
6025     case OPCODE_ADD:
6026       new_inst = OPCODE_SUB;
6027       value = negated;
6028       break;
6029
6030     case OPCODE_CMP:             /* CMP <-> CMN  */
6031       new_inst = OPCODE_CMN;
6032       value = negated;
6033       break;
6034
6035     case OPCODE_CMN:
6036       new_inst = OPCODE_CMP;
6037       value = negated;
6038       break;
6039
6040       /* Now Inverted ops.  */
6041     case OPCODE_MOV:             /* MOV <-> MVN  */
6042       new_inst = OPCODE_MVN;
6043       value = inverted;
6044       break;
6045
6046     case OPCODE_MVN:
6047       new_inst = OPCODE_MOV;
6048       value = inverted;
6049       break;
6050
6051     case OPCODE_AND:             /* AND <-> BIC  */
6052       new_inst = OPCODE_BIC;
6053       value = inverted;
6054       break;
6055
6056     case OPCODE_BIC:
6057       new_inst = OPCODE_AND;
6058       value = inverted;
6059       break;
6060
6061     case OPCODE_ADC:              /* ADC <-> SBC  */
6062       new_inst = OPCODE_SBC;
6063       value = inverted;
6064       break;
6065
6066     case OPCODE_SBC:
6067       new_inst = OPCODE_ADC;
6068       value = inverted;
6069       break;
6070
6071       /* We cannot do anything.  */
6072     default:
6073       return FAIL;
6074     }
6075
6076   if (value == (unsigned) FAIL)
6077     return FAIL;
6078
6079   *instruction &= OPCODE_MASK;
6080   *instruction |= new_inst << DATA_OP_SHIFT;
6081   return value;
6082 }
6083
6084 static int
6085 data_op2 (char ** str)
6086 {
6087   int value;
6088   expressionS expr;
6089
6090   skip_whitespace (* str);
6091
6092   if (reg_required_here (str, 0) != FAIL)
6093     {
6094       if (skip_past_comma (str) == SUCCESS)
6095         /* Shift operation on register.  */
6096         return decode_shift (str, NO_SHIFT_RESTRICT);
6097
6098       return SUCCESS;
6099     }
6100   else
6101     {
6102       /* Immediate expression.  */
6103       if (is_immediate_prefix (**str))
6104         {
6105           (*str)++;
6106           inst.error = NULL;
6107
6108           if (my_get_expression (&inst.reloc.exp, str))
6109             return FAIL;
6110
6111           if (inst.reloc.exp.X_add_symbol)
6112             {
6113               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6114               inst.reloc.pc_rel = 0;
6115             }
6116           else
6117             {
6118               if (skip_past_comma (str) == SUCCESS)
6119                 {
6120                   /* #x, y -- ie explicit rotation by Y.  */
6121                   if (my_get_expression (&expr, str))
6122                     return FAIL;
6123
6124                   if (expr.X_op != O_constant)
6125                     {
6126                       inst.error = _("constant expression expected");
6127                       return FAIL;
6128                     }
6129
6130                   /* Rotate must be a multiple of 2.  */
6131                   if (((unsigned) expr.X_add_number) > 30
6132                       || (expr.X_add_number & 1) != 0
6133                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
6134                     {
6135                       inst.error = _("invalid constant");
6136                       return FAIL;
6137                     }
6138                   inst.instruction |= INST_IMMEDIATE;
6139                   inst.instruction |= inst.reloc.exp.X_add_number;
6140                   inst.instruction |= expr.X_add_number << 7;
6141                   return SUCCESS;
6142                 }
6143
6144               /* Implicit rotation, select a suitable one.  */
6145               value = validate_immediate (inst.reloc.exp.X_add_number);
6146
6147               if (value == FAIL)
6148                 {
6149                   /* Can't be done.  Perhaps the code reads something like
6150                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
6151                   if ((value = negate_data_op (&inst.instruction,
6152                                                inst.reloc.exp.X_add_number))
6153                       == FAIL)
6154                     {
6155                       inst.error = _("invalid constant");
6156                       return FAIL;
6157                     }
6158                 }
6159
6160               inst.instruction |= value;
6161             }
6162
6163           inst.instruction |= INST_IMMEDIATE;
6164           return SUCCESS;
6165         }
6166
6167       (*str)++;
6168       inst.error = _("register or shift expression expected");
6169       return FAIL;
6170     }
6171 }
6172
6173 static int
6174 fp_op2 (char ** str)
6175 {
6176   skip_whitespace (* str);
6177
6178   if (fp_reg_required_here (str, 0) != FAIL)
6179     return SUCCESS;
6180   else
6181     {
6182       /* Immediate expression.  */
6183       if (*((*str)++) == '#')
6184         {
6185           int i;
6186
6187           inst.error = NULL;
6188
6189           skip_whitespace (* str);
6190
6191           /* First try and match exact strings, this is to guarantee
6192              that some formats will work even for cross assembly.  */
6193
6194           for (i = 0; fp_const[i]; i++)
6195             {
6196               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
6197                 {
6198                   char *start = *str;
6199
6200                   *str += strlen (fp_const[i]);
6201                   if (is_end_of_line[(unsigned char) **str])
6202                     {
6203                       inst.instruction |= i + 8;
6204                       return SUCCESS;
6205                     }
6206                   *str = start;
6207                 }
6208             }
6209
6210           /* Just because we didn't get a match doesn't mean that the
6211              constant isn't valid, just that it is in a format that we
6212              don't automatically recognize.  Try parsing it with
6213              the standard expression routines.  */
6214           if ((i = my_get_float_expression (str)) >= 0)
6215             {
6216               inst.instruction |= i + 8;
6217               return SUCCESS;
6218             }
6219
6220           inst.error = _("invalid floating point immediate expression");
6221           return FAIL;
6222         }
6223       inst.error =
6224         _("floating point register or immediate expression expected");
6225       return FAIL;
6226     }
6227 }
6228
6229 static void
6230 do_arit (char * str)
6231 {
6232   skip_whitespace (str);
6233
6234   if (reg_required_here (&str, 12) == FAIL
6235       || skip_past_comma (&str) == FAIL
6236       || reg_required_here (&str, 16) == FAIL
6237       || skip_past_comma (&str) == FAIL
6238       || data_op2 (&str) == FAIL)
6239     {
6240       if (!inst.error)
6241         inst.error = BAD_ARGS;
6242       return;
6243     }
6244
6245   end_of_line (str);
6246 }
6247
6248 static void
6249 do_adr (char * str)
6250 {
6251   /* This is a pseudo-op of the form "adr rd, label" to be converted
6252      into a relative address of the form "add rd, pc, #label-.-8".  */
6253   skip_whitespace (str);
6254
6255   if (reg_required_here (&str, 12) == FAIL
6256       || skip_past_comma (&str) == FAIL
6257       || my_get_expression (&inst.reloc.exp, &str))
6258     {
6259       if (!inst.error)
6260         inst.error = BAD_ARGS;
6261       return;
6262     }
6263
6264   /* Frag hacking will turn this into a sub instruction if the offset turns
6265      out to be negative.  */
6266   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6267 #ifndef TE_WINCE
6268   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
6269 #endif
6270   inst.reloc.pc_rel = 1;
6271
6272   end_of_line (str);
6273 }
6274
6275 static void
6276 do_adrl (char * str)
6277 {
6278   /* This is a pseudo-op of the form "adrl rd, label" to be converted
6279      into a relative address of the form:
6280      add rd, pc, #low(label-.-8)"
6281      add rd, rd, #high(label-.-8)"  */
6282
6283   skip_whitespace (str);
6284
6285   if (reg_required_here (&str, 12) == FAIL
6286       || skip_past_comma (&str) == FAIL
6287       || my_get_expression (&inst.reloc.exp, &str))
6288     {
6289       if (!inst.error)
6290         inst.error = BAD_ARGS;
6291
6292       return;
6293     }
6294
6295   end_of_line (str);
6296   /* Frag hacking will turn this into a sub instruction if the offset turns
6297      out to be negative.  */
6298   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6299 #ifndef TE_WINCE
6300   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
6301 #endif
6302   inst.reloc.pc_rel            = 1;
6303   inst.size                    = INSN_SIZE * 2;
6304 }
6305
6306 static void
6307 do_cmp (char * str)
6308 {
6309   skip_whitespace (str);
6310
6311   if (reg_required_here (&str, 16) == FAIL)
6312     {
6313       if (!inst.error)
6314         inst.error = BAD_ARGS;
6315       return;
6316     }
6317
6318   if (skip_past_comma (&str) == FAIL
6319       || data_op2 (&str) == FAIL)
6320     {
6321       if (!inst.error)
6322         inst.error = BAD_ARGS;
6323       return;
6324     }
6325
6326   end_of_line (str);
6327 }
6328
6329 static void
6330 do_mov (char * str)
6331 {
6332   skip_whitespace (str);
6333
6334   if (reg_required_here (&str, 12) == FAIL)
6335     {
6336       if (!inst.error)
6337         inst.error = BAD_ARGS;
6338       return;
6339     }
6340
6341   if (skip_past_comma (&str) == FAIL
6342       || data_op2 (&str) == FAIL)
6343     {
6344       if (!inst.error)
6345         inst.error = BAD_ARGS;
6346       return;
6347     }
6348
6349   end_of_line (str);
6350 }
6351
6352 static void
6353 do_ldst (char * str)
6354 {
6355   int pre_inc = 0;
6356   int conflict_reg;
6357   int value;
6358
6359   skip_whitespace (str);
6360
6361   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6362     {
6363       if (!inst.error)
6364         inst.error = BAD_ARGS;
6365       return;
6366     }
6367
6368   if (skip_past_comma (&str) == FAIL)
6369     {
6370       inst.error = _("address expected");
6371       return;
6372     }
6373
6374   if (*str == '[')
6375     {
6376       int reg;
6377
6378       str++;
6379
6380       skip_whitespace (str);
6381
6382       if ((reg = reg_required_here (&str, 16)) == FAIL)
6383         return;
6384
6385       /* Conflicts can occur on stores as well as loads.  */
6386       conflict_reg = (conflict_reg == reg);
6387
6388       skip_whitespace (str);
6389
6390       if (*str == ']')
6391         {
6392           str ++;
6393
6394           if (skip_past_comma (&str) == SUCCESS)
6395             {
6396               /* [Rn],... (post inc)  */
6397               if (ldst_extend (&str) == FAIL)
6398                 return;
6399               if (conflict_reg)
6400                 as_warn (_("%s register same as write-back base"),
6401                          ((inst.instruction & LOAD_BIT)
6402                           ? _("destination") : _("source")));
6403             }
6404           else
6405             {
6406               /* [Rn]  */
6407               skip_whitespace (str);
6408
6409               if (*str == '!')
6410                 {
6411                   if (conflict_reg)
6412                     as_warn (_("%s register same as write-back base"),
6413                              ((inst.instruction & LOAD_BIT)
6414                               ? _("destination") : _("source")));
6415                   str++;
6416                   inst.instruction |= WRITE_BACK;
6417                 }
6418
6419               inst.instruction |= INDEX_UP;
6420               pre_inc = 1;
6421             }
6422         }
6423       else
6424         {
6425           /* [Rn,...]  */
6426           if (skip_past_comma (&str) == FAIL)
6427             {
6428               inst.error = _("pre-indexed expression expected");
6429               return;
6430             }
6431
6432           pre_inc = 1;
6433           if (ldst_extend (&str) == FAIL)
6434             return;
6435
6436           skip_whitespace (str);
6437
6438           if (*str++ != ']')
6439             {
6440               inst.error = _("missing ]");
6441               return;
6442             }
6443
6444           skip_whitespace (str);
6445
6446           if (*str == '!')
6447             {
6448               if (conflict_reg)
6449                 as_warn (_("%s register same as write-back base"),
6450                          ((inst.instruction & LOAD_BIT)
6451                           ? _("destination") : _("source")));
6452               str++;
6453               inst.instruction |= WRITE_BACK;
6454             }
6455         }
6456     }
6457   else if (*str == '=')
6458     {
6459       if ((inst.instruction & LOAD_BIT) == 0)
6460         {
6461           inst.error = _("invalid pseudo operation");
6462           return;
6463         }
6464
6465       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6466       str++;
6467
6468       skip_whitespace (str);
6469
6470       if (my_get_expression (&inst.reloc.exp, &str))
6471         return;
6472
6473       if (inst.reloc.exp.X_op != O_constant
6474           && inst.reloc.exp.X_op != O_symbol)
6475         {
6476           inst.error = _("constant expression expected");
6477           return;
6478         }
6479
6480       if (inst.reloc.exp.X_op == O_constant)
6481         {
6482           value = validate_immediate (inst.reloc.exp.X_add_number);
6483
6484           if (value != FAIL)
6485             {
6486               /* This can be done with a mov instruction.  */
6487               inst.instruction &= LITERAL_MASK;
6488               inst.instruction |= (INST_IMMEDIATE
6489                                    | (OPCODE_MOV << DATA_OP_SHIFT));
6490               inst.instruction |= value & 0xfff;
6491               end_of_line (str);
6492               return;
6493             }
6494
6495           value = validate_immediate (~inst.reloc.exp.X_add_number);
6496
6497           if (value != FAIL)
6498             {
6499               /* This can be done with a mvn instruction.  */
6500               inst.instruction &= LITERAL_MASK;
6501               inst.instruction |= (INST_IMMEDIATE
6502                                    | (OPCODE_MVN << DATA_OP_SHIFT));
6503               inst.instruction |= value & 0xfff;
6504               end_of_line (str);
6505               return;
6506             }
6507         }
6508
6509       /* Insert into literal pool.  */
6510       if (add_to_lit_pool () == FAIL)
6511         {
6512           if (!inst.error)
6513             inst.error = _("literal pool insertion failed");
6514           return;
6515         }
6516
6517       /* Change the instruction exp to point to the pool.  */
6518       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6519       inst.reloc.pc_rel = 1;
6520       inst.instruction |= (REG_PC << 16);
6521       pre_inc = 1;
6522     }
6523   else
6524     {
6525       if (my_get_expression (&inst.reloc.exp, &str))
6526         return;
6527
6528       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6529 #ifndef TE_WINCE
6530       /* PC rel adjust.  */
6531       inst.reloc.exp.X_add_number -= 8;
6532 #endif
6533       inst.reloc.pc_rel = 1;
6534       inst.instruction |= (REG_PC << 16);
6535       pre_inc = 1;
6536     }
6537
6538   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6539   end_of_line (str);
6540 }
6541
6542 static void
6543 do_ldstt (char * str)
6544 {
6545   int conflict_reg;
6546
6547   skip_whitespace (str);
6548
6549   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6550     {
6551       if (!inst.error)
6552         inst.error = BAD_ARGS;
6553       return;
6554     }
6555
6556   if (skip_past_comma (& str) == FAIL)
6557     {
6558       inst.error = _("address expected");
6559       return;
6560     }
6561
6562   if (*str == '[')
6563     {
6564       int reg;
6565
6566       str++;
6567
6568       skip_whitespace (str);
6569
6570       if ((reg = reg_required_here (&str, 16)) == FAIL)
6571         return;
6572
6573       /* ldrt/strt always use post-indexed addressing, so if the base is
6574          the same as Rd, we warn.  */
6575       if (conflict_reg == reg)
6576         as_warn (_("%s register same as write-back base"),
6577                  ((inst.instruction & LOAD_BIT)
6578                   ? _("destination") : _("source")));
6579
6580       skip_whitespace (str);
6581
6582       if (*str == ']')
6583         {
6584           str ++;
6585
6586           if (skip_past_comma (&str) == SUCCESS)
6587             {
6588               /* [Rn],... (post inc)  */
6589               if (ldst_extend (&str) == FAIL)
6590                 return;
6591             }
6592           else
6593             {
6594               /* [Rn]  */
6595               skip_whitespace (str);
6596
6597               /* Skip a write-back '!'.  */
6598               if (*str == '!')
6599                 str++;
6600
6601               inst.instruction |= INDEX_UP;
6602             }
6603         }
6604       else
6605         {
6606           inst.error = _("post-indexed expression expected");
6607           return;
6608         }
6609     }
6610   else
6611     {
6612       inst.error = _("post-indexed expression expected");
6613       return;
6614     }
6615
6616   end_of_line (str);
6617 }
6618
6619 /* Halfword and signed-byte load/store operations.  */
6620
6621 static void
6622 do_ldstv4 (char * str)
6623 {
6624   int pre_inc = 0;
6625   int conflict_reg;
6626   int value;
6627
6628   skip_whitespace (str);
6629
6630   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6631     {
6632       if (!inst.error)
6633         inst.error = BAD_ARGS;
6634       return;
6635     }
6636
6637   if (skip_past_comma (& str) == FAIL)
6638     {
6639       inst.error = _("address expected");
6640       return;
6641     }
6642
6643   if (*str == '[')
6644     {
6645       int reg;
6646
6647       str++;
6648
6649       skip_whitespace (str);
6650
6651       if ((reg = reg_required_here (&str, 16)) == FAIL)
6652         return;
6653
6654       /* Conflicts can occur on stores as well as loads.  */
6655       conflict_reg = (conflict_reg == reg);
6656
6657       skip_whitespace (str);
6658
6659       if (*str == ']')
6660         {
6661           str ++;
6662
6663           if (skip_past_comma (&str) == SUCCESS)
6664             {
6665               /* [Rn],... (post inc)  */
6666               if (ldst_extend_v4 (&str) == FAIL)
6667                 return;
6668               if (conflict_reg)
6669                 as_warn (_("%s register same as write-back base"),
6670                          ((inst.instruction & LOAD_BIT)
6671                           ? _("destination") : _("source")));
6672             }
6673           else
6674             {
6675               /* [Rn]  */
6676               inst.instruction |= HWOFFSET_IMM;
6677
6678               skip_whitespace (str);
6679
6680               if (*str == '!')
6681                 {
6682                   if (conflict_reg)
6683                     as_warn (_("%s register same as write-back base"),
6684                              ((inst.instruction & LOAD_BIT)
6685                               ? _("destination") : _("source")));
6686                   str++;
6687                   inst.instruction |= WRITE_BACK;
6688                 }
6689
6690               inst.instruction |= INDEX_UP;
6691               pre_inc = 1;
6692             }
6693         }
6694       else
6695         {
6696           /* [Rn,...]  */
6697           if (skip_past_comma (&str) == FAIL)
6698             {
6699               inst.error = _("pre-indexed expression expected");
6700               return;
6701             }
6702
6703           pre_inc = 1;
6704           if (ldst_extend_v4 (&str) == FAIL)
6705             return;
6706
6707           skip_whitespace (str);
6708
6709           if (*str++ != ']')
6710             {
6711               inst.error = _("missing ]");
6712               return;
6713             }
6714
6715           skip_whitespace (str);
6716
6717           if (*str == '!')
6718             {
6719               if (conflict_reg)
6720                 as_warn (_("%s register same as write-back base"),
6721                          ((inst.instruction & LOAD_BIT)
6722                           ? _("destination") : _("source")));
6723               str++;
6724               inst.instruction |= WRITE_BACK;
6725             }
6726         }
6727     }
6728   else if (*str == '=')
6729     {
6730       if ((inst.instruction & LOAD_BIT) == 0)
6731         {
6732           inst.error = _("invalid pseudo operation");
6733           return;
6734         }
6735
6736       /* XXX Does this work correctly for half-word/byte ops?  */
6737       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6738       str++;
6739
6740       skip_whitespace (str);
6741
6742       if (my_get_expression (&inst.reloc.exp, &str))
6743         return;
6744
6745       if (inst.reloc.exp.X_op != O_constant
6746           && inst.reloc.exp.X_op != O_symbol)
6747         {
6748           inst.error = _("constant expression expected");
6749           return;
6750         }
6751
6752       if (inst.reloc.exp.X_op == O_constant)
6753         {
6754           value = validate_immediate (inst.reloc.exp.X_add_number);
6755
6756           if (value != FAIL)
6757             {
6758               /* This can be done with a mov instruction.  */
6759               inst.instruction &= LITERAL_MASK;
6760               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6761               inst.instruction |= value & 0xfff;
6762               end_of_line (str);
6763               return;
6764             }
6765
6766           value = validate_immediate (~ inst.reloc.exp.X_add_number);
6767
6768           if (value != FAIL)
6769             {
6770               /* This can be done with a mvn instruction.  */
6771               inst.instruction &= LITERAL_MASK;
6772               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6773               inst.instruction |= value & 0xfff;
6774               end_of_line (str);
6775               return;
6776             }
6777         }
6778
6779       /* Insert into literal pool.  */
6780       if (add_to_lit_pool () == FAIL)
6781         {
6782           if (!inst.error)
6783             inst.error = _("literal pool insertion failed");
6784           return;
6785         }
6786
6787       /* Change the instruction exp to point to the pool.  */
6788       inst.instruction |= HWOFFSET_IMM;
6789       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6790       inst.reloc.pc_rel = 1;
6791       inst.instruction |= (REG_PC << 16);
6792       pre_inc = 1;
6793     }
6794   else
6795     {
6796       if (my_get_expression (&inst.reloc.exp, &str))
6797         return;
6798
6799       inst.instruction |= HWOFFSET_IMM;
6800       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6801 #ifndef TE_WINCE
6802       /* PC rel adjust.  */
6803       inst.reloc.exp.X_add_number -= 8;
6804 #endif
6805       inst.reloc.pc_rel = 1;
6806       inst.instruction |= (REG_PC << 16);
6807       pre_inc = 1;
6808     }
6809
6810   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6811   end_of_line (str);
6812 }
6813
6814 static void
6815 do_ldsttv4 (char * str)
6816 {
6817   int conflict_reg;
6818
6819   skip_whitespace (str);
6820
6821   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6822     {
6823       if (!inst.error)
6824         inst.error = BAD_ARGS;
6825       return;
6826     }
6827
6828   if (skip_past_comma (& str) == FAIL)
6829     {
6830       inst.error = _("address expected");
6831       return;
6832     }
6833
6834   if (*str == '[')
6835     {
6836       int reg;
6837
6838       str++;
6839
6840       skip_whitespace (str);
6841
6842       if ((reg = reg_required_here (&str, 16)) == FAIL)
6843         return;
6844
6845       /* ldrt/strt always use post-indexed addressing, so if the base is
6846          the same as Rd, we warn.  */
6847       if (conflict_reg == reg)
6848         as_warn (_("%s register same as write-back base"),
6849                  ((inst.instruction & LOAD_BIT)
6850                   ? _("destination") : _("source")));
6851
6852       skip_whitespace (str);
6853
6854       if (*str == ']')
6855         {
6856           str ++;
6857
6858           if (skip_past_comma (&str) == SUCCESS)
6859             {
6860               /* [Rn],... (post inc)  */
6861               if (ldst_extend_v4 (&str) == FAIL)
6862                 return;
6863             }
6864           else
6865             {
6866               /* [Rn]  */
6867               skip_whitespace (str);
6868
6869               /* Skip a write-back '!'.  */
6870               if (*str == '!')
6871                 str++;
6872
6873               inst.instruction |= (INDEX_UP|HWOFFSET_IMM);
6874             }
6875         }
6876       else
6877         {
6878           inst.error = _("post-indexed expression expected");
6879           return;
6880         }
6881     }
6882   else
6883     {
6884       inst.error = _("post-indexed expression expected");
6885       return;
6886     }
6887
6888   end_of_line (str);
6889 }
6890
6891
6892 static long
6893 reg_list (char ** strp)
6894 {
6895   char * str = * strp;
6896   long   range = 0;
6897   int    another_range;
6898
6899   /* We come back here if we get ranges concatenated by '+' or '|'.  */
6900   do
6901     {
6902       another_range = 0;
6903
6904       if (*str == '{')
6905         {
6906           int in_range = 0;
6907           int cur_reg = -1;
6908
6909           str++;
6910           do
6911             {
6912               int reg;
6913
6914               skip_whitespace (str);
6915
6916               if ((reg = reg_required_here (& str, -1)) == FAIL)
6917                 return FAIL;
6918
6919               if (in_range)
6920                 {
6921                   int i;
6922
6923                   if (reg <= cur_reg)
6924                     {
6925                       inst.error = _("bad range in register list");
6926                       return FAIL;
6927                     }
6928
6929                   for (i = cur_reg + 1; i < reg; i++)
6930                     {
6931                       if (range & (1 << i))
6932                         as_tsktsk
6933                           (_("Warning: duplicated register (r%d) in register list"),
6934                            i);
6935                       else
6936                         range |= 1 << i;
6937                     }
6938                   in_range = 0;
6939                 }
6940
6941               if (range & (1 << reg))
6942                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6943                            reg);
6944               else if (reg <= cur_reg)
6945                 as_tsktsk (_("Warning: register range not in ascending order"));
6946
6947               range |= 1 << reg;
6948               cur_reg = reg;
6949             }
6950           while (skip_past_comma (&str) != FAIL
6951                  || (in_range = 1, *str++ == '-'));
6952           str--;
6953           skip_whitespace (str);
6954
6955           if (*str++ != '}')
6956             {
6957               inst.error = _("missing `}'");
6958               return FAIL;
6959             }
6960         }
6961       else
6962         {
6963           expressionS expr;
6964
6965           if (my_get_expression (&expr, &str))
6966             return FAIL;
6967
6968           if (expr.X_op == O_constant)
6969             {
6970               if (expr.X_add_number
6971                   != (expr.X_add_number & 0x0000ffff))
6972                 {
6973                   inst.error = _("invalid register mask");
6974                   return FAIL;
6975                 }
6976
6977               if ((range & expr.X_add_number) != 0)
6978                 {
6979                   int regno = range & expr.X_add_number;
6980
6981                   regno &= -regno;
6982                   regno = (1 << regno) - 1;
6983                   as_tsktsk
6984                     (_("Warning: duplicated register (r%d) in register list"),
6985                      regno);
6986                 }
6987
6988               range |= expr.X_add_number;
6989             }
6990           else
6991             {
6992               if (inst.reloc.type != 0)
6993                 {
6994                   inst.error = _("expression too complex");
6995                   return FAIL;
6996                 }
6997
6998               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6999               inst.reloc.type = BFD_RELOC_ARM_MULTI;
7000               inst.reloc.pc_rel = 0;
7001             }
7002         }
7003
7004       skip_whitespace (str);
7005
7006       if (*str == '|' || *str == '+')
7007         {
7008           str++;
7009           another_range = 1;
7010         }
7011     }
7012   while (another_range);
7013
7014   *strp = str;
7015   return range;
7016 }
7017
7018 static void
7019 do_ldmstm (char * str)
7020 {
7021   int base_reg;
7022   long range;
7023
7024   skip_whitespace (str);
7025
7026   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
7027     return;
7028
7029   if (base_reg == REG_PC)
7030     {
7031       inst.error = _("r15 not allowed as base register");
7032       return;
7033     }
7034
7035   skip_whitespace (str);
7036
7037   if (*str == '!')
7038     {
7039       inst.instruction |= WRITE_BACK;
7040       str++;
7041     }
7042
7043   if (skip_past_comma (&str) == FAIL
7044       || (range = reg_list (&str)) == FAIL)
7045     {
7046       if (! inst.error)
7047         inst.error = BAD_ARGS;
7048       return;
7049     }
7050
7051   if (*str == '^')
7052     {
7053       str++;
7054       inst.instruction |= LDM_TYPE_2_OR_3;
7055     }
7056
7057   if (inst.instruction & WRITE_BACK)
7058     {
7059       /* Check for unpredictable uses of writeback.  */
7060       if (inst.instruction & LOAD_BIT)
7061         {
7062           /* Not allowed in LDM type 2.  */
7063           if ((inst.instruction & LDM_TYPE_2_OR_3)
7064               && ((range & (1 << REG_PC)) == 0))
7065             as_warn (_("writeback of base register is UNPREDICTABLE"));
7066           /* Only allowed if base reg not in list for other types.  */
7067           else if (range & (1 << base_reg))
7068             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
7069         }
7070       else /* STM.  */
7071         {
7072           /* Not allowed for type 2.  */
7073           if (inst.instruction & LDM_TYPE_2_OR_3)
7074             as_warn (_("writeback of base register is UNPREDICTABLE"));
7075           /* Only allowed if base reg not in list, or first in list.  */
7076           else if ((range & (1 << base_reg))
7077                    && (range & ((1 << base_reg) - 1)))
7078             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
7079         }
7080     }
7081
7082   inst.instruction |= range;
7083   end_of_line (str);
7084 }
7085
7086 static void
7087 do_smi (char * str)
7088 {
7089   skip_whitespace (str);
7090
7091   /* Allow optional leading '#'.  */
7092   if (is_immediate_prefix (*str))
7093     str++;
7094
7095   if (my_get_expression (& inst.reloc.exp, & str))
7096     return;
7097
7098   inst.reloc.type = BFD_RELOC_ARM_SMI;
7099   inst.reloc.pc_rel = 0;
7100   end_of_line (str);
7101 }
7102
7103 static void
7104 do_swi (char * str)
7105 {
7106   skip_whitespace (str);
7107
7108   /* Allow optional leading '#'.  */
7109   if (is_immediate_prefix (*str))
7110     str++;
7111
7112   if (my_get_expression (& inst.reloc.exp, & str))
7113     return;
7114
7115   inst.reloc.type = BFD_RELOC_ARM_SWI;
7116   inst.reloc.pc_rel = 0;
7117   end_of_line (str);
7118 }
7119
7120 static void
7121 do_swap (char * str)
7122 {
7123   int reg;
7124
7125   skip_whitespace (str);
7126
7127   if ((reg = reg_required_here (&str, 12)) == FAIL)
7128     return;
7129
7130   if (reg == REG_PC)
7131     {
7132       inst.error = _("r15 not allowed in swap");
7133       return;
7134     }
7135
7136   if (skip_past_comma (&str) == FAIL
7137       || (reg = reg_required_here (&str, 0)) == FAIL)
7138     {
7139       if (!inst.error)
7140         inst.error = BAD_ARGS;
7141       return;
7142     }
7143
7144   if (reg == REG_PC)
7145     {
7146       inst.error = _("r15 not allowed in swap");
7147       return;
7148     }
7149
7150   if (skip_past_comma (&str) == FAIL
7151       || *str++ != '[')
7152     {
7153       inst.error = BAD_ARGS;
7154       return;
7155     }
7156
7157   skip_whitespace (str);
7158
7159   if ((reg = reg_required_here (&str, 16)) == FAIL)
7160     return;
7161
7162   if (reg == REG_PC)
7163     {
7164       inst.error = BAD_PC;
7165       return;
7166     }
7167
7168   skip_whitespace (str);
7169
7170   if (*str++ != ']')
7171     {
7172       inst.error = _("missing ]");
7173       return;
7174     }
7175
7176   end_of_line (str);
7177 }
7178
7179 static void
7180 do_branch (char * str)
7181 {
7182   if (my_get_expression (&inst.reloc.exp, &str))
7183     return;
7184
7185 #ifdef OBJ_ELF
7186   {
7187     char * save_in;
7188
7189     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
7190        required for the instruction.  */
7191
7192     /* arm_parse_reloc () works on input_line_pointer.
7193        We actually want to parse the operands to the branch instruction
7194        passed in 'str'.  Save the input pointer and restore it later.  */
7195     save_in = input_line_pointer;
7196     input_line_pointer = str;
7197     if (inst.reloc.exp.X_op == O_symbol
7198         && *str == '('
7199         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
7200       {
7201         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
7202         inst.reloc.pc_rel = 0;
7203         /* Modify str to point to after parsed operands, otherwise
7204            end_of_line() will complain about the (PLT) left in str.  */
7205         str = input_line_pointer;
7206       }
7207     else
7208       {
7209         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
7210         inst.reloc.pc_rel = 1;
7211       }
7212     input_line_pointer = save_in;
7213   }
7214 #else
7215   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
7216   inst.reloc.pc_rel = 1;
7217 #endif /* OBJ_ELF  */
7218
7219   end_of_line (str);
7220 }
7221
7222 static void
7223 do_cdp (char * str)
7224 {
7225   /* Co-processor data operation.
7226      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
7227   skip_whitespace (str);
7228
7229   if (co_proc_number (&str) == FAIL)
7230     {
7231       if (!inst.error)
7232         inst.error = BAD_ARGS;
7233       return;
7234     }
7235
7236   if (skip_past_comma (&str) == FAIL
7237       || cp_opc_expr (&str, 20,4) == FAIL)
7238     {
7239       if (!inst.error)
7240         inst.error = BAD_ARGS;
7241       return;
7242     }
7243
7244   if (skip_past_comma (&str) == FAIL
7245       || cp_reg_required_here (&str, 12) == FAIL)
7246     {
7247       if (!inst.error)
7248         inst.error = BAD_ARGS;
7249       return;
7250     }
7251
7252   if (skip_past_comma (&str) == FAIL
7253       || cp_reg_required_here (&str, 16) == FAIL)
7254     {
7255       if (!inst.error)
7256         inst.error = BAD_ARGS;
7257       return;
7258     }
7259
7260   if (skip_past_comma (&str) == FAIL
7261       || cp_reg_required_here (&str, 0) == FAIL)
7262     {
7263       if (!inst.error)
7264         inst.error = BAD_ARGS;
7265       return;
7266     }
7267
7268   if (skip_past_comma (&str) == SUCCESS)
7269     {
7270       if (cp_opc_expr (&str, 5, 3) == FAIL)
7271         {
7272           if (!inst.error)
7273             inst.error = BAD_ARGS;
7274           return;
7275         }
7276     }
7277
7278   end_of_line (str);
7279 }
7280
7281 static void
7282 do_lstc (char * str)
7283 {
7284   /* Co-processor register load/store.
7285      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
7286
7287   skip_whitespace (str);
7288
7289   if (co_proc_number (&str) == FAIL)
7290     {
7291       if (!inst.error)
7292         inst.error = BAD_ARGS;
7293       return;
7294     }
7295
7296   if (skip_past_comma (&str) == FAIL
7297       || cp_reg_required_here (&str, 12) == FAIL)
7298     {
7299       if (!inst.error)
7300         inst.error = BAD_ARGS;
7301       return;
7302     }
7303
7304   if (skip_past_comma (&str) == FAIL
7305       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7306     {
7307       if (! inst.error)
7308         inst.error = BAD_ARGS;
7309       return;
7310     }
7311
7312   end_of_line (str);
7313 }
7314
7315 static void
7316 do_co_reg (char * str)
7317 {
7318   /* Co-processor register transfer.
7319      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
7320
7321   skip_whitespace (str);
7322
7323   if (co_proc_number (&str) == FAIL)
7324     {
7325       if (!inst.error)
7326         inst.error = BAD_ARGS;
7327       return;
7328     }
7329
7330   if (skip_past_comma (&str) == FAIL
7331       || cp_opc_expr (&str, 21, 3) == FAIL)
7332     {
7333       if (!inst.error)
7334         inst.error = BAD_ARGS;
7335       return;
7336     }
7337
7338   if (skip_past_comma (&str) == FAIL
7339       || reg_required_here (&str, 12) == FAIL)
7340     {
7341       if (!inst.error)
7342         inst.error = BAD_ARGS;
7343       return;
7344     }
7345
7346   if (skip_past_comma (&str) == FAIL
7347       || cp_reg_required_here (&str, 16) == FAIL)
7348     {
7349       if (!inst.error)
7350         inst.error = BAD_ARGS;
7351       return;
7352     }
7353
7354   if (skip_past_comma (&str) == FAIL
7355       || cp_reg_required_here (&str, 0) == FAIL)
7356     {
7357       if (!inst.error)
7358         inst.error = BAD_ARGS;
7359       return;
7360     }
7361
7362   if (skip_past_comma (&str) == SUCCESS)
7363     {
7364       if (cp_opc_expr (&str, 5, 3) == FAIL)
7365         {
7366           if (!inst.error)
7367             inst.error = BAD_ARGS;
7368           return;
7369         }
7370     }
7371
7372   end_of_line (str);
7373 }
7374
7375 static void
7376 do_fpa_ctrl (char * str)
7377 {
7378   /* FP control registers.
7379      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
7380
7381   skip_whitespace (str);
7382
7383   if (reg_required_here (&str, 12) == FAIL)
7384     {
7385       if (!inst.error)
7386         inst.error = BAD_ARGS;
7387       return;
7388     }
7389
7390   end_of_line (str);
7391 }
7392
7393 static void
7394 do_fpa_ldst (char * str)
7395 {
7396   skip_whitespace (str);
7397
7398   if (fp_reg_required_here (&str, 12) == FAIL)
7399     {
7400       if (!inst.error)
7401         inst.error = BAD_ARGS;
7402       return;
7403     }
7404
7405   if (skip_past_comma (&str) == FAIL
7406       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7407     {
7408       if (!inst.error)
7409         inst.error = BAD_ARGS;
7410       return;
7411     }
7412
7413   end_of_line (str);
7414 }
7415
7416 static void
7417 do_fpa_ldmstm (char * str)
7418 {
7419   int num_regs;
7420
7421   skip_whitespace (str);
7422
7423   if (fp_reg_required_here (&str, 12) == FAIL)
7424     {
7425       if (! inst.error)
7426         inst.error = BAD_ARGS;
7427       return;
7428     }
7429
7430   /* Get Number of registers to transfer.  */
7431   if (skip_past_comma (&str) == FAIL
7432       || my_get_expression (&inst.reloc.exp, &str))
7433     {
7434       if (! inst.error)
7435         inst.error = _("constant expression expected");
7436       return;
7437     }
7438
7439   if (inst.reloc.exp.X_op != O_constant)
7440     {
7441       inst.error = _("constant value required for number of registers");
7442       return;
7443     }
7444
7445   num_regs = inst.reloc.exp.X_add_number;
7446
7447   if (num_regs < 1 || num_regs > 4)
7448     {
7449       inst.error = _("number of registers must be in the range [1:4]");
7450       return;
7451     }
7452
7453   switch (num_regs)
7454     {
7455     case 1:
7456       inst.instruction |= CP_T_X;
7457       break;
7458     case 2:
7459       inst.instruction |= CP_T_Y;
7460       break;
7461     case 3:
7462       inst.instruction |= CP_T_Y | CP_T_X;
7463       break;
7464     case 4:
7465       break;
7466     default:
7467       abort ();
7468     }
7469
7470   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
7471     {
7472       int reg;
7473       int write_back;
7474       int offset;
7475
7476       /* The instruction specified "ea" or "fd", so we can only accept
7477          [Rn]{!}.  The instruction does not really support stacking or
7478          unstacking, so we have to emulate these by setting appropriate
7479          bits and offsets.  */
7480       if (skip_past_comma (&str) == FAIL
7481           || *str != '[')
7482         {
7483           if (! inst.error)
7484             inst.error = BAD_ARGS;
7485           return;
7486         }
7487
7488       str++;
7489       skip_whitespace (str);
7490
7491       if ((reg = reg_required_here (&str, 16)) == FAIL)
7492         return;
7493
7494       skip_whitespace (str);
7495
7496       if (*str != ']')
7497         {
7498           inst.error = BAD_ARGS;
7499           return;
7500         }
7501
7502       str++;
7503       if (*str == '!')
7504         {
7505           write_back = 1;
7506           str++;
7507           if (reg == REG_PC)
7508             {
7509               inst.error =
7510                 _("r15 not allowed as base register with write-back");
7511               return;
7512             }
7513         }
7514       else
7515         write_back = 0;
7516
7517       if (inst.instruction & CP_T_Pre)
7518         {
7519           /* Pre-decrement.  */
7520           offset = 3 * num_regs;
7521           if (write_back)
7522             inst.instruction |= CP_T_WB;
7523         }
7524       else
7525         {
7526           /* Post-increment.  */
7527           if (write_back)
7528             {
7529               inst.instruction |= CP_T_WB;
7530               offset = 3 * num_regs;
7531             }
7532           else
7533             {
7534               /* No write-back, so convert this into a standard pre-increment
7535                  instruction -- aesthetically more pleasing.  */
7536               inst.instruction |= CP_T_Pre | CP_T_UD;
7537               offset = 0;
7538             }
7539         }
7540
7541       inst.instruction |= offset;
7542     }
7543   else if (skip_past_comma (&str) == FAIL
7544            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7545     {
7546       if (! inst.error)
7547         inst.error = BAD_ARGS;
7548       return;
7549     }
7550
7551   end_of_line (str);
7552 }
7553
7554 static void
7555 do_fpa_dyadic (char * str)
7556 {
7557   skip_whitespace (str);
7558
7559   if (fp_reg_required_here (&str, 12) == FAIL)
7560     {
7561       if (! inst.error)
7562         inst.error = BAD_ARGS;
7563       return;
7564     }
7565
7566   if (skip_past_comma (&str) == FAIL
7567       || fp_reg_required_here (&str, 16) == FAIL)
7568     {
7569       if (! inst.error)
7570         inst.error = BAD_ARGS;
7571       return;
7572     }
7573
7574   if (skip_past_comma (&str) == FAIL
7575       || fp_op2 (&str) == FAIL)
7576     {
7577       if (! inst.error)
7578         inst.error = BAD_ARGS;
7579       return;
7580     }
7581
7582   end_of_line (str);
7583 }
7584
7585 static void
7586 do_fpa_monadic (char * str)
7587 {
7588   skip_whitespace (str);
7589
7590   if (fp_reg_required_here (&str, 12) == FAIL)
7591     {
7592       if (! inst.error)
7593         inst.error = BAD_ARGS;
7594       return;
7595     }
7596
7597   if (skip_past_comma (&str) == FAIL
7598       || fp_op2 (&str) == FAIL)
7599     {
7600       if (! inst.error)
7601         inst.error = BAD_ARGS;
7602       return;
7603     }
7604
7605   end_of_line (str);
7606 }
7607
7608 static void
7609 do_fpa_cmp (char * str)
7610 {
7611   skip_whitespace (str);
7612
7613   if (fp_reg_required_here (&str, 16) == FAIL)
7614     {
7615       if (! inst.error)
7616         inst.error = BAD_ARGS;
7617       return;
7618     }
7619
7620   if (skip_past_comma (&str) == FAIL
7621       || fp_op2 (&str) == FAIL)
7622     {
7623       if (! inst.error)
7624         inst.error = BAD_ARGS;
7625       return;
7626     }
7627
7628   end_of_line (str);
7629 }
7630
7631 static void
7632 do_fpa_from_reg (char * str)
7633 {
7634   skip_whitespace (str);
7635
7636   if (fp_reg_required_here (&str, 16) == FAIL)
7637     {
7638       if (! inst.error)
7639         inst.error = BAD_ARGS;
7640       return;
7641     }
7642
7643   if (skip_past_comma (&str) == FAIL
7644       || reg_required_here (&str, 12) == FAIL)
7645     {
7646       if (! inst.error)
7647         inst.error = BAD_ARGS;
7648       return;
7649     }
7650
7651   end_of_line (str);
7652 }
7653
7654 static void
7655 do_fpa_to_reg (char * str)
7656 {
7657   skip_whitespace (str);
7658
7659   if (reg_required_here (&str, 12) == FAIL)
7660     return;
7661
7662   if (skip_past_comma (&str) == FAIL
7663       || fp_reg_required_here (&str, 0) == FAIL)
7664     {
7665       if (! inst.error)
7666         inst.error = BAD_ARGS;
7667       return;
7668     }
7669
7670   end_of_line (str);
7671 }
7672
7673 /* Encode a VFP SP register number.  */
7674
7675 static void
7676 vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
7677 {
7678   switch (pos)
7679     {
7680     case VFP_REG_Sd:
7681       inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7682       break;
7683
7684     case VFP_REG_Sn:
7685       inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7686       break;
7687
7688     case VFP_REG_Sm:
7689       inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7690       break;
7691
7692     default:
7693       abort ();
7694     }
7695 }
7696
7697 static int
7698 vfp_sp_reg_required_here (char ** str,
7699                           enum vfp_sp_reg_pos pos)
7700 {
7701   int    reg;
7702   char * start = *str;
7703
7704   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7705     {
7706       vfp_sp_encode_reg (reg, pos);
7707       return reg;
7708     }
7709
7710   /* In the few cases where we might be able to accept something else
7711      this error can be overridden.  */
7712   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7713
7714   /* Restore the start point.  */
7715   *str = start;
7716   return FAIL;
7717 }
7718
7719 static int
7720 vfp_dp_reg_required_here (char ** str,
7721                           enum vfp_dp_reg_pos pos)
7722 {
7723   int    reg;
7724   char * start = *str;
7725
7726   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7727     {
7728       switch (pos)
7729         {
7730         case VFP_REG_Dd:
7731           inst.instruction |= reg << 12;
7732           break;
7733
7734         case VFP_REG_Dn:
7735           inst.instruction |= reg << 16;
7736           break;
7737
7738         case VFP_REG_Dm:
7739           inst.instruction |= reg << 0;
7740           break;
7741
7742         default:
7743           abort ();
7744         }
7745       return reg;
7746     }
7747
7748   /* In the few cases where we might be able to accept something else
7749      this error can be overridden.  */
7750   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7751
7752   /* Restore the start point.  */
7753   *str = start;
7754   return FAIL;
7755 }
7756
7757 static void
7758 do_vfp_sp_monadic (char * str)
7759 {
7760   skip_whitespace (str);
7761
7762   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7763     return;
7764
7765   if (skip_past_comma (&str) == FAIL
7766       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7767     {
7768       if (! inst.error)
7769         inst.error = BAD_ARGS;
7770       return;
7771     }
7772
7773   end_of_line (str);
7774 }
7775
7776 static void
7777 do_vfp_dp_monadic (char * str)
7778 {
7779   skip_whitespace (str);
7780
7781   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7782     return;
7783
7784   if (skip_past_comma (&str) == FAIL
7785       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7786     {
7787       if (! inst.error)
7788         inst.error = BAD_ARGS;
7789       return;
7790     }
7791
7792   end_of_line (str);
7793 }
7794
7795 static void
7796 do_vfp_sp_dyadic (char * str)
7797 {
7798   skip_whitespace (str);
7799
7800   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7801     return;
7802
7803   if (skip_past_comma (&str) == FAIL
7804       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7805       || skip_past_comma (&str) == FAIL
7806       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7807     {
7808       if (! inst.error)
7809         inst.error = BAD_ARGS;
7810       return;
7811     }
7812
7813   end_of_line (str);
7814 }
7815
7816 static void
7817 do_vfp_dp_dyadic (char * str)
7818 {
7819   skip_whitespace (str);
7820
7821   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7822     return;
7823
7824   if (skip_past_comma (&str) == FAIL
7825       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7826       || skip_past_comma (&str) == FAIL
7827       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7828     {
7829       if (! inst.error)
7830         inst.error = BAD_ARGS;
7831       return;
7832     }
7833
7834   end_of_line (str);
7835 }
7836
7837 static void
7838 do_vfp_reg_from_sp (char * str)
7839 {
7840   skip_whitespace (str);
7841
7842   if (reg_required_here (&str, 12) == FAIL)
7843     return;
7844
7845   if (skip_past_comma (&str) == FAIL
7846       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7847     {
7848       if (! inst.error)
7849         inst.error = BAD_ARGS;
7850       return;
7851     }
7852
7853   end_of_line (str);
7854 }
7855
7856 /* Parse a VFP register list.  If the string is invalid return FAIL.
7857    Otherwise return the number of registers, and set PBASE to the first
7858    register.  Double precision registers are matched if DP is nonzero.  */
7859
7860 static int
7861 vfp_parse_reg_list (char **str, int *pbase, int dp)
7862 {
7863   int base_reg;
7864   int new_base;
7865   int regtype;
7866   int max_regs;
7867   int count = 0;
7868   int warned = 0;
7869   unsigned long mask = 0;
7870   int i;
7871
7872   if (**str != '{')
7873     return FAIL;
7874
7875   (*str)++;
7876   skip_whitespace (*str);
7877
7878   if (dp)
7879     {
7880       regtype = REG_TYPE_DN;
7881       max_regs = 16;
7882     }
7883   else
7884     {
7885       regtype = REG_TYPE_SN;
7886       max_regs = 32;
7887     }
7888
7889   base_reg = max_regs;
7890
7891   do
7892     {
7893       new_base = arm_reg_parse (str, all_reg_maps[regtype].htab);
7894       if (new_base == FAIL)
7895         {
7896           inst.error = _(all_reg_maps[regtype].expected);
7897           return FAIL;
7898         }
7899
7900       if (new_base < base_reg)
7901         base_reg = new_base;
7902
7903       if (mask & (1 << new_base))
7904         {
7905           inst.error = _("invalid register list");
7906           return FAIL;
7907         }
7908
7909       if ((mask >> new_base) != 0 && ! warned)
7910         {
7911           as_tsktsk (_("register list not in ascending order"));
7912           warned = 1;
7913         }
7914
7915       mask |= 1 << new_base;
7916       count++;
7917
7918       skip_whitespace (*str);
7919
7920       if (**str == '-') /* We have the start of a range expression */
7921         {
7922           int high_range;
7923
7924           (*str)++;
7925
7926           if ((high_range
7927                = arm_reg_parse (str, all_reg_maps[regtype].htab))
7928               == FAIL)
7929             {
7930               inst.error = _(all_reg_maps[regtype].expected);
7931               return FAIL;
7932             }
7933
7934           if (high_range <= new_base)
7935             {
7936               inst.error = _("register range not in ascending order");
7937               return FAIL;
7938             }
7939
7940           for (new_base++; new_base <= high_range; new_base++)
7941             {
7942               if (mask & (1 << new_base))
7943                 {
7944                   inst.error = _("invalid register list");
7945                   return FAIL;
7946                 }
7947
7948               mask |= 1 << new_base;
7949               count++;
7950             }
7951         }
7952     }
7953   while (skip_past_comma (str) != FAIL);
7954
7955   (*str)++;
7956
7957   /* Sanity check -- should have raised a parse error above.  */
7958   if (count == 0 || count > max_regs)
7959     abort ();
7960
7961   *pbase = base_reg;
7962
7963   /* Final test -- the registers must be consecutive.  */
7964   mask >>= base_reg;
7965   for (i = 0; i < count; i++)
7966     {
7967       if ((mask & (1u << i)) == 0)
7968         {
7969           inst.error = _("non-contiguous register range");
7970           return FAIL;
7971         }
7972     }
7973
7974   return count;
7975 }
7976
7977 static void
7978 do_vfp_reg2_from_sp2 (char * str)
7979 {
7980   int reg;
7981
7982   skip_whitespace (str);
7983
7984   if (reg_required_here (&str, 12) == FAIL
7985       || skip_past_comma (&str) == FAIL
7986       || reg_required_here (&str, 16) == FAIL
7987       || skip_past_comma (&str) == FAIL)
7988     {
7989       if (! inst.error)
7990         inst.error = BAD_ARGS;
7991       return;
7992     }
7993
7994   /* We require exactly two consecutive SP registers.  */
7995   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7996     {
7997       if (! inst.error)
7998         inst.error = _("only two consecutive VFP SP registers allowed here");
7999     }
8000   vfp_sp_encode_reg (reg, VFP_REG_Sm);
8001
8002   end_of_line (str);
8003 }
8004
8005 static void
8006 do_vfp_sp_from_reg (char * str)
8007 {
8008   skip_whitespace (str);
8009
8010   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8011     return;
8012
8013   if (skip_past_comma (&str) == FAIL
8014       || reg_required_here (&str, 12) == FAIL)
8015     {
8016       if (! inst.error)
8017         inst.error = BAD_ARGS;
8018       return;
8019     }
8020
8021   end_of_line (str);
8022 }
8023
8024 static void
8025 do_vfp_sp2_from_reg2 (char * str)
8026 {
8027   int reg;
8028
8029   skip_whitespace (str);
8030
8031   /* We require exactly two consecutive SP registers.  */
8032   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
8033     {
8034       if (! inst.error)
8035         inst.error = _("only two consecutive VFP SP registers allowed here");
8036     }
8037   vfp_sp_encode_reg (reg, VFP_REG_Sm);
8038
8039   if (skip_past_comma (&str) == FAIL
8040       || reg_required_here (&str, 12) == FAIL
8041       || skip_past_comma (&str) == FAIL
8042       || reg_required_here (&str, 16) == FAIL)
8043     {
8044       if (! inst.error)
8045         inst.error = BAD_ARGS;
8046       return;
8047     }
8048
8049   end_of_line (str);
8050 }
8051
8052 static void
8053 do_vfp_reg_from_dp (char * str)
8054 {
8055   skip_whitespace (str);
8056
8057   if (reg_required_here (&str, 12) == FAIL)
8058     return;
8059
8060   if (skip_past_comma (&str) == FAIL
8061       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
8062     {
8063       if (! inst.error)
8064         inst.error = BAD_ARGS;
8065       return;
8066     }
8067
8068   end_of_line (str);
8069 }
8070
8071 static void
8072 do_vfp_reg2_from_dp (char * str)
8073 {
8074   skip_whitespace (str);
8075
8076   if (reg_required_here (&str, 12) == FAIL)
8077     return;
8078
8079   if (skip_past_comma (&str) == FAIL
8080       || reg_required_here (&str, 16) == FAIL
8081       || skip_past_comma (&str) == FAIL
8082       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8083     {
8084       if (! inst.error)
8085         inst.error = BAD_ARGS;
8086       return;
8087     }
8088
8089   end_of_line (str);
8090 }
8091
8092 static void
8093 do_vfp_dp_from_reg (char * str)
8094 {
8095   skip_whitespace (str);
8096
8097   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
8098     return;
8099
8100   if (skip_past_comma (&str) == FAIL
8101       || reg_required_here (&str, 12) == FAIL)
8102     {
8103       if (! inst.error)
8104         inst.error = BAD_ARGS;
8105       return;
8106     }
8107
8108   end_of_line (str);
8109 }
8110
8111 static void
8112 do_vfp_dp_from_reg2 (char * str)
8113 {
8114   skip_whitespace (str);
8115
8116   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8117     return;
8118
8119   if (skip_past_comma (&str) == FAIL
8120       || reg_required_here (&str, 12) == FAIL
8121       || skip_past_comma (&str) == FAIL
8122       || reg_required_here (&str, 16) == FAIL)
8123     {
8124       if (! inst.error)
8125         inst.error = BAD_ARGS;
8126       return;
8127     }
8128
8129   end_of_line (str);
8130 }
8131
8132 static const struct vfp_reg *
8133 vfp_psr_parse (char ** str)
8134 {
8135   char *start = *str;
8136   char  c;
8137   char *p;
8138   const struct vfp_reg *vreg;
8139
8140   p = start;
8141
8142   /* Find the end of the current token.  */
8143   do
8144     {
8145       c = *p++;
8146     }
8147   while (ISALPHA (c));
8148
8149   /* Mark it.  */
8150   *--p = 0;
8151
8152   for (vreg = vfp_regs + 0;
8153        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
8154        vreg++)
8155     {
8156       if (streq (start, vreg->name))
8157         {
8158           *p = c;
8159           *str = p;
8160           return vreg;
8161         }
8162     }
8163
8164   *p = c;
8165   return NULL;
8166 }
8167
8168 static int
8169 vfp_psr_required_here (char ** str)
8170 {
8171   char *start = *str;
8172   const struct vfp_reg *vreg;
8173
8174   vreg = vfp_psr_parse (str);
8175
8176   if (vreg)
8177     {
8178       inst.instruction |= vreg->regno;
8179       return SUCCESS;
8180     }
8181
8182   inst.error = _("VFP system register expected");
8183
8184   *str = start;
8185   return FAIL;
8186 }
8187
8188 static void
8189 do_vfp_reg_from_ctrl (char * str)
8190 {
8191   skip_whitespace (str);
8192
8193   if (reg_required_here (&str, 12) == FAIL)
8194     return;
8195
8196   if (skip_past_comma (&str) == FAIL
8197       || vfp_psr_required_here (&str) == FAIL)
8198     {
8199       if (! inst.error)
8200         inst.error = BAD_ARGS;
8201       return;
8202     }
8203
8204   end_of_line (str);
8205 }
8206
8207 static void
8208 do_vfp_ctrl_from_reg (char * str)
8209 {
8210   skip_whitespace (str);
8211
8212   if (vfp_psr_required_here (&str) == FAIL)
8213     return;
8214
8215   if (skip_past_comma (&str) == FAIL
8216       || reg_required_here (&str, 12) == FAIL)
8217     {
8218       if (! inst.error)
8219         inst.error = BAD_ARGS;
8220       return;
8221     }
8222
8223   end_of_line (str);
8224 }
8225
8226 static void
8227 do_vfp_sp_ldst (char * str)
8228 {
8229   skip_whitespace (str);
8230
8231   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8232     {
8233       if (!inst.error)
8234         inst.error = BAD_ARGS;
8235       return;
8236     }
8237
8238   if (skip_past_comma (&str) == FAIL
8239       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8240     {
8241       if (!inst.error)
8242         inst.error = BAD_ARGS;
8243       return;
8244     }
8245
8246   end_of_line (str);
8247 }
8248
8249 static void
8250 do_vfp_dp_ldst (char * str)
8251 {
8252   skip_whitespace (str);
8253
8254   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8255     {
8256       if (!inst.error)
8257         inst.error = BAD_ARGS;
8258       return;
8259     }
8260
8261   if (skip_past_comma (&str) == FAIL
8262       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8263     {
8264       if (!inst.error)
8265         inst.error = BAD_ARGS;
8266       return;
8267     }
8268
8269   end_of_line (str);
8270 }
8271
8272
8273 static void
8274 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
8275 {
8276   int count;
8277   int reg;
8278
8279   skip_whitespace (str);
8280
8281   if (reg_required_here (&str, 16) == FAIL)
8282     return;
8283
8284   skip_whitespace (str);
8285
8286   if (*str == '!')
8287     {
8288       inst.instruction |= WRITE_BACK;
8289       str++;
8290     }
8291   else if (ldstm_type != VFP_LDSTMIA)
8292     {
8293       inst.error = _("this addressing mode requires base-register writeback");
8294       return;
8295     }
8296
8297   if (skip_past_comma (&str) == FAIL
8298       || (count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
8299     {
8300       if (!inst.error)
8301         inst.error = BAD_ARGS;
8302       return;
8303     }
8304   vfp_sp_encode_reg (reg, VFP_REG_Sd);
8305
8306   inst.instruction |= count;
8307   end_of_line (str);
8308 }
8309
8310 static void
8311 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
8312 {
8313   int count;
8314   int reg;
8315
8316   skip_whitespace (str);
8317
8318   if (reg_required_here (&str, 16) == FAIL)
8319     return;
8320
8321   skip_whitespace (str);
8322
8323   if (*str == '!')
8324     {
8325       inst.instruction |= WRITE_BACK;
8326       str++;
8327     }
8328   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
8329     {
8330       inst.error = _("this addressing mode requires base-register writeback");
8331       return;
8332     }
8333
8334   if (skip_past_comma (&str) == FAIL
8335       || (count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
8336     {
8337       if (!inst.error)
8338         inst.error = BAD_ARGS;
8339       return;
8340     }
8341
8342   count <<= 1;
8343   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
8344     count += 1;
8345
8346   inst.instruction |= (reg << 12) | count;
8347   end_of_line (str);
8348 }
8349
8350 static void
8351 do_vfp_sp_ldstmia (char * str)
8352 {
8353   vfp_sp_ldstm (str, VFP_LDSTMIA);
8354 }
8355
8356 static void
8357 do_vfp_sp_ldstmdb (char * str)
8358 {
8359   vfp_sp_ldstm (str, VFP_LDSTMDB);
8360 }
8361
8362 static void
8363 do_vfp_dp_ldstmia (char * str)
8364 {
8365   vfp_dp_ldstm (str, VFP_LDSTMIA);
8366 }
8367
8368 static void
8369 do_vfp_dp_ldstmdb (char * str)
8370 {
8371   vfp_dp_ldstm (str, VFP_LDSTMDB);
8372 }
8373
8374 static void
8375 do_vfp_xp_ldstmia (char *str)
8376 {
8377   vfp_dp_ldstm (str, VFP_LDSTMIAX);
8378 }
8379
8380 static void
8381 do_vfp_xp_ldstmdb (char * str)
8382 {
8383   vfp_dp_ldstm (str, VFP_LDSTMDBX);
8384 }
8385
8386 static void
8387 do_vfp_sp_compare_z (char * str)
8388 {
8389   skip_whitespace (str);
8390
8391   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8392     {
8393       if (!inst.error)
8394         inst.error = BAD_ARGS;
8395       return;
8396     }
8397
8398   end_of_line (str);
8399 }
8400
8401 static void
8402 do_vfp_dp_compare_z (char * str)
8403 {
8404   skip_whitespace (str);
8405
8406   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8407     {
8408       if (!inst.error)
8409         inst.error = BAD_ARGS;
8410       return;
8411     }
8412
8413   end_of_line (str);
8414 }
8415
8416 static void
8417 do_vfp_dp_sp_cvt (char * str)
8418 {
8419   skip_whitespace (str);
8420
8421   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8422     return;
8423
8424   if (skip_past_comma (&str) == FAIL
8425       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8426     {
8427       if (! inst.error)
8428         inst.error = BAD_ARGS;
8429       return;
8430     }
8431
8432   end_of_line (str);
8433 }
8434
8435 static void
8436 do_vfp_sp_dp_cvt (char * str)
8437 {
8438   skip_whitespace (str);
8439
8440   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8441     return;
8442
8443   if (skip_past_comma (&str) == FAIL
8444       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8445     {
8446       if (! inst.error)
8447         inst.error = BAD_ARGS;
8448       return;
8449     }
8450
8451   end_of_line (str);
8452 }
8453
8454 /* Thumb specific routines.  */
8455
8456 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8457    was SUB.  */
8458
8459 static void
8460 thumb_add_sub (char * str, int subtract)
8461 {
8462   int Rd, Rs, Rn = FAIL;
8463
8464   skip_whitespace (str);
8465
8466   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8467       || skip_past_comma (&str) == FAIL)
8468     {
8469       if (! inst.error)
8470         inst.error = BAD_ARGS;
8471       return;
8472     }
8473
8474   if (is_immediate_prefix (*str))
8475     {
8476       Rs = Rd;
8477       str++;
8478       if (my_get_expression (&inst.reloc.exp, &str))
8479         return;
8480     }
8481   else
8482     {
8483       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8484         return;
8485
8486       if (skip_past_comma (&str) == FAIL)
8487         {
8488           /* Two operand format, shuffle the registers
8489              and pretend there are 3.  */
8490           Rn = Rs;
8491           Rs = Rd;
8492         }
8493       else if (is_immediate_prefix (*str))
8494         {
8495           str++;
8496           if (my_get_expression (&inst.reloc.exp, &str))
8497             return;
8498         }
8499       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8500         return;
8501     }
8502
8503   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8504      for the latter case, EXPR contains the immediate that was found.  */
8505   if (Rn != FAIL)
8506     {
8507       /* All register format.  */
8508       if (Rd > 7 || Rs > 7 || Rn > 7)
8509         {
8510           if (Rs != Rd)
8511             {
8512               inst.error = _("dest and source1 must be the same register");
8513               return;
8514             }
8515
8516           /* Can't do this for SUB.  */
8517           if (subtract)
8518             {
8519               inst.error = _("subtract valid only on lo regs");
8520               return;
8521             }
8522
8523           inst.instruction = (T_OPCODE_ADD_HI
8524                               | (Rd > 7 ? THUMB_H1 : 0)
8525                               | (Rn > 7 ? THUMB_H2 : 0));
8526           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8527         }
8528       else
8529         {
8530           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8531           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8532         }
8533     }
8534   else
8535     {
8536       /* Immediate expression, now things start to get nasty.  */
8537
8538       /* First deal with HI regs, only very restricted cases allowed:
8539          Adjusting SP, and using PC or SP to get an address.  */
8540       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8541           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8542         {
8543           inst.error = _("invalid Hi register with immediate");
8544           return;
8545         }
8546
8547       if (inst.reloc.exp.X_op != O_constant)
8548         {
8549           /* Value isn't known yet, all we can do is store all the fragments
8550              we know about in the instruction and let the reloc hacking
8551              work it all out.  */
8552           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8553           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8554         }
8555       else
8556         {
8557           int offset = inst.reloc.exp.X_add_number;
8558
8559           if (subtract)
8560             offset = - offset;
8561
8562           if (offset < 0)
8563             {
8564               offset = - offset;
8565               subtract = 1;
8566
8567               /* Quick check, in case offset is MIN_INT.  */
8568               if (offset < 0)
8569                 {
8570                   inst.error = _("immediate value out of range");
8571                   return;
8572                 }
8573             }
8574           /* Note - you cannot convert a subtract of 0 into an
8575              add of 0 because the carry flag is set differently.  */
8576           else if (offset > 0)
8577             subtract = 0;
8578
8579           if (Rd == REG_SP)
8580             {
8581               if (offset & ~0x1fc)
8582                 {
8583                   inst.error = _("invalid immediate value for stack adjust");
8584                   return;
8585                 }
8586               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8587               inst.instruction |= offset >> 2;
8588             }
8589           else if (Rs == REG_PC || Rs == REG_SP)
8590             {
8591               if (subtract
8592                   || (offset & ~0x3fc))
8593                 {
8594                   inst.error = _("invalid immediate for address calculation");
8595                   return;
8596                 }
8597               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8598                                   : T_OPCODE_ADD_SP);
8599               inst.instruction |= (Rd << 8) | (offset >> 2);
8600             }
8601           else if (Rs == Rd)
8602             {
8603               if (offset & ~0xff)
8604                 {
8605                   inst.error = _("immediate value out of range");
8606                   return;
8607                 }
8608               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8609               inst.instruction |= (Rd << 8) | offset;
8610             }
8611           else
8612             {
8613               if (offset & ~0x7)
8614                 {
8615                   inst.error = _("immediate value out of range");
8616                   return;
8617                 }
8618               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8619               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8620             }
8621         }
8622     }
8623
8624   end_of_line (str);
8625 }
8626
8627 static void
8628 thumb_shift (char * str, int shift)
8629 {
8630   int Rd, Rs, Rn = FAIL;
8631
8632   skip_whitespace (str);
8633
8634   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8635       || skip_past_comma (&str) == FAIL)
8636     {
8637       if (! inst.error)
8638         inst.error = BAD_ARGS;
8639       return;
8640     }
8641
8642   if (is_immediate_prefix (*str))
8643     {
8644       /* Two operand immediate format, set Rs to Rd.  */
8645       Rs = Rd;
8646       str ++;
8647       if (my_get_expression (&inst.reloc.exp, &str))
8648         return;
8649     }
8650   else
8651     {
8652       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8653         return;
8654
8655       if (skip_past_comma (&str) == FAIL)
8656         {
8657           /* Two operand format, shuffle the registers
8658              and pretend there are 3.  */
8659           Rn = Rs;
8660           Rs = Rd;
8661         }
8662       else if (is_immediate_prefix (*str))
8663         {
8664           str++;
8665           if (my_get_expression (&inst.reloc.exp, &str))
8666             return;
8667         }
8668       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8669         return;
8670     }
8671
8672   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8673      for the latter case, EXPR contains the immediate that was found.  */
8674
8675   if (Rn != FAIL)
8676     {
8677       if (Rs != Rd)
8678         {
8679           inst.error = _("source1 and dest must be same register");
8680           return;
8681         }
8682
8683       switch (shift)
8684         {
8685         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8686         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8687         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8688         }
8689
8690       inst.instruction |= Rd | (Rn << 3);
8691     }
8692   else
8693     {
8694       switch (shift)
8695         {
8696         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8697         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8698         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8699         }
8700
8701       if (inst.reloc.exp.X_op != O_constant)
8702         {
8703           /* Value isn't known yet, create a dummy reloc and let reloc
8704              hacking fix it up.  */
8705           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8706         }
8707       else
8708         {
8709           unsigned shift_value = inst.reloc.exp.X_add_number;
8710
8711           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8712             {
8713               inst.error = _("invalid immediate for shift");
8714               return;
8715             }
8716
8717           /* Shifts of zero are handled by converting to LSL.  */
8718           if (shift_value == 0)
8719             inst.instruction = T_OPCODE_LSL_I;
8720
8721           /* Shifts of 32 are encoded as a shift of zero.  */
8722           if (shift_value == 32)
8723             shift_value = 0;
8724
8725           inst.instruction |= shift_value << 6;
8726         }
8727
8728       inst.instruction |= Rd | (Rs << 3);
8729     }
8730
8731   end_of_line (str);
8732 }
8733
8734 static void
8735 thumb_load_store (char * str, int load_store, int size)
8736 {
8737   int Rd, Rb, Ro = FAIL;
8738
8739   skip_whitespace (str);
8740
8741   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8742       || skip_past_comma (&str) == FAIL)
8743     {
8744       if (! inst.error)
8745         inst.error = BAD_ARGS;
8746       return;
8747     }
8748
8749   if (*str == '[')
8750     {
8751       str++;
8752       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8753         return;
8754
8755       if (skip_past_comma (&str) != FAIL)
8756         {
8757           if (is_immediate_prefix (*str))
8758             {
8759               str++;
8760               if (my_get_expression (&inst.reloc.exp, &str))
8761                 return;
8762             }
8763           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8764             return;
8765         }
8766       else
8767         {
8768           inst.reloc.exp.X_op = O_constant;
8769           inst.reloc.exp.X_add_number = 0;
8770         }
8771
8772       if (*str != ']')
8773         {
8774           inst.error = _("expected ']'");
8775           return;
8776         }
8777       str++;
8778     }
8779   else if (*str == '=')
8780     {
8781       if (load_store != THUMB_LOAD)
8782         {
8783           inst.error = _("invalid pseudo operation");
8784           return;
8785         }
8786
8787       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
8788       str++;
8789
8790       skip_whitespace (str);
8791
8792       if (my_get_expression (& inst.reloc.exp, & str))
8793         return;
8794
8795       end_of_line (str);
8796
8797       if (   inst.reloc.exp.X_op != O_constant
8798           && inst.reloc.exp.X_op != O_symbol)
8799         {
8800           inst.error = "Constant expression expected";
8801           return;
8802         }
8803
8804       if (inst.reloc.exp.X_op == O_constant
8805           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8806         {
8807           /* This can be done with a mov instruction.  */
8808
8809           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
8810           inst.instruction |= inst.reloc.exp.X_add_number;
8811           return;
8812         }
8813
8814       /* Insert into literal pool.  */
8815       if (add_to_lit_pool () == FAIL)
8816         {
8817           if (!inst.error)
8818             inst.error = "literal pool insertion failed";
8819           return;
8820         }
8821
8822       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
8823       inst.reloc.pc_rel = 1;
8824       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
8825       /* Adjust ARM pipeline offset to Thumb.  */
8826       inst.reloc.exp.X_add_number += 4;
8827
8828       return;
8829     }
8830   else
8831     {
8832       if (my_get_expression (&inst.reloc.exp, &str))
8833         return;
8834
8835       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8836       inst.reloc.pc_rel = 1;
8837       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
8838       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8839       end_of_line (str);
8840       return;
8841     }
8842
8843   if (Rb == REG_PC || Rb == REG_SP)
8844     {
8845       if (size != THUMB_WORD)
8846         {
8847           inst.error = _("byte or halfword not valid for base register");
8848           return;
8849         }
8850       else if (Rb == REG_PC && load_store != THUMB_LOAD)
8851         {
8852           inst.error = _("r15 based store not allowed");
8853           return;
8854         }
8855       else if (Ro != FAIL)
8856         {
8857           inst.error = _("invalid base register for register offset");
8858           return;
8859         }
8860
8861       if (Rb == REG_PC)
8862         inst.instruction = T_OPCODE_LDR_PC;
8863       else if (load_store == THUMB_LOAD)
8864         inst.instruction = T_OPCODE_LDR_SP;
8865       else
8866         inst.instruction = T_OPCODE_STR_SP;
8867
8868       inst.instruction |= Rd << 8;
8869       if (inst.reloc.exp.X_op == O_constant)
8870         {
8871           unsigned offset = inst.reloc.exp.X_add_number;
8872
8873           if (offset & ~0x3fc)
8874             {
8875               inst.error = _("invalid offset");
8876               return;
8877             }
8878
8879           inst.instruction |= offset >> 2;
8880         }
8881       else
8882         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8883     }
8884   else if (Rb > 7)
8885     {
8886       inst.error = _("invalid base register in load/store");
8887       return;
8888     }
8889   else if (Ro == FAIL)
8890     {
8891       /* Immediate offset.  */
8892       if (size == THUMB_WORD)
8893         inst.instruction = (load_store == THUMB_LOAD
8894                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8895       else if (size == THUMB_HALFWORD)
8896         inst.instruction = (load_store == THUMB_LOAD
8897                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8898       else
8899         inst.instruction = (load_store == THUMB_LOAD
8900                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8901
8902       inst.instruction |= Rd | (Rb << 3);
8903
8904       if (inst.reloc.exp.X_op == O_constant)
8905         {
8906           unsigned offset = inst.reloc.exp.X_add_number;
8907
8908           if (offset & ~(0x1f << size))
8909             {
8910               inst.error = _("invalid offset");
8911               return;
8912             }
8913           inst.instruction |= (offset >> size) << 6;
8914         }
8915       else
8916         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8917     }
8918   else
8919     {
8920       /* Register offset.  */
8921       if (size == THUMB_WORD)
8922         inst.instruction = (load_store == THUMB_LOAD
8923                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8924       else if (size == THUMB_HALFWORD)
8925         inst.instruction = (load_store == THUMB_LOAD
8926                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8927       else
8928         inst.instruction = (load_store == THUMB_LOAD
8929                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8930
8931       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8932     }
8933
8934   end_of_line (str);
8935 }
8936
8937 /* A register must be given at this point.
8938
8939    Shift is the place to put it in inst.instruction.
8940
8941    Restores input start point on err.
8942    Returns the reg#, or FAIL.  */
8943
8944 static int
8945 mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
8946 {
8947   int   reg;
8948   char *start = *str;
8949
8950   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8951     {
8952       if (shift >= 0)
8953         inst.instruction |= reg << shift;
8954
8955       return reg;
8956     }
8957
8958   /* Restore the start point.  */
8959   *str = start;
8960
8961   /* Try generic coprocessor name if applicable.  */
8962   if (regtype == REG_TYPE_MVF ||
8963       regtype == REG_TYPE_MVD ||
8964       regtype == REG_TYPE_MVFX ||
8965       regtype == REG_TYPE_MVDX)
8966     {
8967       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
8968         {
8969           if (shift >= 0)
8970             inst.instruction |= reg << shift;
8971
8972           return reg;
8973         }
8974
8975       /* Restore the start point.  */
8976       *str = start;
8977     }
8978
8979   /* In the few cases where we might be able to accept something else
8980      this error can be overridden.  */
8981   inst.error = _(all_reg_maps[regtype].expected);
8982
8983   return FAIL;
8984 }
8985
8986 /* Cirrus Maverick Instructions.  */
8987
8988 /* Isnsn like "foo X,Y".  */
8989
8990 static void
8991 do_mav_binops (char * str,
8992                int mode,
8993                enum arm_reg_type reg0,
8994                enum arm_reg_type reg1)
8995 {
8996   int shift0, shift1;
8997
8998   shift0 = mode & 0xff;
8999   shift1 = (mode >> 8) & 0xff;
9000
9001   skip_whitespace (str);
9002
9003   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9004       || skip_past_comma (&str) == FAIL
9005       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
9006     {
9007       if (!inst.error)
9008         inst.error = BAD_ARGS;
9009     }
9010   else
9011     end_of_line (str);
9012 }
9013
9014 /* Isnsn like "foo X,Y,Z".  */
9015
9016 static void
9017 do_mav_triple (char * str,
9018                int mode,
9019                enum arm_reg_type reg0,
9020                enum arm_reg_type reg1,
9021                enum arm_reg_type reg2)
9022 {
9023   int shift0, shift1, shift2;
9024
9025   shift0 = mode & 0xff;
9026   shift1 = (mode >> 8) & 0xff;
9027   shift2 = (mode >> 16) & 0xff;
9028
9029   skip_whitespace (str);
9030
9031   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9032       || skip_past_comma (&str) == FAIL
9033       || mav_reg_required_here (&str, shift1, reg1) == FAIL
9034       || skip_past_comma (&str) == FAIL
9035       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
9036     {
9037       if (!inst.error)
9038         inst.error = BAD_ARGS;
9039     }
9040   else
9041     end_of_line (str);
9042 }
9043
9044 /* Wrapper functions.  */
9045
9046 static void
9047 do_mav_binops_1a (char * str)
9048 {
9049   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
9050 }
9051
9052 static void
9053 do_mav_binops_1b (char * str)
9054 {
9055   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
9056 }
9057
9058 static void
9059 do_mav_binops_1c (char * str)
9060 {
9061   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
9062 }
9063
9064 static void
9065 do_mav_binops_1d (char * str)
9066 {
9067   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
9068 }
9069
9070 static void
9071 do_mav_binops_1e (char * str)
9072 {
9073   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
9074 }
9075
9076 static void
9077 do_mav_binops_1f (char * str)
9078 {
9079   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
9080 }
9081
9082 static void
9083 do_mav_binops_1g (char * str)
9084 {
9085   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
9086 }
9087
9088 static void
9089 do_mav_binops_1h (char * str)
9090 {
9091   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
9092 }
9093
9094 static void
9095 do_mav_binops_1i (char * str)
9096 {
9097   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
9098 }
9099
9100 static void
9101 do_mav_binops_1j (char * str)
9102 {
9103   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
9104 }
9105
9106 static void
9107 do_mav_binops_1k (char * str)
9108 {
9109   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
9110 }
9111
9112 static void
9113 do_mav_binops_1l (char * str)
9114 {
9115   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
9116 }
9117
9118 static void
9119 do_mav_binops_1m (char * str)
9120 {
9121   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
9122 }
9123
9124 static void
9125 do_mav_binops_1n (char * str)
9126 {
9127   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
9128 }
9129
9130 static void
9131 do_mav_binops_1o (char * str)
9132 {
9133   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
9134 }
9135
9136 static void
9137 do_mav_binops_2a (char * str)
9138 {
9139   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
9140 }
9141
9142 static void
9143 do_mav_binops_2b (char * str)
9144 {
9145   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
9146 }
9147
9148 static void
9149 do_mav_binops_2c (char * str)
9150 {
9151   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
9152 }
9153
9154 static void
9155 do_mav_binops_3a (char * str)
9156 {
9157   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
9158 }
9159
9160 static void
9161 do_mav_binops_3b (char * str)
9162 {
9163   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
9164 }
9165
9166 static void
9167 do_mav_binops_3c (char * str)
9168 {
9169   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
9170 }
9171
9172 static void
9173 do_mav_binops_3d (char * str)
9174 {
9175   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
9176 }
9177
9178 static void
9179 do_mav_triple_4a (char * str)
9180 {
9181   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
9182 }
9183
9184 static void
9185 do_mav_triple_4b (char * str)
9186 {
9187   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
9188 }
9189
9190 static void
9191 do_mav_triple_5a (char * str)
9192 {
9193   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
9194 }
9195
9196 static void
9197 do_mav_triple_5b (char * str)
9198 {
9199   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
9200 }
9201
9202 static void
9203 do_mav_triple_5c (char * str)
9204 {
9205   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
9206 }
9207
9208 static void
9209 do_mav_triple_5d (char * str)
9210 {
9211   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
9212 }
9213
9214 static void
9215 do_mav_triple_5e (char * str)
9216 {
9217   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
9218 }
9219
9220 static void
9221 do_mav_triple_5f (char * str)
9222 {
9223   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
9224 }
9225
9226 static void
9227 do_mav_triple_5g (char * str)
9228 {
9229   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
9230 }
9231
9232 static void
9233 do_mav_triple_5h (char * str)
9234 {
9235   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
9236 }
9237
9238 /* Isnsn like "foo W,X,Y,Z".
9239     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
9240
9241 static void
9242 do_mav_quad (char * str,
9243              int mode,
9244              enum arm_reg_type reg0,
9245              enum arm_reg_type reg1,
9246              enum arm_reg_type reg2,
9247              enum arm_reg_type reg3)
9248 {
9249   int shift0, shift1, shift2, shift3;
9250
9251   shift0= mode & 0xff;
9252   shift1 = (mode >> 8) & 0xff;
9253   shift2 = (mode >> 16) & 0xff;
9254   shift3 = (mode >> 24) & 0xff;
9255
9256   skip_whitespace (str);
9257
9258   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9259       || skip_past_comma (&str) == FAIL
9260       || mav_reg_required_here (&str, shift1, reg1) == FAIL
9261       || skip_past_comma (&str) == FAIL
9262       || mav_reg_required_here (&str, shift2, reg2) == FAIL
9263       || skip_past_comma (&str) == FAIL
9264       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
9265     {
9266       if (!inst.error)
9267         inst.error = BAD_ARGS;
9268     }
9269   else
9270     end_of_line (str);
9271 }
9272
9273 static void
9274 do_mav_quad_6a (char * str)
9275 {
9276   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
9277                REG_TYPE_MVFX);
9278 }
9279
9280 static void
9281 do_mav_quad_6b (char * str)
9282 {
9283   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
9284                REG_TYPE_MVFX);
9285 }
9286
9287 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
9288 static void
9289 do_mav_dspsc_1 (char * str)
9290 {
9291   skip_whitespace (str);
9292
9293   /* cfmvsc32.  */
9294   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
9295       || skip_past_comma (&str) == FAIL
9296       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
9297     {
9298       if (!inst.error)
9299         inst.error = BAD_ARGS;
9300
9301       return;
9302     }
9303
9304   end_of_line (str);
9305 }
9306
9307 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
9308 static void
9309 do_mav_dspsc_2 (char * str)
9310 {
9311   skip_whitespace (str);
9312
9313   /* cfmv32sc.  */
9314   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
9315       || skip_past_comma (&str) == FAIL
9316       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
9317     {
9318       if (!inst.error)
9319         inst.error = BAD_ARGS;
9320
9321       return;
9322     }
9323
9324   end_of_line (str);
9325 }
9326
9327 /* Maverick shift immediate instructions.
9328    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
9329    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
9330
9331 static void
9332 do_mav_shift (char * str,
9333               enum arm_reg_type reg0,
9334               enum arm_reg_type reg1)
9335 {
9336   int error;
9337   int imm, neg = 0;
9338
9339   skip_whitespace (str);
9340
9341   error = 0;
9342
9343   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9344       || skip_past_comma (&str) == FAIL
9345       || mav_reg_required_here (&str, 16, reg1) == FAIL
9346       || skip_past_comma  (&str) == FAIL)
9347     {
9348       if (!inst.error)
9349         inst.error = BAD_ARGS;
9350       return;
9351     }
9352
9353   /* Calculate the immediate operand.
9354      The operand is a 7bit signed number.  */
9355   skip_whitespace (str);
9356
9357   if (*str == '#')
9358     ++str;
9359
9360   if (!ISDIGIT (*str) && *str != '-')
9361     {
9362       inst.error = _("expecting immediate, 7bit operand");
9363       return;
9364     }
9365
9366   if (*str == '-')
9367     {
9368       neg = 1;
9369       ++str;
9370     }
9371
9372   for (imm = 0; *str && ISDIGIT (*str); ++str)
9373     imm = imm * 10 + *str - '0';
9374
9375   if (imm > 64)
9376     {
9377       inst.error = _("immediate out of range");
9378       return;
9379     }
9380
9381   /* Make negative imm's into 7bit signed numbers.  */
9382   if (neg)
9383     {
9384       imm = -imm;
9385       imm &= 0x0000007f;
9386     }
9387
9388   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9389      Bits 5-7 of the insn should have bits 4-6 of the immediate.
9390      Bit 4 should be 0.  */
9391   imm = (imm & 0xf) | ((imm & 0x70) << 1);
9392
9393   inst.instruction |= imm;
9394   end_of_line (str);
9395 }
9396
9397 static void
9398 do_mav_shift_1 (char * str)
9399 {
9400   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9401 }
9402
9403 static void
9404 do_mav_shift_2 (char * str)
9405 {
9406   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9407 }
9408
9409 static int
9410 mav_parse_offset (char ** str, int * negative)
9411 {
9412   char * p = *str;
9413   int offset;
9414
9415   *negative = 0;
9416
9417   skip_whitespace (p);
9418
9419   if (*p == '#')
9420     ++p;
9421
9422   if (*p == '-')
9423     {
9424       *negative = 1;
9425       ++p;
9426     }
9427
9428   if (!ISDIGIT (*p))
9429     {
9430       inst.error = _("offset expected");
9431       return 0;
9432     }
9433
9434   for (offset = 0; *p && ISDIGIT (*p); ++p)
9435     offset = offset * 10 + *p - '0';
9436
9437   if (offset > 0x3fc)
9438     {
9439       inst.error = _("offset out of range");
9440       return 0;
9441     }
9442   if (offset & 0x3)
9443     {
9444       inst.error = _("offset not a multiple of 4");
9445       return 0;
9446     }
9447
9448   *str = p;
9449
9450   return *negative ? -offset : offset;
9451 }
9452
9453 /* Maverick load/store instructions.
9454   <insn><cond> CRd,[Rn,<offset>]{!}.
9455   <insn><cond> CRd,[Rn],<offset>.  */
9456
9457 static void
9458 do_mav_ldst (char * str, enum arm_reg_type reg0)
9459 {
9460   int offset, negative;
9461
9462   skip_whitespace (str);
9463
9464   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9465       || skip_past_comma (&str) == FAIL
9466       || *str++ != '['
9467       || reg_required_here (&str, 16) == FAIL)
9468     goto fail_ldst;
9469
9470   if (skip_past_comma (&str) == SUCCESS)
9471     {
9472       /* You are here: "<offset>]{!}".  */
9473       inst.instruction |= PRE_INDEX;
9474
9475       offset = mav_parse_offset (&str, &negative);
9476
9477       if (inst.error)
9478         return;
9479
9480       if (*str++ != ']')
9481         {
9482           inst.error = _("missing ]");
9483           return;
9484         }
9485
9486       if (*str == '!')
9487         {
9488           inst.instruction |= WRITE_BACK;
9489           ++str;
9490         }
9491     }
9492   else
9493     {
9494       /* You are here: "], <offset>".  */
9495       if (*str++ != ']')
9496         {
9497           inst.error = _("missing ]");
9498           return;
9499         }
9500
9501       if (skip_past_comma (&str) == FAIL
9502           || (offset = mav_parse_offset (&str, &negative), inst.error))
9503         goto fail_ldst;
9504
9505       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
9506     }
9507
9508   if (negative)
9509     offset = -offset;
9510   else
9511     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
9512
9513   inst.instruction |= offset >> 2;
9514   end_of_line (str);
9515   return;
9516
9517 fail_ldst:
9518   if (!inst.error)
9519      inst.error = BAD_ARGS;
9520 }
9521
9522 static void
9523 do_mav_ldst_1 (char * str)
9524 {
9525   do_mav_ldst (str, REG_TYPE_MVF);
9526 }
9527
9528 static void
9529 do_mav_ldst_2 (char * str)
9530 {
9531   do_mav_ldst (str, REG_TYPE_MVD);
9532 }
9533
9534 static void
9535 do_mav_ldst_3 (char * str)
9536 {
9537   do_mav_ldst (str, REG_TYPE_MVFX);
9538 }
9539
9540 static void
9541 do_mav_ldst_4 (char * str)
9542 {
9543   do_mav_ldst (str, REG_TYPE_MVDX);
9544 }
9545
9546 static void
9547 do_t_nop (char * str)
9548 {
9549   /* Do nothing.  */
9550   end_of_line (str);
9551 }
9552
9553 /* Handle the Format 4 instructions that do not have equivalents in other
9554    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9555    BIC and MVN.  */
9556
9557 static void
9558 do_t_arit (char * str)
9559 {
9560   int Rd, Rs, Rn;
9561
9562   skip_whitespace (str);
9563
9564   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9565       || skip_past_comma (&str) == FAIL
9566       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9567     {
9568       inst.error = BAD_ARGS;
9569       return;
9570     }
9571
9572   if (skip_past_comma (&str) != FAIL)
9573     {
9574       /* Three operand format not allowed for TST, CMN, NEG and MVN.
9575          (It isn't allowed for CMP either, but that isn't handled by this
9576          function.)  */
9577       if (inst.instruction == T_OPCODE_TST
9578           || inst.instruction == T_OPCODE_CMN
9579           || inst.instruction == T_OPCODE_NEG
9580           || inst.instruction == T_OPCODE_MVN)
9581         {
9582           inst.error = BAD_ARGS;
9583           return;
9584         }
9585
9586       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9587         return;
9588
9589       if (Rs != Rd)
9590         {
9591           inst.error = _("dest and source1 must be the same register");
9592           return;
9593         }
9594       Rs = Rn;
9595     }
9596
9597   if (inst.instruction == T_OPCODE_MUL
9598       && Rs == Rd)
9599     as_tsktsk (_("Rs and Rd must be different in MUL"));
9600
9601   inst.instruction |= Rd | (Rs << 3);
9602   end_of_line (str);
9603 }
9604
9605 static void
9606 do_t_add (char * str)
9607 {
9608   thumb_add_sub (str, 0);
9609 }
9610
9611 static void
9612 do_t_asr (char * str)
9613 {
9614   thumb_shift (str, THUMB_ASR);
9615 }
9616
9617 static void
9618 do_t_branch9 (char * str)
9619 {
9620   if (my_get_expression (&inst.reloc.exp, &str))
9621     return;
9622   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9623   inst.reloc.pc_rel = 1;
9624   end_of_line (str);
9625 }
9626
9627 static void
9628 do_t_branch12 (char * str)
9629 {
9630   if (my_get_expression (&inst.reloc.exp, &str))
9631     return;
9632   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9633   inst.reloc.pc_rel = 1;
9634   end_of_line (str);
9635 }
9636
9637 /* Find the real, Thumb encoded start of a Thumb function.  */
9638
9639 static symbolS *
9640 find_real_start (symbolS * symbolP)
9641 {
9642   char *       real_start;
9643   const char * name = S_GET_NAME (symbolP);
9644   symbolS *    new_target;
9645
9646   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
9647 #define STUB_NAME ".real_start_of"
9648
9649   if (name == NULL)
9650     abort ();
9651
9652   /* Names that start with '.' are local labels, not function entry points.
9653      The compiler may generate BL instructions to these labels because it
9654      needs to perform a branch to a far away location.  */
9655   if (name[0] == '.')
9656     return symbolP;
9657
9658   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9659   sprintf (real_start, "%s%s", STUB_NAME, name);
9660
9661   new_target = symbol_find (real_start);
9662
9663   if (new_target == NULL)
9664     {
9665       as_warn ("Failed to find real start of function: %s\n", name);
9666       new_target = symbolP;
9667     }
9668
9669   free (real_start);
9670
9671   return new_target;
9672 }
9673
9674 static void
9675 do_t_branch23 (char * str)
9676 {
9677   if (my_get_expression (& inst.reloc.exp, & str))
9678     return;
9679
9680   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
9681   inst.reloc.pc_rel = 1;
9682   end_of_line (str);
9683
9684   /* If the destination of the branch is a defined symbol which does not have
9685      the THUMB_FUNC attribute, then we must be calling a function which has
9686      the (interfacearm) attribute.  We look for the Thumb entry point to that
9687      function and change the branch to refer to that function instead.  */
9688   if (   inst.reloc.exp.X_op == O_symbol
9689       && inst.reloc.exp.X_add_symbol != NULL
9690       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9691       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9692     inst.reloc.exp.X_add_symbol =
9693       find_real_start (inst.reloc.exp.X_add_symbol);
9694 }
9695
9696 static void
9697 do_t_bx (char * str)
9698 {
9699   int reg;
9700
9701   skip_whitespace (str);
9702
9703   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9704     return;
9705
9706   /* This sets THUMB_H2 from the top bit of reg.  */
9707   inst.instruction |= reg << 3;
9708
9709   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
9710      should cause the alignment to be checked once it is known.  This is
9711      because BX PC only works if the instruction is word aligned.  */
9712
9713   end_of_line (str);
9714 }
9715
9716 static void
9717 do_t_compare (char * str)
9718 {
9719   thumb_mov_compare (str, THUMB_COMPARE);
9720 }
9721
9722 static void
9723 do_t_ldmstm (char * str)
9724 {
9725   int Rb;
9726   long range;
9727
9728   skip_whitespace (str);
9729
9730   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9731     return;
9732
9733   if (*str != '!')
9734     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9735   else
9736     str++;
9737
9738   if (skip_past_comma (&str) == FAIL
9739       || (range = reg_list (&str)) == FAIL)
9740     {
9741       if (! inst.error)
9742         inst.error = BAD_ARGS;
9743       return;
9744     }
9745
9746   if (inst.reloc.type != BFD_RELOC_UNUSED)
9747     {
9748       /* This really doesn't seem worth it.  */
9749       inst.reloc.type = BFD_RELOC_UNUSED;
9750       inst.error = _("expression too complex");
9751       return;
9752     }
9753
9754   if (range & ~0xff)
9755     {
9756       inst.error = _("only lo-regs valid in load/store multiple");
9757       return;
9758     }
9759
9760   inst.instruction |= (Rb << 8) | range;
9761   end_of_line (str);
9762 }
9763
9764 static void
9765 do_t_ldr (char * str)
9766 {
9767   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9768 }
9769
9770 static void
9771 do_t_ldrb (char * str)
9772 {
9773   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9774 }
9775
9776 static void
9777 do_t_ldrh (char * str)
9778 {
9779   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9780 }
9781
9782 static void
9783 do_t_lds (char * str)
9784 {
9785   int Rd, Rb, Ro;
9786
9787   skip_whitespace (str);
9788
9789   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9790       || skip_past_comma (&str) == FAIL
9791       || *str++ != '['
9792       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9793       || skip_past_comma (&str) == FAIL
9794       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9795       || *str++ != ']')
9796     {
9797       if (! inst.error)
9798         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9799       return;
9800     }
9801
9802   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9803   end_of_line (str);
9804 }
9805
9806 static void
9807 do_t_lsl (char * str)
9808 {
9809   thumb_shift (str, THUMB_LSL);
9810 }
9811
9812 static void
9813 do_t_lsr (char * str)
9814 {
9815   thumb_shift (str, THUMB_LSR);
9816 }
9817
9818 static void
9819 do_t_mov (char * str)
9820 {
9821   thumb_mov_compare (str, THUMB_MOVE);
9822 }
9823
9824 static void
9825 do_t_push_pop (char * str)
9826 {
9827   long range;
9828
9829   skip_whitespace (str);
9830
9831   if ((range = reg_list (&str)) == FAIL)
9832     {
9833       if (! inst.error)
9834         inst.error = BAD_ARGS;
9835       return;
9836     }
9837
9838   if (inst.reloc.type != BFD_RELOC_UNUSED)
9839     {
9840       /* This really doesn't seem worth it.  */
9841       inst.reloc.type = BFD_RELOC_UNUSED;
9842       inst.error = _("expression too complex");
9843       return;
9844     }
9845
9846   if (range & ~0xff)
9847     {
9848       if ((inst.instruction == T_OPCODE_PUSH
9849            && (range & ~0xff) == 1 << REG_LR)
9850           || (inst.instruction == T_OPCODE_POP
9851               && (range & ~0xff) == 1 << REG_PC))
9852         {
9853           inst.instruction |= THUMB_PP_PC_LR;
9854           range &= 0xff;
9855         }
9856       else
9857         {
9858           inst.error = _("invalid register list to push/pop instruction");
9859           return;
9860         }
9861     }
9862
9863   inst.instruction |= range;
9864   end_of_line (str);
9865 }
9866
9867 static void
9868 do_t_str (char * str)
9869 {
9870   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9871 }
9872
9873 static void
9874 do_t_strb (char * str)
9875 {
9876   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9877 }
9878
9879 static void
9880 do_t_strh (char * str)
9881 {
9882   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9883 }
9884
9885 static void
9886 do_t_sub (char * str)
9887 {
9888   thumb_add_sub (str, 1);
9889 }
9890
9891 static void
9892 do_t_swi (char * str)
9893 {
9894   skip_whitespace (str);
9895
9896   if (my_get_expression (&inst.reloc.exp, &str))
9897     return;
9898
9899   inst.reloc.type = BFD_RELOC_ARM_SWI;
9900   end_of_line (str);
9901 }
9902
9903 static void
9904 do_t_adr (char * str)
9905 {
9906   int reg;
9907
9908   /* This is a pseudo-op of the form "adr rd, label" to be converted
9909      into a relative address of the form "add rd, pc, #label-.-4".  */
9910   skip_whitespace (str);
9911
9912   /* Store Rd in temporary location inside instruction.  */
9913   if ((reg = reg_required_here (&str, 4)) == FAIL
9914       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
9915       || skip_past_comma (&str) == FAIL
9916       || my_get_expression (&inst.reloc.exp, &str))
9917     {
9918       if (!inst.error)
9919         inst.error = BAD_ARGS;
9920       return;
9921     }
9922
9923   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9924   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
9925   inst.reloc.pc_rel = 1;
9926   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
9927
9928   end_of_line (str);
9929 }
9930
9931 static void
9932 insert_reg (const struct reg_entry * r,
9933             struct hash_control * htab)
9934 {
9935   int    len  = strlen (r->name) + 2;
9936   char * buf  = xmalloc (len);
9937   char * buf2 = xmalloc (len);
9938   int    i    = 0;
9939
9940 #ifdef REGISTER_PREFIX
9941   buf[i++] = REGISTER_PREFIX;
9942 #endif
9943
9944   strcpy (buf + i, r->name);
9945
9946   for (i = 0; buf[i]; i++)
9947     buf2[i] = TOUPPER (buf[i]);
9948
9949   buf2[i] = '\0';
9950
9951   hash_insert (htab, buf,  (PTR) r);
9952   hash_insert (htab, buf2, (PTR) r);
9953 }
9954
9955 static void
9956 build_reg_hsh (struct reg_map * map)
9957 {
9958   const struct reg_entry *r;
9959
9960   if ((map->htab = hash_new ()) == NULL)
9961     as_fatal (_("virtual memory exhausted"));
9962
9963   for (r = map->names; r->name != NULL; r++)
9964     insert_reg (r, map->htab);
9965 }
9966
9967 static void
9968 insert_reg_alias (char * str,
9969                   int regnum,
9970                   struct hash_control *htab)
9971 {
9972   const char * error;
9973   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
9974   const char * name = xmalloc (strlen (str) + 1);
9975
9976   strcpy ((char *) name, str);
9977
9978   new->name = name;
9979   new->number = regnum;
9980   new->builtin = FALSE;
9981
9982   error = hash_insert (htab, name, (PTR) new);
9983   if (error)
9984     {
9985       as_bad (_("failed to create an alias for %s, reason: %s"),
9986             str, error);
9987       free ((char *) name);
9988       free (new);
9989     }
9990 }
9991
9992 /* Look for the .req directive.  This is of the form:
9993
9994         new_register_name .req existing_register_name
9995
9996    If we find one, or if it looks sufficiently like one that we want to
9997    handle any error here, return non-zero.  Otherwise return zero.  */
9998
9999 static int
10000 create_register_alias (char * newname, char * p)
10001 {
10002   char * q;
10003   char c;
10004
10005   q = p;
10006   skip_whitespace (q);
10007
10008   c = *p;
10009   *p = '\0';
10010
10011   if (*q && !strncmp (q, ".req ", 5))
10012     {
10013       char *copy_of_str;
10014       char *r;
10015
10016 #ifndef IGNORE_OPCODE_CASE
10017       newname = original_case_string;
10018 #endif
10019       copy_of_str = newname;
10020
10021       q += 4;
10022       skip_whitespace (q);
10023
10024       for (r = q; *r != '\0'; r++)
10025         if (*r == ' ')
10026           break;
10027
10028       if (r != q)
10029         {
10030           enum arm_reg_type new_type, old_type;
10031           int old_regno;
10032           char d = *r;
10033
10034           *r = '\0';
10035           old_type = arm_reg_parse_any (q);
10036           *r = d;
10037
10038           new_type = arm_reg_parse_any (newname);
10039
10040           if (new_type == REG_TYPE_MAX)
10041             {
10042               if (old_type != REG_TYPE_MAX)
10043                 {
10044                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
10045                   insert_reg_alias (newname, old_regno,
10046                                     all_reg_maps[old_type].htab);
10047                 }
10048               else
10049                 as_warn (_("register '%s' does not exist\n"), q);
10050             }
10051           else if (old_type == REG_TYPE_MAX)
10052             {
10053               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
10054                        copy_of_str, q);
10055             }
10056           else
10057             {
10058               /* Do not warn about redefinitions to the same alias.  */
10059               if (new_type != old_type
10060                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
10061                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
10062                 as_warn (_("ignoring redefinition of register alias '%s'"),
10063                          copy_of_str);
10064
10065             }
10066         }
10067       else
10068         as_warn (_("ignoring incomplete .req pseuso op"));
10069
10070       *p = c;
10071       return 1;
10072     }
10073
10074   *p = c;
10075   return 0;
10076 }
10077
10078 static void
10079 set_constant_flonums (void)
10080 {
10081   int i;
10082
10083   for (i = 0; i < NUM_FLOAT_VALS; i++)
10084     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
10085       abort ();
10086 }
10087
10088 \f
10089 static const struct asm_opcode insns[] =
10090 {
10091   /* Core ARM Instructions.  */
10092   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
10093   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
10094   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
10095   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
10096   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
10097   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
10098   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
10099   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
10100   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
10101   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
10102   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
10103   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
10104   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
10105   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
10106   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
10107   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
10108   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
10109   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
10110   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
10111   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
10112
10113   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
10114   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
10115   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
10116   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
10117   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
10118   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
10119   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
10120   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
10121   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
10122   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
10123   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
10124   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
10125
10126   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
10127   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
10128   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
10129   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
10130
10131   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
10132   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
10133   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
10134   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
10135   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
10136   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
10137   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
10138   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
10139
10140   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
10141   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
10142   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
10143   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
10144   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
10145   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
10146   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
10147   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
10148
10149   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
10150   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
10151   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
10152   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
10153   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
10154   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
10155   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
10156   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
10157
10158   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
10159 #ifdef TE_WINCE
10160   /* XXX This is the wrong place to do this.  Think multi-arch.  */
10161   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
10162   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
10163 #else
10164   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
10165   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
10166 #endif
10167
10168   /* Pseudo ops.  */
10169   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
10170   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
10171   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_nop},
10172
10173   /* ARM 2 multiplies.  */
10174   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
10175   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
10176   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
10177   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
10178
10179   /* Generic coprocessor instructions.  */
10180   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
10181   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
10182   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
10183   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
10184   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
10185   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
10186   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
10187
10188   /* ARM 3 - swp instructions.  */
10189   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
10190   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
10191
10192   /* ARM 6 Status register instructions.  */
10193   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
10194   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
10195   /* ScottB: our code uses     0xe128f000 for msr.
10196      NickC:  but this is wrong because the bits 16 through 19 are
10197              handled by the PSR_xxx defines above.  */
10198
10199   /* ARM 7M long multiplies.  */
10200   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
10201   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
10202   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
10203   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
10204   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
10205   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
10206   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
10207   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
10208
10209   /* ARM Architecture 4.  */
10210   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
10211   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
10212   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
10213   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
10214
10215   /* ARM Architecture 4T.  */
10216   /* Note: bx (and blx) are required on V5, even if the processor does
10217      not support Thumb.  */
10218   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
10219
10220   /*  ARM Architecture 5T.  */
10221   /* Note: blx has 2 variants, so the .value is set dynamically.
10222      Only one of the variants has conditional execution.  */
10223   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
10224   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
10225   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
10226   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
10227   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
10228   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
10229   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
10230   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
10231   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
10232   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
10233
10234   /*  ARM Architecture 5TExP.  */
10235   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
10236   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
10237   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
10238   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
10239
10240   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
10241   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
10242
10243   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
10244   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
10245   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
10246   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
10247
10248   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
10249   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
10250   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
10251   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
10252
10253   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
10254   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
10255
10256   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
10257   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
10258   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
10259   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
10260
10261   /*  ARM Architecture 5TE.  */
10262   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
10263   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
10264   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
10265
10266   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
10267   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
10268
10269   /*  ARM Architecture 5TEJ.  */
10270   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
10271
10272   /*  ARM V6.  */
10273   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
10274   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
10275   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
10276   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
10277   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
10278   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
10279   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
10280   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
10281   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
10282   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
10283   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
10284   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
10285   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
10286   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
10287   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
10288   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
10289   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
10290   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
10291   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
10292   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
10293   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
10294   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
10295   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
10296   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
10297   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
10298   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
10299   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
10300   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
10301   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
10302   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
10303   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
10304   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
10305   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
10306   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
10307   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
10308   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
10309   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
10310   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
10311   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
10312   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
10313   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
10314   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
10315   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
10316   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
10317   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
10318   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
10319   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
10320   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
10321   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
10322   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
10323   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
10324   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
10325   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
10326   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
10327   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
10328   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
10329   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
10330   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
10331   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
10332   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
10333   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
10334   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
10335   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
10336   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
10337   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
10338   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
10339   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
10340   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
10341   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
10342   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
10343   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
10344   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
10345   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
10346   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
10347   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
10348   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
10349   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
10350   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
10351   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
10352   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
10353   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
10354   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
10355   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
10356   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
10357   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
10358   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
10359   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
10360   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
10361   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
10362   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
10363   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
10364   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
10365   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
10366   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
10367   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
10368   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
10369   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
10370   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
10371   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
10372
10373   /*  ARM V6K.  */
10374   { "clrex",     0xf57ff01f, 0,  ARM_EXT_V6K,      do_empty},
10375   { "ldrexb",    0xe1d00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10376   { "ldrexd",    0xe1b00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10377   { "ldrexh",    0xe1f00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10378   { "sev",       0xe320f004, 3,  ARM_EXT_V6K,      do_empty},
10379   { "strexb",    0xe1c00f90, 6,  ARM_EXT_V6K,      do_strex},
10380   { "strexd",    0xe1a00f90, 6,  ARM_EXT_V6K,      do_strex},
10381   { "strexh",    0xe1e00f90, 6,  ARM_EXT_V6K,      do_strex},
10382   { "wfe",       0xe320f002, 3,  ARM_EXT_V6K,      do_empty},
10383   { "wfi",       0xe320f003, 3,  ARM_EXT_V6K,      do_empty},
10384   { "yield",     0xe320f001, 5,  ARM_EXT_V6K,      do_empty},
10385
10386   /*  ARM V6Z.  */
10387   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
10388
10389   /*  ARM V6T2.  */
10390   { "bfc",       0xe7c0001f, 3,  ARM_EXT_V6T2,     do_bfc},
10391   { "bfi",       0xe7c00010, 3,  ARM_EXT_V6T2,     do_bfi},
10392   { "mls",       0xe0600090, 3,  ARM_EXT_V6T2,     do_mls},
10393   { "movw",      0xe3000000, 4,  ARM_EXT_V6T2,     do_mov16},
10394   { "movt",      0xe3400000, 4,  ARM_EXT_V6T2,     do_mov16},
10395   { "rbit",      0xe3ff0f30, 4,  ARM_EXT_V6T2,     do_rbit},
10396   { "sbfx",      0xe7a00050, 4,  ARM_EXT_V6T2,     do_bfx},
10397   { "ubfx",      0xe7e00050, 4,  ARM_EXT_V6T2,     do_bfx},
10398
10399   { "ldrht",     0xe03000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10400   { "ldrsht",    0xe03000f0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10401   { "ldrsbt",    0xe03000d0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10402   { "strht",     0xe02000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10403
10404   /* Core FPA instruction set (V1).  */
10405   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10406   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10407   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10408   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10409
10410   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10411   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10412   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10413   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10414
10415   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10416   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10417   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10418   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10419
10420   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10421   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10422   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10423   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10424   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10425   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10426   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10427   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10428   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10429   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10430   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10431   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10432
10433   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10434   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10435   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10436   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10437   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10438   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10439   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10440   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10441   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10442   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10443   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10444   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10445
10446   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10447   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10448   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10449   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10450   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10451   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10452   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10453   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10454   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10455   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10456   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10457   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10458
10459   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10460   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10461   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10462   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10463   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10464   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10465   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10466   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10467   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10468   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10469   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10470   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10471
10472   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10473   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10474   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10475   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10476   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10477   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10478   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10479   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10480   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10481   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10482   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10483   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10484
10485   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10486   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10487   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10488   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10489   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10490   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10491   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10492   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10493   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10494   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10495   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10496   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10497
10498   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10499   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10500   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10501   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10502   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10503   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10504   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10505   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10506   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10507   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10508   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10509   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10510
10511   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10512   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10513   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10514   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10515   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10516   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10517   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10518   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10519   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10520   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10521   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10522   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10523
10524   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10525   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10526   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10527   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10528   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10529   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10530   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10531   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10532   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10533   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10534   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10535   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10536
10537   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10538   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10539   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10540   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10541   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10542   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10543   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10544   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10545   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10546   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10547   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10548   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10549
10550   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10551   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10552   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10553   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10554   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10555   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10556   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10557   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10558   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10559   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10560   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10561   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10562
10563   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10564   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10565   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10566   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10567   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10568   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10569   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10570   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10571   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10572   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10573   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10574   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10575
10576   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10577   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10578   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10579   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10580   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10581   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10582   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10583   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10584   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10585   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10586   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10587   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10588
10589   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10590   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10591   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10592   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10593   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10594   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10595   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10596   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10597   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10598   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10599   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10600   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10601
10602   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10603   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10604   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10605   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10606   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10607   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10608   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10609   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10610   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10611   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10612   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10613   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10614
10615   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10616   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10617   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10618   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10619   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10620   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10621   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10622   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10623   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10624   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10625   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10626   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10627
10628   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10629   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10630   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10631   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10632   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10633   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10634   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10635   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10636   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10637   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10638   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10639   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10640
10641   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10642   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10643   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10644   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10645   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10646   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10647   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10648   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10649   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10650   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10651   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10652   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10653
10654   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10655   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10656   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10657   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10658   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10659   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10660   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10661   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10662   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10663   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10664   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10665   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10666
10667   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10668   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10669   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10670   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10671   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10672   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10673   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10674   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10675   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10676   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10677   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10678   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10679
10680   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10681   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10682   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10683   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10684   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10685   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10686   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10687   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10688   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10689   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10690   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10691   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10692
10693   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10694   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10695   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10696   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10697   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10698   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10699   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10700   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10701   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10702   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10703   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10704   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10705
10706   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10707   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10708   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10709   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10710   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10711   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10712   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10713   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10714   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10715   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10716   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10717   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10718
10719   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10720   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10721   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10722   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10723   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10724   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10725   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10726   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10727   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10728   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10729   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10730   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10731
10732   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10733   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10734   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10735   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10736   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10737   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10738   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10739   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10740   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10741   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10742   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10743   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10744
10745   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10746   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10747   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10748   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10749   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10750   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10751   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10752   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10753   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10754   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10755   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10756   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10757
10758   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10759   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10760   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10761   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10762   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10763   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10764   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10765   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10766   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10767   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10768   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10769   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10770
10771   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10772   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10773   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10774   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10775   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10776   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10777   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10778   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10779   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10780   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10781   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10782   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10783
10784   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10785   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10786   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10787   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10788   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10789   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10790   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10791   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10792   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10793   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10794   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10795   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10796
10797   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10798   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10799   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10800   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10801   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
10802      not be an optional suffix, but part of the instruction.  To be
10803      compatible, we accept either.  */
10804   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10805   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10806
10807   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10808   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10809   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10810   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10811   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10812   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10813   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10814   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10815   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10816   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10817   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10818   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10819
10820   /* The implementation of the FIX instruction is broken on some
10821      assemblers, in that it accepts a precision specifier as well as a
10822      rounding specifier, despite the fact that this is meaningless.
10823      To be more compatible, we accept it as well, though of course it
10824      does not set any bits.  */
10825   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10826   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10827   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10828   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10829   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10830   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10831   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10832   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10833   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10834   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10835   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10836   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10837   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10838
10839   /* Instructions that were new with the real FPA, call them V2.  */
10840   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10841   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10842   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10843   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10844   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10845   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10846
10847   /* VFP V1xD (single precision).  */
10848   /* Moves and type conversions.  */
10849   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10850   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
10851   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
10852   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
10853   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10854   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10855   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10856   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10857   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10858   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10859   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
10860   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
10861
10862   /* Memory operations.  */
10863   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10864   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10865   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10866   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10867   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10868   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10869   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10870   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10871   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10872   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10873   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10874   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10875   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10876   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10877   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10878   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10879   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10880   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10881
10882   /* Monadic operations.  */
10883   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10884   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10885   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10886
10887   /* Dyadic operations.  */
10888   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10889   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10890   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10891   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10892   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10893   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10894   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10895   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10896   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10897
10898   /* Comparisons.  */
10899   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10900   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10901   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10902   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10903
10904   /* VFP V1 (Double precision).  */
10905   /* Moves and type conversions.  */
10906   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10907   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10908   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10909   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10910   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10911   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10912   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10913   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10914   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10915   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10916   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10917   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10918   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10919
10920   /* Memory operations.  */
10921   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10922   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10923   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10924   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10925   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10926   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10927   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10928   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10929   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10930   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10931
10932   /* Monadic operations.  */
10933   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10934   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10935   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10936
10937   /* Dyadic operations.  */
10938   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10939   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10940   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10941   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10942   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10943   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10944   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10945   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10946   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10947
10948   /* Comparisons.  */
10949   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10950   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10951   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10952   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10953
10954   /* VFP V2.  */
10955   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
10956   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
10957   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
10958   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
10959
10960   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
10961   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
10962   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10963   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10964   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10965   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10966   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10967   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
10968   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
10969
10970   /* Intel Wireless MMX technology instructions.  */
10971   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10972   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10973   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10974   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10975   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10976   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10977   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10978   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10979   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10980   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10981   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10982   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10983   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10984   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10985   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10986   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10987   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10988   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10989   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
10990   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
10991   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10992   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10993   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10994   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10995   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10996   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10997   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10998   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10999   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
11000   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
11001   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
11002   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
11003   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
11004   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
11005   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11006   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11007   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11008   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11009   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11010   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11011   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11012   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11013   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11014   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11015   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11016   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11017   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
11018   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11019   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11020   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11021   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11022   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11023   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11024   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11025   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11026   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11027   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11028   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11029   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11030   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11031   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11032   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11033   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11034   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11035   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11036   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11037   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11038   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11039   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11040   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11041   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11042   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11043   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11044   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11045   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11046   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11047   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11048   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11049   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11050   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11051   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11052   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11053   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11054   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11055   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11056   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11057   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11058   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11059   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
11060   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11061   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11062   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11063   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11064   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11065   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11066   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11067   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11068   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11069   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11070   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11071   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11072   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11073   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11074   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11075   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11076   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11077   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11078   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11079   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11080   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11081   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
11082   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11083   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11084   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11085   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11086   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11087   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11088   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11089   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11090   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11091   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11092   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11093   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11094   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11095   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11096   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11097   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11098   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11099   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11100   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11101   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11102   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11103   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11104   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11105   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11106   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11107   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11108   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11109   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11110   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11111   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11112   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11113   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11114   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11115   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11116   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11117   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11118   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11119   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11120   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11121   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11122   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11123   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11124   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11125   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11126   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11127   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11128   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11129   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11130   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11131   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11132   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
11133
11134   /* Cirrus Maverick instructions.  */
11135   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
11136   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
11137   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
11138   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
11139   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
11140   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
11141   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
11142   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
11143   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
11144   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
11145   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
11146   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
11147   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
11148   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
11149   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
11150   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
11151   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
11152   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
11153   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11154   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11155   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11156   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11157   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11158   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11159   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11160   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11161   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
11162   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
11163   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
11164   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
11165   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11166   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11167   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
11168   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
11169   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
11170   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
11171   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
11172   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
11173   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
11174   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
11175   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
11176   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
11177   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
11178   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
11179   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
11180   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
11181   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
11182   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
11183   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
11184   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
11185   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11186   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11187   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11188   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11189   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11190   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11191   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11192   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11193   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11194   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11195   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
11196   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
11197   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
11198   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
11199   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11200   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11201   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11202   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11203   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11204   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11205   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11206   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11207   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
11208   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
11209   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
11210   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
11211 };
11212
11213 /* Iterate over the base tables to create the instruction patterns.  */
11214
11215 static void
11216 build_arm_ops_hsh (void)
11217 {
11218   unsigned int i;
11219   unsigned int j;
11220   static struct obstack insn_obstack;
11221
11222   obstack_begin (&insn_obstack, 4000);
11223
11224   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11225     {
11226       const struct asm_opcode *insn = insns + i;
11227
11228       if (insn->cond_offset != 0)
11229         {
11230           /* Insn supports conditional execution.  Build the varaints
11231              and insert them in the hash table.  */
11232           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11233             {
11234               unsigned len = strlen (insn->template);
11235               struct asm_opcode *new;
11236               char *template;
11237
11238               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11239               /* All condition codes are two characters.  */
11240               template = obstack_alloc (&insn_obstack, len + 3);
11241
11242               strncpy (template, insn->template, insn->cond_offset);
11243               strcpy (template + insn->cond_offset, conds[j].template);
11244               if (len > insn->cond_offset)
11245                 strcpy (template + insn->cond_offset + 2,
11246                         insn->template + insn->cond_offset);
11247               new->template = template;
11248               new->cond_offset = 0;
11249               new->variant = insn->variant;
11250               new->parms = insn->parms;
11251               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11252
11253               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11254             }
11255         }
11256       /* Finally, insert the unconditional insn in the table directly;
11257          no need to build a copy.  */
11258       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11259     }
11260 }
11261
11262 \f
11263 static const struct thumb_opcode tinsns[] =
11264 {
11265   /* Thumb v1 (ARMv4T).  */
11266   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
11267   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
11268   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
11269   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
11270   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
11271   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
11272   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
11273   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
11274   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
11275   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11276   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11277   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11278   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
11279   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
11280   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
11281   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
11282   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
11283   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
11284   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
11285   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
11286   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
11287   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
11288   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
11289   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
11290   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
11291   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
11292   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
11293   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
11294   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
11295   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
11296   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
11297   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
11298   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
11299   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
11300   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
11301   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
11302   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
11303   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
11304   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
11305   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
11306   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
11307   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
11308   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
11309   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
11310   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
11311   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
11312   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
11313   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
11314   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
11315   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
11316   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
11317   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
11318   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
11319   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
11320   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
11321   /* Pseudo ops:  */
11322   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
11323   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
11324   /* Thumb v2 (ARMv5T).  */
11325   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
11326   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
11327
11328   /* ARM V6.  */
11329   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
11330   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
11331   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
11332   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
11333   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
11334   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
11335   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
11336   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
11337   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
11338   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
11339   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
11340
11341   /* ARM V6K.  */
11342   {"sev",       0xbf40,         2,      ARM_EXT_V6K, do_empty},
11343   {"wfe",       0xbf20,         2,      ARM_EXT_V6K, do_empty},
11344   {"wfi",       0xbf30,         2,      ARM_EXT_V6K, do_empty},
11345   {"yield",     0xbf10,         2,      ARM_EXT_V6K, do_empty},
11346 };
11347
11348 void
11349 md_begin (void)
11350 {
11351   unsigned mach;
11352   unsigned int i;
11353
11354   if (   (arm_ops_hsh = hash_new ()) == NULL
11355       || (arm_tops_hsh = hash_new ()) == NULL
11356       || (arm_cond_hsh = hash_new ()) == NULL
11357       || (arm_shift_hsh = hash_new ()) == NULL
11358       || (arm_psr_hsh = hash_new ()) == NULL)
11359     as_fatal (_("virtual memory exhausted"));
11360
11361   build_arm_ops_hsh ();
11362   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11363     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11364   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11365     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11366   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11367     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11368   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11369     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11370
11371   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11372     build_reg_hsh (all_reg_maps + i);
11373
11374   set_constant_flonums ();
11375
11376   /* Set the cpu variant based on the command-line options.  We prefer
11377      -mcpu= over -march= if both are set (as for GCC); and we prefer
11378      -mfpu= over any other way of setting the floating point unit.
11379      Use of legacy options with new options are faulted.  */
11380   if (legacy_cpu != -1)
11381     {
11382       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11383         as_bad (_("use of old and new-style options to set CPU type"));
11384
11385       mcpu_cpu_opt = legacy_cpu;
11386     }
11387   else if (mcpu_cpu_opt == -1)
11388     mcpu_cpu_opt = march_cpu_opt;
11389
11390   if (legacy_fpu != -1)
11391     {
11392       if (mfpu_opt != -1)
11393         as_bad (_("use of old and new-style options to set FPU type"));
11394
11395       mfpu_opt = legacy_fpu;
11396     }
11397   else if (mfpu_opt == -1)
11398     {
11399 #if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) 
11400       /* Some environments specify a default FPU.  If they don't, infer it
11401          from the processor.  */
11402       if (mcpu_fpu_opt != -1)
11403         mfpu_opt = mcpu_fpu_opt;
11404       else
11405         mfpu_opt = march_fpu_opt;
11406 #else
11407       mfpu_opt = FPU_DEFAULT;
11408 #endif
11409     }
11410
11411   if (mfpu_opt == -1)
11412     {
11413       if (mcpu_cpu_opt == -1)
11414         mfpu_opt = FPU_DEFAULT;
11415       else if (mcpu_cpu_opt & ARM_EXT_V5)
11416         mfpu_opt = FPU_ARCH_VFP_V2;
11417       else
11418         mfpu_opt = FPU_ARCH_FPA;
11419     }
11420
11421   if (mcpu_cpu_opt == -1)
11422     mcpu_cpu_opt = CPU_DEFAULT;
11423
11424   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11425
11426 #if defined OBJ_COFF || defined OBJ_ELF
11427   {
11428     unsigned int flags = 0;
11429
11430 #if defined OBJ_ELF
11431     flags = meabi_flags;
11432
11433     switch (meabi_flags)
11434       {
11435       case EF_ARM_EABI_UNKNOWN:
11436 #endif
11437         /* Set the flags in the private structure.  */
11438         if (uses_apcs_26)      flags |= F_APCS26;
11439         if (support_interwork) flags |= F_INTERWORK;
11440         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11441         if (pic_code)          flags |= F_PIC;
11442         if ((cpu_variant & FPU_ANY) == FPU_NONE
11443              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11444           flags |= F_SOFT_FLOAT;
11445
11446         switch (mfloat_abi_opt)
11447           {
11448           case ARM_FLOAT_ABI_SOFT:
11449           case ARM_FLOAT_ABI_SOFTFP:
11450             flags |= F_SOFT_FLOAT;
11451             break;
11452
11453           case ARM_FLOAT_ABI_HARD:
11454             if (flags & F_SOFT_FLOAT)
11455               as_bad (_("hard-float conflicts with specified fpu"));
11456             break;
11457           }
11458
11459         /* Using VFP conventions (even if soft-float).  */
11460         if (cpu_variant & FPU_VFP_EXT_NONE)
11461           flags |= F_VFP_FLOAT;
11462
11463 #if defined OBJ_ELF
11464         if (cpu_variant & FPU_ARCH_MAVERICK)
11465             flags |= EF_ARM_MAVERICK_FLOAT;
11466         break;
11467
11468       case EF_ARM_EABI_VER4:
11469         /* No additional flags to set.  */
11470         break;
11471
11472       default:
11473         abort ();
11474       }
11475 #endif
11476     bfd_set_private_flags (stdoutput, flags);
11477
11478     /* We have run out flags in the COFF header to encode the
11479        status of ATPCS support, so instead we create a dummy,
11480        empty, debug section called .arm.atpcs.  */
11481     if (atpcs)
11482       {
11483         asection * sec;
11484
11485         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11486
11487         if (sec != NULL)
11488           {
11489             bfd_set_section_flags
11490               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11491             bfd_set_section_size (stdoutput, sec, 0);
11492             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11493           }
11494       }
11495   }
11496 #endif
11497
11498   /* Record the CPU type as well.  */
11499   switch (cpu_variant & ARM_CPU_MASK)
11500     {
11501     case ARM_2:
11502       mach = bfd_mach_arm_2;
11503       break;
11504
11505     case ARM_3:                 /* Also ARM_250.  */
11506       mach = bfd_mach_arm_2a;
11507       break;
11508
11509     case ARM_6:                 /* Also ARM_7.  */
11510       mach = bfd_mach_arm_3;
11511       break;
11512
11513     default:
11514       mach = bfd_mach_arm_unknown;
11515       break;
11516     }
11517
11518   /* Catch special cases.  */
11519   if (cpu_variant & ARM_CEXT_IWMMXT)
11520     mach = bfd_mach_arm_iWMMXt;
11521   else if (cpu_variant & ARM_CEXT_XSCALE)
11522     mach = bfd_mach_arm_XScale;
11523   else if (cpu_variant & ARM_CEXT_MAVERICK)
11524     mach = bfd_mach_arm_ep9312;
11525   else if (cpu_variant & ARM_EXT_V5E)
11526     mach = bfd_mach_arm_5TE;
11527   else if (cpu_variant & ARM_EXT_V5)
11528     {
11529       if (cpu_variant & ARM_EXT_V4T)
11530         mach = bfd_mach_arm_5T;
11531       else
11532         mach = bfd_mach_arm_5;
11533     }
11534   else if (cpu_variant & ARM_EXT_V4)
11535     {
11536       if (cpu_variant & ARM_EXT_V4T)
11537         mach = bfd_mach_arm_4T;
11538       else
11539         mach = bfd_mach_arm_4;
11540     }
11541   else if (cpu_variant & ARM_EXT_V3M)
11542     mach = bfd_mach_arm_3M;
11543
11544   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11545 }
11546
11547 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11548    for use in the a.out file, and stores them in the array pointed to by buf.
11549    This knows about the endian-ness of the target machine and does
11550    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11551    2 (short) and 4 (long)  Floating numbers are put out as a series of
11552    LITTLENUMS (shorts, here at least).  */
11553
11554 void
11555 md_number_to_chars (char * buf, valueT val, int n)
11556 {
11557   if (target_big_endian)
11558     number_to_chars_bigendian (buf, val, n);
11559   else
11560     number_to_chars_littleendian (buf, val, n);
11561 }
11562
11563 static valueT
11564 md_chars_to_number (char * buf, int n)
11565 {
11566   valueT result = 0;
11567   unsigned char * where = (unsigned char *) buf;
11568
11569   if (target_big_endian)
11570     {
11571       while (n--)
11572         {
11573           result <<= 8;
11574           result |= (*where++ & 255);
11575         }
11576     }
11577   else
11578     {
11579       while (n--)
11580         {
11581           result <<= 8;
11582           result |= (where[n] & 255);
11583         }
11584     }
11585
11586   return result;
11587 }
11588
11589 /* Turn a string in input_line_pointer into a floating point constant
11590    of type TYPE, and store the appropriate bytes in *LITP.  The number
11591    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11592    returned, or NULL on OK.
11593
11594    Note that fp constants aren't represent in the normal way on the ARM.
11595    In big endian mode, things are as expected.  However, in little endian
11596    mode fp constants are big-endian word-wise, and little-endian byte-wise
11597    within the words.  For example, (double) 1.1 in big endian mode is
11598    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11599    the byte sequence 99 99 f1 3f 9a 99 99 99.
11600
11601    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11602
11603 char *
11604 md_atof (int type, char * litP, int * sizeP)
11605 {
11606   int prec;
11607   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11608   char *t;
11609   int i;
11610
11611   switch (type)
11612     {
11613     case 'f':
11614     case 'F':
11615     case 's':
11616     case 'S':
11617       prec = 2;
11618       break;
11619
11620     case 'd':
11621     case 'D':
11622     case 'r':
11623     case 'R':
11624       prec = 4;
11625       break;
11626
11627     case 'x':
11628     case 'X':
11629       prec = 6;
11630       break;
11631
11632     case 'p':
11633     case 'P':
11634       prec = 6;
11635       break;
11636
11637     default:
11638       *sizeP = 0;
11639       return _("bad call to MD_ATOF()");
11640     }
11641
11642   t = atof_ieee (input_line_pointer, type, words);
11643   if (t)
11644     input_line_pointer = t;
11645   *sizeP = prec * 2;
11646
11647   if (target_big_endian)
11648     {
11649       for (i = 0; i < prec; i++)
11650         {
11651           md_number_to_chars (litP, (valueT) words[i], 2);
11652           litP += 2;
11653         }
11654     }
11655   else
11656     {
11657       if (cpu_variant & FPU_ARCH_VFP)
11658         for (i = prec - 1; i >= 0; i--)
11659           {
11660             md_number_to_chars (litP, (valueT) words[i], 2);
11661             litP += 2;
11662           }
11663       else
11664         /* For a 4 byte float the order of elements in `words' is 1 0.
11665            For an 8 byte float the order is 1 0 3 2.  */
11666         for (i = 0; i < prec; i += 2)
11667           {
11668             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11669             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11670             litP += 4;
11671           }
11672     }
11673
11674   return 0;
11675 }
11676
11677 /* The knowledge of the PC's pipeline offset is built into the insns
11678    themselves.  */
11679
11680 long
11681 md_pcrel_from (fixS * fixP)
11682 {
11683   if (fixP->fx_addsy
11684       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11685       && fixP->fx_subsy == NULL)
11686     return 0;
11687
11688   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11689     {
11690       /* PC relative addressing on the Thumb is slightly odd
11691          as the bottom two bits of the PC are forced to zero
11692          for the calculation.  */
11693       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11694     }
11695
11696 #ifdef TE_WINCE
11697   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11698      so we un-adjust here to compensate for the accommodation.  */
11699   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11700 #else
11701   return fixP->fx_where + fixP->fx_frag->fr_address;
11702 #endif
11703 }
11704
11705 /* Round up a section size to the appropriate boundary.  */
11706
11707 valueT
11708 md_section_align (segT   segment ATTRIBUTE_UNUSED,
11709                   valueT size)
11710 {
11711 #ifdef OBJ_ELF
11712   return size;
11713 #else
11714   /* Round all sects to multiple of 4.  */
11715   return (size + 3) & ~3;
11716 #endif
11717 }
11718
11719 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
11720    Otherwise we have no need to default values of symbols.  */
11721
11722 symbolS *
11723 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
11724 {
11725 #ifdef OBJ_ELF
11726   if (name[0] == '_' && name[1] == 'G'
11727       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
11728     {
11729       if (!GOT_symbol)
11730         {
11731           if (symbol_find (name))
11732             as_bad ("GOT already in the symbol table");
11733
11734           GOT_symbol = symbol_new (name, undefined_section,
11735                                    (valueT) 0, & zero_address_frag);
11736         }
11737
11738       return GOT_symbol;
11739     }
11740 #endif
11741
11742   return 0;
11743 }
11744
11745 void
11746 md_apply_fix3 (fixS *   fixP,
11747                valueT * valP,
11748                segT     seg)
11749 {
11750   offsetT        value = * valP;
11751   offsetT        newval;
11752   unsigned int   newimm;
11753   unsigned long  temp;
11754   int            sign;
11755   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
11756   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
11757
11758   assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
11759
11760   /* Note whether this will delete the relocation.  */
11761   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11762     fixP->fx_done = 1;
11763
11764   /* If this symbol is in a different section then we need to leave it for
11765      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
11766      so we have to undo it's effects here.  */
11767   if (fixP->fx_pcrel)
11768     {
11769       if (fixP->fx_addsy != NULL
11770           && S_IS_DEFINED (fixP->fx_addsy)
11771           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11772         value += md_pcrel_from (fixP);
11773     }
11774
11775   /* Remember value for emit_reloc.  */
11776   fixP->fx_addnumber = value;
11777
11778   switch (fixP->fx_r_type)
11779     {
11780     case BFD_RELOC_NONE:
11781       /* This will need to go in the object file.  */
11782       fixP->fx_done = 0;
11783       break;
11784   
11785     case BFD_RELOC_ARM_IMMEDIATE:
11786       /* We claim that this fixup has been processed here,
11787          even if in fact we generate an error because we do
11788          not have a reloc for it, so tc_gen_reloc will reject it.  */
11789       fixP->fx_done = 1;
11790
11791       if (fixP->fx_addsy
11792           && ! S_IS_DEFINED (fixP->fx_addsy))
11793         {
11794           as_bad_where (fixP->fx_file, fixP->fx_line,
11795                         _("undefined symbol %s used as an immediate value"),
11796                         S_GET_NAME (fixP->fx_addsy));
11797           break;
11798         }
11799
11800       newimm = validate_immediate (value);
11801       temp = md_chars_to_number (buf, INSN_SIZE);
11802
11803       /* If the instruction will fail, see if we can fix things up by
11804          changing the opcode.  */
11805       if (newimm == (unsigned int) FAIL
11806           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11807         {
11808           as_bad_where (fixP->fx_file, fixP->fx_line,
11809                         _("invalid constant (%lx) after fixup"),
11810                         (unsigned long) value);
11811           break;
11812         }
11813
11814       newimm |= (temp & 0xfffff000);
11815       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11816       break;
11817
11818     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11819       {
11820         unsigned int highpart = 0;
11821         unsigned int newinsn  = 0xe1a00000; /* nop.  */
11822
11823         newimm = validate_immediate (value);
11824         temp = md_chars_to_number (buf, INSN_SIZE);
11825
11826         /* If the instruction will fail, see if we can fix things up by
11827            changing the opcode.  */
11828         if (newimm == (unsigned int) FAIL
11829             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11830           {
11831             /* No ?  OK - try using two ADD instructions to generate
11832                the value.  */
11833             newimm = validate_immediate_twopart (value, & highpart);
11834
11835             /* Yes - then make sure that the second instruction is
11836                also an add.  */
11837             if (newimm != (unsigned int) FAIL)
11838               newinsn = temp;
11839             /* Still No ?  Try using a negated value.  */
11840             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11841               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11842             /* Otherwise - give up.  */
11843             else
11844               {
11845                 as_bad_where (fixP->fx_file, fixP->fx_line,
11846                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11847                               (long) value);
11848                 break;
11849               }
11850
11851             /* Replace the first operand in the 2nd instruction (which
11852                is the PC) with the destination register.  We have
11853                already added in the PC in the first instruction and we
11854                do not want to do it again.  */
11855             newinsn &= ~ 0xf0000;
11856             newinsn |= ((newinsn & 0x0f000) << 4);
11857           }
11858
11859         newimm |= (temp & 0xfffff000);
11860         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11861
11862         highpart |= (newinsn & 0xfffff000);
11863         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11864       }
11865       break;
11866
11867     case BFD_RELOC_ARM_OFFSET_IMM:
11868       sign = value >= 0;
11869
11870       if (value < 0)
11871         value = - value;
11872
11873       if (validate_offset_imm (value, 0) == FAIL)
11874         {
11875           as_bad_where (fixP->fx_file, fixP->fx_line,
11876                         _("bad immediate value for offset (%ld)"),
11877                         (long) value);
11878           break;
11879         }
11880
11881       newval = md_chars_to_number (buf, INSN_SIZE);
11882       newval &= 0xff7ff000;
11883       newval |= value | (sign ? INDEX_UP : 0);
11884       md_number_to_chars (buf, newval, INSN_SIZE);
11885       break;
11886
11887     case BFD_RELOC_ARM_OFFSET_IMM8:
11888     case BFD_RELOC_ARM_HWLITERAL:
11889       sign = value >= 0;
11890
11891       if (value < 0)
11892         value = - value;
11893
11894       if (validate_offset_imm (value, 1) == FAIL)
11895         {
11896           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11897             as_bad_where (fixP->fx_file, fixP->fx_line,
11898                           _("invalid literal constant: pool needs to be closer"));
11899           else
11900             as_bad (_("bad immediate value for half-word offset (%ld)"),
11901                     (long) value);
11902           break;
11903         }
11904
11905       newval = md_chars_to_number (buf, INSN_SIZE);
11906       newval &= 0xff7ff0f0;
11907       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11908       md_number_to_chars (buf, newval, INSN_SIZE);
11909       break;
11910
11911     case BFD_RELOC_ARM_LITERAL:
11912       sign = value >= 0;
11913
11914       if (value < 0)
11915         value = - value;
11916
11917       if (validate_offset_imm (value, 0) == FAIL)
11918         {
11919           as_bad_where (fixP->fx_file, fixP->fx_line,
11920                         _("invalid literal constant: pool needs to be closer"));
11921           break;
11922         }
11923
11924       newval = md_chars_to_number (buf, INSN_SIZE);
11925       newval &= 0xff7ff000;
11926       newval |= value | (sign ? INDEX_UP : 0);
11927       md_number_to_chars (buf, newval, INSN_SIZE);
11928       break;
11929
11930     case BFD_RELOC_ARM_SHIFT_IMM:
11931       newval = md_chars_to_number (buf, INSN_SIZE);
11932       if (((unsigned long) value) > 32
11933           || (value == 32
11934               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11935         {
11936           as_bad_where (fixP->fx_file, fixP->fx_line,
11937                         _("shift expression is too large"));
11938           break;
11939         }
11940
11941       if (value == 0)
11942         /* Shifts of zero must be done as lsl.  */
11943         newval &= ~0x60;
11944       else if (value == 32)
11945         value = 0;
11946       newval &= 0xfffff07f;
11947       newval |= (value & 0x1f) << 7;
11948       md_number_to_chars (buf, newval, INSN_SIZE);
11949       break;
11950
11951     case BFD_RELOC_ARM_SMI:
11952       if (((unsigned long) value) > 0xffff)
11953         as_bad_where (fixP->fx_file, fixP->fx_line,
11954                       _("invalid smi expression"));
11955       newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0;
11956       newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11957       md_number_to_chars (buf, newval, INSN_SIZE);
11958       break;
11959
11960     case BFD_RELOC_ARM_SWI:
11961       if (arm_data->thumb_mode)
11962         {
11963           if (((unsigned long) value) > 0xff)
11964             as_bad_where (fixP->fx_file, fixP->fx_line,
11965                           _("invalid swi expression"));
11966           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11967           newval |= value;
11968           md_number_to_chars (buf, newval, THUMB_SIZE);
11969         }
11970       else
11971         {
11972           if (((unsigned long) value) > 0x00ffffff)
11973             as_bad_where (fixP->fx_file, fixP->fx_line,
11974                           _("invalid swi expression"));
11975           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11976           newval |= value;
11977           md_number_to_chars (buf, newval, INSN_SIZE);
11978         }
11979       break;
11980
11981     case BFD_RELOC_ARM_MULTI:
11982       if (((unsigned long) value) > 0xffff)
11983         as_bad_where (fixP->fx_file, fixP->fx_line,
11984                       _("invalid expression in load/store multiple"));
11985       newval = value | md_chars_to_number (buf, INSN_SIZE);
11986       md_number_to_chars (buf, newval, INSN_SIZE);
11987       break;
11988
11989     case BFD_RELOC_ARM_PCREL_BRANCH:
11990       newval = md_chars_to_number (buf, INSN_SIZE);
11991
11992       /* Sign-extend a 24-bit number.  */
11993 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11994
11995 #ifdef OBJ_ELF
11996       value = fixP->fx_offset;
11997 #endif
11998
11999       /* We are going to store value (shifted right by two) in the
12000          instruction, in a 24 bit, signed field.  Thus we need to check
12001          that none of the top 8 bits of the shifted value (top 7 bits of
12002          the unshifted, unsigned value) are set, or that they are all set.  */
12003       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12004           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12005         {
12006 #ifdef OBJ_ELF
12007           /* Normally we would be stuck at this point, since we cannot store
12008              the absolute address that is the destination of the branch in the
12009              24 bits of the branch instruction.  If however, we happen to know
12010              that the destination of the branch is in the same section as the
12011              branch instruction itself, then we can compute the relocation for
12012              ourselves and not have to bother the linker with it.
12013
12014              FIXME: The test for OBJ_ELF is only here because I have not
12015              worked out how to do this for OBJ_COFF.  */
12016           if (fixP->fx_addsy != NULL
12017               && S_IS_DEFINED (fixP->fx_addsy)
12018               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12019             {
12020               /* Get pc relative value to go into the branch.  */
12021               value = * valP;
12022
12023               /* Permit a backward branch provided that enough bits
12024                  are set.  Allow a forwards branch, provided that
12025                  enough bits are clear.  */
12026               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12027                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12028                 fixP->fx_done = 1;
12029             }
12030
12031           if (! fixP->fx_done)
12032 #endif
12033             as_bad_where (fixP->fx_file, fixP->fx_line,
12034                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12035         }
12036
12037       value >>= 2;
12038       value += SEXT24 (newval);
12039
12040       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12041           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12042         as_bad_where (fixP->fx_file, fixP->fx_line,
12043                       _("out of range branch"));
12044
12045       if (seg->use_rela_p && !fixP->fx_done)
12046         {
12047           /* Must unshift the value before storing it in the addend.  */
12048           value <<= 2;
12049 #ifdef OBJ_ELF
12050           fixP->fx_offset = value;
12051 #endif
12052           fixP->fx_addnumber = value;
12053           newval = newval & 0xff000000;
12054         }
12055       else
12056           newval = (value & 0x00ffffff) | (newval & 0xff000000);
12057       md_number_to_chars (buf, newval, INSN_SIZE);
12058       break;
12059
12060     case BFD_RELOC_ARM_PCREL_BLX:
12061       {
12062         offsetT hbit;
12063         newval = md_chars_to_number (buf, INSN_SIZE);
12064
12065 #ifdef OBJ_ELF
12066         value = fixP->fx_offset;
12067 #endif
12068         hbit   = (value >> 1) & 1;
12069         value  = (value >> 2) & 0x00ffffff;
12070         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12071
12072         if (seg->use_rela_p && !fixP->fx_done)
12073           {
12074             /* Must sign-extend and unshift the value before storing
12075                it in the addend.  */
12076             value = SEXT24 (value);
12077             value = (value << 2) | hbit;
12078 #ifdef OBJ_ELF
12079             fixP->fx_offset = value;
12080 #endif
12081             fixP->fx_addnumber = value;
12082             newval = newval & 0xfe000000;
12083           }
12084         else
12085           newval = value | (newval & 0xfe000000) | (hbit << 24);
12086         md_number_to_chars (buf, newval, INSN_SIZE);
12087       }
12088       break;
12089
12090     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12091       newval = md_chars_to_number (buf, THUMB_SIZE);
12092       {
12093         addressT diff = (newval & 0xff) << 1;
12094         if (diff & 0x100)
12095           diff |= ~0xff;
12096
12097         value += diff;
12098         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12099           as_bad_where (fixP->fx_file, fixP->fx_line,
12100                         _("branch out of range"));
12101         if (seg->use_rela_p && !fixP->fx_done)
12102           {
12103 #ifdef OBJ_ELF
12104             fixP->fx_offset = value;
12105 #endif
12106             fixP->fx_addnumber = value;
12107             newval = newval & 0xff00;
12108           }
12109         else
12110           newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12111       }
12112       md_number_to_chars (buf, newval, THUMB_SIZE);
12113       break;
12114
12115     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12116       newval = md_chars_to_number (buf, THUMB_SIZE);
12117       {
12118         addressT diff = (newval & 0x7ff) << 1;
12119         if (diff & 0x800)
12120           diff |= ~0x7ff;
12121
12122         value += diff;
12123         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12124           as_bad_where (fixP->fx_file, fixP->fx_line,
12125                         _("branch out of range"));
12126         if (seg->use_rela_p && !fixP->fx_done)
12127           {
12128 #ifdef OBJ_ELF
12129             fixP->fx_offset = value;
12130 #endif
12131             fixP->fx_addnumber = value;
12132             newval = newval & 0xf800;
12133           }
12134         else
12135           newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12136       }
12137       md_number_to_chars (buf, newval, THUMB_SIZE);
12138       break;
12139
12140     case BFD_RELOC_THUMB_PCREL_BLX:
12141     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12142       {
12143         offsetT newval2;
12144         addressT diff;
12145
12146         newval  = md_chars_to_number (buf, THUMB_SIZE);
12147         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12148         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12149         if (diff & 0x400000)
12150           diff |= ~0x3fffff;
12151 #ifdef OBJ_ELF
12152         value = fixP->fx_offset;
12153 #endif
12154         value += diff;
12155
12156         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12157           as_bad_where (fixP->fx_file, fixP->fx_line,
12158                         _("branch with link out of range"));
12159
12160         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12161           /* For a BLX instruction, make sure that the relocation is rounded up
12162              to a word boundary.  This follows the semantics of the instruction
12163              which specifies that bit 1 of the target address will come from bit
12164              1 of the base address.  */
12165           value = (value + 1) & ~ 1;
12166
12167         if (seg->use_rela_p && !fixP->fx_done)
12168           {
12169 #ifdef OBJ_ELF
12170             fixP->fx_offset = value;
12171 #endif
12172             fixP->fx_addnumber = value;
12173             newval = newval & 0xf800;
12174             newval2 = newval2 & 0xf800;
12175           }
12176         else
12177           {
12178             newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12179             newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12180           }
12181         md_number_to_chars (buf, newval, THUMB_SIZE);
12182         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12183       }
12184       break;
12185
12186     case BFD_RELOC_8:
12187       if (seg->use_rela_p && !fixP->fx_done)
12188         break;
12189       if (fixP->fx_done || fixP->fx_pcrel)
12190         md_number_to_chars (buf, value, 1);
12191 #ifdef OBJ_ELF
12192       else
12193         {
12194           value = fixP->fx_offset;
12195           md_number_to_chars (buf, value, 1);
12196         }
12197 #endif
12198       break;
12199
12200     case BFD_RELOC_16:
12201       if (seg->use_rela_p && !fixP->fx_done)
12202         break;
12203       if (fixP->fx_done || fixP->fx_pcrel)
12204         md_number_to_chars (buf, value, 2);
12205 #ifdef OBJ_ELF
12206       else
12207         {
12208           value = fixP->fx_offset;
12209           md_number_to_chars (buf, value, 2);
12210         }
12211 #endif
12212       break;
12213
12214 #ifdef OBJ_ELF
12215     case BFD_RELOC_ARM_GOT32:
12216     case BFD_RELOC_ARM_GOTOFF:
12217     case BFD_RELOC_ARM_TARGET2:
12218       if (seg->use_rela_p && !fixP->fx_done)
12219         break;
12220       md_number_to_chars (buf, 0, 4);
12221       break;
12222 #endif
12223
12224     case BFD_RELOC_RVA:
12225     case BFD_RELOC_32:
12226     case BFD_RELOC_ARM_TARGET1:
12227     case BFD_RELOC_ARM_ROSEGREL32:
12228     case BFD_RELOC_ARM_SBREL32:
12229     case BFD_RELOC_32_PCREL:
12230       if (seg->use_rela_p && !fixP->fx_done)
12231         break;
12232       if (fixP->fx_done || fixP->fx_pcrel)
12233         md_number_to_chars (buf, value, 4);
12234 #ifdef OBJ_ELF
12235       else
12236         {
12237           value = fixP->fx_offset;
12238           md_number_to_chars (buf, value, 4);
12239         }
12240 #endif
12241       break;
12242
12243 #ifdef OBJ_ELF
12244     case BFD_RELOC_ARM_PREL31:
12245       if (fixP->fx_done || fixP->fx_pcrel)
12246         {
12247           newval = md_chars_to_number (buf, 4) & 0x80000000;
12248           if ((value ^ (value >> 1)) & 0x40000000)
12249             {
12250               as_bad_where (fixP->fx_file, fixP->fx_line,
12251                             _("rel31 relocation overflow"));
12252             }
12253           newval |= value & 0x7fffffff;
12254           md_number_to_chars (buf, newval, 4);
12255         }
12256       break;
12257
12258     case BFD_RELOC_ARM_PLT32:
12259       /* It appears the instruction is fully prepared at this point.  */
12260       break;
12261 #endif
12262
12263     case BFD_RELOC_ARM_CP_OFF_IMM:
12264       sign = value >= 0;
12265       if (value < -1023 || value > 1023 || (value & 3))
12266         as_bad_where (fixP->fx_file, fixP->fx_line,
12267                       _("illegal value for co-processor offset"));
12268       if (value < 0)
12269         value = -value;
12270       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12271       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12272       md_number_to_chars (buf, newval, INSN_SIZE);
12273       break;
12274
12275     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12276       sign = value >= 0;
12277       if (value < -255 || value > 255)
12278         as_bad_where (fixP->fx_file, fixP->fx_line,
12279                       _("Illegal value for co-processor offset"));
12280       if (value < 0)
12281         value = -value;
12282       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12283       newval |= value | (sign ?  INDEX_UP : 0);
12284       md_number_to_chars (buf, newval , INSN_SIZE);
12285       break;
12286
12287     case BFD_RELOC_ARM_THUMB_OFFSET:
12288       newval = md_chars_to_number (buf, THUMB_SIZE);
12289       /* Exactly what ranges, and where the offset is inserted depends
12290          on the type of instruction, we can establish this from the
12291          top 4 bits.  */
12292       switch (newval >> 12)
12293         {
12294         case 4: /* PC load.  */
12295           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12296              forced to zero for these loads, so we will need to round
12297              up the offset if the instruction address is not word
12298              aligned (since the final address produced must be, and
12299              we can only describe word-aligned immediate offsets).  */
12300
12301           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12302             as_bad_where (fixP->fx_file, fixP->fx_line,
12303                           _("invalid offset, target not word aligned (0x%08X)"),
12304                           (unsigned int) (fixP->fx_frag->fr_address
12305                                           + fixP->fx_where + value));
12306
12307           if ((value + 2) & ~0x3fe)
12308             as_bad_where (fixP->fx_file, fixP->fx_line,
12309                           _("invalid offset, value too big (0x%08lX)"),
12310                           (long) value);
12311
12312           /* Round up, since pc will be rounded down.  */
12313           newval |= (value + 2) >> 2;
12314           break;
12315
12316         case 9: /* SP load/store.  */
12317           if (value & ~0x3fc)
12318             as_bad_where (fixP->fx_file, fixP->fx_line,
12319                           _("invalid offset, value too big (0x%08lX)"),
12320                           (long) value);
12321           newval |= value >> 2;
12322           break;
12323
12324         case 6: /* Word load/store.  */
12325           if (value & ~0x7c)
12326             as_bad_where (fixP->fx_file, fixP->fx_line,
12327                           _("invalid offset, value too big (0x%08lX)"),
12328                           (long) value);
12329           newval |= value << 4; /* 6 - 2.  */
12330           break;
12331
12332         case 7: /* Byte load/store.  */
12333           if (value & ~0x1f)
12334             as_bad_where (fixP->fx_file, fixP->fx_line,
12335                           _("invalid offset, value too big (0x%08lX)"),
12336                           (long) value);
12337           newval |= value << 6;
12338           break;
12339
12340         case 8: /* Halfword load/store.  */
12341           if (value & ~0x3e)
12342             as_bad_where (fixP->fx_file, fixP->fx_line,
12343                           _("invalid offset, value too big (0x%08lX)"),
12344                           (long) value);
12345           newval |= value << 5; /* 6 - 1.  */
12346           break;
12347
12348         default:
12349           as_bad_where (fixP->fx_file, fixP->fx_line,
12350                         "Unable to process relocation for thumb opcode: %lx",
12351                         (unsigned long) newval);
12352           break;
12353         }
12354       md_number_to_chars (buf, newval, THUMB_SIZE);
12355       break;
12356
12357     case BFD_RELOC_ARM_THUMB_ADD:
12358       /* This is a complicated relocation, since we use it for all of
12359          the following immediate relocations:
12360
12361             3bit ADD/SUB
12362             8bit ADD/SUB
12363             9bit ADD/SUB SP word-aligned
12364            10bit ADD PC/SP word-aligned
12365
12366          The type of instruction being processed is encoded in the
12367          instruction field:
12368
12369            0x8000  SUB
12370            0x00F0  Rd
12371            0x000F  Rs
12372       */
12373       newval = md_chars_to_number (buf, THUMB_SIZE);
12374       {
12375         int rd = (newval >> 4) & 0xf;
12376         int rs = newval & 0xf;
12377         int subtract = newval & 0x8000;
12378
12379         if (rd == REG_SP)
12380           {
12381             if (value & ~0x1fc)
12382               as_bad_where (fixP->fx_file, fixP->fx_line,
12383                             _("invalid immediate for stack address calculation"));
12384             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12385             newval |= value >> 2;
12386           }
12387         else if (rs == REG_PC || rs == REG_SP)
12388           {
12389             if (subtract ||
12390                 value & ~0x3fc)
12391               as_bad_where (fixP->fx_file, fixP->fx_line,
12392                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12393                             (unsigned long) value);
12394             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12395             newval |= rd << 8;
12396             newval |= value >> 2;
12397           }
12398         else if (rs == rd)
12399           {
12400             if (value & ~0xff)
12401               as_bad_where (fixP->fx_file, fixP->fx_line,
12402                             _("invalid 8bit immediate"));
12403             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12404             newval |= (rd << 8) | value;
12405           }
12406         else
12407           {
12408             if (value & ~0x7)
12409               as_bad_where (fixP->fx_file, fixP->fx_line,
12410                             _("invalid 3bit immediate"));
12411             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12412             newval |= rd | (rs << 3) | (value << 6);
12413           }
12414       }
12415       md_number_to_chars (buf, newval, THUMB_SIZE);
12416       break;
12417
12418     case BFD_RELOC_ARM_THUMB_IMM:
12419       newval = md_chars_to_number (buf, THUMB_SIZE);
12420       switch (newval >> 11)
12421         {
12422         case 0x04: /* 8bit immediate MOV.  */
12423         case 0x05: /* 8bit immediate CMP.  */
12424           if (value < 0 || value > 255)
12425             as_bad_where (fixP->fx_file, fixP->fx_line,
12426                           _("invalid immediate: %ld is too large"),
12427                           (long) value);
12428           newval |= value;
12429           break;
12430
12431         default:
12432           abort ();
12433         }
12434       md_number_to_chars (buf, newval, THUMB_SIZE);
12435       break;
12436
12437     case BFD_RELOC_ARM_THUMB_SHIFT:
12438       /* 5bit shift value (0..31).  */
12439       if (value < 0 || value > 31)
12440         as_bad_where (fixP->fx_file, fixP->fx_line,
12441                       _("illegal Thumb shift value: %ld"), (long) value);
12442       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12443       newval |= value << 6;
12444       md_number_to_chars (buf, newval, THUMB_SIZE);
12445       break;
12446
12447     case BFD_RELOC_VTABLE_INHERIT:
12448     case BFD_RELOC_VTABLE_ENTRY:
12449       fixP->fx_done = 0;
12450       return;
12451
12452     case BFD_RELOC_UNUSED:
12453     default:
12454       as_bad_where (fixP->fx_file, fixP->fx_line,
12455                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12456     }
12457 }
12458
12459 /* Translate internal representation of relocation info to BFD target
12460    format.  */
12461
12462 arelent *
12463 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
12464               fixS *     fixp)
12465 {
12466   arelent * reloc;
12467   bfd_reloc_code_real_type code;
12468
12469   reloc = xmalloc (sizeof (arelent));
12470
12471   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
12472   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12473   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12474
12475   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12476 #ifndef OBJ_ELF
12477   if (fixp->fx_pcrel == 0)
12478     reloc->addend = fixp->fx_offset;
12479   else
12480     reloc->addend = fixp->fx_offset = reloc->address;
12481 #else  /* OBJ_ELF */
12482   reloc->addend = fixp->fx_offset;
12483 #endif
12484
12485   switch (fixp->fx_r_type)
12486     {
12487     case BFD_RELOC_8:
12488       if (fixp->fx_pcrel)
12489         {
12490           code = BFD_RELOC_8_PCREL;
12491           break;
12492         }
12493
12494     case BFD_RELOC_16:
12495       if (fixp->fx_pcrel)
12496         {
12497           code = BFD_RELOC_16_PCREL;
12498           break;
12499         }
12500
12501     case BFD_RELOC_32:
12502       if (fixp->fx_pcrel)
12503         {
12504           code = BFD_RELOC_32_PCREL;
12505           break;
12506         }
12507
12508     case BFD_RELOC_NONE:
12509     case BFD_RELOC_ARM_PCREL_BRANCH:
12510     case BFD_RELOC_ARM_PCREL_BLX:
12511     case BFD_RELOC_RVA:
12512     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12513     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12514     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12515     case BFD_RELOC_THUMB_PCREL_BLX:
12516     case BFD_RELOC_VTABLE_ENTRY:
12517     case BFD_RELOC_VTABLE_INHERIT:
12518       code = fixp->fx_r_type;
12519       break;
12520
12521     case BFD_RELOC_ARM_LITERAL:
12522     case BFD_RELOC_ARM_HWLITERAL:
12523       /* If this is called then the a literal has
12524          been referenced across a section boundary.  */
12525       as_bad_where (fixp->fx_file, fixp->fx_line,
12526                     _("literal referenced across section boundary"));
12527       return NULL;
12528
12529 #ifdef OBJ_ELF
12530     case BFD_RELOC_ARM_GOT32:
12531     case BFD_RELOC_ARM_GOTOFF:
12532     case BFD_RELOC_ARM_PLT32:
12533     case BFD_RELOC_ARM_TARGET1:
12534     case BFD_RELOC_ARM_ROSEGREL32:
12535     case BFD_RELOC_ARM_SBREL32:
12536     case BFD_RELOC_ARM_PREL31:
12537     case BFD_RELOC_ARM_TARGET2:
12538       code = fixp->fx_r_type;
12539       break;
12540 #endif
12541
12542     case BFD_RELOC_ARM_IMMEDIATE:
12543       as_bad_where (fixp->fx_file, fixp->fx_line,
12544                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12545       return NULL;
12546
12547     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12548       as_bad_where (fixp->fx_file, fixp->fx_line,
12549                     _("ADRL used for a symbol not defined in the same file"));
12550       return NULL;
12551
12552     case BFD_RELOC_ARM_OFFSET_IMM:
12553       if (fixp->fx_addsy != NULL
12554           && !S_IS_DEFINED (fixp->fx_addsy)
12555           && S_IS_LOCAL (fixp->fx_addsy))
12556         {
12557           as_bad_where (fixp->fx_file, fixp->fx_line,
12558                         _("undefined local label `%s'"),
12559                         S_GET_NAME (fixp->fx_addsy));
12560           return NULL;
12561         }
12562
12563       as_bad_where (fixp->fx_file, fixp->fx_line,
12564                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12565       return NULL;
12566
12567     default:
12568       {
12569         char * type;
12570
12571         switch (fixp->fx_r_type)
12572           {
12573           case BFD_RELOC_NONE:             type = "NONE";         break;
12574           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12575           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12576           case BFD_RELOC_ARM_SMI:          type = "SMI";          break;
12577           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12578           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12579           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12580           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12581           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12582           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12583           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12584           default:                         type = _("<unknown>"); break;
12585           }
12586         as_bad_where (fixp->fx_file, fixp->fx_line,
12587                       _("cannot represent %s relocation in this object file format"),
12588                       type);
12589         return NULL;
12590       }
12591     }
12592
12593 #ifdef OBJ_ELF
12594   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12595       && GOT_symbol
12596       && fixp->fx_addsy == GOT_symbol)
12597     {
12598       code = BFD_RELOC_ARM_GOTPC;
12599       reloc->addend = fixp->fx_offset = reloc->address;
12600     }
12601 #endif
12602
12603   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12604
12605   if (reloc->howto == NULL)
12606     {
12607       as_bad_where (fixp->fx_file, fixp->fx_line,
12608                     _("cannot represent %s relocation in this object file format"),
12609                     bfd_get_reloc_code_name (code));
12610       return NULL;
12611     }
12612
12613   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12614      vtable entry to be used in the relocation's section offset.  */
12615   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12616     reloc->address = fixp->fx_offset;
12617
12618   return reloc;
12619 }
12620
12621 int
12622 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
12623                                segT    segtype ATTRIBUTE_UNUSED)
12624 {
12625   as_fatal (_("md_estimate_size_before_relax\n"));
12626   return 1;
12627 }
12628
12629 /* We need to be able to fix up arbitrary expressions in some statements.
12630    This is so that we can handle symbols that are an arbitrary distance from
12631    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12632    which returns part of an address in a form which will be valid for
12633    a data instruction.  We do this by pushing the expression into a symbol
12634    in the expr_section, and creating a fix for that.  */
12635
12636 static void
12637 fix_new_arm (fragS *       frag,
12638              int           where,
12639              short int     size,
12640              expressionS * exp,
12641              int           pc_rel,
12642              int           reloc)
12643 {
12644   fixS *           new_fix;
12645   arm_fix_data *   arm_data;
12646
12647   switch (exp->X_op)
12648     {
12649     case O_constant:
12650     case O_symbol:
12651     case O_add:
12652     case O_subtract:
12653       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12654       break;
12655
12656     default:
12657       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12658                          pc_rel, reloc);
12659       break;
12660     }
12661
12662   /* Mark whether the fix is to a THUMB instruction, or an ARM
12663      instruction.  */
12664   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
12665   new_fix->tc_fix_data = (PTR) arm_data;
12666   arm_data->thumb_mode = thumb_mode;
12667 }
12668
12669 static void
12670 output_inst (const char * str)
12671 {
12672   char * to = NULL;
12673
12674   if (inst.error)
12675     {
12676       as_bad ("%s -- `%s'", inst.error, str);
12677       return;
12678     }
12679
12680   to = frag_more (inst.size);
12681
12682   if (thumb_mode && (inst.size > THUMB_SIZE))
12683     {
12684       assert (inst.size == (2 * THUMB_SIZE));
12685       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12686       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12687     }
12688   else if (inst.size > INSN_SIZE)
12689     {
12690       assert (inst.size == (2 * INSN_SIZE));
12691       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12692       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12693     }
12694   else
12695     md_number_to_chars (to, inst.instruction, inst.size);
12696
12697   if (inst.reloc.type != BFD_RELOC_UNUSED)
12698     fix_new_arm (frag_now, to - frag_now->fr_literal,
12699                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12700                  inst.reloc.type);
12701
12702 #ifdef OBJ_ELF
12703   dwarf2_emit_insn (inst.size);
12704 #endif
12705 }
12706
12707 void
12708 md_assemble (char * str)
12709 {
12710   char  c;
12711   char *p;
12712   char *start;
12713
12714   /* Align the previous label if needed.  */
12715   if (last_label_seen != NULL)
12716     {
12717       symbol_set_frag (last_label_seen, frag_now);
12718       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12719       S_SET_SEGMENT (last_label_seen, now_seg);
12720     }
12721
12722   memset (&inst, '\0', sizeof (inst));
12723   inst.reloc.type = BFD_RELOC_UNUSED;
12724
12725   skip_whitespace (str);
12726
12727   /* Scan up to the end of the op-code, which must end in white space or
12728      end of string.  */
12729   for (start = p = str; *p != '\0'; p++)
12730     if (*p == ' ')
12731       break;
12732
12733   if (p == str)
12734     {
12735       as_bad (_("no operator -- statement `%s'\n"), str);
12736       return;
12737     }
12738
12739   if (thumb_mode)
12740     {
12741       const struct thumb_opcode * opcode;
12742
12743       c = *p;
12744       *p = '\0';
12745       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12746       *p = c;
12747
12748       if (opcode)
12749         {
12750           /* Check that this instruction is supported for this CPU.  */
12751           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12752             {
12753               as_bad (_("selected processor does not support `%s'"), str);
12754               return;
12755             }
12756
12757           mapping_state (MAP_THUMB);
12758           inst.instruction = opcode->value;
12759           inst.size = opcode->size;
12760           opcode->parms (p);
12761           output_inst (str);
12762           return;
12763         }
12764     }
12765   else
12766     {
12767       const struct asm_opcode * opcode;
12768
12769       c = *p;
12770       *p = '\0';
12771       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12772       *p = c;
12773
12774       if (opcode)
12775         {
12776           /* Check that this instruction is supported for this CPU.  */
12777           if ((opcode->variant & cpu_variant) == 0)
12778             {
12779               as_bad (_("selected processor does not support `%s'"), str);
12780               return;
12781             }
12782
12783           mapping_state (MAP_ARM);
12784           inst.instruction = opcode->value;
12785           inst.size = INSN_SIZE;
12786           opcode->parms (p);
12787           output_inst (str);
12788           return;
12789         }
12790     }
12791
12792   /* It wasn't an instruction, but it might be a register alias of the form
12793      alias .req reg.  */
12794   if (create_register_alias (str, p))
12795     return;
12796
12797   as_bad (_("bad instruction `%s'"), start);
12798 }
12799
12800 /* md_parse_option
12801       Invocation line includes a switch not recognized by the base assembler.
12802       See if it's a processor-specific option.
12803
12804       This routine is somewhat complicated by the need for backwards
12805       compatibility (since older releases of gcc can't be changed).
12806       The new options try to make the interface as compatible as
12807       possible with GCC.
12808
12809       New options (supported) are:
12810
12811               -mcpu=<cpu name>           Assemble for selected processor
12812               -march=<architecture name> Assemble for selected architecture
12813               -mfpu=<fpu architecture>   Assemble for selected FPU.
12814               -EB/-mbig-endian           Big-endian
12815               -EL/-mlittle-endian        Little-endian
12816               -k                         Generate PIC code
12817               -mthumb                    Start in Thumb mode
12818               -mthumb-interwork          Code supports ARM/Thumb interworking
12819
12820       For now we will also provide support for:
12821
12822               -mapcs-32                  32-bit Program counter
12823               -mapcs-26                  26-bit Program counter
12824               -macps-float               Floats passed in FP registers
12825               -mapcs-reentrant           Reentrant code
12826               -matpcs
12827       (sometime these will probably be replaced with -mapcs=<list of options>
12828       and -matpcs=<list of options>)
12829
12830       The remaining options are only supported for back-wards compatibility.
12831       Cpu variants, the arm part is optional:
12832               -m[arm]1                Currently not supported.
12833               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
12834               -m[arm]3                Arm 3 processor
12835               -m[arm]6[xx],           Arm 6 processors
12836               -m[arm]7[xx][t][[d]m]   Arm 7 processors
12837               -m[arm]8[10]            Arm 8 processors
12838               -m[arm]9[20][tdmi]      Arm 9 processors
12839               -mstrongarm[110[0]]     StrongARM processors
12840               -mxscale                XScale processors
12841               -m[arm]v[2345[t[e]]]    Arm architectures
12842               -mall                   All (except the ARM1)
12843       FP variants:
12844               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
12845               -mfpe-old               (No float load/store multiples)
12846               -mvfpxd                 VFP Single precision
12847               -mvfp                   All VFP
12848               -mno-fpu                Disable all floating point instructions
12849
12850       The following CPU names are recognized:
12851               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12852               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12853               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12854               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12855               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12856               arm10t arm10e, arm1020t, arm1020e, arm10200e,
12857               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
12858
12859       */
12860
12861 const char * md_shortopts = "m:k";
12862
12863 #ifdef ARM_BI_ENDIAN
12864 #define OPTION_EB (OPTION_MD_BASE + 0)
12865 #define OPTION_EL (OPTION_MD_BASE + 1)
12866 #else
12867 #if TARGET_BYTES_BIG_ENDIAN
12868 #define OPTION_EB (OPTION_MD_BASE + 0)
12869 #else
12870 #define OPTION_EL (OPTION_MD_BASE + 1)
12871 #endif
12872 #endif
12873
12874 struct option md_longopts[] =
12875 {
12876 #ifdef OPTION_EB
12877   {"EB", no_argument, NULL, OPTION_EB},
12878 #endif
12879 #ifdef OPTION_EL
12880   {"EL", no_argument, NULL, OPTION_EL},
12881 #endif
12882   {NULL, no_argument, NULL, 0}
12883 };
12884
12885 size_t md_longopts_size = sizeof (md_longopts);
12886
12887 struct arm_option_table
12888 {
12889   char *option;         /* Option name to match.  */
12890   char *help;           /* Help information.  */
12891   int  *var;            /* Variable to change.  */
12892   int   value;          /* What to change it to.  */
12893   char *deprecated;     /* If non-null, print this message.  */
12894 };
12895
12896 struct arm_option_table arm_opts[] =
12897 {
12898   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
12899   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
12900   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12901    &support_interwork, 1, NULL},
12902   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12903   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12904   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12905    1, NULL},
12906   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12907   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12908   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12909   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
12910    NULL},
12911
12912   /* These are recognized by the assembler, but have no affect on code.  */
12913   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12914   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12915
12916   /* DON'T add any new processors to this list -- we want the whole list
12917      to go away...  Add them to the processors table instead.  */
12918   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12919   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12920   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12921   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12922   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12923   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12924   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12925   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12926   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12927   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12928   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12929   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12930   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12931   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12932   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12933   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12934   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12935   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12936   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12937   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12938   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12939   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12940   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12941   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12942   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12943   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12944   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12945   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12946   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12947   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12948   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12949   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12950   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12951   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12952   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12953   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12954   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12955   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12956   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12957   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12958   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12959   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12960   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12961   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12962   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12963   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12964   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12965   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12966   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12967   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12968   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12969   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12970   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12971   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12972   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12973   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12974   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12975   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12976   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12977   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12978   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12979   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12980   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12981   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12982   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12983   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12984   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12985   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12986   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
12987   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12988    N_("use -mcpu=strongarm110")},
12989   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12990    N_("use -mcpu=strongarm1100")},
12991   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12992    N_("use -mcpu=strongarm1110")},
12993   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12994   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12995   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
12996
12997   /* Architecture variants -- don't add any more to this list either.  */
12998   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12999   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13000   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13001   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13002   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13003   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13004   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13005   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13006   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13007   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13008   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13009   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13010   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13011   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13012   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13013   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13014   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13015   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13016
13017   /* Floating point variants -- don't add any more to this list either.  */
13018   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13019   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13020   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13021   {"mno-fpu",  NULL, &legacy_fpu, 0,
13022    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13023
13024   {NULL, NULL, NULL, 0, NULL}
13025 };
13026
13027 struct arm_cpu_option_table
13028 {
13029   char *name;
13030   int   value;
13031   /* For some CPUs we assume an FPU unless the user explicitly sets
13032      -mfpu=...  */
13033   int   default_fpu;
13034 };
13035
13036 /* This list should, at a minimum, contain all the cpu names
13037    recognized by GCC.  */
13038 static struct arm_cpu_option_table arm_cpus[] =
13039 {
13040   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13041   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13042   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13043   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13044   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13045   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13046   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13047   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13048   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13049   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13050   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13051   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13052   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13053   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13054   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13055   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13056   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13057   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13058   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13059   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13060   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13061   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13062   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13063   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13064   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13065   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13066   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13067   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13068   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13069   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13070   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
13071   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13072   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13073   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13074   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13075   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13076   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13077   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13078   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13079   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13080   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13081   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13082   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13083   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13084   /* For V5 or later processors we default to using VFP; but the user
13085      should really set the FPU type explicitly.  */
13086   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13087   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13088   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13089   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13090   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13091   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13092   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13093   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13094   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13095   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13096   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13097   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13098   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13099   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13100   {"arm1026ejs",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13101   {"arm1026ej-s",       ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13102   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13103   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
13104   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13105   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13106   {"mpcore",            ARM_ARCH_V6K,    FPU_ARCH_VFP_V2},
13107   {"mpcorenovfp",       ARM_ARCH_V6K,    FPU_NONE},
13108   {"arm1176jz-s",       ARM_ARCH_V6ZK,   FPU_NONE},
13109   {"arm1176jzf-s",      ARM_ARCH_V6ZK,   FPU_ARCH_VFP_V2},
13110   /* ??? XSCALE is really an architecture.  */
13111   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13112   /* ??? iwmmxt is not a processor.  */
13113   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13114   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13115   /* Maverick */
13116   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13117   {NULL, 0, 0}
13118 };
13119
13120 struct arm_arch_option_table
13121 {
13122   char *name;
13123   int   value;
13124   int   default_fpu;
13125 };
13126
13127 /* This list should, at a minimum, contain all the architecture names
13128    recognized by GCC.  */
13129 static struct arm_arch_option_table arm_archs[] =
13130 {
13131   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13132   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13133   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13134   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13135   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13136   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13137   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13138   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13139   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13140   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13141   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13142   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13143   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13144   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13145   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13146   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13147   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13148   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13149   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13150   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
13151   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
13152   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
13153   {"armv6t2",           ARM_ARCH_V6T2,   FPU_ARCH_VFP},
13154   {"armv6kt2",          ARM_ARCH_V6KT2,  FPU_ARCH_VFP},
13155   {"armv6zt2",          ARM_ARCH_V6ZT2,  FPU_ARCH_VFP},
13156   {"armv6zkt2",         ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
13157   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13158   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13159   {NULL, 0, 0}
13160 };
13161
13162 /* ISA extensions in the co-processor space.  */
13163 struct arm_arch_extension_table
13164 {
13165   char *name;
13166   int value;
13167 };
13168
13169 static struct arm_arch_extension_table arm_extensions[] =
13170 {
13171   {"maverick",          ARM_CEXT_MAVERICK},
13172   {"xscale",            ARM_CEXT_XSCALE},
13173   {"iwmmxt",            ARM_CEXT_IWMMXT},
13174   {NULL,                0}
13175 };
13176
13177 struct arm_fpu_option_table
13178 {
13179   char *name;
13180   int   value;
13181 };
13182
13183 /* This list should, at a minimum, contain all the fpu names
13184    recognized by GCC.  */
13185 static struct arm_fpu_option_table arm_fpus[] =
13186 {
13187   {"softfpa",           FPU_NONE},
13188   {"fpe",               FPU_ARCH_FPE},
13189   {"fpe2",              FPU_ARCH_FPE},
13190   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13191   {"fpa",               FPU_ARCH_FPA},
13192   {"fpa10",             FPU_ARCH_FPA},
13193   {"fpa11",             FPU_ARCH_FPA},
13194   {"arm7500fe",         FPU_ARCH_FPA},
13195   {"softvfp",           FPU_ARCH_VFP},
13196   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13197   {"vfp",               FPU_ARCH_VFP_V2},
13198   {"vfp9",              FPU_ARCH_VFP_V2},
13199   {"vfp10",             FPU_ARCH_VFP_V2},
13200   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13201   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13202   {"arm1020t",          FPU_ARCH_VFP_V1},
13203   {"arm1020e",          FPU_ARCH_VFP_V2},
13204   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13205   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
13206   {"maverick",          FPU_ARCH_MAVERICK},
13207   {NULL, 0}
13208 };
13209
13210 struct arm_float_abi_option_table
13211 {
13212   char *name;
13213   int value;
13214 };
13215
13216 static struct arm_float_abi_option_table arm_float_abis[] =
13217 {
13218   {"hard",      ARM_FLOAT_ABI_HARD},
13219   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13220   {"soft",      ARM_FLOAT_ABI_SOFT},
13221   {NULL, 0}
13222 };
13223
13224 struct arm_eabi_option_table
13225 {
13226   char *name;
13227   unsigned int value;
13228 };
13229
13230 #ifdef OBJ_ELF
13231 /* We only know how to output GNU and ver 4 (AAELF) formats.  */
13232 static struct arm_eabi_option_table arm_eabis[] =
13233 {
13234   {"gnu",       EF_ARM_EABI_UNKNOWN},
13235   {"4",         EF_ARM_EABI_VER4},
13236   {NULL, 0}
13237 };
13238 #endif
13239
13240 struct arm_long_option_table
13241 {
13242   char * option;                /* Substring to match.  */
13243   char * help;                  /* Help information.  */
13244   int (* func) (char * subopt); /* Function to decode sub-option.  */
13245   char * deprecated;            /* If non-null, print this message.  */
13246 };
13247
13248 static int
13249 arm_parse_extension (char * str, int * opt_p)
13250 {
13251   while (str != NULL && *str != 0)
13252     {
13253       struct arm_arch_extension_table * opt;
13254       char * ext;
13255       int optlen;
13256
13257       if (*str != '+')
13258         {
13259           as_bad (_("invalid architectural extension"));
13260           return 0;
13261         }
13262
13263       str++;
13264       ext = strchr (str, '+');
13265
13266       if (ext != NULL)
13267         optlen = ext - str;
13268       else
13269         optlen = strlen (str);
13270
13271       if (optlen == 0)
13272         {
13273           as_bad (_("missing architectural extension"));
13274           return 0;
13275         }
13276
13277       for (opt = arm_extensions; opt->name != NULL; opt++)
13278         if (strncmp (opt->name, str, optlen) == 0)
13279           {
13280             *opt_p |= opt->value;
13281             break;
13282           }
13283
13284       if (opt->name == NULL)
13285         {
13286           as_bad (_("unknown architectural extnsion `%s'"), str);
13287           return 0;
13288         }
13289
13290       str = ext;
13291     };
13292
13293   return 1;
13294 }
13295
13296 static int
13297 arm_parse_cpu (char * str)
13298 {
13299   struct arm_cpu_option_table * opt;
13300   char * ext = strchr (str, '+');
13301   int optlen;
13302
13303   if (ext != NULL)
13304     optlen = ext - str;
13305   else
13306     optlen = strlen (str);
13307
13308   if (optlen == 0)
13309     {
13310       as_bad (_("missing cpu name `%s'"), str);
13311       return 0;
13312     }
13313
13314   for (opt = arm_cpus; opt->name != NULL; opt++)
13315     if (strncmp (opt->name, str, optlen) == 0)
13316       {
13317         mcpu_cpu_opt = opt->value;
13318         mcpu_fpu_opt = opt->default_fpu;
13319
13320         if (ext != NULL)
13321           return arm_parse_extension (ext, &mcpu_cpu_opt);
13322
13323         return 1;
13324       }
13325
13326   as_bad (_("unknown cpu `%s'"), str);
13327   return 0;
13328 }
13329
13330 static int
13331 arm_parse_arch (char * str)
13332 {
13333   struct arm_arch_option_table *opt;
13334   char *ext = strchr (str, '+');
13335   int optlen;
13336
13337   if (ext != NULL)
13338     optlen = ext - str;
13339   else
13340     optlen = strlen (str);
13341
13342   if (optlen == 0)
13343     {
13344       as_bad (_("missing architecture name `%s'"), str);
13345       return 0;
13346     }
13347
13348
13349   for (opt = arm_archs; opt->name != NULL; opt++)
13350     if (streq (opt->name, str))
13351       {
13352         march_cpu_opt = opt->value;
13353         march_fpu_opt = opt->default_fpu;
13354
13355         if (ext != NULL)
13356           return arm_parse_extension (ext, &march_cpu_opt);
13357
13358         return 1;
13359       }
13360
13361   as_bad (_("unknown architecture `%s'\n"), str);
13362   return 0;
13363 }
13364
13365 static int
13366 arm_parse_fpu (char * str)
13367 {
13368   struct arm_fpu_option_table * opt;
13369
13370   for (opt = arm_fpus; opt->name != NULL; opt++)
13371     if (streq (opt->name, str))
13372       {
13373         mfpu_opt = opt->value;
13374         return 1;
13375       }
13376
13377   as_bad (_("unknown floating point format `%s'\n"), str);
13378   return 0;
13379 }
13380
13381 static int
13382 arm_parse_float_abi (char * str)
13383 {
13384   struct arm_float_abi_option_table * opt;
13385
13386   for (opt = arm_float_abis; opt->name != NULL; opt++)
13387     if (streq (opt->name, str))
13388       {
13389         mfloat_abi_opt = opt->value;
13390         return 1;
13391       }
13392
13393   as_bad (_("unknown floating point abi `%s'\n"), str);
13394   return 0;
13395 }
13396
13397 #ifdef OBJ_ELF
13398 static int
13399 arm_parse_eabi (char * str)
13400 {
13401   struct arm_eabi_option_table *opt;
13402
13403   for (opt = arm_eabis; opt->name != NULL; opt++)
13404     if (streq (opt->name, str))
13405       {
13406         meabi_flags = opt->value;
13407         return 1;
13408       }
13409   as_bad (_("unknown EABI `%s'\n"), str);
13410   return 0;
13411 }
13412 #endif
13413
13414 struct arm_long_option_table arm_long_opts[] =
13415 {
13416   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13417    arm_parse_cpu, NULL},
13418   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13419    arm_parse_arch, NULL},
13420   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13421    arm_parse_fpu, NULL},
13422   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13423    arm_parse_float_abi, NULL},
13424 #ifdef OBJ_ELF
13425   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13426    arm_parse_eabi, NULL},
13427 #endif
13428   {NULL, NULL, 0, NULL}
13429 };
13430
13431 int
13432 md_parse_option (int c, char * arg)
13433 {
13434   struct arm_option_table *opt;
13435   struct arm_long_option_table *lopt;
13436
13437   switch (c)
13438     {
13439 #ifdef OPTION_EB
13440     case OPTION_EB:
13441       target_big_endian = 1;
13442       break;
13443 #endif
13444
13445 #ifdef OPTION_EL
13446     case OPTION_EL:
13447       target_big_endian = 0;
13448       break;
13449 #endif
13450
13451     case 'a':
13452       /* Listing option.  Just ignore these, we don't support additional
13453          ones.  */
13454       return 0;
13455
13456     default:
13457       for (opt = arm_opts; opt->option != NULL; opt++)
13458         {
13459           if (c == opt->option[0]
13460               && ((arg == NULL && opt->option[1] == 0)
13461                   || streq (arg, opt->option + 1)))
13462             {
13463 #if WARN_DEPRECATED
13464               /* If the option is deprecated, tell the user.  */
13465               if (opt->deprecated != NULL)
13466                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13467                            arg ? arg : "", _(opt->deprecated));
13468 #endif
13469
13470               if (opt->var != NULL)
13471                 *opt->var = opt->value;
13472
13473               return 1;
13474             }
13475         }
13476
13477       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13478         {
13479           /* These options are expected to have an argument.  */
13480           if (c == lopt->option[0]
13481               && arg != NULL
13482               && strncmp (arg, lopt->option + 1,
13483                           strlen (lopt->option + 1)) == 0)
13484             {
13485 #if WARN_DEPRECATED
13486               /* If the option is deprecated, tell the user.  */
13487               if (lopt->deprecated != NULL)
13488                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13489                            _(lopt->deprecated));
13490 #endif
13491
13492               /* Call the sup-option parser.  */
13493               return lopt->func (arg + strlen (lopt->option) - 1);
13494             }
13495         }
13496
13497       return 0;
13498     }
13499
13500   return 1;
13501 }
13502
13503 void
13504 md_show_usage (FILE * fp)
13505 {
13506   struct arm_option_table *opt;
13507   struct arm_long_option_table *lopt;
13508
13509   fprintf (fp, _(" ARM-specific assembler options:\n"));
13510
13511   for (opt = arm_opts; opt->option != NULL; opt++)
13512     if (opt->help != NULL)
13513       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13514
13515   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13516     if (lopt->help != NULL)
13517       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13518
13519 #ifdef OPTION_EB
13520   fprintf (fp, _("\
13521   -EB                     assemble code for a big-endian cpu\n"));
13522 #endif
13523
13524 #ifdef OPTION_EL
13525   fprintf (fp, _("\
13526   -EL                     assemble code for a little-endian cpu\n"));
13527 #endif
13528 }
13529
13530 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13531
13532 void
13533 cons_fix_new_arm (fragS *       frag,
13534                   int           where,
13535                   int           size,
13536                   expressionS * exp)
13537 {
13538   bfd_reloc_code_real_type type;
13539   int pcrel = 0;
13540
13541   /* Pick a reloc.
13542      FIXME: @@ Should look at CPU word size.  */
13543   switch (size)
13544     {
13545     case 1:
13546       type = BFD_RELOC_8;
13547       break;
13548     case 2:
13549       type = BFD_RELOC_16;
13550       break;
13551     case 4:
13552     default:
13553       type = BFD_RELOC_32;
13554       break;
13555     case 8:
13556       type = BFD_RELOC_64;
13557       break;
13558     }
13559
13560   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13561 }
13562
13563 /* A good place to do this, although this was probably not intended
13564    for this kind of use.  We need to dump the literal pool before
13565    references are made to a null symbol pointer.  */
13566
13567 void
13568 arm_cleanup (void)
13569 {
13570   literal_pool * pool;
13571
13572   for (pool = list_of_pools; pool; pool = pool->next)
13573     {
13574       /* Put it at the end of the relevent section.  */
13575       subseg_set (pool->section, pool->sub_section);
13576 #ifdef OBJ_ELF
13577       arm_elf_change_section ();
13578 #endif
13579       s_ltorg (0);
13580     }
13581 }
13582
13583 void
13584 arm_start_line_hook (void)
13585 {
13586   last_label_seen = NULL;
13587 }
13588
13589 void
13590 arm_frob_label (symbolS * sym)
13591 {
13592   last_label_seen = sym;
13593
13594   ARM_SET_THUMB (sym, thumb_mode);
13595
13596 #if defined OBJ_COFF || defined OBJ_ELF
13597   ARM_SET_INTERWORK (sym, support_interwork);
13598 #endif
13599
13600   /* Note - do not allow local symbols (.Lxxx) to be labeled
13601      as Thumb functions.  This is because these labels, whilst
13602      they exist inside Thumb code, are not the entry points for
13603      possible ARM->Thumb calls.  Also, these labels can be used
13604      as part of a computed goto or switch statement.  eg gcc
13605      can generate code that looks like this:
13606
13607                 ldr  r2, [pc, .Laaa]
13608                 lsl  r3, r3, #2
13609                 ldr  r2, [r3, r2]
13610                 mov  pc, r2
13611
13612        .Lbbb:  .word .Lxxx
13613        .Lccc:  .word .Lyyy
13614        ..etc...
13615        .Laaa:   .word Lbbb
13616
13617      The first instruction loads the address of the jump table.
13618      The second instruction converts a table index into a byte offset.
13619      The third instruction gets the jump address out of the table.
13620      The fourth instruction performs the jump.
13621
13622      If the address stored at .Laaa is that of a symbol which has the
13623      Thumb_Func bit set, then the linker will arrange for this address
13624      to have the bottom bit set, which in turn would mean that the
13625      address computation performed by the third instruction would end
13626      up with the bottom bit set.  Since the ARM is capable of unaligned
13627      word loads, the instruction would then load the incorrect address
13628      out of the jump table, and chaos would ensue.  */
13629   if (label_is_thumb_function_name
13630       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13631       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13632     {
13633       /* When the address of a Thumb function is taken the bottom
13634          bit of that address should be set.  This will allow
13635          interworking between Arm and Thumb functions to work
13636          correctly.  */
13637
13638       THUMB_SET_FUNC (sym, 1);
13639
13640       label_is_thumb_function_name = FALSE;
13641     }
13642 }
13643
13644 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13645    ARM ones.  */
13646
13647 void
13648 arm_adjust_symtab (void)
13649 {
13650 #ifdef OBJ_COFF
13651   symbolS * sym;
13652
13653   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13654     {
13655       if (ARM_IS_THUMB (sym))
13656         {
13657           if (THUMB_IS_FUNC (sym))
13658             {
13659               /* Mark the symbol as a Thumb function.  */
13660               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13661                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13662                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13663
13664               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13665                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13666               else
13667                 as_bad (_("%s: unexpected function type: %d"),
13668                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13669             }
13670           else switch (S_GET_STORAGE_CLASS (sym))
13671             {
13672             case C_EXT:
13673               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13674               break;
13675             case C_STAT:
13676               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13677               break;
13678             case C_LABEL:
13679               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13680               break;
13681             default:
13682               /* Do nothing.  */
13683               break;
13684             }
13685         }
13686
13687       if (ARM_IS_INTERWORK (sym))
13688         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13689     }
13690 #endif
13691 #ifdef OBJ_ELF
13692   symbolS * sym;
13693   char      bind;
13694
13695   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13696     {
13697       if (ARM_IS_THUMB (sym))
13698         {
13699           elf_symbol_type * elf_sym;
13700
13701           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13702           bind = ELF_ST_BIND (elf_sym);
13703
13704           /* If it's a .thumb_func, declare it as so,
13705              otherwise tag label as .code 16.  */
13706           if (THUMB_IS_FUNC (sym))
13707             elf_sym->internal_elf_sym.st_info =
13708               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13709           else
13710             elf_sym->internal_elf_sym.st_info =
13711               ELF_ST_INFO (bind, STT_ARM_16BIT);
13712         }
13713     }
13714 #endif
13715 }
13716
13717 int
13718 arm_data_in_code (void)
13719 {
13720   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13721     {
13722       *input_line_pointer = '/';
13723       input_line_pointer += 5;
13724       *input_line_pointer = 0;
13725       return 1;
13726     }
13727
13728   return 0;
13729 }
13730
13731 char *
13732 arm_canonicalize_symbol_name (char * name)
13733 {
13734   int len;
13735
13736   if (thumb_mode && (len = strlen (name)) > 5
13737       && streq (name + len - 5, "/data"))
13738     *(name + len - 5) = 0;
13739
13740   return name;
13741 }
13742
13743 #if defined OBJ_COFF || defined OBJ_ELF
13744 void
13745 arm_validate_fix (fixS * fixP)
13746 {
13747   /* If the destination of the branch is a defined symbol which does not have
13748      the THUMB_FUNC attribute, then we must be calling a function which has
13749      the (interfacearm) attribute.  We look for the Thumb entry point to that
13750      function and change the branch to refer to that function instead.  */
13751   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13752       && fixP->fx_addsy != NULL
13753       && S_IS_DEFINED (fixP->fx_addsy)
13754       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13755     {
13756       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13757     }
13758 }
13759 #endif
13760
13761 int
13762 arm_force_relocation (struct fix * fixp)
13763 {
13764 #if defined (OBJ_COFF) && defined (TE_PE)
13765   if (fixp->fx_r_type == BFD_RELOC_RVA)
13766     return 1;
13767 #endif
13768 #ifdef OBJ_ELF
13769   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13770       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13771       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13772       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13773     return 1;
13774 #endif
13775
13776   /* Resolve these relocations even if the symbol is extern or weak.  */
13777   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13778       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13779       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13780     return 0;
13781
13782   return generic_force_reloc (fixp);
13783 }
13784
13785 #ifdef OBJ_COFF
13786 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13787    local labels from being added to the output symbol table when they
13788    are used with the ADRL pseudo op.  The ADRL relocation should always
13789    be resolved before the binbary is emitted, so it is safe to say that
13790    it is adjustable.  */
13791
13792 bfd_boolean
13793 arm_fix_adjustable (fixS * fixP)
13794 {
13795   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13796     return 1;
13797   return 0;
13798 }
13799 #endif
13800
13801 #ifdef OBJ_ELF
13802 /* Relocations against Thumb function names must be left unadjusted,
13803    so that the linker can use this information to correctly set the
13804    bottom bit of their addresses.  The MIPS version of this function
13805    also prevents relocations that are mips-16 specific, but I do not
13806    know why it does this.
13807
13808    FIXME:
13809    There is one other problem that ought to be addressed here, but
13810    which currently is not:  Taking the address of a label (rather
13811    than a function) and then later jumping to that address.  Such
13812    addresses also ought to have their bottom bit set (assuming that
13813    they reside in Thumb code), but at the moment they will not.  */
13814
13815 bfd_boolean
13816 arm_fix_adjustable (fixS * fixP)
13817 {
13818   if (fixP->fx_addsy == NULL)
13819     return 1;
13820
13821   if (THUMB_IS_FUNC (fixP->fx_addsy)
13822       && fixP->fx_subsy == NULL)
13823     return 0;
13824
13825   /* We need the symbol name for the VTABLE entries.  */
13826   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
13827       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
13828     return 0;
13829
13830   /* Don't allow symbols to be discarded on GOT related relocs.  */
13831   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
13832       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
13833       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
13834       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
13835     return 0;
13836
13837   return 1;
13838 }
13839
13840 const char *
13841 elf32_arm_target_format (void)
13842 {
13843 #ifdef TE_SYMBIAN
13844   return (target_big_endian
13845           ? "elf32-bigarm-symbian"
13846           : "elf32-littlearm-symbian");
13847 #elif defined (TE_VXWORKS)
13848   return (target_big_endian
13849           ? "elf32-bigarm-vxworks"
13850           : "elf32-littlearm-vxworks");
13851 #else
13852   if (target_big_endian)
13853     return "elf32-bigarm";
13854   else
13855     return "elf32-littlearm";
13856 #endif
13857 }
13858
13859 void
13860 armelf_frob_symbol (symbolS * symp,
13861                     int *     puntp)
13862 {
13863   elf_frob_symbol (symp, puntp);
13864 }
13865
13866 static void
13867 s_arm_elf_cons (int nbytes)
13868 {
13869   expressionS exp;
13870
13871 #ifdef md_flush_pending_output
13872   md_flush_pending_output ();
13873 #endif
13874
13875   if (is_it_end_of_statement ())
13876     {
13877       demand_empty_rest_of_line ();
13878       return;
13879     }
13880
13881 #ifdef md_cons_align
13882   md_cons_align (nbytes);
13883 #endif
13884
13885   mapping_state (MAP_DATA);
13886   do
13887     {
13888       bfd_reloc_code_real_type reloc;
13889
13890       expression (& exp);
13891
13892       if (exp.X_op == O_symbol
13893           && * input_line_pointer == '('
13894           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
13895         {
13896           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13897           int size = bfd_get_reloc_size (howto);
13898
13899           if (size > nbytes)
13900             as_bad ("%s relocations do not fit in %d bytes",
13901                     howto->name, nbytes);
13902           else
13903             {
13904               char *p = frag_more ((int) nbytes);
13905               int offset = nbytes - size;
13906
13907               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13908                            &exp, 0, reloc);
13909             }
13910         }
13911       else
13912         emit_expr (&exp, (unsigned int) nbytes);
13913     }
13914   while (*input_line_pointer++ == ',');
13915
13916   /* Put terminator back into stream.  */
13917   input_line_pointer --;
13918   demand_empty_rest_of_line ();
13919 }
13920
13921
13922 /* Parse a .rel31 directive.  */
13923
13924 static void
13925 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
13926 {
13927   expressionS exp;
13928   char *p;
13929   valueT highbit;
13930
13931   SKIP_WHITESPACE ();
13932
13933   highbit = 0;
13934   if (*input_line_pointer == '1')
13935     highbit = 0x80000000;
13936   else if (*input_line_pointer != '0')
13937     as_bad (_("expected 0 or 1"));
13938
13939   input_line_pointer++;
13940   SKIP_WHITESPACE ();
13941   if (*input_line_pointer != ',')
13942     as_bad (_("missing comma"));
13943   input_line_pointer++;
13944
13945 #ifdef md_flush_pending_output
13946   md_flush_pending_output ();
13947 #endif
13948
13949 #ifdef md_cons_align
13950   md_cons_align (4);
13951 #endif
13952
13953   mapping_state (MAP_DATA);
13954
13955   expression (&exp);
13956
13957   p = frag_more (4);
13958   md_number_to_chars (p, highbit, 4);
13959   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
13960                BFD_RELOC_ARM_PREL31);
13961
13962   demand_empty_rest_of_line ();
13963 }
13964 \f
13965 /* Code to deal with unwinding tables.  */
13966
13967 static void add_unwind_adjustsp (offsetT);
13968
13969 /* Switch to section NAME and create section if necessary.  It's
13970    rather ugly that we have to manipulate input_line_pointer but I
13971    don't see any other way to accomplish the same thing without
13972    changing obj-elf.c (which may be the Right Thing, in the end).
13973    Copied from tc-ia64.c.  */
13974
13975 static void
13976 set_section (char *name)
13977 {
13978   char *saved_input_line_pointer;
13979
13980   saved_input_line_pointer = input_line_pointer;
13981   input_line_pointer = name;
13982   obj_elf_section (0);
13983   input_line_pointer = saved_input_line_pointer;
13984 }
13985
13986 /* Cenerate and deferred unwind frame offset.  */
13987
13988 static void
13989 flush_pending_unwind (void)
13990 {
13991   offsetT offset;
13992
13993   offset = unwind.pending_offset;
13994   unwind.pending_offset = 0;
13995   if (offset != 0)
13996     add_unwind_adjustsp (offset);
13997 }
13998
13999 /* Add an opcode to this list for this function.  Two-byte opcodes should
14000    be passed as op[0] << 8 | op[1].  The list of opcodes is built in reverse
14001    order.  */
14002
14003 static void
14004 add_unwind_opcode (valueT op, int length)
14005 {
14006   /* Add any deferred stack adjustment.  */
14007   if (unwind.pending_offset)
14008     flush_pending_unwind ();
14009
14010   unwind.sp_restored = 0;
14011
14012   if (unwind.opcode_count + length > unwind.opcode_alloc)
14013     {
14014       unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
14015       if (unwind.opcodes)
14016         unwind.opcodes = xrealloc (unwind.opcodes,
14017                                    unwind.opcode_alloc);
14018       else
14019         unwind.opcodes = xmalloc (unwind.opcode_alloc);
14020     }
14021   while (length > 0)
14022     {
14023       length--;
14024       unwind.opcodes[unwind.opcode_count] = op & 0xff;
14025       op >>= 8;
14026       unwind.opcode_count++;
14027     }
14028 }
14029
14030 /* Add unwind opcodes to adjust the stack pointer.  */
14031
14032 static void
14033 add_unwind_adjustsp (offsetT offset)
14034 {
14035   valueT op;
14036
14037   if (offset > 0x200)
14038     {
14039       /* We need at most 5 bytes to hold a 32-bit value in a uleb128.  */
14040       char bytes[5];
14041       int n;
14042       valueT o;
14043
14044       /* Long form: 0xb2, uleb128.  */
14045       /* This might not fit in a word so add the individual bytes,
14046          remembering the list is built in reverse order.  */
14047       o = (valueT) ((offset - 0x204) >> 2);
14048       if (o == 0)
14049         add_unwind_opcode (0, 1);
14050
14051       /* Calculate the uleb128 encoding of the offset.  */
14052       n = 0;
14053       while (o)
14054         {
14055           bytes[n] = o & 0x7f;
14056           o >>= 7;
14057           if (o)
14058             bytes[n] |= 0x80;
14059           n++;
14060         }
14061       /* Add the insn.  */
14062       for (; n; n--)
14063         add_unwind_opcode (bytes[n - 1], 1);
14064       add_unwind_opcode (0xb2, 1);
14065     }
14066   else if (offset > 0x100)
14067     {
14068       /* Two short opcodes.  */
14069       add_unwind_opcode (0x3f, 1);
14070       op = (offset - 0x104) >> 2;
14071       add_unwind_opcode (op, 1);
14072     }
14073   else if (offset > 0)
14074     {
14075       /* Short opcode.  */
14076       op = (offset - 4) >> 2;
14077       add_unwind_opcode (op, 1);
14078     }
14079   else if (offset < 0)
14080     {
14081       offset = -offset;
14082       while (offset > 0x100)
14083         {
14084           add_unwind_opcode (0x7f, 1);
14085           offset -= 0x100;
14086         }
14087       op = ((offset - 4) >> 2) | 0x40;
14088       add_unwind_opcode (op, 1);
14089     }
14090 }
14091
14092 /* Finish the list of unwind opcodes for this function.  */
14093 static void
14094 finish_unwind_opcodes (void)
14095 {
14096   valueT op;
14097
14098   if (unwind.fp_used)
14099     {
14100       /* Adjust sp as neccessary.  */
14101       unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
14102       flush_pending_unwind ();
14103
14104       /* After restoring sp from the frame pointer.  */
14105       op = 0x90 | unwind.fp_reg;
14106       add_unwind_opcode (op, 1);
14107     }
14108   else
14109     flush_pending_unwind ();
14110 }
14111
14112
14113 /* Start an exception table entry.  If idx is nonzero this is an index table
14114    entry.  */
14115
14116 static void
14117 start_unwind_section (const segT text_seg, int idx)
14118 {
14119   const char * text_name;
14120   const char * prefix;
14121   const char * prefix_once;
14122   size_t prefix_len;
14123   size_t text_len;
14124   char * sec_name;
14125   size_t sec_name_len;
14126
14127   if (idx)
14128     {
14129       prefix = ELF_STRING_ARM_unwind;
14130       prefix_once = ELF_STRING_ARM_unwind_once;
14131     }
14132   else
14133     {
14134       prefix = ELF_STRING_ARM_unwind_info;
14135       prefix_once = ELF_STRING_ARM_unwind_info_once;
14136     }
14137
14138   text_name = segment_name (text_seg);
14139   if (streq (text_name, ".text"))
14140     text_name = "";
14141
14142   if (strncmp (text_name, ".gnu.linkonce.t.",
14143                strlen (".gnu.linkonce.t.")) == 0)
14144     {
14145       prefix = prefix_once;
14146       text_name += strlen (".gnu.linkonce.t.");
14147     }
14148
14149   prefix_len = strlen (prefix);
14150   text_len = strlen (text_name);
14151   sec_name_len = prefix_len + text_len;
14152   sec_name = alloca (sec_name_len + 1);
14153   memcpy (sec_name, prefix, prefix_len);
14154   memcpy (sec_name + prefix_len, text_name, text_len);
14155   sec_name[prefix_len + text_len] = '\0';
14156
14157   /* Handle COMDAT group.  */
14158   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
14159     {
14160       char *section;
14161       size_t len, group_name_len;
14162       const char *group_name = elf_group_name (text_seg);
14163
14164       if (group_name == NULL)
14165         {
14166           as_bad ("Group section `%s' has no group signature",
14167                   segment_name (text_seg));
14168           ignore_rest_of_line ();
14169           return;
14170         }
14171       /* We have to construct a fake section directive.  */
14172       group_name_len = strlen (group_name);
14173       if (idx)
14174         prefix_len = 13;
14175       else
14176         prefix_len = 16;
14177
14178       len = (sec_name_len
14179              + prefix_len             /* ,"aG",%sectiontype,  */
14180              + group_name_len         /* ,group_name  */
14181              + 7);                    /* ,comdat  */
14182
14183       section = alloca (len + 1);
14184       memcpy (section, sec_name, sec_name_len);
14185       if (idx)
14186           memcpy (section + sec_name_len, ",\"aG\",%exidx,", 13);
14187       else
14188           memcpy (section + sec_name_len, ",\"aG\",%progbits,", 16);
14189       memcpy (section + sec_name_len + prefix_len, group_name, group_name_len);
14190       memcpy (section + len - 7, ",comdat", 7);
14191       section [len] = '\0';
14192       set_section (section);
14193     }
14194   else
14195     {
14196       set_section (sec_name);
14197       bfd_set_section_flags (stdoutput, now_seg,
14198                              SEC_LOAD | SEC_ALLOC | SEC_READONLY);
14199     }
14200
14201   /* Set the setion link for index tables.  */
14202   if (idx)
14203     elf_linked_to_section (now_seg) = text_seg;
14204 }
14205
14206
14207 /* Start an unwind table entry.  HAVE_DATA is nonzero if we have additional
14208    personality routine data.  Returns zero, or the index table value for
14209    and inline entry.  */
14210
14211 static valueT
14212 create_unwind_entry (int have_data)
14213 {
14214   int size;
14215   addressT where;
14216   char *ptr;
14217   /* The current word of data.  */
14218   valueT data;
14219   /* The number of bytes left in this word.  */
14220   int n;
14221
14222   finish_unwind_opcodes ();
14223
14224   /* Remember the current text section.  */
14225   unwind.saved_seg = now_seg;
14226   unwind.saved_subseg = now_subseg;
14227
14228   start_unwind_section (now_seg, 0);
14229
14230   if (unwind.personality_routine == NULL)
14231     {
14232       if (unwind.personality_index == -2)
14233         {
14234           if (have_data)
14235             as_bad (_("handerdata in cantunwind frame"));
14236           return 1; /* EXIDX_CANTUNWIND.  */
14237         }
14238
14239       /* Use a default personality routine if none is specified.  */
14240       if (unwind.personality_index == -1)
14241         {
14242           if (unwind.opcode_count > 3)
14243             unwind.personality_index = 1;
14244           else
14245             unwind.personality_index = 0;
14246         }
14247
14248       /* Space for the personality routine entry.  */
14249       if (unwind.personality_index == 0)
14250         {
14251           if (unwind.opcode_count > 3)
14252             as_bad (_("too many unwind opcodes for personality routine 0"));
14253
14254           if (!have_data)
14255             {
14256               /* All the data is inline in the index table.  */
14257               data = 0x80;
14258               n = 3;
14259               while (unwind.opcode_count > 0)
14260                 {
14261                   unwind.opcode_count--;
14262                   data = (data << 8) | unwind.opcodes[unwind.opcode_count];
14263                   n--;
14264                 }
14265
14266               /* Pad with "finish" opcodes.  */
14267               while (n--)
14268                 data = (data << 8) | 0xb0;
14269
14270               return data;
14271             }
14272           size = 0;
14273         }
14274       else
14275         /* We get two opcodes "free" in the first word.  */
14276         size = unwind.opcode_count - 2;
14277     }
14278   else
14279     /* An extra byte is required for the opcode count.  */
14280     size = unwind.opcode_count + 1;
14281
14282   size = (size + 3) >> 2;
14283   if (size > 0xff)
14284     as_bad (_("too many unwind opcodes"));
14285
14286   frag_align (2, 0, 0);
14287   record_alignment (now_seg, 2);
14288   unwind.table_entry = expr_build_dot ();
14289
14290   /* Allocate the table entry.  */
14291   ptr = frag_more ((size << 2) + 4);
14292   where = frag_now_fix () - ((size << 2) + 4);
14293
14294   switch (unwind.personality_index)
14295     {
14296     case -1:
14297       /* ??? Should this be a PLT generating relocation?  */
14298       /* Custom personality routine.  */
14299       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
14300                BFD_RELOC_ARM_PREL31);
14301
14302       /* Indicate dependency to linker.  */
14303         {
14304           char *name = "__aeabi_unwind_cpp_pr0";
14305           symbolS *pr = symbol_find_or_make (name);
14306           fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
14307         }
14308
14309       where += 4;
14310       ptr += 4;
14311
14312       /* Set the first byte to the number of additional words.  */
14313       data = size - 1;
14314       n = 3;
14315       break;
14316
14317     /* ABI defined personality routines.  */
14318     case 0:
14319       /* Three opcodes bytes are packed into the first word.  */
14320       data = 0x80;
14321       n = 3;
14322       goto emit_reloc;
14323
14324     case 1:
14325     case 2:
14326       /* The size and first two opcode bytes go in the first word.  */
14327       data = ((0x80 + unwind.personality_index) << 8) | size;
14328       n = 2;
14329       goto emit_reloc;
14330
14331     emit_reloc:
14332       {
14333         /* Indicate dependency to linker.  */
14334         char *name[] = { "__aeabi_unwind_cpp_pr0",
14335                          "__aeabi_unwind_cpp_pr1",
14336                          "__aeabi_unwind_cpp_pr2" };
14337         symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
14338         fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
14339       }
14340       break;
14341
14342     default:
14343       /* Should never happen.  */
14344       abort ();
14345     }
14346
14347   /* Pack the opcodes into words (MSB first), reversing the list at the same
14348      time.  */
14349   while (unwind.opcode_count > 0)
14350     {
14351       if (n == 0)
14352         {
14353           md_number_to_chars (ptr, data, 4);
14354           ptr += 4;
14355           n = 4;
14356           data = 0;
14357         }
14358       unwind.opcode_count--;
14359       n--;
14360       data = (data << 8) | unwind.opcodes[unwind.opcode_count];
14361     }
14362
14363   /* Finish off the last word.  */
14364   if (n < 4)
14365     {
14366       /* Pad with "finish" opcodes.  */
14367       while (n--)
14368         data = (data << 8) | 0xb0;
14369
14370       md_number_to_chars (ptr, data, 4);
14371     }
14372
14373   if (!have_data)
14374     {
14375       /* Add an empty descriptor if there is no user-specified data.   */
14376       ptr = frag_more (4);
14377       md_number_to_chars (ptr, 0, 4);
14378     }
14379
14380   return 0;
14381 }
14382
14383
14384 /* Parse an unwind_fnstart directive.  Simply records the current location.  */
14385
14386 static void
14387 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
14388 {
14389   demand_empty_rest_of_line ();
14390   /* Mark the start of the function.  */
14391   unwind.proc_start = expr_build_dot ();
14392
14393   /* Reset the rest of the unwind info.  */
14394   unwind.opcode_count = 0;
14395   unwind.table_entry = NULL;
14396   unwind.personality_routine = NULL;
14397   unwind.personality_index = -1;
14398   unwind.frame_size = 0;
14399   unwind.fp_offset = 0;
14400   unwind.fp_reg = 13;
14401   unwind.fp_used = 0;
14402   unwind.sp_restored = 0;
14403 }
14404
14405
14406 /* Parse a handlerdata directive.  Creates the exception handling table entry
14407    for the function.  */
14408
14409 static void
14410 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
14411 {
14412   demand_empty_rest_of_line ();
14413   if (unwind.table_entry)
14414     as_bad (_("dupicate .handlerdata directive"));
14415
14416   create_unwind_entry (1);
14417 }
14418
14419 /* Parse an unwind_fnend directive.  Generates the index table entry.  */
14420
14421 static void
14422 s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
14423 {
14424   long where;
14425   char *ptr;
14426   valueT val;
14427
14428   demand_empty_rest_of_line ();
14429
14430   /* Add eh table entry.  */
14431   if (unwind.table_entry == NULL)
14432     val = create_unwind_entry (0);
14433   else
14434     val = 0;
14435
14436   /* Add index table entry.  This is two words.  */
14437   start_unwind_section (unwind.saved_seg, 1);
14438   frag_align (2, 0, 0);
14439   record_alignment (now_seg, 2);
14440
14441   ptr = frag_more (8);
14442   where = frag_now_fix () - 8;
14443
14444   /* Self relative offset of the function start.  */
14445   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
14446            BFD_RELOC_ARM_PREL31);
14447
14448   if (val)
14449     /* Inline exception table entry.  */
14450     md_number_to_chars (ptr + 4, val, 4);
14451   else
14452     /* Self relative offset of the table entry.  */
14453     fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
14454              BFD_RELOC_ARM_PREL31);
14455
14456   /* Restore the original section.  */
14457   subseg_set (unwind.saved_seg, unwind.saved_subseg);
14458 }
14459
14460
14461 /* Parse an unwind_cantunwind directive.  */
14462
14463 static void
14464 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
14465 {
14466   demand_empty_rest_of_line ();
14467   if (unwind.personality_routine || unwind.personality_index != -1)
14468     as_bad (_("personality routine specified for cantunwind frame"));
14469
14470   unwind.personality_index = -2;
14471 }
14472
14473
14474 /* Parse a personalityindex directive.  */
14475
14476 static void
14477 s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
14478 {
14479   expressionS exp;
14480
14481   if (unwind.personality_routine || unwind.personality_index != -1)
14482     as_bad (_("duplicate .personalityindex directive"));
14483
14484   SKIP_WHITESPACE ();
14485
14486   expression (&exp);
14487
14488   if (exp.X_op != O_constant
14489       || exp.X_add_number < 0 || exp.X_add_number > 15)
14490     {
14491       as_bad (_("bad personality routine number"));
14492       ignore_rest_of_line ();
14493       return;
14494     }
14495
14496   unwind.personality_index = exp.X_add_number;
14497
14498   demand_empty_rest_of_line ();
14499 }
14500
14501
14502 /* Parse a personality directive.  */
14503
14504 static void
14505 s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
14506 {
14507   char *name, *p, c;
14508
14509   if (unwind.personality_routine || unwind.personality_index != -1)
14510     as_bad (_("duplicate .personality directive"));
14511
14512   SKIP_WHITESPACE ();
14513   name = input_line_pointer;
14514   c = get_symbol_end ();
14515   p = input_line_pointer;
14516   unwind.personality_routine = symbol_find_or_make (name);
14517   *p = c;
14518   SKIP_WHITESPACE ();
14519   demand_empty_rest_of_line ();
14520 }
14521
14522
14523 /* Parse a directive saving core registers.  */
14524
14525 static void
14526 s_arm_unwind_save_core (void)
14527 {
14528   valueT op;
14529   long range;
14530   int n;
14531
14532   SKIP_WHITESPACE ();
14533   range = reg_list (&input_line_pointer);
14534   if (range == FAIL)
14535     {
14536       as_bad (_("expected register list"));
14537       ignore_rest_of_line ();
14538       return;
14539     }
14540
14541   demand_empty_rest_of_line ();
14542
14543   /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
14544      into .unwind_save {..., sp...}.  We aren't bothered about the value of
14545      ip because it is clobbered by calls.  */
14546   if (unwind.sp_restored && unwind.fp_reg == 12
14547       && (range & 0x3000) == 0x1000)
14548     {
14549       unwind.opcode_count--;
14550       unwind.sp_restored = 0;
14551       range = (range | 0x2000) & ~0x1000;
14552       unwind.pending_offset = 0;
14553     }
14554
14555   /* See if we can use the short opcodes.  These pop a block of upto 8
14556      registers starting with r4, plus maybe r14.  */
14557   for (n = 0; n < 8; n++)
14558     {
14559       /* Break at the first non-saved register.  */
14560       if ((range & (1 << (n + 4))) == 0)
14561         break;
14562     }
14563   /* See if there are any other bits set.  */
14564   if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
14565     {
14566       /* Use the long form.  */
14567       op = 0x8000 | ((range >> 4) & 0xfff);
14568       add_unwind_opcode (op, 2);
14569     }
14570   else
14571     {
14572       /* Use the short form.  */
14573       if (range & 0x4000)
14574         op = 0xa8; /* Pop r14.  */
14575       else
14576         op = 0xa0; /* Do not pop r14.  */
14577       op |= (n - 1);
14578       add_unwind_opcode (op, 1);
14579     }
14580
14581   /* Pop r0-r3.  */
14582   if (range & 0xf)
14583     {
14584       op = 0xb100 | (range & 0xf);
14585       add_unwind_opcode (op, 2);
14586     }
14587
14588   /* Record the number of bytes pushed.  */
14589   for (n = 0; n < 16; n++)
14590     {
14591       if (range & (1 << n))
14592         unwind.frame_size += 4;
14593     }
14594 }
14595
14596
14597 /* Parse a directive saving FPA registers.  */
14598
14599 static void
14600 s_arm_unwind_save_fpa (int reg)
14601 {
14602   expressionS exp;
14603   int num_regs;
14604   valueT op;
14605
14606   /* Get Number of registers to transfer.  */
14607   if (skip_past_comma (&input_line_pointer) != FAIL)
14608     expression (&exp);
14609   else
14610     exp.X_op = O_illegal;
14611
14612   if (exp.X_op != O_constant)
14613     {
14614       as_bad (_("expected , <constant>"));
14615       ignore_rest_of_line ();
14616       return;
14617     }
14618
14619   num_regs = exp.X_add_number;
14620
14621   if (num_regs < 1 || num_regs > 4)
14622     {
14623       as_bad (_("number of registers must be in the range [1:4]"));
14624       ignore_rest_of_line ();
14625       return;
14626     }
14627
14628   demand_empty_rest_of_line ();
14629
14630   if (reg == 4)
14631     {
14632       /* Short form.  */
14633       op = 0xb4 | (num_regs - 1);
14634       add_unwind_opcode (op, 1);
14635     }
14636   else
14637     {
14638       /* Long form.  */
14639       op = 0xc800 | (reg << 4) | (num_regs - 1);
14640       add_unwind_opcode (op, 2);
14641     }
14642   unwind.frame_size += num_regs * 12;
14643 }
14644
14645
14646 /* Parse a directive saving VFP registers.  */
14647
14648 static void
14649 s_arm_unwind_save_vfp (void)
14650 {
14651   int count;
14652   int reg;
14653   valueT op;
14654
14655   count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
14656   if (count == FAIL)
14657     {
14658       as_bad (_("expected register list"));
14659       ignore_rest_of_line ();
14660       return;
14661     }
14662
14663   demand_empty_rest_of_line ();
14664
14665   if (reg == 8)
14666     {
14667       /* Short form.  */
14668       op = 0xb8 | (count - 1);
14669       add_unwind_opcode (op, 1);
14670     }
14671   else
14672     {
14673       /* Long form.  */
14674       op = 0xb300 | (reg << 4) | (count - 1);
14675       add_unwind_opcode (op, 2);
14676     }
14677   unwind.frame_size += count * 8 + 4;
14678 }
14679
14680
14681 /* Parse a directive saving iWMMXt registers.  */
14682
14683 static void
14684 s_arm_unwind_save_wmmx (void)
14685 {
14686   int reg;
14687   int hi_reg;
14688   int i;
14689   unsigned wcg_mask;
14690   unsigned wr_mask;
14691   valueT op;
14692
14693   if (*input_line_pointer == '{')
14694     input_line_pointer++;
14695
14696   wcg_mask = 0;
14697   wr_mask = 0;
14698   do
14699     {
14700       reg = arm_reg_parse (&input_line_pointer,
14701                            all_reg_maps[REG_TYPE_IWMMXT].htab);
14702
14703       if (wr_register (reg))
14704         {
14705           i = reg & ~WR_PREFIX;
14706           if (wr_mask >> i)
14707             as_tsktsk (_("register list not in ascending order"));
14708           wr_mask |= 1 << i;
14709         }
14710       else if (wcg_register (reg))
14711         {
14712           i = (reg & ~WC_PREFIX) - 8;
14713           if (wcg_mask >> i)
14714             as_tsktsk (_("register list not in ascending order"));
14715           wcg_mask |= 1 << i;
14716         }
14717       else
14718         {
14719           as_bad (_("expected wr or wcgr"));
14720           goto error;
14721         }
14722
14723       SKIP_WHITESPACE ();
14724       if (*input_line_pointer == '-')
14725         {
14726           hi_reg = arm_reg_parse (&input_line_pointer,
14727                                   all_reg_maps[REG_TYPE_IWMMXT].htab);
14728           if (wr_register (reg) && wr_register (hi_reg))
14729             {
14730               for (; reg < hi_reg; reg++)
14731                 wr_mask |= 1 << (reg & ~WR_PREFIX);
14732             }
14733           else if (wcg_register (reg) && wcg_register (hi_reg))
14734             {
14735               for (; reg < hi_reg; reg++)
14736                 wcg_mask |= 1 << ((reg & ~WC_PREFIX) - 8);
14737             }
14738           else
14739             {
14740               as_bad (_("bad register range"));
14741               goto error;
14742             }
14743         }
14744     }
14745   while (skip_past_comma (&input_line_pointer) != FAIL);
14746
14747   SKIP_WHITESPACE ();
14748   if (*input_line_pointer == '}')
14749     input_line_pointer++;
14750
14751   demand_empty_rest_of_line ();
14752
14753   if (wr_mask && wcg_mask)
14754     {
14755       as_bad (_("inconsistent register types"));
14756       goto error;
14757     }
14758
14759   /* Generate any deferred opcodes becuuse we're going to be looking at
14760      the list.  */
14761   flush_pending_unwind ();
14762
14763   if (wcg_mask)
14764     {
14765       for (i = 0; i < 16; i++)
14766         {
14767           if (wcg_mask & (1 << i))
14768             unwind.frame_size += 4;
14769         }
14770       op = 0xc700 | wcg_mask;
14771       add_unwind_opcode (op, 2);
14772     }
14773   else
14774     {
14775       for (i = 0; i < 16; i++)
14776         {
14777           if (wr_mask & (1 << i))
14778             unwind.frame_size += 8;
14779         }
14780       /* Attempt to combine with a previous opcode.  We do this because gcc
14781          likes to output separate unwind directives for a single block of
14782          registers.  */
14783       if (unwind.opcode_count > 0)
14784         {
14785           i = unwind.opcodes[unwind.opcode_count - 1];
14786           if ((i & 0xf8) == 0xc0)
14787             {
14788               i &= 7;
14789               /* Only merge if the blocks are contiguous.  */
14790               if (i < 6)
14791                 {
14792                   if ((wr_mask & 0xfe00) == (1 << 9))
14793                     {
14794                       wr_mask |= ((1 << (i + 11)) - 1) & 0xfc00;
14795                       unwind.opcode_count--;
14796                     }
14797                 }
14798               else if (i == 6 && unwind.opcode_count >= 2)
14799                 {
14800                   i = unwind.opcodes[unwind.opcode_count - 2];
14801                   reg = i >> 4;
14802                   i &= 0xf;
14803
14804                   op = 0xffff << (reg - 1);
14805                   if (reg > 0
14806                       || ((wr_mask & op) == (1u << (reg - 1))))
14807                     {
14808                       op = (1 << (reg + i + 1)) - 1;
14809                       op &= ~((1 << reg) - 1);
14810                       wr_mask |= op;
14811                       unwind.opcode_count -= 2;
14812                     }
14813                 }
14814             }
14815         }
14816
14817       hi_reg = 15;
14818       /* We want to generate opcodes in the order the registers have been
14819          saved, ie. descending order.  */
14820       for (reg = 15; reg >= -1; reg--)
14821         {
14822           /* Save registers in blocks.  */
14823           if (reg < 0
14824               || !(wr_mask & (1 << reg)))
14825             {
14826               /* We found an unsaved reg.  Generate opcodes to save the
14827                  preceeding block.  */
14828               if (reg != hi_reg)
14829                 {
14830                   if (reg == 9)
14831                     {
14832                       /* Short form.  */
14833                       op = 0xc0 | (hi_reg - 10);
14834                       add_unwind_opcode (op, 1);
14835                     }
14836                   else
14837                     {
14838                       /* Long form.  */
14839                       op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
14840                       add_unwind_opcode (op, 2);
14841                     }
14842                 }
14843               hi_reg = reg - 1;
14844             }
14845         }
14846     }
14847   return;
14848 error:
14849   ignore_rest_of_line ();
14850 }
14851
14852
14853 /* Parse an unwind_save directive.  */
14854
14855 static void
14856 s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
14857 {
14858   char *saved_ptr;
14859   int reg;
14860
14861   /* Figure out what sort of save we have.  */
14862   SKIP_WHITESPACE ();
14863   saved_ptr = input_line_pointer;
14864
14865   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_FN].htab);
14866   if (reg != FAIL)
14867     {
14868       s_arm_unwind_save_fpa (reg);
14869       return;
14870     }
14871
14872   if (*input_line_pointer == '{')
14873     input_line_pointer++;
14874
14875   SKIP_WHITESPACE ();
14876
14877   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_RN].htab);
14878   if (reg != FAIL)
14879     {
14880       input_line_pointer = saved_ptr;
14881       s_arm_unwind_save_core ();
14882       return;
14883     }
14884
14885   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_DN].htab);
14886   if (reg != FAIL)
14887     {
14888       input_line_pointer = saved_ptr;
14889       s_arm_unwind_save_vfp ();
14890       return;
14891     }
14892
14893   reg = arm_reg_parse (&input_line_pointer,
14894                        all_reg_maps[REG_TYPE_IWMMXT].htab);
14895   if (reg != FAIL)
14896     {
14897       input_line_pointer = saved_ptr;
14898       s_arm_unwind_save_wmmx ();
14899       return;
14900     }
14901
14902   /* TODO: Maverick registers.  */
14903   as_bad (_("unrecognised register"));
14904 }
14905
14906
14907 /* Parse an unwind_movsp directive.  */
14908
14909 static void
14910 s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
14911 {
14912   int reg;
14913   valueT op;
14914
14915   SKIP_WHITESPACE ();
14916   reg = reg_required_here (&input_line_pointer, -1);
14917   if (reg == FAIL)
14918     {
14919       as_bad (_("ARM register expected"));
14920       ignore_rest_of_line ();
14921       return;
14922     }
14923
14924   if (reg == 13 || reg == 15)
14925     {
14926       as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
14927       ignore_rest_of_line ();
14928       return;
14929     }
14930
14931   if (unwind.fp_reg != 13)
14932     as_bad (_("unexpected .unwind_movsp directive"));
14933
14934   /* Generate opcode to restore the value.  */
14935   op = 0x90 | reg;
14936   add_unwind_opcode (op, 1);
14937
14938   /* Record the information for later.  */
14939   unwind.fp_reg = reg;
14940   unwind.fp_offset = unwind.frame_size;
14941   unwind.sp_restored = 1;
14942   demand_empty_rest_of_line ();
14943 }
14944
14945
14946 /* Parse #<number>.  */
14947
14948 static int
14949 require_hashconst (int * val)
14950 {
14951   expressionS exp;
14952
14953   SKIP_WHITESPACE ();
14954   if (*input_line_pointer == '#')
14955     {
14956       input_line_pointer++;
14957       expression (&exp);
14958     }
14959   else
14960     exp.X_op = O_illegal;
14961
14962   if (exp.X_op != O_constant)
14963     {
14964       as_bad (_("expected #constant"));
14965       ignore_rest_of_line ();
14966       return FAIL;
14967     }
14968   *val = exp.X_add_number;
14969   return SUCCESS;
14970 }
14971
14972 /* Parse an unwind_pad directive.  */
14973
14974 static void
14975 s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
14976 {
14977   int offset;
14978
14979   if (require_hashconst (&offset) == FAIL)
14980     return;
14981
14982   if (offset & 3)
14983     {
14984       as_bad (_("stack increment must be multiple of 4"));
14985       ignore_rest_of_line ();
14986       return;
14987     }
14988
14989   /* Don't generate any opcodes, just record the details for later.  */
14990   unwind.frame_size += offset;
14991   unwind.pending_offset += offset;
14992
14993   demand_empty_rest_of_line ();
14994 }
14995
14996 /* Parse an unwind_setfp directive.  */
14997
14998 static void
14999 s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
15000 {
15001   int sp_reg;
15002   int fp_reg;
15003   int offset;
15004
15005   fp_reg = reg_required_here (&input_line_pointer, -1);
15006   if (skip_past_comma (&input_line_pointer) == FAIL)
15007     sp_reg = FAIL;
15008   else
15009     sp_reg = reg_required_here (&input_line_pointer, -1);
15010
15011   if (fp_reg == FAIL || sp_reg == FAIL)
15012     {
15013       as_bad (_("expected <reg>, <reg>"));
15014       ignore_rest_of_line ();
15015       return;
15016     }
15017
15018   /* Optonal constant.  */
15019   if (skip_past_comma (&input_line_pointer) != FAIL)
15020     {
15021       if (require_hashconst (&offset) == FAIL)
15022         return;
15023     }
15024   else
15025     offset = 0;
15026
15027   demand_empty_rest_of_line ();
15028
15029   if (sp_reg != 13 && sp_reg != unwind.fp_reg)
15030     {
15031       as_bad (_("register must be either sp or set by a previous"
15032                 "unwind_movsp directive"));
15033       return;
15034     }
15035
15036   /* Don't generate any opcodes, just record the information for later.  */
15037   unwind.fp_reg = fp_reg;
15038   unwind.fp_used = 1;
15039   if (sp_reg == 13)
15040     unwind.fp_offset = unwind.frame_size - offset;
15041   else
15042     unwind.fp_offset -= offset;
15043 }
15044
15045 /* Parse an unwind_raw directive.  */
15046
15047 static void
15048 s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
15049 {
15050   expressionS exp;
15051   /* This is an arbitary limit.  */
15052   unsigned char op[16];
15053   int count;
15054
15055   SKIP_WHITESPACE ();
15056   expression (&exp);
15057   if (exp.X_op == O_constant
15058       && skip_past_comma (&input_line_pointer) != FAIL)
15059     {
15060       unwind.frame_size += exp.X_add_number;
15061       expression (&exp);
15062     }
15063   else
15064     exp.X_op = O_illegal;
15065
15066   if (exp.X_op != O_constant)
15067     {
15068       as_bad (_("expected <offset>, <opcode>"));
15069       ignore_rest_of_line ();
15070       return;
15071     }
15072
15073   count = 0;
15074
15075   /* Parse the opcode.  */
15076   for (;;)
15077     {
15078       if (count >= 16)
15079         {
15080           as_bad (_("unwind opcode too long"));
15081           ignore_rest_of_line ();
15082         }
15083       if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
15084         {
15085           as_bad (_("invalid unwind opcode"));
15086           ignore_rest_of_line ();
15087           return;
15088         }
15089       op[count++] = exp.X_add_number;
15090
15091       /* Parse the next byte.  */
15092       if (skip_past_comma (&input_line_pointer) == FAIL)
15093         break;
15094
15095       expression (&exp);
15096     }
15097
15098   /* Add the opcode bytes in reverse order.  */
15099   while (count--)
15100     add_unwind_opcode (op[count], 1);
15101
15102   demand_empty_rest_of_line ();
15103 }
15104
15105 #endif /* OBJ_ELF */
15106
15107 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
15108    of an rs_align_code fragment.  */
15109
15110 void
15111 arm_handle_align (fragS * fragP)
15112 {
15113   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
15114   static char const thumb_noop[2] = { 0xc0, 0x46 };
15115   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
15116   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
15117
15118   int bytes, fix, noop_size;
15119   char * p;
15120   const char * noop;
15121
15122   if (fragP->fr_type != rs_align_code)
15123     return;
15124
15125   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
15126   p = fragP->fr_literal + fragP->fr_fix;
15127   fix = 0;
15128
15129   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
15130     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
15131
15132   if (fragP->tc_frag_data)
15133     {
15134       if (target_big_endian)
15135         noop = thumb_bigend_noop;
15136       else
15137         noop = thumb_noop;
15138       noop_size = sizeof (thumb_noop);
15139     }
15140   else
15141     {
15142       if (target_big_endian)
15143         noop = arm_bigend_noop;
15144       else
15145         noop = arm_noop;
15146       noop_size = sizeof (arm_noop);
15147     }
15148
15149   if (bytes & (noop_size - 1))
15150     {
15151       fix = bytes & (noop_size - 1);
15152       memset (p, 0, fix);
15153       p += fix;
15154       bytes -= fix;
15155     }
15156
15157   while (bytes >= noop_size)
15158     {
15159       memcpy (p, noop, noop_size);
15160       p += noop_size;
15161       bytes -= noop_size;
15162       fix += noop_size;
15163     }
15164
15165   fragP->fr_fix += fix;
15166   fragP->fr_var = noop_size;
15167 }
15168
15169 /* Called from md_do_align.  Used to create an alignment
15170    frag in a code section.  */
15171
15172 void
15173 arm_frag_align_code (int n, int max)
15174 {
15175   char * p;
15176
15177   /* We assume that there will never be a requirement
15178      to support alignments greater than 32 bytes.  */
15179   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
15180     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
15181
15182   p = frag_var (rs_align_code,
15183                 MAX_MEM_FOR_RS_ALIGN_CODE,
15184                 1,
15185                 (relax_substateT) max,
15186                 (symbolS *) NULL,
15187                 (offsetT) n,
15188                 (char *) NULL);
15189   *p = 0;
15190 }
15191
15192 /* Perform target specific initialisation of a frag.  */
15193
15194 void
15195 arm_init_frag (fragS * fragP)
15196 {
15197   /* Record whether this frag is in an ARM or a THUMB area.  */
15198   fragP->tc_frag_data = thumb_mode;
15199 }
15200
15201 #ifdef OBJ_ELF
15202
15203 /* Convert REGNAME to a DWARF-2 register number.  */
15204
15205 int
15206 tc_arm_regname_to_dw2regnum (const char *regname)
15207 {
15208   unsigned int i;
15209
15210   for (i = 0; rn_table[i].name; i++)
15211     if (streq (regname, rn_table[i].name))
15212       return rn_table[i].number;
15213
15214   return -1;
15215 }
15216
15217 /* Initialize the DWARF-2 unwind information for this procedure.  */
15218
15219 void
15220 tc_arm_frame_initial_instructions (void)
15221 {
15222   cfi_add_CFA_def_cfa (REG_SP, 0);
15223 }
15224 #endif
15225
15226 /* This table describes all the machine specific pseudo-ops the assembler
15227    has to support.  The fields are:
15228      pseudo-op name without dot
15229      function to call to execute this pseudo-op
15230      Integer arg to pass to the function.  */
15231
15232 const pseudo_typeS md_pseudo_table[] =
15233 {
15234   /* Never called because '.req' does not start a line.  */
15235   { "req",         s_req,         0 },
15236   { "unreq",       s_unreq,       0 },
15237   { "bss",         s_bss,         0 },
15238   { "align",       s_align,       0 },
15239   { "arm",         s_arm,         0 },
15240   { "thumb",       s_thumb,       0 },
15241   { "code",        s_code,        0 },
15242   { "force_thumb", s_force_thumb, 0 },
15243   { "thumb_func",  s_thumb_func,  0 },
15244   { "thumb_set",   s_thumb_set,   0 },
15245   { "even",        s_even,        0 },
15246   { "ltorg",       s_ltorg,       0 },
15247   { "pool",        s_ltorg,       0 },
15248 #ifdef OBJ_ELF
15249   { "word",        s_arm_elf_cons, 4 },
15250   { "long",        s_arm_elf_cons, 4 },
15251   { "rel31",       s_arm_rel31,   0 },
15252   { "fnstart",          s_arm_unwind_fnstart,   0 },
15253   { "fnend",            s_arm_unwind_fnend,     0 },
15254   { "cantunwind",       s_arm_unwind_cantunwind, 0 },
15255   { "personality",      s_arm_unwind_personality, 0 },
15256   { "personalityindex", s_arm_unwind_personalityindex, 0 },
15257   { "handlerdata",      s_arm_unwind_handlerdata, 0 },
15258   { "save",             s_arm_unwind_save,      0 },
15259   { "movsp",            s_arm_unwind_movsp,     0 },
15260   { "pad",              s_arm_unwind_pad,       0 },
15261   { "setfp",            s_arm_unwind_setfp,     0 },
15262   { "unwind_raw",       s_arm_unwind_raw,       0 },
15263 #else
15264   { "word",        cons, 4},
15265 #endif
15266   { "extend",      float_cons, 'x' },
15267   { "ldouble",     float_cons, 'x' },
15268   { "packed",      float_cons, 'p' },
15269   { 0, 0, 0 }
15270 };