Make -mlittle-endian switch set the target_big_endian variable to false.
[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, 51 Franklin Street - Fifth Floor, Boston, MA
26    02110-1301, 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 /* Bit N indicates that an R_ARM_NONE relocation has been output for
87    __aeabi_unwind_cpp_prN already if set. This enables dependencies to be
88    emitted only once per section, to save unnecessary bloat.  */
89 static unsigned int marked_pr_dependency = 0;
90
91 #endif /* OBJ_ELF */
92
93 enum arm_float_abi
94 {
95   ARM_FLOAT_ABI_HARD,
96   ARM_FLOAT_ABI_SOFTFP,
97   ARM_FLOAT_ABI_SOFT
98 };
99
100 /* Types of processor to assemble for.  */
101 #define ARM_1           ARM_ARCH_V1
102 #define ARM_2           ARM_ARCH_V2
103 #define ARM_3           ARM_ARCH_V2S
104 #define ARM_250         ARM_ARCH_V2S
105 #define ARM_6           ARM_ARCH_V3
106 #define ARM_7           ARM_ARCH_V3
107 #define ARM_8           ARM_ARCH_V4
108 #define ARM_9           ARM_ARCH_V4T
109 #define ARM_STRONG      ARM_ARCH_V4
110 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
111
112 #ifndef CPU_DEFAULT
113 #if defined __XSCALE__
114 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
115 #else
116 #if defined __thumb__
117 #define CPU_DEFAULT     (ARM_ARCH_V5T)
118 #else
119 #define CPU_DEFAULT     ARM_ANY
120 #endif
121 #endif
122 #endif
123
124 #ifndef FPU_DEFAULT
125 # ifdef TE_LINUX
126 #  define FPU_DEFAULT FPU_ARCH_FPA
127 # elif defined (TE_NetBSD)
128 #  ifdef OBJ_ELF
129 #   define FPU_DEFAULT FPU_ARCH_VFP     /* Soft-float, but VFP order.  */
130 #  else
131     /* Legacy a.out format.  */
132 #   define FPU_DEFAULT FPU_ARCH_FPA     /* Soft-float, but FPA order.  */
133 #  endif
134 # elif defined (TE_VXWORKS)
135 #  define FPU_DEFAULT FPU_ARCH_VFP      /* Soft-float, VFP order.  */
136 # else
137    /* For backwards compatibility, default to FPA.  */
138 #  define FPU_DEFAULT FPU_ARCH_FPA
139 # endif
140 #endif /* ifndef FPU_DEFAULT */
141
142 #define streq(a, b)           (strcmp (a, b) == 0)
143 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
144
145 static unsigned long cpu_variant;
146
147 /* Flags stored in private area of BFD structure.  */
148 static int uses_apcs_26      = FALSE;
149 static int atpcs             = FALSE;
150 static int support_interwork = FALSE;
151 static int uses_apcs_float   = FALSE;
152 static int pic_code          = FALSE;
153
154 /* Variables that we set while parsing command-line options.  Once all
155    options have been read we re-process these values to set the real
156    assembly flags.  */
157 static int legacy_cpu = -1;
158 static int legacy_fpu = -1;
159
160 static int mcpu_cpu_opt = -1;
161 static int mcpu_fpu_opt = -1;
162 static int march_cpu_opt = -1;
163 static int march_fpu_opt = -1;
164 static int mfpu_opt = -1;
165 static int mfloat_abi_opt = -1;
166 #ifdef OBJ_ELF
167 # ifdef EABI_DEFAULT
168 static int meabi_flags = EABI_DEFAULT;
169 # else
170 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
171 # endif
172 #endif
173
174 /* This array holds the chars that always start a comment.  If the
175    pre-processor is disabled, these aren't very useful.  */
176 const char comment_chars[] = "@";
177
178 /* This array holds the chars that only start a comment at the beginning of
179    a line.  If the line seems to have the form '# 123 filename'
180    .line and .file directives will appear in the pre-processed output.  */
181 /* Note that input_file.c hand checks for '#' at the beginning of the
182    first line of the input file.  This is because the compiler outputs
183    #NO_APP at the beginning of its output.  */
184 /* Also note that comments like this one will always work.  */
185 const char line_comment_chars[] = "#";
186
187 const char line_separator_chars[] = ";";
188
189 /* Chars that can be used to separate mant
190    from exp in floating point numbers.  */
191 const char EXP_CHARS[] = "eE";
192
193 /* Chars that mean this number is a floating point constant.  */
194 /* As in 0f12.456  */
195 /* or    0d1.2345e12  */
196
197 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
198
199 /* Prefix characters that indicate the start of an immediate
200    value.  */
201 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
202
203 #ifdef OBJ_ELF
204 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
205 symbolS * GOT_symbol;
206 #endif
207
208 /* Size of relocation record.  */
209 const int md_reloc_size = 8;
210
211 /* 0: assemble for ARM,
212    1: assemble for Thumb,
213    2: assemble for Thumb even though target CPU does not support thumb
214       instructions.  */
215 static int thumb_mode = 0;
216
217 typedef struct arm_fix
218 {
219   int thumb_mode;
220 } arm_fix_data;
221
222 struct arm_it
223 {
224   const char *  error;
225   unsigned long instruction;
226   int           size;
227   struct
228   {
229     bfd_reloc_code_real_type type;
230     expressionS              exp;
231     int                      pc_rel;
232   } reloc;
233 };
234
235 struct arm_it inst;
236
237 enum asm_shift_index
238 {
239   SHIFT_LSL = 0,
240   SHIFT_LSR,
241   SHIFT_ASR,
242   SHIFT_ROR,
243   SHIFT_RRX
244 };
245
246 struct asm_shift_properties
247 {
248   enum asm_shift_index index;
249   unsigned long        bit_field;
250   unsigned int         allows_0  : 1;
251   unsigned int         allows_32 : 1;
252 };
253
254 static const struct asm_shift_properties shift_properties [] =
255 {
256   { SHIFT_LSL, 0,    1, 0},
257   { SHIFT_LSR, 0x20, 0, 1},
258   { SHIFT_ASR, 0x40, 0, 1},
259   { SHIFT_ROR, 0x60, 0, 0},
260   { SHIFT_RRX, 0x60, 0, 0}
261 };
262
263 struct asm_shift_name
264 {
265   const char *                        name;
266   const struct asm_shift_properties * properties;
267 };
268
269 static const struct asm_shift_name shift_names [] =
270 {
271   { "asl", shift_properties + SHIFT_LSL },
272   { "lsl", shift_properties + SHIFT_LSL },
273   { "lsr", shift_properties + SHIFT_LSR },
274   { "asr", shift_properties + SHIFT_ASR },
275   { "ror", shift_properties + SHIFT_ROR },
276   { "rrx", shift_properties + SHIFT_RRX },
277   { "ASL", shift_properties + SHIFT_LSL },
278   { "LSL", shift_properties + SHIFT_LSL },
279   { "LSR", shift_properties + SHIFT_LSR },
280   { "ASR", shift_properties + SHIFT_ASR },
281   { "ROR", shift_properties + SHIFT_ROR },
282   { "RRX", shift_properties + SHIFT_RRX }
283 };
284
285 /* Any kind of shift is accepted.  */
286 #define NO_SHIFT_RESTRICT 1
287 /* The shift operand must be an immediate value, not a register.  */
288 #define SHIFT_IMMEDIATE   0
289 /* The shift must be LSL or ASR and the operand must be an immediate.  */
290 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
291 /* The shift must be ASR and the operand must be an immediate.  */
292 #define SHIFT_ASR_IMMEDIATE 3
293 /* The shift must be LSL and the operand must be an immediate.  */
294 #define SHIFT_LSL_IMMEDIATE 4
295
296 #define NUM_FLOAT_VALS 8
297
298 const char * fp_const[] =
299 {
300   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
301 };
302
303 /* Number of littlenums required to hold an extended precision number.  */
304 #define MAX_LITTLENUMS 6
305
306 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
307
308 #define FAIL    (-1)
309 #define SUCCESS (0)
310
311 /* Whether a Co-processor load/store operation accepts write-back forms.  */
312 #define CP_WB_OK 1
313 #define CP_NO_WB 0
314
315 #define SUFF_S 1
316 #define SUFF_D 2
317 #define SUFF_E 3
318 #define SUFF_P 4
319
320 #define CP_T_X   0x00008000
321 #define CP_T_Y   0x00400000
322 #define CP_T_Pre 0x01000000
323 #define CP_T_UD  0x00800000
324 #define CP_T_WB  0x00200000
325
326 #define CONDS_BIT        0x00100000
327 #define LOAD_BIT         0x00100000
328
329 #define DOUBLE_LOAD_FLAG 0x00000001
330
331 struct asm_cond
332 {
333   const char *  template;
334   unsigned long value;
335 };
336
337 #define COND_ALWAYS 0xe0000000
338 #define COND_MASK   0xf0000000
339
340 static const struct asm_cond conds[] =
341 {
342   {"eq", 0x00000000},
343   {"ne", 0x10000000},
344   {"cs", 0x20000000}, {"hs", 0x20000000},
345   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
346   {"mi", 0x40000000},
347   {"pl", 0x50000000},
348   {"vs", 0x60000000},
349   {"vc", 0x70000000},
350   {"hi", 0x80000000},
351   {"ls", 0x90000000},
352   {"ge", 0xa0000000},
353   {"lt", 0xb0000000},
354   {"gt", 0xc0000000},
355   {"le", 0xd0000000},
356   {"al", 0xe0000000},
357   {"nv", 0xf0000000}
358 };
359
360 struct asm_psr
361 {
362   const char *template;
363   bfd_boolean cpsr;
364   unsigned long field;
365 };
366
367 /* The bit that distinguishes CPSR and SPSR.  */
368 #define SPSR_BIT   (1 << 22)
369
370 /* How many bits to shift the PSR_xxx bits up by.  */
371 #define PSR_SHIFT  16
372
373 #define PSR_c   (1 << 0)
374 #define PSR_x   (1 << 1)
375 #define PSR_s   (1 << 2)
376 #define PSR_f   (1 << 3)
377
378 static const struct asm_psr psrs[] =
379 {
380   {"CPSR",      TRUE,  PSR_c | PSR_f},
381   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
382   {"SPSR",      FALSE, PSR_c | PSR_f},
383   {"SPSR_all",  FALSE, PSR_c | PSR_f},
384   {"CPSR_flg",  TRUE,  PSR_f},
385   {"CPSR_f",    TRUE,  PSR_f},
386   {"SPSR_flg",  FALSE, PSR_f},
387   {"SPSR_f",    FALSE, PSR_f},
388   {"CPSR_c",    TRUE,  PSR_c},
389   {"CPSR_ctl",  TRUE,  PSR_c},
390   {"SPSR_c",    FALSE, PSR_c},
391   {"SPSR_ctl",  FALSE, PSR_c},
392   {"CPSR_x",    TRUE,  PSR_x},
393   {"CPSR_s",    TRUE,  PSR_s},
394   {"SPSR_x",    FALSE, PSR_x},
395   {"SPSR_s",    FALSE, PSR_s},
396   /* Combinations of flags.  */
397   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
398   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
399   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
400   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
401   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
402   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
403   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
404   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
405   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
406   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
407   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
408   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
409   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
410   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
411   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
412   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
413   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
414   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
415   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
416   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
417   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
418   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
419   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
420   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
421   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
422   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
423   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
424   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
425   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
426   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
427   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
428   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
429   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
430   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
431   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
432   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
433   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
434   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
435   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
436   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
437   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
438   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
439   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
440   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
441   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
442   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
443   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
444   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
445   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
446   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
447   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
448   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
449   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
450   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
451   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
452   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
453   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
454   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
455   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
456   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
457   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
458   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
459   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
460   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
461   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
462   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
463   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
464   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
465   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
466   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
467   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
468   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
469   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
470   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
471   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
472   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
473   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
474   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
475   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
476   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
477   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
478   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
479   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
480   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
481   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
482   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
483   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
484   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
485   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
486   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
487   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
488   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
489   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
490   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
491   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
492   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
493   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
494   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
495   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
496   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
497   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
498   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
499   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
500   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
501   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
502   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
503   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
504   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
505   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
506   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
507   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
508   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
509   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
510   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
511   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
512   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
513   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
514   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
515   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
516   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
517 };
518
519 enum wreg_type
520   {
521     IWMMXT_REG_WR = 0,
522     IWMMXT_REG_WC = 1,
523     IWMMXT_REG_WR_OR_WC = 2,
524     IWMMXT_REG_WCG
525   };
526
527 enum iwmmxt_insn_type
528 {
529   check_rd,
530   check_wr,
531   check_wrwr,
532   check_wrwrwr,
533   check_wrwrwcg,
534   check_tbcst,
535   check_tmovmsk,
536   check_tmia,
537   check_tmcrr,
538   check_tmrrc,
539   check_tmcr,
540   check_tmrc,
541   check_tinsr,
542   check_textrc,
543   check_waligni,
544   check_textrm,
545   check_wshufh
546 };
547
548 enum vfp_dp_reg_pos
549 {
550   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
551 };
552
553 enum vfp_sp_reg_pos
554 {
555   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
556 };
557
558 enum vfp_ldstm_type
559 {
560   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
561 };
562
563 /* VFP system registers.  */
564 struct vfp_reg
565 {
566   const char *name;
567   unsigned long regno;
568 };
569
570 static const struct vfp_reg vfp_regs[] =
571 {
572   {"fpsid", 0x00000000},
573   {"FPSID", 0x00000000},
574   {"fpscr", 0x00010000},
575   {"FPSCR", 0x00010000},
576   {"fpexc", 0x00080000},
577   {"FPEXC", 0x00080000}
578 };
579
580 /* Structure for a hash table entry for a register.  */
581 struct reg_entry
582 {
583   const char * name;
584   int          number;
585   bfd_boolean  builtin;
586 };
587
588 /* Some well known registers that we refer to directly elsewhere.  */
589 #define REG_SP  13
590 #define REG_LR  14
591 #define REG_PC  15
592
593 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
594 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
595 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
596
597 /* These are the standard names.  Users can add aliases with .req.
598    and delete them with .unreq.  */
599
600 /* Integer Register Numbers.  */
601 static const struct reg_entry rn_table[] =
602 {
603   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
604   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
605   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
606   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
607   /* ATPCS Synonyms.  */
608   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
609   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
610   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
611   /* Well-known aliases.  */
612   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
613   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
614   {NULL, 0, TRUE}
615 };
616
617 #define WR_PREFIX 0x200
618 #define WC_PREFIX 0x400
619
620 static const struct reg_entry iwmmxt_table[] =
621 {
622   /* Intel Wireless MMX technology register names.  */
623   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
624   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
625   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
626   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
627   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
628   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
629   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
630   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
631   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
632   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
633   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
634   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
635
636   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
637   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
638   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
639   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
640   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
641   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
642   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
643   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
644   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
645   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
646   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
647   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
648   {NULL, 0, TRUE}
649 };
650
651 /* Co-processor Numbers.  */
652 static const struct reg_entry cp_table[] =
653 {
654   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
655   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
656   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
657   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
658   {NULL, 0, TRUE}
659 };
660
661 /* Co-processor Register Numbers.  */
662 static const struct reg_entry cn_table[] =
663 {
664   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
665   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
666   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
667   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
668   /* Not really valid, but kept for back-wards compatibility.  */
669   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
670   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
671   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
672   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
673   {NULL, 0, TRUE}
674 };
675
676 /* FPA Registers.  */
677 static const struct reg_entry fn_table[] =
678 {
679   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
680   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
681   {NULL, 0, TRUE}
682 };
683
684 /* VFP SP Registers.  */
685 static const struct reg_entry sn_table[] =
686 {
687   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
688   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
689   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
690   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
691   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
692   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
693   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
694   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
695   {NULL, 0, TRUE}
696 };
697
698 /* VFP DP Registers.  */
699 static const struct reg_entry dn_table[] =
700 {
701   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
702   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
703   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
704   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
705   {NULL, 0, TRUE}
706 };
707
708 /* Maverick DSP coprocessor registers.  */
709 static const struct reg_entry mav_mvf_table[] =
710 {
711   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
712   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
713   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
714   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
715   {NULL, 0, TRUE}
716 };
717
718 static const struct reg_entry mav_mvd_table[] =
719 {
720   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
721   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
722   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
723   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
724   {NULL, 0, TRUE}
725 };
726
727 static const struct reg_entry mav_mvfx_table[] =
728 {
729   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
730   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
731   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
732   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
733   {NULL, 0, TRUE}
734 };
735
736 static const struct reg_entry mav_mvdx_table[] =
737 {
738   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
739   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
740   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
741   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
742   {NULL, 0, TRUE}
743 };
744
745 static const struct reg_entry mav_mvax_table[] =
746 {
747   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
748   {NULL, 0, TRUE}
749 };
750
751 static const struct reg_entry mav_dspsc_table[] =
752 {
753   {"dspsc", 0, TRUE},
754   {NULL, 0, TRUE}
755 };
756
757 struct reg_map
758 {
759   const struct reg_entry * names;
760   int                      max_regno;
761   struct hash_control *    htab;
762   const char *             expected;
763 };
764
765 struct reg_map all_reg_maps[] =
766 {
767   {rn_table,        15, NULL, N_("ARM register expected")},
768   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
769   {cn_table,        15, NULL, N_("co-processor register expected")},
770   {fn_table,         7, NULL, N_("FPA register expected")},
771   {sn_table,        31, NULL, N_("VFP single precision register expected")},
772   {dn_table,        15, NULL, N_("VFP double precision register expected")},
773   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
774   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
775   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
776   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
777   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
778   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
779   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
780 };
781
782 /* Enumeration matching entries in table above.  */
783 enum arm_reg_type
784 {
785   REG_TYPE_RN = 0,
786 #define REG_TYPE_FIRST REG_TYPE_RN
787   REG_TYPE_CP = 1,
788   REG_TYPE_CN = 2,
789   REG_TYPE_FN = 3,
790   REG_TYPE_SN = 4,
791   REG_TYPE_DN = 5,
792   REG_TYPE_MVF = 6,
793   REG_TYPE_MVD = 7,
794   REG_TYPE_MVFX = 8,
795   REG_TYPE_MVDX = 9,
796   REG_TYPE_MVAX = 10,
797   REG_TYPE_DSPSC = 11,
798   REG_TYPE_IWMMXT = 12,
799
800   REG_TYPE_MAX = 13
801 };
802
803 /* ARM instructions take 4bytes in the object file, Thumb instructions
804    take 2:  */
805 #define INSN_SIZE       4
806
807 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
808 #define MAV_MODE1       0x100c
809
810 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
811 #define MAV_MODE2       0x0c10
812
813 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
814 #define MAV_MODE3       0x100c
815
816 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
817 #define MAV_MODE4       0x0c0010
818
819 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
820 #define MAV_MODE5       0x00100c
821
822 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
823 #define MAV_MODE6       0x00100c05
824
825 struct asm_opcode
826 {
827   /* Basic string to match.  */
828   const char * template;
829
830   /* Basic instruction code.  */
831   unsigned long value;
832
833   /* Offset into the template where the condition code (if any) will be.
834      If zero, then the instruction is never conditional.  */
835   unsigned cond_offset;
836
837   /* Which architecture variant provides this instruction.  */
838   unsigned long variant;
839
840   /* Function to call to parse args.  */
841   void (* parms) (char *);
842 };
843
844 /* Defines for various bits that we will want to toggle.  */
845 #define INST_IMMEDIATE  0x02000000
846 #define OFFSET_REG      0x02000000
847 #define HWOFFSET_IMM    0x00400000
848 #define SHIFT_BY_REG    0x00000010
849 #define PRE_INDEX       0x01000000
850 #define INDEX_UP        0x00800000
851 #define WRITE_BACK      0x00200000
852 #define LDM_TYPE_2_OR_3 0x00400000
853
854 #define LITERAL_MASK    0xf000f000
855 #define OPCODE_MASK     0xfe1fffff
856 #define V4_STR_BIT      0x00000020
857
858 #define DATA_OP_SHIFT   21
859
860 /* Codes to distinguish the arithmetic instructions.  */
861 #define OPCODE_AND      0
862 #define OPCODE_EOR      1
863 #define OPCODE_SUB      2
864 #define OPCODE_RSB      3
865 #define OPCODE_ADD      4
866 #define OPCODE_ADC      5
867 #define OPCODE_SBC      6
868 #define OPCODE_RSC      7
869 #define OPCODE_TST      8
870 #define OPCODE_TEQ      9
871 #define OPCODE_CMP      10
872 #define OPCODE_CMN      11
873 #define OPCODE_ORR      12
874 #define OPCODE_MOV      13
875 #define OPCODE_BIC      14
876 #define OPCODE_MVN      15
877
878 #define T_OPCODE_MUL 0x4340
879 #define T_OPCODE_TST 0x4200
880 #define T_OPCODE_CMN 0x42c0
881 #define T_OPCODE_NEG 0x4240
882 #define T_OPCODE_MVN 0x43c0
883
884 #define T_OPCODE_ADD_R3 0x1800
885 #define T_OPCODE_SUB_R3 0x1a00
886 #define T_OPCODE_ADD_HI 0x4400
887 #define T_OPCODE_ADD_ST 0xb000
888 #define T_OPCODE_SUB_ST 0xb080
889 #define T_OPCODE_ADD_SP 0xa800
890 #define T_OPCODE_ADD_PC 0xa000
891 #define T_OPCODE_ADD_I8 0x3000
892 #define T_OPCODE_SUB_I8 0x3800
893 #define T_OPCODE_ADD_I3 0x1c00
894 #define T_OPCODE_SUB_I3 0x1e00
895
896 #define T_OPCODE_ASR_R  0x4100
897 #define T_OPCODE_LSL_R  0x4080
898 #define T_OPCODE_LSR_R  0x40c0
899 #define T_OPCODE_ASR_I  0x1000
900 #define T_OPCODE_LSL_I  0x0000
901 #define T_OPCODE_LSR_I  0x0800
902
903 #define T_OPCODE_MOV_I8 0x2000
904 #define T_OPCODE_CMP_I8 0x2800
905 #define T_OPCODE_CMP_LR 0x4280
906 #define T_OPCODE_MOV_HR 0x4600
907 #define T_OPCODE_CMP_HR 0x4500
908
909 #define T_OPCODE_LDR_PC 0x4800
910 #define T_OPCODE_LDR_SP 0x9800
911 #define T_OPCODE_STR_SP 0x9000
912 #define T_OPCODE_LDR_IW 0x6800
913 #define T_OPCODE_STR_IW 0x6000
914 #define T_OPCODE_LDR_IH 0x8800
915 #define T_OPCODE_STR_IH 0x8000
916 #define T_OPCODE_LDR_IB 0x7800
917 #define T_OPCODE_STR_IB 0x7000
918 #define T_OPCODE_LDR_RW 0x5800
919 #define T_OPCODE_STR_RW 0x5000
920 #define T_OPCODE_LDR_RH 0x5a00
921 #define T_OPCODE_STR_RH 0x5200
922 #define T_OPCODE_LDR_RB 0x5c00
923 #define T_OPCODE_STR_RB 0x5400
924
925 #define T_OPCODE_PUSH   0xb400
926 #define T_OPCODE_POP    0xbc00
927
928 #define T_OPCODE_BRANCH 0xe7fe
929
930 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
931 #define THUMB_REG_LO    0x1
932 #define THUMB_REG_HI    0x2
933 #define THUMB_REG_ANY   0x3
934
935 #define THUMB_H1        0x0080
936 #define THUMB_H2        0x0040
937
938 #define THUMB_ASR 0
939 #define THUMB_LSL 1
940 #define THUMB_LSR 2
941
942 #define THUMB_MOVE 0
943 #define THUMB_COMPARE 1
944 #define THUMB_CPY 2
945
946 #define THUMB_LOAD 0
947 #define THUMB_STORE 1
948
949 #define THUMB_PP_PC_LR 0x0100
950
951 /* These three are used for immediate shifts, do not alter.  */
952 #define THUMB_WORD 2
953 #define THUMB_HALFWORD 1
954 #define THUMB_BYTE 0
955
956 struct thumb_opcode
957 {
958   /* Basic string to match.  */
959   const char * template;
960
961   /* Basic instruction code.  */
962   unsigned long value;
963
964   int size;
965
966   /* Which CPU variants this exists for.  */
967   unsigned long variant;
968
969   /* Function to call to parse args.  */
970   void (* parms) (char *);
971 };
972
973 #define BAD_ARGS        _("bad arguments to instruction")
974 #define BAD_PC          _("r15 not allowed here")
975 #define BAD_COND        _("instruction is not conditional")
976 #define ERR_NO_ACCUM    _("acc0 expected")
977
978 static struct hash_control * arm_ops_hsh   = NULL;
979 static struct hash_control * arm_tops_hsh  = NULL;
980 static struct hash_control * arm_cond_hsh  = NULL;
981 static struct hash_control * arm_shift_hsh = NULL;
982 static struct hash_control * arm_psr_hsh   = NULL;
983
984 /* Stuff needed to resolve the label ambiguity
985    As:
986      ...
987      label:   <insn>
988    may differ from:
989      ...
990      label:
991               <insn>
992 */
993
994 symbolS *  last_label_seen;
995 static int label_is_thumb_function_name = FALSE;
996 \f
997 /* Literal Pool stuff.  */
998
999 #define MAX_LITERAL_POOL_SIZE 1024
1000
1001 /* Literal pool structure.  Held on a per-section
1002    and per-sub-section basis.  */
1003
1004 typedef struct literal_pool
1005 {
1006   expressionS    literals [MAX_LITERAL_POOL_SIZE];
1007   unsigned int   next_free_entry;
1008   unsigned int   id;
1009   symbolS *      symbol;
1010   segT           section;
1011   subsegT        sub_section;
1012   struct literal_pool * next;
1013 } literal_pool;
1014
1015 /* Pointer to a linked list of literal pools.  */
1016 literal_pool * list_of_pools = NULL;
1017
1018 static literal_pool *
1019 find_literal_pool (void)
1020 {
1021   literal_pool * pool;
1022
1023   for (pool = list_of_pools; pool != NULL; pool = pool->next)
1024     {
1025       if (pool->section == now_seg
1026           && pool->sub_section == now_subseg)
1027         break;
1028     }
1029
1030   return pool;
1031 }
1032
1033 static literal_pool *
1034 find_or_make_literal_pool (void)
1035 {
1036   /* Next literal pool ID number.  */
1037   static unsigned int latest_pool_num = 1;
1038   literal_pool *      pool;
1039
1040   pool = find_literal_pool ();
1041
1042   if (pool == NULL)
1043     {
1044       /* Create a new pool.  */
1045       pool = xmalloc (sizeof (* pool));
1046       if (! pool)
1047         return NULL;
1048
1049       pool->next_free_entry = 0;
1050       pool->section         = now_seg;
1051       pool->sub_section     = now_subseg;
1052       pool->next            = list_of_pools;
1053       pool->symbol          = NULL;
1054
1055       /* Add it to the list.  */
1056       list_of_pools = pool;
1057     }
1058
1059   /* New pools, and emptied pools, will have a NULL symbol.  */
1060   if (pool->symbol == NULL)
1061     {
1062       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
1063                                     (valueT) 0, &zero_address_frag);
1064       pool->id = latest_pool_num ++;
1065     }
1066
1067   /* Done.  */
1068   return pool;
1069 }
1070
1071 /* Add the literal in the global 'inst'
1072    structure to the relevent literal pool.  */
1073
1074 static int
1075 add_to_lit_pool (void)
1076 {
1077   literal_pool * pool;
1078   unsigned int entry;
1079
1080   pool = find_or_make_literal_pool ();
1081
1082   /* Check if this literal value is already in the pool.  */
1083   for (entry = 0; entry < pool->next_free_entry; entry ++)
1084     {
1085       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1086           && (inst.reloc.exp.X_op == O_constant)
1087           && (pool->literals[entry].X_add_number
1088               == inst.reloc.exp.X_add_number)
1089           && (pool->literals[entry].X_unsigned
1090               == inst.reloc.exp.X_unsigned))
1091         break;
1092
1093       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1094           && (inst.reloc.exp.X_op == O_symbol)
1095           && (pool->literals[entry].X_add_number
1096               == inst.reloc.exp.X_add_number)
1097           && (pool->literals[entry].X_add_symbol
1098               == inst.reloc.exp.X_add_symbol)
1099           && (pool->literals[entry].X_op_symbol
1100               == inst.reloc.exp.X_op_symbol))
1101         break;
1102     }
1103
1104   /* Do we need to create a new entry?  */
1105   if (entry == pool->next_free_entry)
1106     {
1107       if (entry >= MAX_LITERAL_POOL_SIZE)
1108         {
1109           inst.error = _("literal pool overflow");
1110           return FAIL;
1111         }
1112
1113       pool->literals[entry] = inst.reloc.exp;
1114       pool->next_free_entry += 1;
1115     }
1116
1117   inst.reloc.exp.X_op         = O_symbol;
1118   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
1119   inst.reloc.exp.X_add_symbol = pool->symbol;
1120
1121   return SUCCESS;
1122 }
1123
1124 /* Can't use symbol_new here, so have to create a symbol and then at
1125    a later date assign it a value. Thats what these functions do.  */
1126
1127 static void
1128 symbol_locate (symbolS *    symbolP,
1129                const char * name,       /* It is copied, the caller can modify.  */
1130                segT         segment,    /* Segment identifier (SEG_<something>).  */
1131                valueT       valu,       /* Symbol value.  */
1132                fragS *      frag)       /* Associated fragment.  */
1133 {
1134   unsigned int name_length;
1135   char * preserved_copy_of_name;
1136
1137   name_length = strlen (name) + 1;   /* +1 for \0.  */
1138   obstack_grow (&notes, name, name_length);
1139   preserved_copy_of_name = obstack_finish (&notes);
1140
1141 #ifdef tc_canonicalize_symbol_name
1142   preserved_copy_of_name =
1143     tc_canonicalize_symbol_name (preserved_copy_of_name);
1144 #endif
1145
1146   S_SET_NAME (symbolP, preserved_copy_of_name);
1147
1148   S_SET_SEGMENT (symbolP, segment);
1149   S_SET_VALUE (symbolP, valu);
1150   symbol_clear_list_pointers (symbolP);
1151
1152   symbol_set_frag (symbolP, frag);
1153
1154   /* Link to end of symbol chain.  */
1155   {
1156     extern int symbol_table_frozen;
1157
1158     if (symbol_table_frozen)
1159       abort ();
1160   }
1161
1162   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1163
1164   obj_symbol_new_hook (symbolP);
1165
1166 #ifdef tc_symbol_new_hook
1167   tc_symbol_new_hook (symbolP);
1168 #endif
1169
1170 #ifdef DEBUG_SYMS
1171   verify_symbol_chain (symbol_rootP, symbol_lastP);
1172 #endif /* DEBUG_SYMS  */
1173 }
1174
1175 /* Check that an immediate is valid.
1176    If so, convert it to the right format.  */
1177
1178 static unsigned int
1179 validate_immediate (unsigned int val)
1180 {
1181   unsigned int a;
1182   unsigned int i;
1183
1184 #define rotate_left(v, n) (v << n | v >> (32 - n))
1185
1186   for (i = 0; i < 32; i += 2)
1187     if ((a = rotate_left (val, i)) <= 0xff)
1188       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
1189
1190   return FAIL;
1191 }
1192
1193 /* Check to see if an immediate can be computed as two separate immediate
1194    values, added together.  We already know that this value cannot be
1195    computed by just one ARM instruction.  */
1196
1197 static unsigned int
1198 validate_immediate_twopart (unsigned int   val,
1199                             unsigned int * highpart)
1200 {
1201   unsigned int a;
1202   unsigned int i;
1203
1204   for (i = 0; i < 32; i += 2)
1205     if (((a = rotate_left (val, i)) & 0xff) != 0)
1206       {
1207         if (a & 0xff00)
1208           {
1209             if (a & ~ 0xffff)
1210               continue;
1211             * highpart = (a  >> 8) | ((i + 24) << 7);
1212           }
1213         else if (a & 0xff0000)
1214           {
1215             if (a & 0xff000000)
1216               continue;
1217             * highpart = (a >> 16) | ((i + 16) << 7);
1218           }
1219         else
1220           {
1221             assert (a & 0xff000000);
1222             * highpart = (a >> 24) | ((i + 8) << 7);
1223           }
1224
1225         return (a & 0xff) | (i << 7);
1226       }
1227
1228   return FAIL;
1229 }
1230
1231 static int
1232 validate_offset_imm (unsigned int val, int hwse)
1233 {
1234   if ((hwse && val > 255) || val > 4095)
1235     return FAIL;
1236   return val;
1237 }
1238
1239 \f
1240 #ifdef OBJ_ELF
1241 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
1242    (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
1243    Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
1244    and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped.  */
1245
1246 static enum mstate mapstate = MAP_UNDEFINED;
1247
1248 static void
1249 mapping_state (enum mstate state)
1250 {
1251   symbolS * symbolP;
1252   const char * symname;
1253   int type;
1254
1255   if (mapstate == state)
1256     /* The mapping symbol has already been emitted.
1257        There is nothing else to do.  */
1258     return;
1259
1260   mapstate = state;
1261
1262   switch (state)
1263     {
1264     case MAP_DATA:
1265       symname = "$d";
1266       type = BSF_NO_FLAGS;
1267       break;
1268     case MAP_ARM:
1269       symname = "$a";
1270       type = BSF_NO_FLAGS;
1271       break;
1272     case MAP_THUMB:
1273       symname = "$t";
1274       type = BSF_NO_FLAGS;
1275       break;
1276     case MAP_UNDEFINED:
1277       return;
1278     default:
1279       abort ();
1280     }
1281
1282   seg_info (now_seg)->tc_segment_info_data.mapstate = state;
1283
1284   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
1285   symbol_table_insert (symbolP);
1286   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1287
1288   switch (state)
1289     {
1290     case MAP_ARM:
1291       THUMB_SET_FUNC (symbolP, 0);
1292       ARM_SET_THUMB (symbolP, 0);
1293       ARM_SET_INTERWORK (symbolP, support_interwork);
1294       break;
1295
1296     case MAP_THUMB:
1297       THUMB_SET_FUNC (symbolP, 1);
1298       ARM_SET_THUMB (symbolP, 1);
1299       ARM_SET_INTERWORK (symbolP, support_interwork);
1300       break;
1301
1302     case MAP_DATA:
1303     default:
1304       return;
1305     }
1306 }
1307
1308 /* When we change sections we need to issue a new mapping symbol.  */
1309
1310 void
1311 arm_elf_change_section (void)
1312 {
1313   flagword flags;
1314   segment_info_type *seginfo;
1315
1316   /* Link an unlinked unwind index table section to the .text section.  */
1317   if (elf_section_type (now_seg) == SHT_ARM_EXIDX
1318       && elf_linked_to_section (now_seg) == NULL)
1319     elf_linked_to_section (now_seg) = text_section;
1320
1321   if (!SEG_NORMAL (now_seg))
1322     return;
1323
1324   flags = bfd_get_section_flags (stdoutput, now_seg);
1325
1326   /* We can ignore sections that only contain debug info.  */
1327   if ((flags & SEC_ALLOC) == 0)
1328     return;
1329
1330   seginfo = seg_info (now_seg);
1331   mapstate = seginfo->tc_segment_info_data.mapstate;
1332   marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
1333 }
1334
1335 int
1336 arm_elf_section_type (const char * str, size_t len)
1337 {
1338   if (len == 5 && strncmp (str, "exidx", 5) == 0)
1339     return SHT_ARM_EXIDX;
1340
1341   return -1;
1342 }
1343 #else
1344 #define mapping_state(a)
1345 #endif /* OBJ_ELF */
1346 \f
1347 /* arm_reg_parse () := if it looks like a register, return its token and
1348    advance the pointer.  */
1349
1350 static int
1351 arm_reg_parse (char ** ccp, struct hash_control * htab)
1352 {
1353   char * start = * ccp;
1354   char   c;
1355   char * p;
1356   struct reg_entry * reg;
1357
1358 #ifdef REGISTER_PREFIX
1359   if (*start != REGISTER_PREFIX)
1360     return FAIL;
1361   p = start + 1;
1362 #else
1363   p = start;
1364 #ifdef OPTIONAL_REGISTER_PREFIX
1365   if (*p == OPTIONAL_REGISTER_PREFIX)
1366     p++, start++;
1367 #endif
1368 #endif
1369   if (!ISALPHA (*p) || !is_name_beginner (*p))
1370     return FAIL;
1371
1372   c = *p++;
1373   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
1374     c = *p++;
1375
1376   *--p = 0;
1377   reg = (struct reg_entry *) hash_find (htab, start);
1378   *p = c;
1379
1380   if (reg)
1381     {
1382       *ccp = p;
1383       return reg->number;
1384     }
1385
1386   return FAIL;
1387 }
1388
1389 /* Search for the following register name in each of the possible reg name
1390    tables.  Return the classification if found, or REG_TYPE_MAX if not
1391    present.  */
1392
1393 static enum arm_reg_type
1394 arm_reg_parse_any (char *cp)
1395 {
1396   int i;
1397
1398   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
1399     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
1400       return (enum arm_reg_type) i;
1401
1402   return REG_TYPE_MAX;
1403 }
1404
1405 static void
1406 opcode_select (int width)
1407 {
1408   switch (width)
1409     {
1410     case 16:
1411       if (! thumb_mode)
1412         {
1413           if (! (cpu_variant & ARM_EXT_V4T))
1414             as_bad (_("selected processor does not support THUMB opcodes"));
1415
1416           thumb_mode = 1;
1417           /* No need to force the alignment, since we will have been
1418              coming from ARM mode, which is word-aligned.  */
1419           record_alignment (now_seg, 1);
1420         }
1421       mapping_state (MAP_THUMB);
1422       break;
1423
1424     case 32:
1425       if (thumb_mode)
1426         {
1427           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
1428             as_bad (_("selected processor does not support ARM opcodes"));
1429
1430           thumb_mode = 0;
1431
1432           if (!need_pass_2)
1433             frag_align (2, 0, 0);
1434
1435           record_alignment (now_seg, 1);
1436         }
1437       mapping_state (MAP_ARM);
1438       break;
1439
1440     default:
1441       as_bad (_("invalid instruction size selected (%d)"), width);
1442     }
1443 }
1444
1445 static void
1446 s_req (int a ATTRIBUTE_UNUSED)
1447 {
1448   as_bad (_("invalid syntax for .req directive"));
1449 }
1450
1451 /* The .unreq directive deletes an alias which was previously defined
1452    by .req.  For example:
1453
1454        my_alias .req r11
1455        .unreq my_alias    */
1456
1457 static void
1458 s_unreq (int a ATTRIBUTE_UNUSED)
1459 {
1460   char * name;
1461   char saved_char;
1462
1463   skip_whitespace (input_line_pointer);
1464   name = input_line_pointer;
1465
1466   while (*input_line_pointer != 0
1467          && *input_line_pointer != ' '
1468          && *input_line_pointer != '\n')
1469     ++input_line_pointer;
1470
1471   saved_char = *input_line_pointer;
1472   *input_line_pointer = 0;
1473
1474   if (*name)
1475     {
1476       enum arm_reg_type req_type = arm_reg_parse_any (name);
1477
1478       if (req_type != REG_TYPE_MAX)
1479         {
1480           char *temp_name = name;
1481           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
1482
1483           if (req_no != FAIL)
1484             {
1485               struct reg_entry *req_entry;
1486
1487               /* Check to see if this alias is a builtin one.  */
1488               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
1489
1490               if (!req_entry)
1491                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
1492               else if (req_entry->builtin)
1493                 /* FIXME: We are deleting a built in register alias which
1494                    points to a const data structure, so we only need to
1495                    free up the memory used by the key in the hash table.
1496                    Unfortunately we have not recorded this value, so this
1497                    is a memory leak.  */
1498                   /* FIXME: Should we issue a warning message ?  */
1499                 ;
1500               else
1501                 {
1502                   /* Deleting a user defined alias.  We need to free the
1503                      key and the value, but fortunately the key is the same
1504                      as the value->name field.  */
1505                   free ((char *) req_entry->name);
1506                   free (req_entry);
1507                 }
1508             }
1509           else
1510             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1511         }
1512       else
1513         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1514     }
1515   else
1516     as_bad (_("invalid syntax for .unreq directive"));
1517
1518   *input_line_pointer = saved_char;
1519   demand_empty_rest_of_line ();
1520 }
1521
1522 static void
1523 s_bss (int ignore ATTRIBUTE_UNUSED)
1524 {
1525   /* We don't support putting frags in the BSS segment, we fake it by
1526      marking in_bss, then looking at s_skip for clues.  */
1527   subseg_set (bss_section, 0);
1528   demand_empty_rest_of_line ();
1529   mapping_state (MAP_DATA);
1530 }
1531
1532 static void
1533 s_even (int ignore ATTRIBUTE_UNUSED)
1534 {
1535   /* Never make frag if expect extra pass.  */
1536   if (!need_pass_2)
1537     frag_align (1, 0, 0);
1538
1539   record_alignment (now_seg, 1);
1540
1541   demand_empty_rest_of_line ();
1542 }
1543
1544 static void
1545 s_ltorg (int ignored ATTRIBUTE_UNUSED)
1546 {
1547   unsigned int entry;
1548   literal_pool * pool;
1549   char sym_name[20];
1550
1551   pool = find_literal_pool ();
1552   if (pool == NULL
1553       || pool->symbol == NULL
1554       || pool->next_free_entry == 0)
1555     return;
1556
1557   mapping_state (MAP_DATA);
1558
1559   /* Align pool as you have word accesses.
1560      Only make a frag if we have to.  */
1561   if (!need_pass_2)
1562     frag_align (2, 0, 0);
1563
1564   record_alignment (now_seg, 2);
1565
1566   sprintf (sym_name, "$$lit_\002%x", pool->id);
1567
1568   symbol_locate (pool->symbol, sym_name, now_seg,
1569                  (valueT) frag_now_fix (), frag_now);
1570   symbol_table_insert (pool->symbol);
1571
1572   ARM_SET_THUMB (pool->symbol, thumb_mode);
1573
1574 #if defined OBJ_COFF || defined OBJ_ELF
1575   ARM_SET_INTERWORK (pool->symbol, support_interwork);
1576 #endif
1577
1578   for (entry = 0; entry < pool->next_free_entry; entry ++)
1579     /* First output the expression in the instruction to the pool.  */
1580     emit_expr (&(pool->literals[entry]), 4); /* .word  */
1581
1582   /* Mark the pool as empty.  */
1583   pool->next_free_entry = 0;
1584   pool->symbol = NULL;
1585 }
1586
1587 /* Same as s_align_ptwo but align 0 => align 2.  */
1588
1589 static void
1590 s_align (int unused ATTRIBUTE_UNUSED)
1591 {
1592   int temp;
1593   long temp_fill;
1594   long max_alignment = 15;
1595
1596   temp = get_absolute_expression ();
1597   if (temp > max_alignment)
1598     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
1599   else if (temp < 0)
1600     {
1601       as_bad (_("alignment negative. 0 assumed."));
1602       temp = 0;
1603     }
1604
1605   if (*input_line_pointer == ',')
1606     {
1607       input_line_pointer++;
1608       temp_fill = get_absolute_expression ();
1609     }
1610   else
1611     temp_fill = 0;
1612
1613   if (!temp)
1614     temp = 2;
1615
1616   /* Only make a frag if we HAVE to.  */
1617   if (temp && !need_pass_2)
1618     frag_align (temp, (int) temp_fill, 0);
1619   demand_empty_rest_of_line ();
1620
1621   record_alignment (now_seg, temp);
1622 }
1623
1624 static void
1625 s_force_thumb (int ignore ATTRIBUTE_UNUSED)
1626 {
1627   /* If we are not already in thumb mode go into it, EVEN if
1628      the target processor does not support thumb instructions.
1629      This is used by gcc/config/arm/lib1funcs.asm for example
1630      to compile interworking support functions even if the
1631      target processor should not support interworking.  */
1632   if (! thumb_mode)
1633     {
1634       thumb_mode = 2;
1635
1636       record_alignment (now_seg, 1);
1637     }
1638
1639   demand_empty_rest_of_line ();
1640 }
1641
1642 static void
1643 s_thumb_func (int ignore ATTRIBUTE_UNUSED)
1644 {
1645   if (! thumb_mode)
1646     opcode_select (16);
1647
1648   /* The following label is the name/address of the start of a Thumb function.
1649      We need to know this for the interworking support.  */
1650   label_is_thumb_function_name = TRUE;
1651
1652   demand_empty_rest_of_line ();
1653 }
1654
1655 /* Perform a .set directive, but also mark the alias as
1656    being a thumb function.  */
1657
1658 static void
1659 s_thumb_set (int equiv)
1660 {
1661   /* XXX the following is a duplicate of the code for s_set() in read.c
1662      We cannot just call that code as we need to get at the symbol that
1663      is created.  */
1664   char *    name;
1665   char      delim;
1666   char *    end_name;
1667   symbolS * symbolP;
1668
1669   /* Especial apologies for the random logic:
1670      This just grew, and could be parsed much more simply!
1671      Dean - in haste.  */
1672   name      = input_line_pointer;
1673   delim     = get_symbol_end ();
1674   end_name  = input_line_pointer;
1675   *end_name = delim;
1676
1677   SKIP_WHITESPACE ();
1678
1679   if (*input_line_pointer != ',')
1680     {
1681       *end_name = 0;
1682       as_bad (_("expected comma after name \"%s\""), name);
1683       *end_name = delim;
1684       ignore_rest_of_line ();
1685       return;
1686     }
1687
1688   input_line_pointer++;
1689   *end_name = 0;
1690
1691   if (name[0] == '.' && name[1] == '\0')
1692     {
1693       /* XXX - this should not happen to .thumb_set.  */
1694       abort ();
1695     }
1696
1697   if ((symbolP = symbol_find (name)) == NULL
1698       && (symbolP = md_undefined_symbol (name)) == NULL)
1699     {
1700 #ifndef NO_LISTING
1701       /* When doing symbol listings, play games with dummy fragments living
1702          outside the normal fragment chain to record the file and line info
1703          for this symbol.  */
1704       if (listing & LISTING_SYMBOLS)
1705         {
1706           extern struct list_info_struct * listing_tail;
1707           fragS * dummy_frag = xmalloc (sizeof (fragS));
1708
1709           memset (dummy_frag, 0, sizeof (fragS));
1710           dummy_frag->fr_type = rs_fill;
1711           dummy_frag->line = listing_tail;
1712           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1713           dummy_frag->fr_symbol = symbolP;
1714         }
1715       else
1716 #endif
1717         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1718
1719 #ifdef OBJ_COFF
1720       /* "set" symbols are local unless otherwise specified.  */
1721       SF_SET_LOCAL (symbolP);
1722 #endif /* OBJ_COFF  */
1723     }                           /* Make a new symbol.  */
1724
1725   symbol_table_insert (symbolP);
1726
1727   * end_name = delim;
1728
1729   if (equiv
1730       && S_IS_DEFINED (symbolP)
1731       && S_GET_SEGMENT (symbolP) != reg_section)
1732     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1733
1734   pseudo_set (symbolP);
1735
1736   demand_empty_rest_of_line ();
1737
1738   /* XXX Now we come to the Thumb specific bit of code.  */
1739
1740   THUMB_SET_FUNC (symbolP, 1);
1741   ARM_SET_THUMB (symbolP, 1);
1742 #if defined OBJ_ELF || defined OBJ_COFF
1743   ARM_SET_INTERWORK (symbolP, support_interwork);
1744 #endif
1745 }
1746
1747 static void
1748 s_arm (int ignore ATTRIBUTE_UNUSED)
1749 {
1750   opcode_select (32);
1751   demand_empty_rest_of_line ();
1752 }
1753
1754 static void
1755 s_thumb (int ignore ATTRIBUTE_UNUSED)
1756 {
1757   opcode_select (16);
1758   demand_empty_rest_of_line ();
1759 }
1760
1761 static void
1762 s_code (int unused ATTRIBUTE_UNUSED)
1763 {
1764   int temp;
1765
1766   temp = get_absolute_expression ();
1767   switch (temp)
1768     {
1769     case 16:
1770     case 32:
1771       opcode_select (temp);
1772       break;
1773
1774     default:
1775       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1776     }
1777 }
1778
1779 static void
1780 end_of_line (char * str)
1781 {
1782   skip_whitespace (str);
1783
1784   if (*str != '\0' && !inst.error)
1785     inst.error = _("garbage following instruction");
1786 }
1787
1788 static int
1789 skip_past_comma (char ** str)
1790 {
1791   char * p = * str, c;
1792   int comma = 0;
1793
1794   while ((c = *p) == ' ' || c == ',')
1795     {
1796       p++;
1797       if (c == ',' && comma++)
1798         return FAIL;
1799     }
1800
1801   if (c == '\0')
1802     return FAIL;
1803
1804   *str = p;
1805   return comma ? SUCCESS : FAIL;
1806 }
1807
1808 /* Return TRUE if anything in the expression is a bignum.  */
1809
1810 static int
1811 walk_no_bignums (symbolS * sp)
1812 {
1813   if (symbol_get_value_expression (sp)->X_op == O_big)
1814     return 1;
1815
1816   if (symbol_get_value_expression (sp)->X_add_symbol)
1817     {
1818       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1819               || (symbol_get_value_expression (sp)->X_op_symbol
1820                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
1821     }
1822
1823   return 0;
1824 }
1825
1826 static int in_my_get_expression = 0;
1827
1828 static int
1829 my_get_expression (expressionS * ep, char ** str)
1830 {
1831   char * save_in;
1832   segT   seg;
1833
1834   save_in = input_line_pointer;
1835   input_line_pointer = *str;
1836   in_my_get_expression = 1;
1837   seg = expression (ep);
1838   in_my_get_expression = 0;
1839
1840   if (ep->X_op == O_illegal)
1841     {
1842       /* We found a bad expression in md_operand().  */
1843       *str = input_line_pointer;
1844       input_line_pointer = save_in;
1845       return 1;
1846     }
1847
1848 #ifdef OBJ_AOUT
1849   if (seg != absolute_section
1850       && seg != text_section
1851       && seg != data_section
1852       && seg != bss_section
1853       && seg != undefined_section)
1854     {
1855       inst.error = _("bad_segment");
1856       *str = input_line_pointer;
1857       input_line_pointer = save_in;
1858       return 1;
1859     }
1860 #endif
1861
1862   /* Get rid of any bignums now, so that we don't generate an error for which
1863      we can't establish a line number later on.  Big numbers are never valid
1864      in instructions, which is where this routine is always called.  */
1865   if (ep->X_op == O_big
1866       || (ep->X_add_symbol
1867           && (walk_no_bignums (ep->X_add_symbol)
1868               || (ep->X_op_symbol
1869                   && walk_no_bignums (ep->X_op_symbol)))))
1870     {
1871       inst.error = _("invalid constant");
1872       *str = input_line_pointer;
1873       input_line_pointer = save_in;
1874       return 1;
1875     }
1876
1877   *str = input_line_pointer;
1878   input_line_pointer = save_in;
1879   return 0;
1880 }
1881
1882 /* A standard register must be given at this point.
1883    SHIFT is the place to put it in inst.instruction.
1884    Restores input start point on error.
1885    Returns the reg#, or FAIL.  */
1886
1887 static int
1888 reg_required_here (char ** str, int shift)
1889 {
1890   static char buff [128]; /* XXX  */
1891   int         reg;
1892   char *      start = * str;
1893
1894   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
1895     {
1896       if (shift >= 0)
1897         inst.instruction |= reg << shift;
1898       return reg;
1899     }
1900
1901   /* Restore the start point, we may have got a reg of the wrong class.  */
1902   *str = start;
1903
1904   /* In the few cases where we might be able to accept something else
1905      this error can be overridden.  */
1906   sprintf (buff, _("register expected, not '%.100s'"), start);
1907   inst.error = buff;
1908
1909   return FAIL;
1910 }
1911
1912 /* A Intel Wireless MMX technology register
1913    must be given at this point.
1914    Shift is the place to put it in inst.instruction.
1915    Restores input start point on err.
1916    Returns the reg#, or FAIL.  */
1917
1918 static int
1919 wreg_required_here (char ** str,
1920                     int shift,
1921                     enum wreg_type reg_type)
1922 {
1923   static char buff [128];
1924   int    reg;
1925   char * start = *str;
1926
1927   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
1928     {
1929       if (wr_register (reg)
1930           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
1931         {
1932           if (shift >= 0)
1933             inst.instruction |= (reg ^ WR_PREFIX) << shift;
1934           return reg;
1935         }
1936       else if (wc_register (reg)
1937                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
1938         {
1939           if (shift >= 0)
1940             inst.instruction |= (reg ^ WC_PREFIX) << shift;
1941           return reg;
1942         }
1943       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
1944         {
1945           if (shift >= 0)
1946             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
1947           return reg;
1948         }
1949     }
1950
1951   /* Restore the start point, we may have got a reg of the wrong class.  */
1952   *str = start;
1953
1954   /* In the few cases where we might be able to accept
1955      something else this error can be overridden.  */
1956   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
1957   inst.error = buff;
1958
1959   return FAIL;
1960 }
1961
1962 static const struct asm_psr *
1963 arm_psr_parse (char ** ccp)
1964 {
1965   char * start = * ccp;
1966   char   c;
1967   char * p;
1968   const struct asm_psr * psr;
1969
1970   p = start;
1971
1972   /* Skip to the end of the next word in the input stream.  */
1973   do
1974     {
1975       c = *p++;
1976     }
1977   while (ISALPHA (c) || c == '_');
1978
1979   /* Terminate the word.  */
1980   *--p = 0;
1981
1982   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
1983      feature for ease of use and backwards compatibility.  */
1984   if (!strncmp (start, "cpsr", 4))
1985     strncpy (start, "CPSR", 4);
1986   else if (!strncmp (start, "spsr", 4))
1987     strncpy (start, "SPSR", 4);
1988
1989   /* Now locate the word in the psr hash table.  */
1990   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
1991
1992   /* Restore the input stream.  */
1993   *p = c;
1994
1995   /* If we found a valid match, advance the
1996      stream pointer past the end of the word.  */
1997   *ccp = p;
1998
1999   return psr;
2000 }
2001
2002 /* Parse the input looking for a PSR flag.  */
2003
2004 static int
2005 psr_required_here (char ** str)
2006 {
2007   char * start = * str;
2008   const struct asm_psr * psr;
2009
2010   psr = arm_psr_parse (str);
2011
2012   if (psr)
2013     {
2014       /* If this is the SPSR that is being modified, set the R bit.  */
2015       if (! psr->cpsr)
2016         inst.instruction |= SPSR_BIT;
2017
2018       /* Set the psr flags in the MSR instruction.  */
2019       inst.instruction |= psr->field << PSR_SHIFT;
2020
2021       return SUCCESS;
2022     }
2023
2024   /* In the few cases where we might be able to accept
2025      something else this error can be overridden.  */
2026   inst.error = _("flag for {c}psr instruction expected");
2027
2028   /* Restore the start point.  */
2029   *str = start;
2030   return FAIL;
2031 }
2032
2033 static int
2034 co_proc_number (char ** str)
2035 {
2036   int processor, pchar;
2037   char *start;
2038
2039   skip_whitespace (*str);
2040   start = *str;
2041
2042   /* The data sheet seems to imply that just a number on its own is valid
2043      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
2044      accept either.  */
2045   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2046       == FAIL)
2047     {
2048       *str = start;
2049
2050       pchar = *(*str)++;
2051       if (pchar >= '0' && pchar <= '9')
2052         {
2053           processor = pchar - '0';
2054           if (**str >= '0' && **str <= '9')
2055             {
2056               processor = processor * 10 + *(*str)++ - '0';
2057               if (processor > 15)
2058                 {
2059                   inst.error = _("illegal co-processor number");
2060                   return FAIL;
2061                 }
2062             }
2063         }
2064       else
2065         {
2066           inst.error = all_reg_maps[REG_TYPE_CP].expected;
2067           return FAIL;
2068         }
2069     }
2070
2071   inst.instruction |= processor << 8;
2072   return SUCCESS;
2073 }
2074
2075 static int
2076 cp_opc_expr (char ** str, int where, int length)
2077 {
2078   expressionS expr;
2079
2080   skip_whitespace (* str);
2081
2082   memset (&expr, '\0', sizeof (expr));
2083
2084   if (my_get_expression (&expr, str))
2085     return FAIL;
2086   if (expr.X_op != O_constant)
2087     {
2088       inst.error = _("bad or missing expression");
2089       return FAIL;
2090     }
2091
2092   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2093     {
2094       inst.error = _("immediate co-processor expression too large");
2095       return FAIL;
2096     }
2097
2098   inst.instruction |= expr.X_add_number << where;
2099   return SUCCESS;
2100 }
2101
2102 static int
2103 cp_reg_required_here (char ** str, int where)
2104 {
2105   int    reg;
2106   char * start = *str;
2107
2108   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2109     {
2110       inst.instruction |= reg << where;
2111       return reg;
2112     }
2113
2114   /* In the few cases where we might be able to accept something else
2115      this error can be overridden.  */
2116   inst.error = all_reg_maps[REG_TYPE_CN].expected;
2117
2118   /* Restore the start point.  */
2119   *str = start;
2120   return FAIL;
2121 }
2122
2123 static int
2124 fp_reg_required_here (char ** str, int where)
2125 {
2126   int    reg;
2127   char * start = * str;
2128
2129   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2130     {
2131       inst.instruction |= reg << where;
2132       return reg;
2133     }
2134
2135   /* In the few cases where we might be able to accept something else
2136      this error can be overridden.  */
2137   inst.error = all_reg_maps[REG_TYPE_FN].expected;
2138
2139   /* Restore the start point.  */
2140   *str = start;
2141   return FAIL;
2142 }
2143
2144 static int
2145 cp_address_offset (char ** str)
2146 {
2147   int offset;
2148
2149   skip_whitespace (* str);
2150
2151   if (! is_immediate_prefix (**str))
2152     {
2153       inst.error = _("immediate expression expected");
2154       return FAIL;
2155     }
2156
2157   (*str)++;
2158
2159   if (my_get_expression (& inst.reloc.exp, str))
2160     return FAIL;
2161
2162   if (inst.reloc.exp.X_op == O_constant)
2163     {
2164       offset = inst.reloc.exp.X_add_number;
2165
2166       if (offset & 3)
2167         {
2168           inst.error = _("co-processor address must be word aligned");
2169           return FAIL;
2170         }
2171
2172       if (offset > 1023 || offset < -1023)
2173         {
2174           inst.error = _("offset too large");
2175           return FAIL;
2176         }
2177
2178       if (offset >= 0)
2179         inst.instruction |= INDEX_UP;
2180       else
2181         offset = -offset;
2182
2183       inst.instruction |= offset >> 2;
2184     }
2185   else
2186     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2187
2188   return SUCCESS;
2189 }
2190
2191 static int
2192 cp_address_required_here (char ** str, int wb_ok)
2193 {
2194   char * p = * str;
2195   int    pre_inc = 0;
2196   int    write_back = 0;
2197
2198   if (*p == '[')
2199     {
2200       int reg;
2201
2202       p++;
2203       skip_whitespace (p);
2204
2205       if ((reg = reg_required_here (& p, 16)) == FAIL)
2206         return FAIL;
2207
2208       skip_whitespace (p);
2209
2210       if (*p == ']')
2211         {
2212           p++;
2213
2214           skip_whitespace (p);
2215
2216           if (*p == '\0')
2217             {
2218               /* As an extension to the official ARM syntax we allow:
2219                    [Rn]
2220                  as a short hand for:
2221                    [Rn,#0]  */
2222               inst.instruction |= PRE_INDEX | INDEX_UP;
2223               *str = p;
2224               return SUCCESS;
2225             }
2226
2227           if (skip_past_comma (& p) == FAIL)
2228             {
2229               inst.error = _("comma expected after closing square bracket");
2230               return FAIL;
2231             }
2232
2233           skip_whitespace (p);
2234
2235           if (*p == '#')
2236             {
2237               if (wb_ok)
2238                 {
2239                   /* [Rn], #expr  */
2240                   write_back = WRITE_BACK;
2241
2242                   if (reg == REG_PC)
2243                     {
2244                       inst.error = _("pc may not be used in post-increment");
2245                       return FAIL;
2246                     }
2247
2248                   if (cp_address_offset (& p) == FAIL)
2249                     return FAIL;
2250                 }
2251               else
2252                 pre_inc = PRE_INDEX | INDEX_UP;
2253             }
2254           else if (*p == '{')
2255             {
2256               int option;
2257
2258               /* [Rn], {<expr>}  */
2259               p++;
2260
2261               skip_whitespace (p);
2262
2263               if (my_get_expression (& inst.reloc.exp, & p))
2264                 return FAIL;
2265
2266               if (inst.reloc.exp.X_op == O_constant)
2267                 {
2268                   option = inst.reloc.exp.X_add_number;
2269
2270                   if (option > 255 || option < 0)
2271                     {
2272                       inst.error = _("'option' field too large");
2273                       return FAIL;
2274                     }
2275
2276                   skip_whitespace (p);
2277
2278                   if (*p != '}')
2279                     {
2280                       inst.error = _("'}' expected at end of 'option' field");
2281                       return FAIL;
2282                     }
2283                   else
2284                     {
2285                       p++;
2286                       inst.instruction |= option;
2287                       inst.instruction |= INDEX_UP;
2288                     }
2289                 }
2290               else
2291                 {
2292                   inst.error = _("non-constant expressions for 'option' field not supported");
2293                   return FAIL;
2294                 }
2295             }
2296           else
2297             {
2298               inst.error = _("# or { expected after comma");
2299               return FAIL;
2300             }
2301         }
2302       else
2303         {
2304           /* '['Rn, #expr']'[!]  */
2305
2306           if (skip_past_comma (& p) == FAIL)
2307             {
2308               inst.error = _("pre-indexed expression expected");
2309               return FAIL;
2310             }
2311
2312           pre_inc = PRE_INDEX;
2313
2314           if (cp_address_offset (& p) == FAIL)
2315             return FAIL;
2316
2317           skip_whitespace (p);
2318
2319           if (*p++ != ']')
2320             {
2321               inst.error = _("missing ]");
2322               return FAIL;
2323             }
2324
2325           skip_whitespace (p);
2326
2327           if (wb_ok && *p == '!')
2328             {
2329               if (reg == REG_PC)
2330                 {
2331                   inst.error = _("pc may not be used with write-back");
2332                   return FAIL;
2333                 }
2334
2335               p++;
2336               write_back = WRITE_BACK;
2337             }
2338         }
2339     }
2340   else
2341     {
2342       if (my_get_expression (&inst.reloc.exp, &p))
2343         return FAIL;
2344
2345       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2346       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2347       inst.reloc.pc_rel = 1;
2348       inst.instruction |= (REG_PC << 16);
2349       pre_inc = PRE_INDEX;
2350     }
2351
2352   inst.instruction |= write_back | pre_inc;
2353   *str = p;
2354   return SUCCESS;
2355 }
2356
2357 static int
2358 cp_byte_address_offset (char ** str)
2359 {
2360   int offset;
2361
2362   skip_whitespace (* str);
2363
2364   if (! is_immediate_prefix (**str))
2365     {
2366       inst.error = _("immediate expression expected");
2367       return FAIL;
2368     }
2369
2370   (*str)++;
2371
2372   if (my_get_expression (& inst.reloc.exp, str))
2373     return FAIL;
2374
2375   if (inst.reloc.exp.X_op == O_constant)
2376     {
2377       offset = inst.reloc.exp.X_add_number;
2378
2379       if (offset > 255 || offset < -255)
2380         {
2381           inst.error = _("offset too large");
2382           return FAIL;
2383         }
2384
2385       if (offset >= 0)
2386         inst.instruction |= INDEX_UP;
2387       else
2388         offset = -offset;
2389
2390       inst.instruction |= offset;
2391     }
2392   else
2393     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2394
2395   return SUCCESS;
2396 }
2397
2398 static int
2399 cp_byte_address_required_here (char ** str)
2400 {
2401   char * p = * str;
2402   int    pre_inc = 0;
2403   int    write_back = 0;
2404
2405   if (*p == '[')
2406     {
2407       int reg;
2408
2409       p++;
2410       skip_whitespace (p);
2411
2412       if ((reg = reg_required_here (& p, 16)) == FAIL)
2413         return FAIL;
2414
2415       skip_whitespace (p);
2416
2417       if (*p == ']')
2418         {
2419           p++;
2420
2421           if (skip_past_comma (& p) == SUCCESS)
2422             {
2423               /* [Rn], #expr */
2424               write_back = WRITE_BACK;
2425
2426               if (reg == REG_PC)
2427                 {
2428                   inst.error = _("pc may not be used in post-increment");
2429                   return FAIL;
2430                 }
2431
2432               if (cp_byte_address_offset (& p) == FAIL)
2433                 return FAIL;
2434             }
2435           else
2436             pre_inc = PRE_INDEX | INDEX_UP;
2437         }
2438       else
2439         {
2440           /* '['Rn, #expr']'[!] */
2441
2442           if (skip_past_comma (& p) == FAIL)
2443             {
2444               inst.error = _("pre-indexed expression expected");
2445               return FAIL;
2446             }
2447
2448           pre_inc = PRE_INDEX;
2449
2450           if (cp_byte_address_offset (& p) == FAIL)
2451             return FAIL;
2452
2453           skip_whitespace (p);
2454
2455           if (*p++ != ']')
2456             {
2457               inst.error = _("missing ]");
2458               return FAIL;
2459             }
2460
2461           skip_whitespace (p);
2462
2463           if (*p == '!')
2464             {
2465               if (reg == REG_PC)
2466                 {
2467                   inst.error = _("pc may not be used with write-back");
2468                   return FAIL;
2469                 }
2470
2471               p++;
2472               write_back = WRITE_BACK;
2473             }
2474         }
2475     }
2476   else
2477     {
2478       if (my_get_expression (&inst.reloc.exp, &p))
2479         return FAIL;
2480
2481       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2482       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2483       inst.reloc.pc_rel = 1;
2484       inst.instruction |= (REG_PC << 16);
2485       pre_inc = PRE_INDEX;
2486     }
2487
2488   inst.instruction |= write_back | pre_inc;
2489   *str = p;
2490   return SUCCESS;
2491 }
2492
2493 static void
2494 do_nop (char * str)
2495 {
2496   skip_whitespace (str);
2497   if (*str == '{')
2498     {
2499       str++;
2500
2501       if (my_get_expression (&inst.reloc.exp, &str))
2502         inst.reloc.exp.X_op = O_illegal;
2503       else
2504         {
2505           skip_whitespace (str);
2506           if (*str == '}')
2507             str++;
2508           else
2509             inst.reloc.exp.X_op = O_illegal;
2510         }
2511
2512       if (inst.reloc.exp.X_op != O_constant
2513           || inst.reloc.exp.X_add_number > 255
2514           || inst.reloc.exp.X_add_number < 0)
2515         {
2516           inst.error = _("Invalid NOP hint");
2517           return;
2518         }
2519
2520       /* Arcitectural NOP hints are CPSR sets with no bits selected.  */
2521       inst.instruction &= 0xf0000000;
2522       inst.instruction |= 0x0320f000 + inst.reloc.exp.X_add_number;
2523     }
2524
2525   end_of_line (str);
2526 }
2527
2528 static void
2529 do_empty (char * str)
2530 {
2531   /* Do nothing really.  */
2532   end_of_line (str);
2533 }
2534
2535 static void
2536 do_mrs (char * str)
2537 {
2538   int skip = 0;
2539
2540   /* Only one syntax.  */
2541   skip_whitespace (str);
2542
2543   if (reg_required_here (&str, 12) == FAIL)
2544     {
2545       inst.error = BAD_ARGS;
2546       return;
2547     }
2548
2549   if (skip_past_comma (&str) == FAIL)
2550     {
2551       inst.error = _("comma expected after register name");
2552       return;
2553     }
2554
2555   skip_whitespace (str);
2556
2557   if (   streq (str, "CPSR")
2558       || streq (str, "SPSR")
2559          /* Lower case versions for backwards compatibility.  */
2560       || streq (str, "cpsr")
2561       || streq (str, "spsr"))
2562     skip = 4;
2563
2564   /* This is for backwards compatibility with older toolchains.  */
2565   else if (   streq (str, "cpsr_all")
2566            || streq (str, "spsr_all"))
2567     skip = 8;
2568   else
2569     {
2570       inst.error = _("CPSR or SPSR expected");
2571       return;
2572     }
2573
2574   if (* str == 's' || * str == 'S')
2575     inst.instruction |= SPSR_BIT;
2576   str += skip;
2577
2578   end_of_line (str);
2579 }
2580
2581 /* Two possible forms:
2582       "{C|S}PSR_<field>, Rm",
2583       "{C|S}PSR_f, #expression".  */
2584
2585 static void
2586 do_msr (char * str)
2587 {
2588   skip_whitespace (str);
2589
2590   if (psr_required_here (& str) == FAIL)
2591     return;
2592
2593   if (skip_past_comma (& str) == FAIL)
2594     {
2595       inst.error = _("comma missing after psr flags");
2596       return;
2597     }
2598
2599   skip_whitespace (str);
2600
2601   if (reg_required_here (& str, 0) != FAIL)
2602     {
2603       inst.error = NULL;
2604       end_of_line (str);
2605       return;
2606     }
2607
2608   if (! is_immediate_prefix (* str))
2609     {
2610       inst.error =
2611         _("only a register or immediate value can follow a psr flag");
2612       return;
2613     }
2614
2615   str ++;
2616   inst.error = NULL;
2617
2618   if (my_get_expression (& inst.reloc.exp, & str))
2619     {
2620       inst.error =
2621         _("only a register or immediate value can follow a psr flag");
2622       return;
2623     }
2624
2625   inst.instruction |= INST_IMMEDIATE;
2626
2627   if (inst.reloc.exp.X_add_symbol)
2628     {
2629       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2630       inst.reloc.pc_rel = 0;
2631     }
2632   else
2633     {
2634       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2635
2636       if (value == (unsigned) FAIL)
2637         {
2638           inst.error = _("invalid constant");
2639           return;
2640         }
2641
2642       inst.instruction |= value;
2643     }
2644
2645   inst.error = NULL;
2646   end_of_line (str);
2647 }
2648
2649 /* Long Multiply Parser
2650    UMULL RdLo, RdHi, Rm, Rs
2651    SMULL RdLo, RdHi, Rm, Rs
2652    UMLAL RdLo, RdHi, Rm, Rs
2653    SMLAL RdLo, RdHi, Rm, Rs.  */
2654
2655 static void
2656 do_mull (char * str)
2657 {
2658   int rdlo, rdhi, rm, rs;
2659
2660   /* Only one format "rdlo, rdhi, rm, rs".  */
2661   skip_whitespace (str);
2662
2663   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2664     {
2665       inst.error = BAD_ARGS;
2666       return;
2667     }
2668
2669   if (skip_past_comma (&str) == FAIL
2670       || (rdhi = reg_required_here (&str, 16)) == FAIL)
2671     {
2672       inst.error = BAD_ARGS;
2673       return;
2674     }
2675
2676   if (skip_past_comma (&str) == FAIL
2677       || (rm = reg_required_here (&str, 0)) == FAIL)
2678     {
2679       inst.error = BAD_ARGS;
2680       return;
2681     }
2682
2683   /* rdhi, rdlo and rm must all be different.  */
2684   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2685     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2686
2687   if (skip_past_comma (&str) == FAIL
2688       || (rs = reg_required_here (&str, 8)) == FAIL)
2689     {
2690       inst.error = BAD_ARGS;
2691       return;
2692     }
2693
2694   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2695     {
2696       inst.error = BAD_PC;
2697       return;
2698     }
2699
2700   end_of_line (str);
2701 }
2702
2703 static void
2704 do_mul (char * str)
2705 {
2706   int rd, rm;
2707
2708   /* Only one format "rd, rm, rs".  */
2709   skip_whitespace (str);
2710
2711   if ((rd = reg_required_here (&str, 16)) == FAIL)
2712     {
2713       inst.error = BAD_ARGS;
2714       return;
2715     }
2716
2717   if (rd == REG_PC)
2718     {
2719       inst.error = BAD_PC;
2720       return;
2721     }
2722
2723   if (skip_past_comma (&str) == FAIL
2724       || (rm = reg_required_here (&str, 0)) == FAIL)
2725     {
2726       inst.error = BAD_ARGS;
2727       return;
2728     }
2729
2730   if (rm == REG_PC)
2731     {
2732       inst.error = BAD_PC;
2733       return;
2734     }
2735
2736   if (rm == rd)
2737     as_tsktsk (_("rd and rm should be different in mul"));
2738
2739   if (skip_past_comma (&str) == FAIL
2740       || (rm = reg_required_here (&str, 8)) == FAIL)
2741     {
2742       inst.error = BAD_ARGS;
2743       return;
2744     }
2745
2746   if (rm == REG_PC)
2747     {
2748       inst.error = BAD_PC;
2749       return;
2750     }
2751
2752   end_of_line (str);
2753 }
2754
2755 static void
2756 do_mlas (char * str, bfd_boolean is_mls)
2757 {
2758   int rd, rm;
2759
2760   /* Only one format "rd, rm, rs, rn".  */
2761   skip_whitespace (str);
2762
2763   if ((rd = reg_required_here (&str, 16)) == FAIL)
2764     {
2765       inst.error = BAD_ARGS;
2766       return;
2767     }
2768
2769   if (rd == REG_PC)
2770     {
2771       inst.error = BAD_PC;
2772       return;
2773     }
2774
2775   if (skip_past_comma (&str) == FAIL
2776       || (rm = reg_required_here (&str, 0)) == FAIL)
2777     {
2778       inst.error = BAD_ARGS;
2779       return;
2780     }
2781
2782   if (rm == REG_PC)
2783     {
2784       inst.error = BAD_PC;
2785       return;
2786     }
2787
2788   /* This restriction does not apply to mls (nor to mla in v6, but
2789      that's hard to detect at present).  */
2790   if (rm == rd && !is_mls)
2791     as_tsktsk (_("rd and rm should be different in mla"));
2792
2793   if (skip_past_comma (&str) == FAIL
2794       || (rd = reg_required_here (&str, 8)) == FAIL
2795       || skip_past_comma (&str) == FAIL
2796       || (rm = reg_required_here (&str, 12)) == FAIL)
2797     {
2798       inst.error = BAD_ARGS;
2799       return;
2800     }
2801
2802   if (rd == REG_PC || rm == REG_PC)
2803     {
2804       inst.error = BAD_PC;
2805       return;
2806     }
2807
2808   end_of_line (str);
2809 }
2810
2811 static void
2812 do_mla (char *str)
2813 {
2814   do_mlas (str, FALSE);
2815 }
2816
2817 static void
2818 do_mls (char *str)
2819 {
2820   do_mlas (str, TRUE);
2821 }
2822
2823 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2824    Advances *str to the next non-alphanumeric.
2825    Returns 0, or else FAIL (in which case sets inst.error).
2826
2827   (In a future XScale, there may be accumulators other than zero.
2828   At that time this routine and its callers can be upgraded to suit.)  */
2829
2830 static int
2831 accum0_required_here (char ** str)
2832 {
2833   static char buff [128];       /* Note the address is taken.  Hence, static.  */
2834   char * p = * str;
2835   char   c;
2836   int result = 0;               /* The accum number.  */
2837
2838   skip_whitespace (p);
2839
2840   *str = p;                     /* Advance caller's string pointer too.  */
2841   c = *p++;
2842   while (ISALNUM (c))
2843     c = *p++;
2844
2845   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
2846
2847   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2848     {
2849       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2850       inst.error = buff;
2851       result = FAIL;
2852     }
2853
2854   *p = c;                       /* Unzap.  */
2855   *str = p;                     /* Caller's string pointer to after match.  */
2856   return result;
2857 }
2858
2859 static int
2860 ldst_extend_v4 (char ** str)
2861 {
2862   int add = INDEX_UP;
2863
2864   switch (**str)
2865     {
2866     case '#':
2867     case '$':
2868       (*str)++;
2869       if (my_get_expression (& inst.reloc.exp, str))
2870         return FAIL;
2871
2872       if (inst.reloc.exp.X_op == O_constant)
2873         {
2874           int value = inst.reloc.exp.X_add_number;
2875
2876           if (value < -255 || value > 255)
2877             {
2878               inst.error = _("address offset too large");
2879               return FAIL;
2880             }
2881
2882           if (value < 0)
2883             {
2884               value = -value;
2885               add = 0;
2886             }
2887
2888           /* Halfword and signextension instructions have the
2889              immediate value split across bits 11..8 and bits 3..0.  */
2890           inst.instruction |= (add | HWOFFSET_IMM
2891                                | ((value >> 4) << 8) | (value & 0xF));
2892         }
2893       else
2894         {
2895           inst.instruction |= HWOFFSET_IMM;
2896           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2897           inst.reloc.pc_rel = 0;
2898         }
2899       return SUCCESS;
2900
2901     case '-':
2902       add = 0;
2903       /* Fall through.  */
2904
2905     case '+':
2906       (*str)++;
2907       /* Fall through.  */
2908
2909     default:
2910       if (reg_required_here (str, 0) == FAIL)
2911         return FAIL;
2912
2913       inst.instruction |= add;
2914       return SUCCESS;
2915     }
2916 }
2917
2918 /* Expects **str -> after a comma. May be leading blanks.
2919    Advances *str, recognizing a load  mode, and setting inst.instruction.
2920    Returns rn, or else FAIL (in which case may set inst.error
2921    and not advance str)
2922
2923    Note: doesn't know Rd, so no err checks that require such knowledge.  */
2924
2925 static int
2926 ld_mode_required_here (char ** string)
2927 {
2928   char * str = * string;
2929   int    rn;
2930   int    pre_inc = 0;
2931
2932   skip_whitespace (str);
2933
2934   if (* str == '[')
2935     {
2936       str++;
2937
2938       skip_whitespace (str);
2939
2940       if ((rn = reg_required_here (& str, 16)) == FAIL)
2941         return FAIL;
2942
2943       skip_whitespace (str);
2944
2945       if (* str == ']')
2946         {
2947           str ++;
2948
2949           if (skip_past_comma (& str) == SUCCESS)
2950             {
2951               /* [Rn],... (post inc) */
2952               if (ldst_extend_v4 (&str) == FAIL)
2953                 return FAIL;
2954             }
2955           else        /* [Rn] */
2956             {
2957               skip_whitespace (str);
2958
2959               if (* str == '!')
2960                 {
2961                   str ++;
2962                   inst.instruction |= WRITE_BACK;
2963                 }
2964
2965               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
2966               pre_inc = 1;
2967             }
2968         }
2969       else        /* [Rn,...] */
2970         {
2971           if (skip_past_comma (& str) == FAIL)
2972             {
2973               inst.error = _("pre-indexed expression expected");
2974               return FAIL;
2975             }
2976
2977           pre_inc = 1;
2978
2979           if (ldst_extend_v4 (&str) == FAIL)
2980             return FAIL;
2981
2982           skip_whitespace (str);
2983
2984           if (* str ++ != ']')
2985             {
2986               inst.error = _("missing ]");
2987               return FAIL;
2988             }
2989
2990           skip_whitespace (str);
2991
2992           if (* str == '!')
2993             {
2994               str ++;
2995               inst.instruction |= WRITE_BACK;
2996             }
2997         }
2998     }
2999   else if (* str == '=')        /* ldr's "r,=label" syntax */
3000     /* We should never reach here, because <text> = <expression> is
3001        caught gas/read.c read_a_source_file() as a .set operation.  */
3002     return FAIL;
3003   else                          /* PC +- 8 bit immediate offset.  */
3004     {
3005       if (my_get_expression (& inst.reloc.exp, & str))
3006         return FAIL;
3007
3008       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3009       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3010       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3011       inst.reloc.pc_rel            = 1;
3012       inst.instruction            |= (REG_PC << 16);
3013
3014       rn = REG_PC;
3015       pre_inc = 1;
3016     }
3017
3018   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3019   * string = str;
3020
3021   return rn;
3022 }
3023
3024 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3025    SMLAxy{cond} Rd,Rm,Rs,Rn
3026    SMLAWy{cond} Rd,Rm,Rs,Rn
3027    Error if any register is R15.  */
3028
3029 static void
3030 do_smla (char * str)
3031 {
3032   int rd, rm, rs, rn;
3033
3034   skip_whitespace (str);
3035
3036   if ((rd = reg_required_here (& str, 16)) == FAIL
3037       || skip_past_comma (& str) == FAIL
3038       || (rm = reg_required_here (& str, 0)) == FAIL
3039       || skip_past_comma (& str) == FAIL
3040       || (rs = reg_required_here (& str, 8)) == FAIL
3041       || skip_past_comma (& str) == FAIL
3042       || (rn = reg_required_here (& str, 12)) == FAIL)
3043     inst.error = BAD_ARGS;
3044
3045   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3046     inst.error = BAD_PC;
3047
3048   else
3049     end_of_line (str);
3050 }
3051
3052 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3053    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3054    Error if any register is R15.
3055    Warning if Rdlo == Rdhi.  */
3056
3057 static void
3058 do_smlal (char * str)
3059 {
3060   int rdlo, rdhi, rm, rs;
3061
3062   skip_whitespace (str);
3063
3064   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3065       || skip_past_comma (& str) == FAIL
3066       || (rdhi = reg_required_here (& str, 16)) == FAIL
3067       || skip_past_comma (& str) == FAIL
3068       || (rm = reg_required_here (& str, 0)) == FAIL
3069       || skip_past_comma (& str) == FAIL
3070       || (rs = reg_required_here (& str, 8)) == FAIL)
3071     {
3072       inst.error = BAD_ARGS;
3073       return;
3074     }
3075
3076   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3077     {
3078       inst.error = BAD_PC;
3079       return;
3080     }
3081
3082   if (rdlo == rdhi)
3083     as_tsktsk (_("rdhi and rdlo must be different"));
3084
3085   end_of_line (str);
3086 }
3087
3088 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3089    SMULxy{cond} Rd,Rm,Rs
3090    Error if any register is R15.  */
3091
3092 static void
3093 do_smul (char * str)
3094 {
3095   int rd, rm, rs;
3096
3097   skip_whitespace (str);
3098
3099   if ((rd = reg_required_here (& str, 16)) == FAIL
3100       || skip_past_comma (& str) == FAIL
3101       || (rm = reg_required_here (& str, 0)) == FAIL
3102       || skip_past_comma (& str) == FAIL
3103       || (rs = reg_required_here (& str, 8)) == FAIL)
3104     inst.error = BAD_ARGS;
3105
3106   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3107     inst.error = BAD_PC;
3108
3109   else
3110     end_of_line (str);
3111 }
3112
3113 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3114    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3115    Error if any register is R15.  */
3116
3117 static void
3118 do_qadd (char * str)
3119 {
3120   int rd, rm, rn;
3121
3122   skip_whitespace (str);
3123
3124   if ((rd = reg_required_here (& str, 12)) == FAIL
3125       || skip_past_comma (& str) == FAIL
3126       || (rm = reg_required_here (& str, 0)) == FAIL
3127       || skip_past_comma (& str) == FAIL
3128       || (rn = reg_required_here (& str, 16)) == FAIL)
3129     inst.error = BAD_ARGS;
3130
3131   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3132     inst.error = BAD_PC;
3133
3134   else
3135     end_of_line (str);
3136 }
3137
3138 /* ARM V5E (el Segundo)
3139    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3140    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3141
3142    These are equivalent to the XScale instructions MAR and MRA,
3143    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3144
3145    Result unpredicatable if Rd or Rn is R15.  */
3146
3147 static void
3148 do_co_reg2c (char * str)
3149 {
3150   int rd, rn;
3151
3152   skip_whitespace (str);
3153
3154   if (co_proc_number (& str) == FAIL)
3155     {
3156       if (!inst.error)
3157         inst.error = BAD_ARGS;
3158       return;
3159     }
3160
3161   if (skip_past_comma (& str) == FAIL
3162       || cp_opc_expr (& str, 4, 4) == FAIL)
3163     {
3164       if (!inst.error)
3165         inst.error = BAD_ARGS;
3166       return;
3167     }
3168
3169   if (skip_past_comma (& str) == FAIL
3170       || (rd = reg_required_here (& str, 12)) == FAIL)
3171     {
3172       if (!inst.error)
3173         inst.error = BAD_ARGS;
3174       return;
3175     }
3176
3177   if (skip_past_comma (& str) == FAIL
3178       || (rn = reg_required_here (& str, 16)) == FAIL)
3179     {
3180       if (!inst.error)
3181         inst.error = BAD_ARGS;
3182       return;
3183     }
3184
3185   /* Unpredictable result if rd or rn is R15.  */
3186   if (rd == REG_PC || rn == REG_PC)
3187     as_tsktsk
3188       (_("Warning: instruction unpredictable when using r15"));
3189
3190   if (skip_past_comma (& str) == FAIL
3191       || cp_reg_required_here (& str, 0) == FAIL)
3192     {
3193       if (!inst.error)
3194         inst.error = BAD_ARGS;
3195       return;
3196     }
3197
3198   end_of_line (str);
3199 }
3200
3201 /* ARM V5 count-leading-zeroes instruction (argument parse)
3202      CLZ{<cond>} <Rd>, <Rm>
3203      Condition defaults to COND_ALWAYS.
3204      Error if Rd or Rm are R15.  */
3205
3206 static void
3207 do_clz (char * str)
3208 {
3209   int rd, rm;
3210
3211   skip_whitespace (str);
3212
3213   if (((rd = reg_required_here (& str, 12)) == FAIL)
3214       || (skip_past_comma (& str) == FAIL)
3215       || ((rm = reg_required_here (& str, 0)) == FAIL))
3216     inst.error = BAD_ARGS;
3217
3218   else if (rd == REG_PC || rm == REG_PC )
3219     inst.error = BAD_PC;
3220
3221   else
3222     end_of_line (str);
3223 }
3224
3225 /* ARM V5 (argument parse)
3226      LDC2{L} <coproc>, <CRd>, <addressing mode>
3227      STC2{L} <coproc>, <CRd>, <addressing mode>
3228      Instruction is not conditional, and has 0xf in the condition field.
3229      Otherwise, it's the same as LDC/STC.  */
3230
3231 static void
3232 do_lstc2 (char * str)
3233 {
3234   skip_whitespace (str);
3235
3236   if (co_proc_number (& str) == FAIL)
3237     {
3238       if (!inst.error)
3239         inst.error = BAD_ARGS;
3240     }
3241   else if (skip_past_comma (& str) == FAIL
3242            || cp_reg_required_here (& str, 12) == FAIL)
3243     {
3244       if (!inst.error)
3245         inst.error = BAD_ARGS;
3246     }
3247   else if (skip_past_comma (& str) == FAIL
3248            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3249     {
3250       if (! inst.error)
3251         inst.error = BAD_ARGS;
3252     }
3253   else
3254     end_of_line (str);
3255 }
3256
3257 /* ARM V5 (argument parse)
3258      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3259      Instruction is not conditional, and has 0xf in the condition field.
3260      Otherwise, it's the same as CDP.  */
3261
3262 static void
3263 do_cdp2 (char * str)
3264 {
3265   skip_whitespace (str);
3266
3267   if (co_proc_number (& str) == FAIL)
3268     {
3269       if (!inst.error)
3270         inst.error = BAD_ARGS;
3271       return;
3272     }
3273
3274   if (skip_past_comma (& str) == FAIL
3275       || cp_opc_expr (& str, 20,4) == FAIL)
3276     {
3277       if (!inst.error)
3278         inst.error = BAD_ARGS;
3279       return;
3280     }
3281
3282   if (skip_past_comma (& str) == FAIL
3283       || cp_reg_required_here (& str, 12) == FAIL)
3284     {
3285       if (!inst.error)
3286         inst.error = BAD_ARGS;
3287       return;
3288     }
3289
3290   if (skip_past_comma (& str) == FAIL
3291       || cp_reg_required_here (& str, 16) == FAIL)
3292     {
3293       if (!inst.error)
3294         inst.error = BAD_ARGS;
3295       return;
3296     }
3297
3298   if (skip_past_comma (& str) == FAIL
3299       || cp_reg_required_here (& str, 0) == FAIL)
3300     {
3301       if (!inst.error)
3302         inst.error = BAD_ARGS;
3303       return;
3304     }
3305
3306   if (skip_past_comma (& str) == SUCCESS)
3307     {
3308       if (cp_opc_expr (& str, 5, 3) == FAIL)
3309         {
3310           if (!inst.error)
3311             inst.error = BAD_ARGS;
3312           return;
3313         }
3314     }
3315
3316   end_of_line (str);
3317 }
3318
3319 /* ARM V5 (argument parse)
3320      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3321      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3322      Instruction is not conditional, and has 0xf in the condition field.
3323      Otherwise, it's the same as MCR/MRC.  */
3324
3325 static void
3326 do_co_reg2 (char * str)
3327 {
3328   skip_whitespace (str);
3329
3330   if (co_proc_number (& str) == FAIL)
3331     {
3332       if (!inst.error)
3333         inst.error = BAD_ARGS;
3334       return;
3335     }
3336
3337   if (skip_past_comma (& str) == FAIL
3338       || cp_opc_expr (& str, 21, 3) == FAIL)
3339     {
3340       if (!inst.error)
3341         inst.error = BAD_ARGS;
3342       return;
3343     }
3344
3345   if (skip_past_comma (& str) == FAIL
3346       || reg_required_here (& str, 12) == FAIL)
3347     {
3348       if (!inst.error)
3349         inst.error = BAD_ARGS;
3350       return;
3351     }
3352
3353   if (skip_past_comma (& str) == FAIL
3354       || cp_reg_required_here (& str, 16) == FAIL)
3355     {
3356       if (!inst.error)
3357         inst.error = BAD_ARGS;
3358       return;
3359     }
3360
3361   if (skip_past_comma (& str) == FAIL
3362       || cp_reg_required_here (& str, 0) == FAIL)
3363     {
3364       if (!inst.error)
3365         inst.error = BAD_ARGS;
3366       return;
3367     }
3368
3369   if (skip_past_comma (& str) == SUCCESS)
3370     {
3371       if (cp_opc_expr (& str, 5, 3) == FAIL)
3372         {
3373           if (!inst.error)
3374             inst.error = BAD_ARGS;
3375           return;
3376         }
3377     }
3378
3379   end_of_line (str);
3380 }
3381
3382 static void
3383 do_bx (char * str)
3384 {
3385   int reg;
3386
3387   skip_whitespace (str);
3388
3389   if ((reg = reg_required_here (&str, 0)) == FAIL)
3390     {
3391       inst.error = BAD_ARGS;
3392       return;
3393     }
3394
3395   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
3396   if (reg == REG_PC)
3397     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
3398
3399   end_of_line (str);
3400 }
3401
3402 /* ARM v5TEJ.  Jump to Jazelle code.  */
3403
3404 static void
3405 do_bxj (char * str)
3406 {
3407   int reg;
3408
3409   skip_whitespace (str);
3410
3411   if ((reg = reg_required_here (&str, 0)) == FAIL)
3412     {
3413       inst.error = BAD_ARGS;
3414       return;
3415     }
3416
3417   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3418   if (reg == REG_PC)
3419     as_tsktsk (_("use of r15 in bxj is not really useful"));
3420
3421   end_of_line (str);
3422 }
3423
3424 /* ARM V6 umaal (argument parse).  */
3425
3426 static void
3427 do_umaal (char * str)
3428 {
3429   int rdlo, rdhi, rm, rs;
3430
3431   skip_whitespace (str);
3432   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3433       || skip_past_comma (& str) == FAIL
3434       || (rdhi = reg_required_here (& str, 16)) == FAIL
3435       || skip_past_comma (& str) == FAIL
3436       || (rm = reg_required_here (& str, 0)) == FAIL
3437       || skip_past_comma (& str) == FAIL
3438       || (rs = reg_required_here (& str, 8)) == FAIL)
3439     {
3440       inst.error = BAD_ARGS;
3441       return;
3442     }
3443
3444   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3445     {
3446       inst.error = BAD_PC;
3447       return;
3448     }
3449
3450   end_of_line (str);
3451 }
3452
3453 /* ARM V6 strex (argument parse).  */
3454
3455 static void
3456 do_strex (char * str)
3457 {
3458   int rd, rm, rn;
3459
3460   /* Parse Rd, Rm,.  */
3461   skip_whitespace (str);
3462   if ((rd = reg_required_here (& str, 12)) == FAIL
3463       || skip_past_comma (& str) == FAIL
3464       || (rm = reg_required_here (& str, 0)) == FAIL
3465       || skip_past_comma (& str) == FAIL)
3466     {
3467       inst.error = BAD_ARGS;
3468       return;
3469     }
3470   if (rd == REG_PC || rm == REG_PC)
3471     {
3472       inst.error = BAD_PC;
3473       return;
3474     }
3475   if (rd == rm)
3476     {
3477       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3478       return;
3479     }
3480
3481   /* Skip past '['.  */
3482   if ((strlen (str) >= 1)
3483       && strncmp (str, "[", 1) == 0)
3484     str += 1;
3485
3486   skip_whitespace (str);
3487
3488   /* Parse Rn.  */
3489   if ((rn = reg_required_here (& str, 16)) == FAIL)
3490     {
3491       inst.error = BAD_ARGS;
3492       return;
3493     }
3494   else if (rn == REG_PC)
3495     {
3496       inst.error = BAD_PC;
3497       return;
3498     }
3499   if (rd == rn)
3500     {
3501       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3502       return;
3503     }
3504   skip_whitespace (str);
3505
3506   /* Skip past ']'.  */
3507   if ((strlen (str) >= 1)
3508       && strncmp (str, "]", 1) == 0)
3509     str += 1;
3510
3511   end_of_line (str);
3512 }
3513
3514 /* KIND indicates what kind of shifts are accepted.  */
3515
3516 static int
3517 decode_shift (char ** str, int kind)
3518 {
3519   const struct asm_shift_name * shift;
3520   char * p;
3521   char   c;
3522
3523   skip_whitespace (* str);
3524
3525   for (p = * str; ISALPHA (* p); p ++)
3526     ;
3527
3528   if (p == * str)
3529     {
3530       inst.error = _("shift expression expected");
3531       return FAIL;
3532     }
3533
3534   c = * p;
3535   * p = '\0';
3536   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3537   * p = c;
3538
3539   if (shift == NULL)
3540     {
3541       inst.error = _("shift expression expected");
3542       return FAIL;
3543     }
3544
3545   assert (shift->properties->index == shift_properties[shift->properties->index].index);
3546
3547   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
3548       && shift->properties->index != SHIFT_LSL
3549       && shift->properties->index != SHIFT_ASR)
3550     {
3551       inst.error = _("'LSL' or 'ASR' required");
3552       return FAIL;
3553     }
3554   else if (kind == SHIFT_LSL_IMMEDIATE
3555            && shift->properties->index != SHIFT_LSL)
3556     {
3557       inst.error = _("'LSL' required");
3558       return FAIL;
3559     }
3560   else if (kind == SHIFT_ASR_IMMEDIATE
3561            && shift->properties->index != SHIFT_ASR)
3562     {
3563       inst.error = _("'ASR' required");
3564       return FAIL;
3565     }
3566
3567   if (shift->properties->index == SHIFT_RRX)
3568     {
3569       * str = p;
3570       inst.instruction |= shift->properties->bit_field;
3571       return SUCCESS;
3572     }
3573
3574   skip_whitespace (p);
3575
3576   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
3577     {
3578       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3579       * str = p;
3580       return SUCCESS;
3581     }
3582   else if (! is_immediate_prefix (* p))
3583     {
3584       inst.error = (NO_SHIFT_RESTRICT
3585                     ? _("shift requires register or #expression")
3586                     : _("shift requires #expression"));
3587       * str = p;
3588       return FAIL;
3589     }
3590
3591   inst.error = NULL;
3592   p ++;
3593
3594   if (my_get_expression (& inst.reloc.exp, & p))
3595     return FAIL;
3596
3597   /* Validate some simple #expressions.  */
3598   if (inst.reloc.exp.X_op == O_constant)
3599     {
3600       unsigned num = inst.reloc.exp.X_add_number;
3601
3602       /* Reject operations greater than 32.  */
3603       if (num > 32
3604           /* Reject a shift of 0 unless the mode allows it.  */
3605           || (num == 0 && shift->properties->allows_0 == 0)
3606           /* Reject a shift of 32 unless the mode allows it.  */
3607           || (num == 32 && shift->properties->allows_32 == 0)
3608           )
3609         {
3610           /* As a special case we allow a shift of zero for
3611              modes that do not support it to be recoded as an
3612              logical shift left of zero (ie nothing).  We warn
3613              about this though.  */
3614           if (num == 0)
3615             {
3616               as_warn (_("shift of 0 ignored."));
3617               shift = & shift_names[0];
3618               assert (shift->properties->index == SHIFT_LSL);
3619             }
3620           else
3621             {
3622               inst.error = _("invalid immediate shift");
3623               return FAIL;
3624             }
3625         }
3626
3627       /* Shifts of 32 are encoded as 0, for those shifts that
3628          support it.  */
3629       if (num == 32)
3630         num = 0;
3631
3632       inst.instruction |= (num << 7) | shift->properties->bit_field;
3633     }
3634   else
3635     {
3636       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
3637       inst.reloc.pc_rel = 0;
3638       inst.instruction |= shift->properties->bit_field;
3639     }
3640
3641   * str = p;
3642   return SUCCESS;
3643 }
3644
3645 static void
3646 do_sat (char ** str, int bias)
3647 {
3648   int rd, rm;
3649   expressionS expr;
3650
3651   skip_whitespace (*str);
3652
3653   /* Parse <Rd>, field.  */
3654   if ((rd = reg_required_here (str, 12)) == FAIL
3655       || skip_past_comma (str) == FAIL)
3656     {
3657       inst.error = BAD_ARGS;
3658       return;
3659     }
3660   if (rd == REG_PC)
3661     {
3662       inst.error = BAD_PC;
3663       return;
3664     }
3665
3666   /* Parse #<immed>,  field.  */
3667   if (is_immediate_prefix (**str))
3668     (*str)++;
3669   else
3670     {
3671       inst.error = _("immediate expression expected");
3672       return;
3673     }
3674   if (my_get_expression (&expr, str))
3675     {
3676       inst.error = _("bad expression");
3677       return;
3678     }
3679   if (expr.X_op != O_constant)
3680     {
3681       inst.error = _("constant expression expected");
3682       return;
3683     }
3684   if (expr.X_add_number + bias < 0
3685       || expr.X_add_number + bias > 31)
3686     {
3687       inst.error = _("immediate value out of range");
3688       return;
3689     }
3690   inst.instruction |= (expr.X_add_number + bias) << 16;
3691   if (skip_past_comma (str) == FAIL)
3692     {
3693       inst.error = BAD_ARGS;
3694       return;
3695     }
3696
3697   /* Parse <Rm> field.  */
3698   if ((rm = reg_required_here (str, 0)) == FAIL)
3699     {
3700       inst.error = BAD_ARGS;
3701       return;
3702     }
3703   if (rm == REG_PC)
3704     {
3705       inst.error = BAD_PC;
3706       return;
3707     }
3708
3709   if (skip_past_comma (str) == SUCCESS)
3710     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
3711 }
3712
3713 /* ARM V6 ssat (argument parse).  */
3714
3715 static void
3716 do_ssat (char * str)
3717 {
3718   do_sat (&str, /*bias=*/-1);
3719   end_of_line (str);
3720 }
3721
3722 /* ARM V6 usat (argument parse).  */
3723
3724 static void
3725 do_usat (char * str)
3726 {
3727   do_sat (&str, /*bias=*/0);
3728   end_of_line (str);
3729 }
3730
3731 static void
3732 do_sat16 (char ** str, int bias)
3733 {
3734   int rd, rm;
3735   expressionS expr;
3736
3737   skip_whitespace (*str);
3738
3739   /* Parse the <Rd> field.  */
3740   if ((rd = reg_required_here (str, 12)) == FAIL
3741       || skip_past_comma (str) == FAIL)
3742     {
3743       inst.error = BAD_ARGS;
3744       return;
3745     }
3746   if (rd == REG_PC)
3747     {
3748       inst.error = BAD_PC;
3749       return;
3750     }
3751
3752   /* Parse #<immed>, field.  */
3753   if (is_immediate_prefix (**str))
3754     (*str)++;
3755   else
3756     {
3757       inst.error = _("immediate expression expected");
3758       return;
3759     }
3760   if (my_get_expression (&expr, str))
3761     {
3762       inst.error = _("bad expression");
3763       return;
3764     }
3765   if (expr.X_op != O_constant)
3766     {
3767       inst.error = _("constant expression expected");
3768       return;
3769     }
3770   if (expr.X_add_number + bias < 0
3771       || expr.X_add_number + bias > 15)
3772     {
3773       inst.error = _("immediate value out of range");
3774       return;
3775     }
3776   inst.instruction |= (expr.X_add_number + bias) << 16;
3777   if (skip_past_comma (str) == FAIL)
3778     {
3779       inst.error = BAD_ARGS;
3780       return;
3781     }
3782
3783   /* Parse <Rm> field.  */
3784   if ((rm = reg_required_here (str, 0)) == FAIL)
3785     {
3786       inst.error = BAD_ARGS;
3787       return;
3788     }
3789   if (rm == REG_PC)
3790     {
3791       inst.error = BAD_PC;
3792       return;
3793     }
3794 }
3795
3796 /* ARM V6 ssat16 (argument parse).  */
3797
3798 static void
3799 do_ssat16 (char * str)
3800 {
3801   do_sat16 (&str, /*bias=*/-1);
3802   end_of_line (str);
3803 }
3804
3805 static void
3806 do_usat16 (char * str)
3807 {
3808   do_sat16 (&str, /*bias=*/0);
3809   end_of_line (str);
3810 }
3811
3812 static void
3813 do_cps_mode (char ** str)
3814 {
3815   expressionS expr;
3816
3817   skip_whitespace (*str);
3818
3819   if (! is_immediate_prefix (**str))
3820     {
3821       inst.error = _("immediate expression expected");
3822       return;
3823     }
3824
3825   (*str)++; /* Strip off the immediate signifier.  */
3826   if (my_get_expression (&expr, str))
3827     {
3828       inst.error = _("bad expression");
3829       return;
3830     }
3831
3832   if (expr.X_op != O_constant)
3833     {
3834       inst.error = _("constant expression expected");
3835       return;
3836     }
3837
3838   /* The mode is a 5 bit field.  Valid values are 0-31.  */
3839   if (((unsigned) expr.X_add_number) > 31
3840       || (inst.reloc.exp.X_add_number) < 0)
3841     {
3842       inst.error = _("invalid constant");
3843       return;
3844     }
3845
3846   inst.instruction |= expr.X_add_number;
3847 }
3848
3849 /* ARM V6 srs (argument parse).  */
3850
3851 static void
3852 do_srs (char * str)
3853 {
3854   char *exclam;
3855   skip_whitespace (str);
3856   exclam = strchr (str, '!');
3857   if (exclam)
3858     *exclam = '\0';
3859   do_cps_mode (&str);
3860   if (exclam)
3861     *exclam = '!';
3862   if (*str == '!')
3863     {
3864       inst.instruction |= WRITE_BACK;
3865       str++;
3866     }
3867   end_of_line (str);
3868 }
3869
3870 /* ARM V6 SMMUL (argument parse).  */
3871
3872 static void
3873 do_smmul (char * str)
3874 {
3875   int rd, rm, rs;
3876
3877   skip_whitespace (str);
3878   if ((rd = reg_required_here (&str, 16)) == FAIL
3879       || skip_past_comma (&str) == FAIL
3880       || (rm = reg_required_here (&str, 0)) == FAIL
3881       || skip_past_comma (&str) == FAIL
3882       || (rs = reg_required_here (&str, 8)) == FAIL)
3883     {
3884       inst.error = BAD_ARGS;
3885       return;
3886     }
3887
3888   if (   rd == REG_PC
3889       || rm == REG_PC
3890       || rs == REG_PC)
3891     {
3892       inst.error = BAD_PC;
3893       return;
3894     }
3895
3896   end_of_line (str);
3897 }
3898
3899 /* ARM V6 SMLALD (argument parse).  */
3900
3901 static void
3902 do_smlald (char * str)
3903 {
3904   int rdlo, rdhi, rm, rs;
3905
3906   skip_whitespace (str);
3907   if ((rdlo = reg_required_here (&str, 12)) == FAIL
3908       || skip_past_comma (&str) == FAIL
3909       || (rdhi = reg_required_here (&str, 16)) == FAIL
3910       || skip_past_comma (&str) == FAIL
3911       || (rm = reg_required_here (&str, 0)) == FAIL
3912       || skip_past_comma (&str) == FAIL
3913       || (rs = reg_required_here (&str, 8)) == FAIL)
3914     {
3915       inst.error = BAD_ARGS;
3916       return;
3917     }
3918
3919   if (   rdlo == REG_PC
3920       || rdhi == REG_PC
3921       || rm == REG_PC
3922       || rs == REG_PC)
3923     {
3924       inst.error = BAD_PC;
3925       return;
3926     }
3927
3928   end_of_line (str);
3929 }
3930
3931 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
3932    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
3933
3934 static void
3935 do_smlad (char * str)
3936 {
3937   int rd, rm, rs, rn;
3938
3939   skip_whitespace (str);
3940   if ((rd = reg_required_here (&str, 16)) == FAIL
3941       || skip_past_comma (&str) == FAIL
3942       || (rm = reg_required_here (&str, 0)) == FAIL
3943       || skip_past_comma (&str) == FAIL
3944       || (rs = reg_required_here (&str, 8)) == FAIL
3945       || skip_past_comma (&str) == FAIL
3946       || (rn = reg_required_here (&str, 12)) == FAIL)
3947     {
3948       inst.error = BAD_ARGS;
3949       return;
3950     }
3951
3952   if (   rd == REG_PC
3953       || rn == REG_PC
3954       || rs == REG_PC
3955       || rm == REG_PC)
3956     {
3957       inst.error = BAD_PC;
3958       return;
3959     }
3960
3961   end_of_line (str);
3962 }
3963
3964 /* Returns true if the endian-specifier indicates big-endianness.  */
3965
3966 static int
3967 do_endian_specifier (char * str)
3968 {
3969   int big_endian = 0;
3970
3971   skip_whitespace (str);
3972   if (strlen (str) < 2)
3973     inst.error = _("missing endian specifier");
3974   else if (strncasecmp (str, "BE", 2) == 0)
3975     {
3976       str += 2;
3977       big_endian = 1;
3978     }
3979   else if (strncasecmp (str, "LE", 2) == 0)
3980     str += 2;
3981   else
3982     inst.error = _("valid endian specifiers are be or le");
3983
3984   end_of_line (str);
3985
3986   return big_endian;
3987 }
3988
3989 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
3990    preserving the other bits.
3991
3992    setend <endian_specifier>, where <endian_specifier> is either
3993    BE or LE.  */
3994
3995 static void
3996 do_setend (char * str)
3997 {
3998   if (do_endian_specifier (str))
3999     inst.instruction |= 0x200;
4000 }
4001
4002 /* ARM V6 SXTH.
4003
4004    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
4005    Condition defaults to COND_ALWAYS.
4006    Error if any register uses R15.  */
4007
4008 static void
4009 do_sxth (char * str)
4010 {
4011   int rd, rm;
4012   expressionS expr;
4013   int rotation_clear_mask = 0xfffff3ff;
4014   int rotation_eight_mask = 0x00000400;
4015   int rotation_sixteen_mask = 0x00000800;
4016   int rotation_twenty_four_mask = 0x00000c00;
4017
4018   skip_whitespace (str);
4019   if ((rd = reg_required_here (&str, 12)) == FAIL
4020       || skip_past_comma (&str) == FAIL
4021       || (rm = reg_required_here (&str, 0)) == FAIL)
4022     {
4023       inst.error = BAD_ARGS;
4024       return;
4025     }
4026
4027   else if (rd == REG_PC || rm == REG_PC)
4028     {
4029       inst.error = BAD_PC;
4030       return;
4031     }
4032
4033   /* Zero out the rotation field.  */
4034   inst.instruction &= rotation_clear_mask;
4035
4036   /* Check for lack of optional rotation field.  */
4037   if (skip_past_comma (&str) == FAIL)
4038     {
4039       end_of_line (str);
4040       return;
4041     }
4042
4043   /* Move past 'ROR'.  */
4044   skip_whitespace (str);
4045   if (strncasecmp (str, "ROR", 3) == 0)
4046     str += 3;
4047   else
4048     {
4049       inst.error = _("missing rotation field after comma");
4050       return;
4051     }
4052
4053   /* Get the immediate constant.  */
4054   skip_whitespace (str);
4055   if (is_immediate_prefix (* str))
4056     str++;
4057   else
4058     {
4059       inst.error = _("immediate expression expected");
4060       return;
4061     }
4062
4063   if (my_get_expression (&expr, &str))
4064     {
4065       inst.error = _("bad expression");
4066       return;
4067     }
4068
4069   if (expr.X_op != O_constant)
4070     {
4071       inst.error = _("constant expression expected");
4072       return;
4073     }
4074
4075   switch (expr.X_add_number)
4076     {
4077     case 0:
4078       /* Rotation field has already been zeroed.  */
4079       break;
4080     case 8:
4081       inst.instruction |= rotation_eight_mask;
4082       break;
4083
4084     case 16:
4085       inst.instruction |= rotation_sixteen_mask;
4086       break;
4087
4088     case 24:
4089       inst.instruction |= rotation_twenty_four_mask;
4090       break;
4091
4092     default:
4093       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4094       break;
4095     }
4096
4097   end_of_line (str);
4098 }
4099
4100 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
4101    extends it to 32-bits, and adds the result to a value in another
4102    register.  You can specify a rotation by 0, 8, 16, or 24 bits
4103    before extracting the 16-bit value.
4104    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
4105    Condition defaults to COND_ALWAYS.
4106    Error if any register uses R15.  */
4107
4108 static void
4109 do_sxtah (char * str)
4110 {
4111   int rd, rn, rm;
4112   expressionS expr;
4113   int rotation_clear_mask = 0xfffff3ff;
4114   int rotation_eight_mask = 0x00000400;
4115   int rotation_sixteen_mask = 0x00000800;
4116   int rotation_twenty_four_mask = 0x00000c00;
4117
4118   skip_whitespace (str);
4119   if ((rd = reg_required_here (&str, 12)) == FAIL
4120       || skip_past_comma (&str) == FAIL
4121       || (rn = reg_required_here (&str, 16)) == FAIL
4122       || skip_past_comma (&str) == FAIL
4123       || (rm = reg_required_here (&str, 0)) == FAIL)
4124     {
4125       inst.error = BAD_ARGS;
4126       return;
4127     }
4128
4129   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4130     {
4131       inst.error = BAD_PC;
4132       return;
4133     }
4134
4135   /* Zero out the rotation field.  */
4136   inst.instruction &= rotation_clear_mask;
4137
4138   /* Check for lack of optional rotation field.  */
4139   if (skip_past_comma (&str) == FAIL)
4140     {
4141       end_of_line (str);
4142       return;
4143     }
4144
4145   /* Move past 'ROR'.  */
4146   skip_whitespace (str);
4147   if (strncasecmp (str, "ROR", 3) == 0)
4148     str += 3;
4149   else
4150     {
4151       inst.error = _("missing rotation field after comma");
4152       return;
4153     }
4154
4155   /* Get the immediate constant.  */
4156   skip_whitespace (str);
4157   if (is_immediate_prefix (* str))
4158     str++;
4159   else
4160     {
4161       inst.error = _("immediate expression expected");
4162       return;
4163     }
4164
4165   if (my_get_expression (&expr, &str))
4166     {
4167       inst.error = _("bad expression");
4168       return;
4169     }
4170
4171   if (expr.X_op != O_constant)
4172     {
4173       inst.error = _("constant expression expected");
4174       return;
4175     }
4176
4177   switch (expr.X_add_number)
4178     {
4179     case 0:
4180       /* Rotation field has already been zeroed.  */
4181       break;
4182
4183     case 8:
4184       inst.instruction |= rotation_eight_mask;
4185       break;
4186
4187     case 16:
4188       inst.instruction |= rotation_sixteen_mask;
4189       break;
4190
4191     case 24:
4192       inst.instruction |= rotation_twenty_four_mask;
4193       break;
4194
4195     default:
4196       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4197       break;
4198     }
4199
4200   end_of_line (str);
4201 }
4202
4203
4204 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
4205    word at the specified address and the following word
4206    respectively.
4207    Unconditionally executed.
4208    Error if Rn is R15.  */
4209
4210 static void
4211 do_rfe (char * str)
4212 {
4213   int rn;
4214
4215   skip_whitespace (str);
4216
4217   if ((rn = reg_required_here (&str, 16)) == FAIL)
4218     return;
4219
4220   if (rn == REG_PC)
4221     {
4222       inst.error = BAD_PC;
4223       return;
4224     }
4225
4226   skip_whitespace (str);
4227
4228   if (*str == '!')
4229     {
4230       inst.instruction |= WRITE_BACK;
4231       str++;
4232     }
4233   end_of_line (str);
4234 }
4235
4236 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
4237    register (argument parse).
4238    REV{<cond>} Rd, Rm.
4239    Condition defaults to COND_ALWAYS.
4240    Error if Rd or Rm are R15.  */
4241
4242 static void
4243 do_rev (char * str)
4244 {
4245   int rd, rm;
4246
4247   skip_whitespace (str);
4248
4249   if ((rd = reg_required_here (&str, 12)) == FAIL
4250       || skip_past_comma (&str) == FAIL
4251       || (rm = reg_required_here (&str, 0)) == FAIL)
4252     inst.error = BAD_ARGS;
4253
4254   else if (rd == REG_PC || rm == REG_PC)
4255     inst.error = BAD_PC;
4256
4257   else
4258     end_of_line (str);
4259 }
4260
4261 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
4262    QADD16{<cond>} <Rd>, <Rn>, <Rm>
4263    Condition defaults to COND_ALWAYS.
4264    Error if Rd, Rn or Rm are R15.  */
4265
4266 static void
4267 do_qadd16 (char * str)
4268 {
4269   int rd, rm, rn;
4270
4271   skip_whitespace (str);
4272
4273   if ((rd = reg_required_here (&str, 12)) == FAIL
4274       || skip_past_comma (&str) == FAIL
4275       || (rn = reg_required_here (&str, 16)) == FAIL
4276       || skip_past_comma (&str) == FAIL
4277       || (rm = reg_required_here (&str, 0)) == FAIL)
4278     inst.error = BAD_ARGS;
4279
4280   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4281     inst.error = BAD_PC;
4282
4283   else
4284     end_of_line (str);
4285 }
4286
4287 static void
4288 do_pkh_core (char * str, int shift)
4289 {
4290   int rd, rn, rm;
4291
4292   skip_whitespace (str);
4293   if (((rd = reg_required_here (&str, 12)) == FAIL)
4294       || (skip_past_comma (&str) == FAIL)
4295       || ((rn = reg_required_here (&str, 16)) == FAIL)
4296       || (skip_past_comma (&str) == FAIL)
4297       || ((rm = reg_required_here (&str, 0)) == FAIL))
4298     {
4299       inst.error = BAD_ARGS;
4300       return;
4301     }
4302
4303   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4304     {
4305       inst.error = BAD_PC;
4306       return;
4307     }
4308
4309   /* Check for optional shift immediate constant.  */
4310   if (skip_past_comma (&str) == FAIL)
4311     {
4312       if (shift == SHIFT_ASR_IMMEDIATE)
4313         {
4314           /* If the shift specifier is ommited, turn the instruction
4315              into pkhbt rd, rm, rn.  First, switch the instruction
4316              code, and clear the rn and rm fields.  */
4317           inst.instruction &= 0xfff0f010;
4318           /* Now, re-encode the registers.  */
4319           inst.instruction |= (rm << 16) | rn;
4320         }
4321       return;
4322     }
4323
4324   decode_shift (&str, shift);
4325 }
4326
4327 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
4328    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
4329    Condition defaults to COND_ALWAYS.
4330    Error if Rd, Rn or Rm are R15.  */
4331
4332 static void
4333 do_pkhbt (char * str)
4334 {
4335   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
4336 }
4337
4338 /* ARM V6 PKHTB (Argument Parse).  */
4339
4340 static void
4341 do_pkhtb (char * str)
4342 {
4343   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
4344 }
4345
4346 /* ARM V6 Load Register Exclusive instruction (argument parse).
4347    LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
4348    Condition defaults to COND_ALWAYS.
4349    Error if Rd or Rn are R15.
4350    See ARMARMv6 A4.1.27: LDREX.  */
4351
4352 static void
4353 do_ldrex (char * str)
4354 {
4355   int rd, rn;
4356
4357   skip_whitespace (str);
4358
4359   /* Parse Rd.  */
4360   if (((rd = reg_required_here (&str, 12)) == FAIL)
4361       || (skip_past_comma (&str) == FAIL))
4362     {
4363       inst.error = BAD_ARGS;
4364       return;
4365     }
4366   else if (rd == REG_PC)
4367     {
4368       inst.error = BAD_PC;
4369       return;
4370     }
4371   skip_whitespace (str);
4372
4373   /* Skip past '['.  */
4374   if ((strlen (str) >= 1)
4375       &&strncmp (str, "[", 1) == 0)
4376     str += 1;
4377   skip_whitespace (str);
4378
4379   /* Parse Rn.  */
4380   if ((rn = reg_required_here (&str, 16)) == FAIL)
4381     {
4382       inst.error = BAD_ARGS;
4383       return;
4384     }
4385   else if (rn == REG_PC)
4386     {
4387       inst.error = BAD_PC;
4388       return;
4389     }
4390   skip_whitespace (str);
4391
4392   /* Skip past ']'.  */
4393   if ((strlen (str) >= 1)
4394       && strncmp (str, "]", 1) == 0)
4395     str += 1;
4396
4397   end_of_line (str);
4398 }
4399
4400 /* ARM V6 change processor state instruction (argument parse)
4401       CPS, CPSIE, CSPID .  */
4402
4403 static void
4404 do_cps (char * str)
4405 {
4406   do_cps_mode (&str);
4407   end_of_line (str);
4408 }
4409
4410 static void
4411 do_cps_flags (char ** str, int thumb_p)
4412 {
4413   struct cps_flag
4414   {
4415     char character;
4416     unsigned long arm_value;
4417     unsigned long thumb_value;
4418   };
4419   static struct cps_flag flag_table[] =
4420   {
4421     {'a', 0x100, 0x4 },
4422     {'i', 0x080, 0x2 },
4423     {'f', 0x040, 0x1 }
4424   };
4425
4426   int saw_a_flag = 0;
4427
4428   skip_whitespace (*str);
4429
4430   /* Get the a, f and i flags.  */
4431   while (**str && **str != ',')
4432     {
4433       struct cps_flag *p;
4434       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
4435
4436       for (p = flag_table; p < q; ++p)
4437         if (strncasecmp (*str, &p->character, 1) == 0)
4438           {
4439             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
4440             saw_a_flag = 1;
4441             break;
4442           }
4443       if (p == q)
4444         {
4445           inst.error = _("unrecognized flag");
4446           return;
4447         }
4448       (*str)++;
4449     }
4450
4451   if (!saw_a_flag)
4452     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
4453 }
4454
4455 static void
4456 do_cpsi (char * str)
4457 {
4458   do_cps_flags (&str, /*thumb_p=*/0);
4459
4460   if (skip_past_comma (&str) == SUCCESS)
4461     {
4462       skip_whitespace (str);
4463       do_cps_mode (&str);
4464     }
4465   end_of_line (str);
4466 }
4467
4468 /* ARM V6T2 bitfield manipulation instructions.  */
4469
4470 static int
4471 five_bit_unsigned_immediate (char **str)
4472 {
4473   expressionS expr;
4474
4475   skip_whitespace (*str);
4476   if (!is_immediate_prefix (**str))
4477     {
4478       inst.error = _("immediate expression expected");
4479       return -1;
4480     }
4481   (*str)++;
4482   if (my_get_expression (&expr, str))
4483     {
4484       inst.error = _("bad expression");
4485       return -1;
4486     }
4487   if (expr.X_op != O_constant)
4488     {
4489       inst.error = _("constant expression expected");
4490       return -1;
4491     }
4492   if (expr.X_add_number < 0 || expr.X_add_number > 32)
4493     {
4494       inst.error = _("immediate value out of range");
4495       return -1;
4496     }
4497   
4498   return expr.X_add_number;
4499 }
4500
4501 static void
4502 bfci_lsb_and_width (char *str)
4503 {
4504   int lsb, width;
4505
4506   if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
4507     return;
4508
4509   if (skip_past_comma (&str) == FAIL)
4510     {
4511       inst.error = BAD_ARGS;
4512       return;
4513     }
4514   if ((width = five_bit_unsigned_immediate (&str)) == -1)
4515     return;
4516
4517   end_of_line (str);
4518
4519   if (width == 0 || lsb == 32)
4520     {
4521       inst.error = _("immediate value out of range");
4522       return;
4523     }
4524   else if (width + lsb > 32)
4525     {
4526       inst.error = _("bit-field extends past end of register");
4527       return;
4528     }
4529
4530   /* Convert to LSB/MSB and write to register.  */
4531   inst.instruction |= lsb << 7;
4532   inst.instruction |= (width + lsb - 1) << 16;
4533 }
4534
4535 static void
4536 do_bfc (char *str)
4537 {
4538   int rd;
4539
4540   /* Rd.  */
4541   skip_whitespace (str);
4542   if (((rd = reg_required_here (&str, 12)) == FAIL)
4543       || (skip_past_comma (&str) == FAIL))
4544     {
4545       inst.error = BAD_ARGS;
4546       return;
4547     }
4548   else if (rd == REG_PC)
4549     {
4550       inst.error = BAD_PC;
4551       return;
4552     }
4553
4554   bfci_lsb_and_width (str);
4555 }
4556
4557 static void
4558 do_bfi (char *str)
4559 {
4560   int rd, rm;
4561
4562   /* Rd.  */
4563   skip_whitespace (str);
4564   if (((rd = reg_required_here (&str, 12)) == FAIL)
4565       || (skip_past_comma (&str) == FAIL))
4566     {
4567       inst.error = BAD_ARGS;
4568       return;
4569     }
4570   else if (rd == REG_PC)
4571     {
4572       inst.error = BAD_PC;
4573       return;
4574     }
4575
4576   /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
4577   skip_whitespace (str);
4578   if (is_immediate_prefix (*str))
4579     {
4580       expressionS expr;
4581       str++;
4582       if (my_get_expression (&expr, &str))
4583         {
4584           inst.error = _("bad expression");
4585           return;
4586         }
4587       if (expr.X_op != O_constant)
4588         {
4589           inst.error = _("constant expression expected");
4590           return;
4591         }
4592       if (expr.X_add_number != 0)
4593         {
4594           inst.error = _("immediate value out of range");
4595           return;
4596         }
4597       inst.instruction |= 0x0000000f;  /* Rm = PC -> bfc, not bfi.  */
4598     }
4599   else
4600     {
4601       if ((rm = reg_required_here (&str, 0)) == FAIL)
4602         {
4603           inst.error = BAD_ARGS;
4604           return;
4605         }
4606       else if (rm == REG_PC)
4607         {
4608           inst.error = BAD_PC;
4609           return;
4610         }
4611     }
4612   if (skip_past_comma (&str) == FAIL)
4613     {
4614       inst.error = BAD_ARGS;
4615       return;
4616     }
4617
4618   bfci_lsb_and_width (str);
4619 }
4620
4621 static void
4622 do_bfx (char *str)
4623 {
4624   int lsb, width;
4625
4626   /* Rd.  */
4627   skip_whitespace (str);
4628   if (reg_required_here (&str, 12) == FAIL
4629       || skip_past_comma (&str) == FAIL)
4630     {
4631       inst.error = BAD_ARGS;
4632       return;
4633     }
4634
4635   /* Rm.  */
4636   skip_whitespace (str);
4637   if (reg_required_here (&str, 0) == FAIL
4638       || skip_past_comma (&str) == FAIL)
4639     {
4640       inst.error = BAD_ARGS;
4641       return;
4642     }
4643
4644   if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
4645     return;
4646
4647   if (skip_past_comma (&str) == FAIL)
4648     {
4649       inst.error = BAD_ARGS;
4650       return;
4651     }
4652   if ((width = five_bit_unsigned_immediate (&str)) == -1)
4653     return;
4654
4655   end_of_line (str);
4656
4657   if (width == 0 || lsb == 32)
4658     {
4659       inst.error = _("immediate value out of range");
4660       return;
4661     }
4662   else if (width + lsb > 32)
4663     {
4664       inst.error = _("bit-field extends past end of register");
4665       return;
4666     }
4667
4668   inst.instruction |= lsb << 7;
4669   inst.instruction |= (width - 1) << 16;
4670 }
4671
4672 static void
4673 do_rbit (char *str)
4674 {
4675   /* Rd.  */
4676   skip_whitespace (str);
4677   if (reg_required_here (&str, 12) == FAIL
4678       || skip_past_comma (&str) == FAIL)
4679     {
4680       inst.error = BAD_ARGS;
4681       return;
4682     }
4683
4684   /* Rm.  */
4685   skip_whitespace (str);
4686   if (reg_required_here (&str, 0) == FAIL)
4687     {
4688       inst.error = BAD_ARGS;
4689       return;
4690     }
4691
4692   end_of_line (str);
4693 }
4694
4695 /* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>.  */
4696 static void
4697 do_mov16 (char *str)
4698 {
4699   int rd;
4700   expressionS expr;
4701
4702   /* Rd.  */
4703   skip_whitespace (str);
4704   if (((rd = reg_required_here (&str, 12)) == FAIL)
4705       || (skip_past_comma (&str) == FAIL))
4706     {
4707       inst.error = BAD_ARGS;
4708       return;
4709     }
4710   else if (rd == REG_PC)
4711     {
4712       inst.error = BAD_PC;
4713       return;
4714     }
4715
4716   /* Imm16.  */
4717   skip_whitespace (str);
4718   if (!is_immediate_prefix (*str))
4719     {
4720       inst.error = _("immediate expression expected");
4721       return;
4722     }
4723   str++;
4724   if (my_get_expression (&expr, &str))
4725     {
4726       inst.error = _("bad expression");
4727       return;
4728     }
4729   if (expr.X_op != O_constant)
4730     {
4731       inst.error = _("constant expression expected");
4732       return;
4733     }
4734   if (expr.X_add_number < 0 || expr.X_add_number > 65535)
4735     {
4736       inst.error = _("immediate value out of range");
4737       return;
4738     }
4739
4740   end_of_line (str);
4741
4742   /* The value is in two pieces: 0:11, 16:19.  */
4743   inst.instruction |= (expr.X_add_number & 0x00000fff);
4744   inst.instruction |= (expr.X_add_number & 0x0000f000) << 4;
4745 }
4746   
4747
4748 /* THUMB V5 breakpoint instruction (argument parse)
4749         BKPT <immed_8>.  */
4750
4751 static void
4752 do_t_bkpt (char * str)
4753 {
4754   expressionS expr;
4755   unsigned long number;
4756
4757   skip_whitespace (str);
4758
4759   /* Allow optional leading '#'.  */
4760   if (is_immediate_prefix (*str))
4761     str ++;
4762
4763   memset (& expr, '\0', sizeof (expr));
4764   if (my_get_expression (& expr, & str)
4765       || (expr.X_op != O_constant
4766           /* As a convenience we allow 'bkpt' without an operand.  */
4767           && expr.X_op != O_absent))
4768     {
4769       inst.error = _("bad expression");
4770       return;
4771     }
4772
4773   number = expr.X_add_number;
4774
4775   /* Check it fits an 8 bit unsigned.  */
4776   if (number != (number & 0xff))
4777     {
4778       inst.error = _("immediate value out of range");
4779       return;
4780     }
4781
4782   inst.instruction |= number;
4783
4784   end_of_line (str);
4785 }
4786
4787 #ifdef OBJ_ELF
4788 static bfd_reloc_code_real_type
4789 arm_parse_reloc (void)
4790 {
4791   char         id [16];
4792   char *       ip;
4793   unsigned int i;
4794   static struct
4795   {
4796     char * str;
4797     int    len;
4798     bfd_reloc_code_real_type reloc;
4799   }
4800   reloc_map[] =
4801   {
4802 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
4803     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
4804     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
4805     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
4806        branch instructions generated by GCC for PLT relocs.  */
4807     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
4808     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
4809     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
4810     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
4811     MAP ("(tlsgd)", BFD_RELOC_ARM_TLS_GD32),
4812     MAP ("(tlsldm)", BFD_RELOC_ARM_TLS_LDM32),
4813     MAP ("(tlsldo)", BFD_RELOC_ARM_TLS_LDO32),
4814     MAP ("(gottpoff)", BFD_RELOC_ARM_TLS_IE32),
4815     MAP ("(tpoff)", BFD_RELOC_ARM_TLS_LE32),
4816     { NULL, 0,         BFD_RELOC_UNUSED }
4817 #undef MAP
4818   };
4819
4820   for (i = 0, ip = input_line_pointer;
4821        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
4822        i++, ip++)
4823     id[i] = TOLOWER (*ip);
4824
4825   for (i = 0; reloc_map[i].str; i++)
4826     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
4827       break;
4828
4829   input_line_pointer += reloc_map[i].len;
4830
4831   return reloc_map[i].reloc;
4832 }
4833 #endif
4834
4835 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4836    Expects inst.instruction is set for BLX(1).
4837    Note: this is cloned from do_branch, and the reloc changed to be a
4838         new one that can cope with setting one extra bit (the H bit).  */
4839
4840 static void
4841 do_branch25 (char * str)
4842 {
4843   if (my_get_expression (& inst.reloc.exp, & str))
4844     return;
4845
4846 #ifdef OBJ_ELF
4847   {
4848     char * save_in;
4849
4850     /* ScottB: February 5, 1998 */
4851     /* Check to see of PLT32 reloc required for the instruction.  */
4852
4853     /* arm_parse_reloc() works on input_line_pointer.
4854        We actually want to parse the operands to the branch instruction
4855        passed in 'str'.  Save the input pointer and restore it later.  */
4856     save_in = input_line_pointer;
4857     input_line_pointer = str;
4858
4859     if (inst.reloc.exp.X_op == O_symbol
4860         && *str == '('
4861         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4862       {
4863         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
4864         inst.reloc.pc_rel = 0;
4865         /* Modify str to point to after parsed operands, otherwise
4866            end_of_line() will complain about the (PLT) left in str.  */
4867         str = input_line_pointer;
4868       }
4869     else
4870       {
4871         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4872         inst.reloc.pc_rel = 1;
4873       }
4874
4875     input_line_pointer = save_in;
4876   }
4877 #else
4878   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4879   inst.reloc.pc_rel = 1;
4880 #endif /* OBJ_ELF */
4881
4882   end_of_line (str);
4883 }
4884
4885 /* ARM V5 branch-link-exchange instruction (argument parse)
4886      BLX <target_addr>          ie BLX(1)
4887      BLX{<condition>} <Rm>      ie BLX(2)
4888    Unfortunately, there are two different opcodes for this mnemonic.
4889    So, the insns[].value is not used, and the code here zaps values
4890         into inst.instruction.
4891    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4892
4893 static void
4894 do_blx (char * str)
4895 {
4896   char * mystr = str;
4897   int rm;
4898
4899   skip_whitespace (mystr);
4900   rm = reg_required_here (& mystr, 0);
4901
4902   /* The above may set inst.error.  Ignore his opinion.  */
4903   inst.error = 0;
4904
4905   if (rm != FAIL)
4906     {
4907       /* Arg is a register.
4908          Use the condition code our caller put in inst.instruction.
4909          Pass ourselves off as a BX with a funny opcode.  */
4910       inst.instruction |= 0x012fff30;
4911       do_bx (str);
4912     }
4913   else
4914     {
4915       /* This must be is BLX <target address>, no condition allowed.  */
4916       if (inst.instruction != COND_ALWAYS)
4917         {
4918           inst.error = BAD_COND;
4919           return;
4920         }
4921
4922       inst.instruction = 0xfafffffe;
4923
4924       /* Process like a B/BL, but with a different reloc.
4925          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4926       do_branch25 (str);
4927     }
4928 }
4929
4930 /* ARM V5 Thumb BLX (argument parse)
4931         BLX <target_addr>       which is BLX(1)
4932         BLX <Rm>                which is BLX(2)
4933    Unfortunately, there are two different opcodes for this mnemonic.
4934    So, the tinsns[].value is not used, and the code here zaps values
4935         into inst.instruction.  */
4936
4937 static void
4938 do_t_blx (char * str)
4939 {
4940   char * mystr = str;
4941   int rm;
4942
4943   skip_whitespace (mystr);
4944   inst.instruction = 0x4780;
4945
4946   /* Note that this call is to the ARM register recognizer.  BLX(2)
4947      uses the ARM register space, not the Thumb one, so a call to
4948      thumb_reg() would be wrong.  */
4949   rm = reg_required_here (& mystr, 3);
4950   inst.error = 0;
4951
4952   if (rm != FAIL)
4953     {
4954       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
4955       inst.size = 2;
4956     }
4957   else
4958     {
4959       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
4960       inst.instruction = 0xf7ffeffe;
4961       inst.size = 4;
4962
4963       if (my_get_expression (& inst.reloc.exp, & mystr))
4964         return;
4965
4966       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
4967       inst.reloc.pc_rel = 1;
4968     }
4969
4970   end_of_line (mystr);
4971 }
4972
4973 /* ARM V5 breakpoint instruction (argument parse)
4974      BKPT <16 bit unsigned immediate>
4975      Instruction is not conditional.
4976         The bit pattern given in insns[] has the COND_ALWAYS condition,
4977         and it is an error if the caller tried to override that.  */
4978
4979 static void
4980 do_bkpt (char * str)
4981 {
4982   expressionS expr;
4983   unsigned long number;
4984
4985   skip_whitespace (str);
4986
4987   /* Allow optional leading '#'.  */
4988   if (is_immediate_prefix (* str))
4989     str++;
4990
4991   memset (& expr, '\0', sizeof (expr));
4992
4993   if (my_get_expression (& expr, & str)
4994       || (expr.X_op != O_constant
4995           /* As a convenience we allow 'bkpt' without an operand.  */
4996           && expr.X_op != O_absent))
4997     {
4998       inst.error = _("bad expression");
4999       return;
5000     }
5001
5002   number = expr.X_add_number;
5003
5004   /* Check it fits a 16 bit unsigned.  */
5005   if (number != (number & 0xffff))
5006     {
5007       inst.error = _("immediate value out of range");
5008       return;
5009     }
5010
5011   /* Top 12 of 16 bits to bits 19:8.  */
5012   inst.instruction |= (number & 0xfff0) << 4;
5013
5014   /* Bottom 4 of 16 bits to bits 3:0.  */
5015   inst.instruction |= number & 0xf;
5016
5017   end_of_line (str);
5018 }
5019
5020 /* THUMB CPS instruction (argument parse).  */
5021
5022 static void
5023 do_t_cps (char * str)
5024 {
5025   do_cps_flags (&str, /*thumb_p=*/1);
5026   end_of_line (str);
5027 }
5028
5029 /* Parse and validate that a register is of the right form, this saves
5030    repeated checking of this information in many similar cases.
5031    Unlike the 32-bit case we do not insert the register into the opcode
5032    here, since the position is often unknown until the full instruction
5033    has been parsed.  */
5034
5035 static int
5036 thumb_reg (char ** strp, int hi_lo)
5037 {
5038   int reg;
5039
5040   if ((reg = reg_required_here (strp, -1)) == FAIL)
5041     return FAIL;
5042
5043   switch (hi_lo)
5044     {
5045     case THUMB_REG_LO:
5046       if (reg > 7)
5047         {
5048           inst.error = _("lo register required");
5049           return FAIL;
5050         }
5051       break;
5052
5053     case THUMB_REG_HI:
5054       if (reg < 8)
5055         {
5056           inst.error = _("hi register required");
5057           return FAIL;
5058         }
5059       break;
5060
5061     default:
5062       break;
5063     }
5064
5065   return reg;
5066 }
5067
5068 static void
5069 thumb_mov_compare (char * str, int move)
5070 {
5071   int Rd, Rs = FAIL;
5072
5073   skip_whitespace (str);
5074
5075   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5076       || skip_past_comma (&str) == FAIL)
5077     {
5078       if (! inst.error)
5079         inst.error = BAD_ARGS;
5080       return;
5081     }
5082
5083   if (move != THUMB_CPY && is_immediate_prefix (*str))
5084     {
5085       str++;
5086       if (my_get_expression (&inst.reloc.exp, &str))
5087         return;
5088     }
5089   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5090     return;
5091
5092   if (Rs != FAIL)
5093     {
5094       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
5095         {
5096           if (move == THUMB_MOVE)
5097             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5098                since a MOV instruction produces unpredictable results.  */
5099             inst.instruction = T_OPCODE_ADD_I3;
5100           else
5101             inst.instruction = T_OPCODE_CMP_LR;
5102           inst.instruction |= Rd | (Rs << 3);
5103         }
5104       else
5105         {
5106           if (move == THUMB_MOVE)
5107             inst.instruction = T_OPCODE_MOV_HR;
5108           else if (move != THUMB_CPY)
5109             inst.instruction = T_OPCODE_CMP_HR;
5110
5111           if (Rd > 7)
5112             inst.instruction |= THUMB_H1;
5113
5114           if (Rs > 7)
5115             inst.instruction |= THUMB_H2;
5116
5117           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
5118         }
5119     }
5120   else
5121     {
5122       if (Rd > 7)
5123         {
5124           inst.error = _("only lo regs allowed with immediate");
5125           return;
5126         }
5127
5128       if (move == THUMB_MOVE)
5129         inst.instruction = T_OPCODE_MOV_I8;
5130       else
5131         inst.instruction = T_OPCODE_CMP_I8;
5132
5133       inst.instruction |= Rd << 8;
5134
5135       if (inst.reloc.exp.X_op != O_constant)
5136         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
5137       else
5138         {
5139           unsigned value = inst.reloc.exp.X_add_number;
5140
5141           if (value > 255)
5142             {
5143               inst.error = _("invalid immediate");
5144               return;
5145             }
5146
5147           inst.instruction |= value;
5148         }
5149     }
5150
5151   end_of_line (str);
5152 }
5153
5154 /* THUMB CPY instruction (argument parse).  */
5155
5156 static void
5157 do_t_cpy (char * str)
5158 {
5159   thumb_mov_compare (str, THUMB_CPY);
5160 }
5161
5162 /* THUMB SETEND instruction (argument parse).  */
5163
5164 static void
5165 do_t_setend (char * str)
5166 {
5167   if (do_endian_specifier (str))
5168     inst.instruction |= 0x8;
5169 }
5170
5171 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
5172
5173 static unsigned long
5174 check_iwmmxt_insn (char * str,
5175                    enum iwmmxt_insn_type insn_type,
5176                    int immediate_size)
5177 {
5178   int reg = 0;
5179   const char *  inst_error;
5180   expressionS expr;
5181   unsigned long number;
5182
5183   inst_error = inst.error;
5184   if (!inst.error)
5185     inst.error = BAD_ARGS;
5186   skip_whitespace (str);
5187
5188   switch (insn_type)
5189     {
5190     case check_rd:
5191       if ((reg = reg_required_here (&str, 12)) == FAIL)
5192         return FAIL;
5193       break;
5194
5195     case check_wr:
5196        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
5197          return FAIL;
5198        break;
5199
5200     case check_wrwr:
5201       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5202            || skip_past_comma (&str) == FAIL
5203            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5204         return FAIL;
5205       break;
5206
5207     case check_wrwrwr:
5208       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5209            || skip_past_comma (&str) == FAIL
5210            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5211            || skip_past_comma (&str) == FAIL
5212            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5213         return FAIL;
5214       break;
5215
5216     case check_wrwrwcg:
5217       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5218            || skip_past_comma (&str) == FAIL
5219            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5220            || skip_past_comma (&str) == FAIL
5221            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
5222         return FAIL;
5223       break;
5224
5225     case check_tbcst:
5226       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5227            || skip_past_comma (&str) == FAIL
5228            || reg_required_here (&str, 12) == FAIL))
5229         return FAIL;
5230       break;
5231
5232     case check_tmovmsk:
5233       if ((reg_required_here (&str, 12) == FAIL
5234            || skip_past_comma (&str) == FAIL
5235            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5236         return FAIL;
5237       break;
5238
5239     case check_tmia:
5240       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5241            || skip_past_comma (&str) == FAIL
5242            || reg_required_here (&str, 0) == FAIL
5243            || skip_past_comma (&str) == FAIL
5244            || reg_required_here (&str, 12) == FAIL))
5245         return FAIL;
5246       break;
5247
5248     case check_tmcrr:
5249       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5250            || skip_past_comma (&str) == FAIL
5251            || reg_required_here (&str, 12) == FAIL
5252            || skip_past_comma (&str) == FAIL
5253            || reg_required_here (&str, 16) == FAIL))
5254         return FAIL;
5255       break;
5256
5257     case check_tmrrc:
5258       if ((reg_required_here (&str, 12) == FAIL
5259            || skip_past_comma (&str) == FAIL
5260            || reg_required_here (&str, 16) == FAIL
5261            || skip_past_comma (&str) == FAIL
5262            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5263         return FAIL;
5264       break;
5265
5266     case check_tmcr:
5267       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5268            || skip_past_comma (&str) == FAIL
5269            || reg_required_here (&str, 12) == FAIL))
5270         return FAIL;
5271       break;
5272
5273     case check_tmrc:
5274       if ((reg_required_here (&str, 12) == FAIL
5275            || skip_past_comma (&str) == FAIL
5276            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5277         return FAIL;
5278       break;
5279
5280     case check_tinsr:
5281       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5282            || skip_past_comma (&str) == FAIL
5283            || reg_required_here (&str, 12) == FAIL
5284            || skip_past_comma (&str) == FAIL))
5285         return FAIL;
5286       break;
5287
5288     case check_textrc:
5289       if ((reg_required_here (&str, 12) == FAIL
5290            || skip_past_comma (&str) == FAIL))
5291         return FAIL;
5292       break;
5293
5294     case check_waligni:
5295       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5296            || skip_past_comma (&str) == FAIL
5297            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5298            || skip_past_comma (&str) == FAIL
5299            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5300            || skip_past_comma (&str) == FAIL))
5301         return FAIL;
5302       break;
5303
5304     case check_textrm:
5305       if ((reg_required_here (&str, 12) == FAIL
5306            || skip_past_comma (&str) == FAIL
5307            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5308            || skip_past_comma (&str) == FAIL))
5309         return FAIL;
5310       break;
5311
5312     case check_wshufh:
5313       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5314            || skip_past_comma (&str) == FAIL
5315            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5316            || skip_past_comma (&str) == FAIL))
5317         return FAIL;
5318       break;
5319     }
5320
5321   if (immediate_size == 0)
5322     {
5323       end_of_line (str);
5324       inst.error = inst_error;
5325       return reg;
5326     }
5327   else
5328     {
5329       skip_whitespace (str);
5330
5331       /* Allow optional leading '#'.  */
5332       if (is_immediate_prefix (* str))
5333         str++;
5334
5335       memset (& expr, '\0', sizeof (expr));
5336
5337       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5338         {
5339           inst.error = _("bad or missing expression");
5340           return FAIL;
5341         }
5342
5343       number = expr.X_add_number;
5344
5345       if (number != (number & immediate_size))
5346         {
5347           inst.error = _("immediate value out of range");
5348           return FAIL;
5349         }
5350       end_of_line (str);
5351       inst.error = inst_error;
5352       return number;
5353     }
5354 }
5355
5356 static void
5357 do_iwmmxt_byte_addr (char * str)
5358 {
5359   int op = (inst.instruction & 0x300) >> 8;
5360   int reg;
5361
5362   inst.instruction &= ~0x300;
5363   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5364
5365   skip_whitespace (str);
5366
5367   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5368       || skip_past_comma (& str) == FAIL
5369       || cp_byte_address_required_here (&str) == FAIL)
5370     {
5371       if (! inst.error)
5372         inst.error = BAD_ARGS;
5373     }
5374   else
5375     end_of_line (str);
5376
5377   if (wc_register (reg))
5378     {
5379       as_bad (_("non-word size not supported with control register"));
5380       inst.instruction |=  0xf0000100;
5381       inst.instruction &= ~0x00400000;
5382     }
5383 }
5384
5385 static void
5386 do_iwmmxt_tandc (char * str)
5387 {
5388   int reg;
5389
5390   reg = check_iwmmxt_insn (str, check_rd, 0);
5391
5392   if (reg != REG_PC && !inst.error)
5393     inst.error = _("only r15 allowed here");
5394 }
5395
5396 static void
5397 do_iwmmxt_tbcst (char * str)
5398 {
5399   check_iwmmxt_insn (str, check_tbcst, 0);
5400 }
5401
5402 static void
5403 do_iwmmxt_textrc (char * str)
5404 {
5405   unsigned long number;
5406
5407   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5408     return;
5409
5410   inst.instruction |= number & 0x7;
5411 }
5412
5413 static void
5414 do_iwmmxt_textrm (char * str)
5415 {
5416   unsigned long number;
5417
5418   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5419     return;
5420
5421   inst.instruction |= number & 0x7;
5422 }
5423
5424 static void
5425 do_iwmmxt_tinsr (char * str)
5426 {
5427   unsigned long number;
5428
5429   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5430     return;
5431
5432   inst.instruction |= number & 0x7;
5433 }
5434
5435 static void
5436 do_iwmmxt_tmcr (char * str)
5437 {
5438   check_iwmmxt_insn (str, check_tmcr, 0);
5439 }
5440
5441 static void
5442 do_iwmmxt_tmcrr (char * str)
5443 {
5444   check_iwmmxt_insn (str, check_tmcrr, 0);
5445 }
5446
5447 static void
5448 do_iwmmxt_tmia (char * str)
5449 {
5450   check_iwmmxt_insn (str, check_tmia, 0);
5451 }
5452
5453 static void
5454 do_iwmmxt_tmovmsk (char * str)
5455 {
5456   check_iwmmxt_insn (str, check_tmovmsk, 0);
5457 }
5458
5459 static void
5460 do_iwmmxt_tmrc (char * str)
5461 {
5462   check_iwmmxt_insn (str, check_tmrc, 0);
5463 }
5464
5465 static void
5466 do_iwmmxt_tmrrc (char * str)
5467 {
5468   check_iwmmxt_insn (str, check_tmrrc, 0);
5469 }
5470
5471 static void
5472 do_iwmmxt_torc (char * str)
5473 {
5474   check_iwmmxt_insn (str, check_rd, 0);
5475 }
5476
5477 static void
5478 do_iwmmxt_waligni (char * str)
5479 {
5480   unsigned long number;
5481
5482   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5483     return;
5484
5485   inst.instruction |= ((number & 0x7) << 20);
5486 }
5487
5488 static void
5489 do_iwmmxt_wmov (char * str)
5490 {
5491   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5492     return;
5493
5494   inst.instruction |= ((inst.instruction >> 16) & 0xf);
5495 }
5496
5497 static void
5498 do_iwmmxt_word_addr (char * str)
5499 {
5500   int op = (inst.instruction & 0x300) >> 8;
5501   int reg;
5502
5503   inst.instruction &= ~0x300;
5504   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5505
5506   skip_whitespace (str);
5507
5508   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5509       || skip_past_comma (& str) == FAIL
5510       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5511     {
5512       if (! inst.error)
5513         inst.error = BAD_ARGS;
5514     }
5515   else
5516     end_of_line (str);
5517
5518   if (wc_register (reg))
5519     {
5520       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5521         as_bad (_("conditional execution not supported with control register"));
5522       if (op != 2)
5523         as_bad (_("non-word size not supported with control register"));
5524       inst.instruction |=  0xf0000100;
5525       inst.instruction &= ~0x00400000;
5526     }
5527 }
5528
5529 static void
5530 do_iwmmxt_wrwr (char * str)
5531 {
5532   check_iwmmxt_insn (str, check_wrwr, 0);
5533 }
5534
5535 static void
5536 do_iwmmxt_wrwrwcg (char * str)
5537 {
5538   check_iwmmxt_insn (str, check_wrwrwcg, 0);
5539 }
5540
5541 static void
5542 do_iwmmxt_wrwrwr (char * str)
5543 {
5544   check_iwmmxt_insn (str, check_wrwrwr, 0);
5545 }
5546
5547 static void
5548 do_iwmmxt_wshufh (char * str)
5549 {
5550   unsigned long number;
5551
5552   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5553     return;
5554
5555   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5556 }
5557
5558 static void
5559 do_iwmmxt_wzero (char * str)
5560 {
5561   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5562     return;
5563
5564   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5565 }
5566
5567 /* Xscale multiply-accumulate (argument parse)
5568      MIAcc   acc0,Rm,Rs
5569      MIAPHcc acc0,Rm,Rs
5570      MIAxycc acc0,Rm,Rs.  */
5571
5572 static void
5573 do_xsc_mia (char * str)
5574 {
5575   int rs;
5576   int rm;
5577
5578   if (accum0_required_here (& str) == FAIL)
5579     inst.error = ERR_NO_ACCUM;
5580
5581   else if (skip_past_comma (& str) == FAIL
5582            || (rm = reg_required_here (& str, 0)) == FAIL)
5583     inst.error = BAD_ARGS;
5584
5585   else if (skip_past_comma (& str) == FAIL
5586            || (rs = reg_required_here (& str, 12)) == FAIL)
5587     inst.error = BAD_ARGS;
5588
5589   /* inst.instruction has now been zapped with both rm and rs.  */
5590   else if (rm == REG_PC || rs == REG_PC)
5591     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
5592
5593   else
5594     end_of_line (str);
5595 }
5596
5597 /* Xscale move-accumulator-register (argument parse)
5598
5599      MARcc   acc0,RdLo,RdHi.  */
5600
5601 static void
5602 do_xsc_mar (char * str)
5603 {
5604   int rdlo, rdhi;
5605
5606   if (accum0_required_here (& str) == FAIL)
5607     inst.error = ERR_NO_ACCUM;
5608
5609   else if (skip_past_comma (& str) == FAIL
5610            || (rdlo = reg_required_here (& str, 12)) == FAIL)
5611     inst.error = BAD_ARGS;
5612
5613   else if (skip_past_comma (& str) == FAIL
5614            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5615     inst.error = BAD_ARGS;
5616
5617   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5618   else if (rdlo == REG_PC || rdhi == REG_PC)
5619     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5620
5621   else
5622     end_of_line (str);
5623 }
5624
5625 /* Xscale move-register-accumulator (argument parse)
5626
5627      MRAcc   RdLo,RdHi,acc0.  */
5628
5629 static void
5630 do_xsc_mra (char * str)
5631 {
5632   int rdlo;
5633   int rdhi;
5634
5635   skip_whitespace (str);
5636
5637   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5638     inst.error = BAD_ARGS;
5639
5640   else if (skip_past_comma (& str) == FAIL
5641            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5642     inst.error = BAD_ARGS;
5643
5644   else if  (skip_past_comma (& str) == FAIL
5645             || accum0_required_here (& str) == FAIL)
5646     inst.error = ERR_NO_ACCUM;
5647
5648   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5649   else if (rdlo == rdhi)
5650     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
5651
5652   else if (rdlo == REG_PC || rdhi == REG_PC)
5653     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5654   else
5655     end_of_line (str);
5656 }
5657
5658 static int
5659 ldst_extend (char ** str)
5660 {
5661   int add = INDEX_UP;
5662
5663   switch (**str)
5664     {
5665     case '#':
5666     case '$':
5667       (*str)++;
5668       if (my_get_expression (& inst.reloc.exp, str))
5669         return FAIL;
5670
5671       if (inst.reloc.exp.X_op == O_constant)
5672         {
5673           int value = inst.reloc.exp.X_add_number;
5674
5675           if (value < -4095 || value > 4095)
5676             {
5677               inst.error = _("address offset too large");
5678               return FAIL;
5679             }
5680
5681           if (value < 0)
5682             {
5683               value = -value;
5684               add = 0;
5685             }
5686
5687           inst.instruction |= add | value;
5688         }
5689       else
5690         {
5691           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5692           inst.reloc.pc_rel = 0;
5693         }
5694       return SUCCESS;
5695
5696     case '-':
5697       add = 0;
5698       /* Fall through.  */
5699
5700     case '+':
5701       (*str)++;
5702       /* Fall through.  */
5703
5704     default:
5705       if (reg_required_here (str, 0) == FAIL)
5706         return FAIL;
5707
5708       inst.instruction |= add | OFFSET_REG;
5709       if (skip_past_comma (str) == SUCCESS)
5710         return decode_shift (str, SHIFT_IMMEDIATE);
5711
5712       return SUCCESS;
5713     }
5714 }
5715
5716 /* ARMv5TE: Preload-Cache
5717
5718     PLD <addr_mode>
5719
5720   Syntactically, like LDR with B=1, W=0, L=1.  */
5721
5722 static void
5723 do_pld (char * str)
5724 {
5725   int rd;
5726
5727   skip_whitespace (str);
5728
5729   if (* str != '[')
5730     {
5731       inst.error = _("'[' expected after PLD mnemonic");
5732       return;
5733     }
5734
5735   ++str;
5736   skip_whitespace (str);
5737
5738   if ((rd = reg_required_here (& str, 16)) == FAIL)
5739     return;
5740
5741   skip_whitespace (str);
5742
5743   if (*str == ']')
5744     {
5745       /* [Rn], ... ?  */
5746       ++str;
5747       skip_whitespace (str);
5748
5749       /* Post-indexed addressing is not allowed with PLD.  */
5750       if (skip_past_comma (&str) == SUCCESS)
5751         {
5752           inst.error
5753             = _("post-indexed expression used in preload instruction");
5754           return;
5755         }
5756       else if (*str == '!') /* [Rn]! */
5757         {
5758           inst.error = _("writeback used in preload instruction");
5759           ++str;
5760         }
5761       else /* [Rn] */
5762         inst.instruction |= INDEX_UP | PRE_INDEX;
5763     }
5764   else /* [Rn, ...] */
5765     {
5766       if (skip_past_comma (& str) == FAIL)
5767         {
5768           inst.error = _("pre-indexed expression expected");
5769           return;
5770         }
5771
5772       if (ldst_extend (&str) == FAIL)
5773         return;
5774
5775       skip_whitespace (str);
5776
5777       if (* str != ']')
5778         {
5779           inst.error = _("missing ]");
5780           return;
5781         }
5782
5783       ++ str;
5784       skip_whitespace (str);
5785
5786       if (* str == '!') /* [Rn]! */
5787         {
5788           inst.error = _("writeback used in preload instruction");
5789           ++ str;
5790         }
5791
5792       inst.instruction |= PRE_INDEX;
5793     }
5794
5795   end_of_line (str);
5796 }
5797
5798 /* ARMv5TE load-consecutive (argument parse)
5799    Mode is like LDRH.
5800
5801      LDRccD R, mode
5802      STRccD R, mode.  */
5803
5804 static void
5805 do_ldrd (char * str)
5806 {
5807   int rd;
5808   int rn;
5809
5810   skip_whitespace (str);
5811
5812   if ((rd = reg_required_here (& str, 12)) == FAIL)
5813     {
5814       inst.error = BAD_ARGS;
5815       return;
5816     }
5817
5818   if (skip_past_comma (& str) == FAIL
5819       || (rn = ld_mode_required_here (& str)) == FAIL)
5820     {
5821       if (!inst.error)
5822         inst.error = BAD_ARGS;
5823       return;
5824     }
5825
5826   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
5827   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
5828     {
5829       inst.error = _("destination register must be even");
5830       return;
5831     }
5832
5833   if (rd == REG_LR)
5834     {
5835       inst.error = _("r14 not allowed here");
5836       return;
5837     }
5838
5839   if (((rd == rn) || (rd + 1 == rn))
5840       && ((inst.instruction & WRITE_BACK)
5841           || (!(inst.instruction & PRE_INDEX))))
5842     as_warn (_("pre/post-indexing used when modified address register is destination"));
5843
5844   /* For an index-register load, the index register must not overlap the
5845      destination (even if not write-back).  */
5846   if ((inst.instruction & V4_STR_BIT) == 0
5847       && (inst.instruction & HWOFFSET_IMM) == 0)
5848     {
5849       int rm = inst.instruction & 0x0000000f;
5850
5851       if (rm == rd || (rm == rd + 1))
5852         as_warn (_("ldrd destination registers must not overlap index register"));
5853     }
5854
5855   end_of_line (str);
5856 }
5857
5858 /* Returns the index into fp_values of a floating point number,
5859    or -1 if not in the table.  */
5860
5861 static int
5862 my_get_float_expression (char ** str)
5863 {
5864   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5865   char *         save_in;
5866   expressionS    exp;
5867   int            i;
5868   int            j;
5869
5870   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5871
5872   /* Look for a raw floating point number.  */
5873   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5874       && is_end_of_line[(unsigned char) *save_in])
5875     {
5876       for (i = 0; i < NUM_FLOAT_VALS; i++)
5877         {
5878           for (j = 0; j < MAX_LITTLENUMS; j++)
5879             {
5880               if (words[j] != fp_values[i][j])
5881                 break;
5882             }
5883
5884           if (j == MAX_LITTLENUMS)
5885             {
5886               *str = save_in;
5887               return i;
5888             }
5889         }
5890     }
5891
5892   /* Try and parse a more complex expression, this will probably fail
5893      unless the code uses a floating point prefix (eg "0f").  */
5894   save_in = input_line_pointer;
5895   input_line_pointer = *str;
5896   if (expression (&exp) == absolute_section
5897       && exp.X_op == O_big
5898       && exp.X_add_number < 0)
5899     {
5900       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5901          Ditto for 15.  */
5902       if (gen_to_words (words, 5, (long) 15) == 0)
5903         {
5904           for (i = 0; i < NUM_FLOAT_VALS; i++)
5905             {
5906               for (j = 0; j < MAX_LITTLENUMS; j++)
5907                 {
5908                   if (words[j] != fp_values[i][j])
5909                     break;
5910                 }
5911
5912               if (j == MAX_LITTLENUMS)
5913                 {
5914                   *str = input_line_pointer;
5915                   input_line_pointer = save_in;
5916                   return i;
5917                 }
5918             }
5919         }
5920     }
5921
5922   *str = input_line_pointer;
5923   input_line_pointer = save_in;
5924   return -1;
5925 }
5926
5927 /* We handle all bad expressions here, so that we can report the faulty
5928    instruction in the error message.  */
5929 void
5930 md_operand (expressionS * expr)
5931 {
5932   if (in_my_get_expression)
5933     {
5934       expr->X_op = O_illegal;
5935       if (inst.error == NULL)
5936         inst.error = _("bad expression");
5937     }
5938 }
5939
5940 /* Do those data_ops which can take a negative immediate constant
5941    by altering the instruction.  A bit of a hack really.
5942         MOV <-> MVN
5943         AND <-> BIC
5944         ADC <-> SBC
5945         by inverting the second operand, and
5946         ADD <-> SUB
5947         CMP <-> CMN
5948         by negating the second operand.  */
5949
5950 static int
5951 negate_data_op (unsigned long * instruction,
5952                 unsigned long   value)
5953 {
5954   int op, new_inst;
5955   unsigned long negated, inverted;
5956
5957   negated = validate_immediate (-value);
5958   inverted = validate_immediate (~value);
5959
5960   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5961   switch (op)
5962     {
5963       /* First negates.  */
5964     case OPCODE_SUB:             /* ADD <-> SUB  */
5965       new_inst = OPCODE_ADD;
5966       value = negated;
5967       break;
5968
5969     case OPCODE_ADD:
5970       new_inst = OPCODE_SUB;
5971       value = negated;
5972       break;
5973
5974     case OPCODE_CMP:             /* CMP <-> CMN  */
5975       new_inst = OPCODE_CMN;
5976       value = negated;
5977       break;
5978
5979     case OPCODE_CMN:
5980       new_inst = OPCODE_CMP;
5981       value = negated;
5982       break;
5983
5984       /* Now Inverted ops.  */
5985     case OPCODE_MOV:             /* MOV <-> MVN  */
5986       new_inst = OPCODE_MVN;
5987       value = inverted;
5988       break;
5989
5990     case OPCODE_MVN:
5991       new_inst = OPCODE_MOV;
5992       value = inverted;
5993       break;
5994
5995     case OPCODE_AND:             /* AND <-> BIC  */
5996       new_inst = OPCODE_BIC;
5997       value = inverted;
5998       break;
5999
6000     case OPCODE_BIC:
6001       new_inst = OPCODE_AND;
6002       value = inverted;
6003       break;
6004
6005     case OPCODE_ADC:              /* ADC <-> SBC  */
6006       new_inst = OPCODE_SBC;
6007       value = inverted;
6008       break;
6009
6010     case OPCODE_SBC:
6011       new_inst = OPCODE_ADC;
6012       value = inverted;
6013       break;
6014
6015       /* We cannot do anything.  */
6016     default:
6017       return FAIL;
6018     }
6019
6020   if (value == (unsigned) FAIL)
6021     return FAIL;
6022
6023   *instruction &= OPCODE_MASK;
6024   *instruction |= new_inst << DATA_OP_SHIFT;
6025   return value;
6026 }
6027
6028 static int
6029 data_op2 (char ** str)
6030 {
6031   int value;
6032   expressionS expr;
6033
6034   skip_whitespace (* str);
6035
6036   if (reg_required_here (str, 0) != FAIL)
6037     {
6038       if (skip_past_comma (str) == SUCCESS)
6039         /* Shift operation on register.  */
6040         return decode_shift (str, NO_SHIFT_RESTRICT);
6041
6042       return SUCCESS;
6043     }
6044   else
6045     {
6046       /* Immediate expression.  */
6047       if (is_immediate_prefix (**str))
6048         {
6049           (*str)++;
6050           inst.error = NULL;
6051
6052           if (my_get_expression (&inst.reloc.exp, str))
6053             return FAIL;
6054
6055           if (inst.reloc.exp.X_add_symbol)
6056             {
6057               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6058               inst.reloc.pc_rel = 0;
6059             }
6060           else
6061             {
6062               if (skip_past_comma (str) == SUCCESS)
6063                 {
6064                   /* #x, y -- ie explicit rotation by Y.  */
6065                   if (my_get_expression (&expr, str))
6066                     return FAIL;
6067
6068                   if (expr.X_op != O_constant)
6069                     {
6070                       inst.error = _("constant expression expected");
6071                       return FAIL;
6072                     }
6073
6074                   /* Rotate must be a multiple of 2.  */
6075                   if (((unsigned) expr.X_add_number) > 30
6076                       || (expr.X_add_number & 1) != 0
6077                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
6078                     {
6079                       inst.error = _("invalid constant");
6080                       return FAIL;
6081                     }
6082                   inst.instruction |= INST_IMMEDIATE;
6083                   inst.instruction |= inst.reloc.exp.X_add_number;
6084                   inst.instruction |= expr.X_add_number << 7;
6085                   return SUCCESS;
6086                 }
6087
6088               /* Implicit rotation, select a suitable one.  */
6089               value = validate_immediate (inst.reloc.exp.X_add_number);
6090
6091               if (value == FAIL)
6092                 {
6093                   /* Can't be done.  Perhaps the code reads something like
6094                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
6095                   if ((value = negate_data_op (&inst.instruction,
6096                                                inst.reloc.exp.X_add_number))
6097                       == FAIL)
6098                     {
6099                       inst.error = _("invalid constant");
6100                       return FAIL;
6101                     }
6102                 }
6103
6104               inst.instruction |= value;
6105             }
6106
6107           inst.instruction |= INST_IMMEDIATE;
6108           return SUCCESS;
6109         }
6110
6111       (*str)++;
6112       inst.error = _("register or shift expression expected");
6113       return FAIL;
6114     }
6115 }
6116
6117 static int
6118 fp_op2 (char ** str)
6119 {
6120   skip_whitespace (* str);
6121
6122   if (fp_reg_required_here (str, 0) != FAIL)
6123     return SUCCESS;
6124   else
6125     {
6126       /* Immediate expression.  */
6127       if (*((*str)++) == '#')
6128         {
6129           int i;
6130
6131           inst.error = NULL;
6132
6133           skip_whitespace (* str);
6134
6135           /* First try and match exact strings, this is to guarantee
6136              that some formats will work even for cross assembly.  */
6137
6138           for (i = 0; fp_const[i]; i++)
6139             {
6140               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
6141                 {
6142                   char *start = *str;
6143
6144                   *str += strlen (fp_const[i]);
6145                   if (is_end_of_line[(unsigned char) **str])
6146                     {
6147                       inst.instruction |= i + 8;
6148                       return SUCCESS;
6149                     }
6150                   *str = start;
6151                 }
6152             }
6153
6154           /* Just because we didn't get a match doesn't mean that the
6155              constant isn't valid, just that it is in a format that we
6156              don't automatically recognize.  Try parsing it with
6157              the standard expression routines.  */
6158           if ((i = my_get_float_expression (str)) >= 0)
6159             {
6160               inst.instruction |= i + 8;
6161               return SUCCESS;
6162             }
6163
6164           inst.error = _("invalid floating point immediate expression");
6165           return FAIL;
6166         }
6167       inst.error =
6168         _("floating point register or immediate expression expected");
6169       return FAIL;
6170     }
6171 }
6172
6173 static void
6174 do_arit (char * str)
6175 {
6176   skip_whitespace (str);
6177
6178   if (reg_required_here (&str, 12) == FAIL
6179       || skip_past_comma (&str) == FAIL
6180       || reg_required_here (&str, 16) == FAIL
6181       || skip_past_comma (&str) == FAIL
6182       || data_op2 (&str) == FAIL)
6183     {
6184       if (!inst.error)
6185         inst.error = BAD_ARGS;
6186       return;
6187     }
6188
6189   end_of_line (str);
6190 }
6191
6192 static void
6193 do_adr (char * str)
6194 {
6195   /* This is a pseudo-op of the form "adr rd, label" to be converted
6196      into a relative address of the form "add rd, pc, #label-.-8".  */
6197   skip_whitespace (str);
6198
6199   if (reg_required_here (&str, 12) == FAIL
6200       || skip_past_comma (&str) == FAIL
6201       || my_get_expression (&inst.reloc.exp, &str))
6202     {
6203       if (!inst.error)
6204         inst.error = BAD_ARGS;
6205       return;
6206     }
6207
6208   /* Frag hacking will turn this into a sub instruction if the offset turns
6209      out to be negative.  */
6210   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
6211 #ifndef TE_WINCE
6212   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
6213 #endif
6214   inst.reloc.pc_rel = 1;
6215
6216   end_of_line (str);
6217 }
6218
6219 static void
6220 do_adrl (char * str)
6221 {
6222   /* This is a pseudo-op of the form "adrl rd, label" to be converted
6223      into a relative address of the form:
6224      add rd, pc, #low(label-.-8)"
6225      add rd, rd, #high(label-.-8)"  */
6226
6227   skip_whitespace (str);
6228
6229   if (reg_required_here (&str, 12) == FAIL
6230       || skip_past_comma (&str) == FAIL
6231       || my_get_expression (&inst.reloc.exp, &str))
6232     {
6233       if (!inst.error)
6234         inst.error = BAD_ARGS;
6235
6236       return;
6237     }
6238
6239   end_of_line (str);
6240   /* Frag hacking will turn this into a sub instruction if the offset turns
6241      out to be negative.  */
6242   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6243 #ifndef TE_WINCE
6244   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
6245 #endif
6246   inst.reloc.pc_rel            = 1;
6247   inst.size                    = INSN_SIZE * 2;
6248 }
6249
6250 static void
6251 do_cmp (char * str)
6252 {
6253   skip_whitespace (str);
6254
6255   if (reg_required_here (&str, 16) == FAIL)
6256     {
6257       if (!inst.error)
6258         inst.error = BAD_ARGS;
6259       return;
6260     }
6261
6262   if (skip_past_comma (&str) == FAIL
6263       || data_op2 (&str) == FAIL)
6264     {
6265       if (!inst.error)
6266         inst.error = BAD_ARGS;
6267       return;
6268     }
6269
6270   end_of_line (str);
6271 }
6272
6273 static void
6274 do_mov (char * str)
6275 {
6276   skip_whitespace (str);
6277
6278   if (reg_required_here (&str, 12) == FAIL)
6279     {
6280       if (!inst.error)
6281         inst.error = BAD_ARGS;
6282       return;
6283     }
6284
6285   if (skip_past_comma (&str) == FAIL
6286       || data_op2 (&str) == FAIL)
6287     {
6288       if (!inst.error)
6289         inst.error = BAD_ARGS;
6290       return;
6291     }
6292
6293   end_of_line (str);
6294 }
6295
6296 static void
6297 do_ldst (char * str)
6298 {
6299   int pre_inc = 0;
6300   int conflict_reg;
6301   int value;
6302
6303   skip_whitespace (str);
6304
6305   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6306     {
6307       if (!inst.error)
6308         inst.error = BAD_ARGS;
6309       return;
6310     }
6311
6312   if (skip_past_comma (&str) == FAIL)
6313     {
6314       inst.error = _("address expected");
6315       return;
6316     }
6317
6318   if (*str == '[')
6319     {
6320       int reg;
6321
6322       str++;
6323
6324       skip_whitespace (str);
6325
6326       if ((reg = reg_required_here (&str, 16)) == FAIL)
6327         return;
6328
6329       /* Conflicts can occur on stores as well as loads.  */
6330       conflict_reg = (conflict_reg == reg);
6331
6332       skip_whitespace (str);
6333
6334       if (*str == ']')
6335         {
6336           str ++;
6337
6338           if (skip_past_comma (&str) == SUCCESS)
6339             {
6340               /* [Rn],... (post inc)  */
6341               if (ldst_extend (&str) == FAIL)
6342                 return;
6343               if (conflict_reg)
6344                 as_warn (_("%s register same as write-back base"),
6345                          ((inst.instruction & LOAD_BIT)
6346                           ? _("destination") : _("source")));
6347             }
6348           else
6349             {
6350               /* [Rn]  */
6351               skip_whitespace (str);
6352
6353               if (*str == '!')
6354                 {
6355                   if (conflict_reg)
6356                     as_warn (_("%s register same as write-back base"),
6357                              ((inst.instruction & LOAD_BIT)
6358                               ? _("destination") : _("source")));
6359                   str++;
6360                   inst.instruction |= WRITE_BACK;
6361                 }
6362
6363               inst.instruction |= INDEX_UP;
6364               pre_inc = 1;
6365             }
6366         }
6367       else
6368         {
6369           /* [Rn,...]  */
6370           if (skip_past_comma (&str) == FAIL)
6371             {
6372               inst.error = _("pre-indexed expression expected");
6373               return;
6374             }
6375
6376           pre_inc = 1;
6377           if (ldst_extend (&str) == FAIL)
6378             return;
6379
6380           skip_whitespace (str);
6381
6382           if (*str++ != ']')
6383             {
6384               inst.error = _("missing ]");
6385               return;
6386             }
6387
6388           skip_whitespace (str);
6389
6390           if (*str == '!')
6391             {
6392               if (conflict_reg)
6393                 as_warn (_("%s register same as write-back base"),
6394                          ((inst.instruction & LOAD_BIT)
6395                           ? _("destination") : _("source")));
6396               str++;
6397               inst.instruction |= WRITE_BACK;
6398             }
6399         }
6400     }
6401   else if (*str == '=')
6402     {
6403       if ((inst.instruction & LOAD_BIT) == 0)
6404         {
6405           inst.error = _("invalid pseudo operation");
6406           return;
6407         }
6408
6409       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6410       str++;
6411
6412       skip_whitespace (str);
6413
6414       if (my_get_expression (&inst.reloc.exp, &str))
6415         return;
6416
6417       if (inst.reloc.exp.X_op != O_constant
6418           && inst.reloc.exp.X_op != O_symbol)
6419         {
6420           inst.error = _("constant expression expected");
6421           return;
6422         }
6423
6424       if (inst.reloc.exp.X_op == O_constant)
6425         {
6426           value = validate_immediate (inst.reloc.exp.X_add_number);
6427
6428           if (value != FAIL)
6429             {
6430               /* This can be done with a mov instruction.  */
6431               inst.instruction &= LITERAL_MASK;
6432               inst.instruction |= (INST_IMMEDIATE
6433                                    | (OPCODE_MOV << DATA_OP_SHIFT));
6434               inst.instruction |= value & 0xfff;
6435               end_of_line (str);
6436               return;
6437             }
6438
6439           value = validate_immediate (~inst.reloc.exp.X_add_number);
6440
6441           if (value != FAIL)
6442             {
6443               /* This can be done with a mvn instruction.  */
6444               inst.instruction &= LITERAL_MASK;
6445               inst.instruction |= (INST_IMMEDIATE
6446                                    | (OPCODE_MVN << DATA_OP_SHIFT));
6447               inst.instruction |= value & 0xfff;
6448               end_of_line (str);
6449               return;
6450             }
6451         }
6452
6453       /* Insert into literal pool.  */
6454       if (add_to_lit_pool () == FAIL)
6455         {
6456           if (!inst.error)
6457             inst.error = _("literal pool insertion failed");
6458           return;
6459         }
6460
6461       /* Change the instruction exp to point to the pool.  */
6462       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6463       inst.reloc.pc_rel = 1;
6464       inst.instruction |= (REG_PC << 16);
6465       pre_inc = 1;
6466     }
6467   else
6468     {
6469       if (my_get_expression (&inst.reloc.exp, &str))
6470         return;
6471
6472       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6473 #ifndef TE_WINCE
6474       /* PC rel adjust.  */
6475       inst.reloc.exp.X_add_number -= 8;
6476 #endif
6477       inst.reloc.pc_rel = 1;
6478       inst.instruction |= (REG_PC << 16);
6479       pre_inc = 1;
6480     }
6481
6482   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6483   end_of_line (str);
6484 }
6485
6486 static void
6487 do_ldstt (char * str)
6488 {
6489   int conflict_reg;
6490
6491   skip_whitespace (str);
6492
6493   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6494     {
6495       if (!inst.error)
6496         inst.error = BAD_ARGS;
6497       return;
6498     }
6499
6500   if (skip_past_comma (& str) == FAIL)
6501     {
6502       inst.error = _("address expected");
6503       return;
6504     }
6505
6506   if (*str == '[')
6507     {
6508       int reg;
6509
6510       str++;
6511
6512       skip_whitespace (str);
6513
6514       if ((reg = reg_required_here (&str, 16)) == FAIL)
6515         return;
6516
6517       /* ldrt/strt always use post-indexed addressing, so if the base is
6518          the same as Rd, we warn.  */
6519       if (conflict_reg == reg)
6520         as_warn (_("%s register same as write-back base"),
6521                  ((inst.instruction & LOAD_BIT)
6522                   ? _("destination") : _("source")));
6523
6524       skip_whitespace (str);
6525
6526       if (*str == ']')
6527         {
6528           str ++;
6529
6530           if (skip_past_comma (&str) == SUCCESS)
6531             {
6532               /* [Rn],... (post inc)  */
6533               if (ldst_extend (&str) == FAIL)
6534                 return;
6535             }
6536           else
6537             {
6538               /* [Rn]  */
6539               skip_whitespace (str);
6540
6541               /* Skip a write-back '!'.  */
6542               if (*str == '!')
6543                 str++;
6544
6545               inst.instruction |= INDEX_UP;
6546             }
6547         }
6548       else
6549         {
6550           inst.error = _("post-indexed expression expected");
6551           return;
6552         }
6553     }
6554   else
6555     {
6556       inst.error = _("post-indexed expression expected");
6557       return;
6558     }
6559
6560   end_of_line (str);
6561 }
6562
6563 /* Halfword and signed-byte load/store operations.  */
6564
6565 static void
6566 do_ldstv4 (char * str)
6567 {
6568   int pre_inc = 0;
6569   int conflict_reg;
6570   int value;
6571
6572   skip_whitespace (str);
6573
6574   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6575     {
6576       if (!inst.error)
6577         inst.error = BAD_ARGS;
6578       return;
6579     }
6580
6581   if (skip_past_comma (& str) == FAIL)
6582     {
6583       inst.error = _("address expected");
6584       return;
6585     }
6586
6587   if (*str == '[')
6588     {
6589       int reg;
6590
6591       str++;
6592
6593       skip_whitespace (str);
6594
6595       if ((reg = reg_required_here (&str, 16)) == FAIL)
6596         return;
6597
6598       /* Conflicts can occur on stores as well as loads.  */
6599       conflict_reg = (conflict_reg == reg);
6600
6601       skip_whitespace (str);
6602
6603       if (*str == ']')
6604         {
6605           str ++;
6606
6607           if (skip_past_comma (&str) == SUCCESS)
6608             {
6609               /* [Rn],... (post inc)  */
6610               if (ldst_extend_v4 (&str) == FAIL)
6611                 return;
6612               if (conflict_reg)
6613                 as_warn (_("%s register same as write-back base"),
6614                          ((inst.instruction & LOAD_BIT)
6615                           ? _("destination") : _("source")));
6616             }
6617           else
6618             {
6619               /* [Rn]  */
6620               inst.instruction |= HWOFFSET_IMM;
6621
6622               skip_whitespace (str);
6623
6624               if (*str == '!')
6625                 {
6626                   if (conflict_reg)
6627                     as_warn (_("%s register same as write-back base"),
6628                              ((inst.instruction & LOAD_BIT)
6629                               ? _("destination") : _("source")));
6630                   str++;
6631                   inst.instruction |= WRITE_BACK;
6632                 }
6633
6634               inst.instruction |= INDEX_UP;
6635               pre_inc = 1;
6636             }
6637         }
6638       else
6639         {
6640           /* [Rn,...]  */
6641           if (skip_past_comma (&str) == FAIL)
6642             {
6643               inst.error = _("pre-indexed expression expected");
6644               return;
6645             }
6646
6647           pre_inc = 1;
6648           if (ldst_extend_v4 (&str) == FAIL)
6649             return;
6650
6651           skip_whitespace (str);
6652
6653           if (*str++ != ']')
6654             {
6655               inst.error = _("missing ]");
6656               return;
6657             }
6658
6659           skip_whitespace (str);
6660
6661           if (*str == '!')
6662             {
6663               if (conflict_reg)
6664                 as_warn (_("%s register same as write-back base"),
6665                          ((inst.instruction & LOAD_BIT)
6666                           ? _("destination") : _("source")));
6667               str++;
6668               inst.instruction |= WRITE_BACK;
6669             }
6670         }
6671     }
6672   else if (*str == '=')
6673     {
6674       if ((inst.instruction & LOAD_BIT) == 0)
6675         {
6676           inst.error = _("invalid pseudo operation");
6677           return;
6678         }
6679
6680       /* XXX Does this work correctly for half-word/byte ops?  */
6681       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6682       str++;
6683
6684       skip_whitespace (str);
6685
6686       if (my_get_expression (&inst.reloc.exp, &str))
6687         return;
6688
6689       if (inst.reloc.exp.X_op != O_constant
6690           && inst.reloc.exp.X_op != O_symbol)
6691         {
6692           inst.error = _("constant expression expected");
6693           return;
6694         }
6695
6696       if (inst.reloc.exp.X_op == O_constant)
6697         {
6698           value = validate_immediate (inst.reloc.exp.X_add_number);
6699
6700           if (value != FAIL)
6701             {
6702               /* This can be done with a mov instruction.  */
6703               inst.instruction &= LITERAL_MASK;
6704               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6705               inst.instruction |= value & 0xfff;
6706               end_of_line (str);
6707               return;
6708             }
6709
6710           value = validate_immediate (~ inst.reloc.exp.X_add_number);
6711
6712           if (value != FAIL)
6713             {
6714               /* This can be done with a mvn instruction.  */
6715               inst.instruction &= LITERAL_MASK;
6716               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6717               inst.instruction |= value & 0xfff;
6718               end_of_line (str);
6719               return;
6720             }
6721         }
6722
6723       /* Insert into literal pool.  */
6724       if (add_to_lit_pool () == FAIL)
6725         {
6726           if (!inst.error)
6727             inst.error = _("literal pool insertion failed");
6728           return;
6729         }
6730
6731       /* Change the instruction exp to point to the pool.  */
6732       inst.instruction |= HWOFFSET_IMM;
6733       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6734       inst.reloc.pc_rel = 1;
6735       inst.instruction |= (REG_PC << 16);
6736       pre_inc = 1;
6737     }
6738   else
6739     {
6740       if (my_get_expression (&inst.reloc.exp, &str))
6741         return;
6742
6743       inst.instruction |= HWOFFSET_IMM;
6744       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6745 #ifndef TE_WINCE
6746       /* PC rel adjust.  */
6747       inst.reloc.exp.X_add_number -= 8;
6748 #endif
6749       inst.reloc.pc_rel = 1;
6750       inst.instruction |= (REG_PC << 16);
6751       pre_inc = 1;
6752     }
6753
6754   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6755   end_of_line (str);
6756 }
6757
6758 static void
6759 do_ldsttv4 (char * str)
6760 {
6761   int conflict_reg;
6762
6763   skip_whitespace (str);
6764
6765   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6766     {
6767       if (!inst.error)
6768         inst.error = BAD_ARGS;
6769       return;
6770     }
6771
6772   if (skip_past_comma (& str) == FAIL)
6773     {
6774       inst.error = _("address expected");
6775       return;
6776     }
6777
6778   if (*str == '[')
6779     {
6780       int reg;
6781
6782       str++;
6783
6784       skip_whitespace (str);
6785
6786       if ((reg = reg_required_here (&str, 16)) == FAIL)
6787         return;
6788
6789       /* ldrt/strt always use post-indexed addressing, so if the base is
6790          the same as Rd, we warn.  */
6791       if (conflict_reg == reg)
6792         as_warn (_("%s register same as write-back base"),
6793                  ((inst.instruction & LOAD_BIT)
6794                   ? _("destination") : _("source")));
6795
6796       skip_whitespace (str);
6797
6798       if (*str == ']')
6799         {
6800           str ++;
6801
6802           if (skip_past_comma (&str) == SUCCESS)
6803             {
6804               /* [Rn],... (post inc)  */
6805               if (ldst_extend_v4 (&str) == FAIL)
6806                 return;
6807             }
6808           else
6809             {
6810               /* [Rn]  */
6811               skip_whitespace (str);
6812
6813               /* Skip a write-back '!'.  */
6814               if (*str == '!')
6815                 str++;
6816
6817               inst.instruction |= (INDEX_UP|HWOFFSET_IMM);
6818             }
6819         }
6820       else
6821         {
6822           inst.error = _("post-indexed expression expected");
6823           return;
6824         }
6825     }
6826   else
6827     {
6828       inst.error = _("post-indexed expression expected");
6829       return;
6830     }
6831
6832   end_of_line (str);
6833 }
6834
6835
6836 static long
6837 reg_list (char ** strp)
6838 {
6839   char * str = * strp;
6840   long   range = 0;
6841   int    another_range;
6842
6843   /* We come back here if we get ranges concatenated by '+' or '|'.  */
6844   do
6845     {
6846       another_range = 0;
6847
6848       if (*str == '{')
6849         {
6850           int in_range = 0;
6851           int cur_reg = -1;
6852
6853           str++;
6854           do
6855             {
6856               int reg;
6857
6858               skip_whitespace (str);
6859
6860               if ((reg = reg_required_here (& str, -1)) == FAIL)
6861                 return FAIL;
6862
6863               if (in_range)
6864                 {
6865                   int i;
6866
6867                   if (reg <= cur_reg)
6868                     {
6869                       inst.error = _("bad range in register list");
6870                       return FAIL;
6871                     }
6872
6873                   for (i = cur_reg + 1; i < reg; i++)
6874                     {
6875                       if (range & (1 << i))
6876                         as_tsktsk
6877                           (_("Warning: duplicated register (r%d) in register list"),
6878                            i);
6879                       else
6880                         range |= 1 << i;
6881                     }
6882                   in_range = 0;
6883                 }
6884
6885               if (range & (1 << reg))
6886                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6887                            reg);
6888               else if (reg <= cur_reg)
6889                 as_tsktsk (_("Warning: register range not in ascending order"));
6890
6891               range |= 1 << reg;
6892               cur_reg = reg;
6893             }
6894           while (skip_past_comma (&str) != FAIL
6895                  || (in_range = 1, *str++ == '-'));
6896           str--;
6897           skip_whitespace (str);
6898
6899           if (*str++ != '}')
6900             {
6901               inst.error = _("missing `}'");
6902               return FAIL;
6903             }
6904         }
6905       else
6906         {
6907           expressionS expr;
6908
6909           if (my_get_expression (&expr, &str))
6910             return FAIL;
6911
6912           if (expr.X_op == O_constant)
6913             {
6914               if (expr.X_add_number
6915                   != (expr.X_add_number & 0x0000ffff))
6916                 {
6917                   inst.error = _("invalid register mask");
6918                   return FAIL;
6919                 }
6920
6921               if ((range & expr.X_add_number) != 0)
6922                 {
6923                   int regno = range & expr.X_add_number;
6924
6925                   regno &= -regno;
6926                   regno = (1 << regno) - 1;
6927                   as_tsktsk
6928                     (_("Warning: duplicated register (r%d) in register list"),
6929                      regno);
6930                 }
6931
6932               range |= expr.X_add_number;
6933             }
6934           else
6935             {
6936               if (inst.reloc.type != 0)
6937                 {
6938                   inst.error = _("expression too complex");
6939                   return FAIL;
6940                 }
6941
6942               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6943               inst.reloc.type = BFD_RELOC_ARM_MULTI;
6944               inst.reloc.pc_rel = 0;
6945             }
6946         }
6947
6948       skip_whitespace (str);
6949
6950       if (*str == '|' || *str == '+')
6951         {
6952           str++;
6953           another_range = 1;
6954         }
6955     }
6956   while (another_range);
6957
6958   *strp = str;
6959   return range;
6960 }
6961
6962 static void
6963 do_ldmstm (char * str)
6964 {
6965   int base_reg;
6966   long range;
6967
6968   skip_whitespace (str);
6969
6970   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6971     return;
6972
6973   if (base_reg == REG_PC)
6974     {
6975       inst.error = _("r15 not allowed as base register");
6976       return;
6977     }
6978
6979   skip_whitespace (str);
6980
6981   if (*str == '!')
6982     {
6983       inst.instruction |= WRITE_BACK;
6984       str++;
6985     }
6986
6987   if (skip_past_comma (&str) == FAIL
6988       || (range = reg_list (&str)) == FAIL)
6989     {
6990       if (! inst.error)
6991         inst.error = BAD_ARGS;
6992       return;
6993     }
6994
6995   if (*str == '^')
6996     {
6997       str++;
6998       inst.instruction |= LDM_TYPE_2_OR_3;
6999     }
7000
7001   if (inst.instruction & WRITE_BACK)
7002     {
7003       /* Check for unpredictable uses of writeback.  */
7004       if (inst.instruction & LOAD_BIT)
7005         {
7006           /* Not allowed in LDM type 2.  */
7007           if ((inst.instruction & LDM_TYPE_2_OR_3)
7008               && ((range & (1 << REG_PC)) == 0))
7009             as_warn (_("writeback of base register is UNPREDICTABLE"));
7010           /* Only allowed if base reg not in list for other types.  */
7011           else if (range & (1 << base_reg))
7012             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
7013         }
7014       else /* STM.  */
7015         {
7016           /* Not allowed for type 2.  */
7017           if (inst.instruction & LDM_TYPE_2_OR_3)
7018             as_warn (_("writeback of base register is UNPREDICTABLE"));
7019           /* Only allowed if base reg not in list, or first in list.  */
7020           else if ((range & (1 << base_reg))
7021                    && (range & ((1 << base_reg) - 1)))
7022             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
7023         }
7024     }
7025
7026   inst.instruction |= range;
7027   end_of_line (str);
7028 }
7029
7030 static void
7031 do_smi (char * str)
7032 {
7033   skip_whitespace (str);
7034
7035   /* Allow optional leading '#'.  */
7036   if (is_immediate_prefix (*str))
7037     str++;
7038
7039   if (my_get_expression (& inst.reloc.exp, & str))
7040     return;
7041
7042   inst.reloc.type = BFD_RELOC_ARM_SMI;
7043   inst.reloc.pc_rel = 0;
7044   end_of_line (str);
7045 }
7046
7047 static void
7048 do_swi (char * str)
7049 {
7050   skip_whitespace (str);
7051
7052   /* Allow optional leading '#'.  */
7053   if (is_immediate_prefix (*str))
7054     str++;
7055
7056   if (my_get_expression (& inst.reloc.exp, & str))
7057     return;
7058
7059   inst.reloc.type = BFD_RELOC_ARM_SWI;
7060   inst.reloc.pc_rel = 0;
7061   end_of_line (str);
7062 }
7063
7064 static void
7065 do_swap (char * str)
7066 {
7067   int reg;
7068
7069   skip_whitespace (str);
7070
7071   if ((reg = reg_required_here (&str, 12)) == FAIL)
7072     return;
7073
7074   if (reg == REG_PC)
7075     {
7076       inst.error = _("r15 not allowed in swap");
7077       return;
7078     }
7079
7080   if (skip_past_comma (&str) == FAIL
7081       || (reg = reg_required_here (&str, 0)) == FAIL)
7082     {
7083       if (!inst.error)
7084         inst.error = BAD_ARGS;
7085       return;
7086     }
7087
7088   if (reg == REG_PC)
7089     {
7090       inst.error = _("r15 not allowed in swap");
7091       return;
7092     }
7093
7094   if (skip_past_comma (&str) == FAIL
7095       || *str++ != '[')
7096     {
7097       inst.error = BAD_ARGS;
7098       return;
7099     }
7100
7101   skip_whitespace (str);
7102
7103   if ((reg = reg_required_here (&str, 16)) == FAIL)
7104     return;
7105
7106   if (reg == REG_PC)
7107     {
7108       inst.error = BAD_PC;
7109       return;
7110     }
7111
7112   skip_whitespace (str);
7113
7114   if (*str++ != ']')
7115     {
7116       inst.error = _("missing ]");
7117       return;
7118     }
7119
7120   end_of_line (str);
7121 }
7122
7123 static void
7124 do_branch (char * str)
7125 {
7126   if (my_get_expression (&inst.reloc.exp, &str))
7127     return;
7128
7129 #ifdef OBJ_ELF
7130   {
7131     char * save_in;
7132
7133     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
7134        required for the instruction.  */
7135
7136     /* arm_parse_reloc () works on input_line_pointer.
7137        We actually want to parse the operands to the branch instruction
7138        passed in 'str'.  Save the input pointer and restore it later.  */
7139     save_in = input_line_pointer;
7140     input_line_pointer = str;
7141     if (inst.reloc.exp.X_op == O_symbol
7142         && *str == '('
7143         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
7144       {
7145         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
7146         inst.reloc.pc_rel = 0;
7147         /* Modify str to point to after parsed operands, otherwise
7148            end_of_line() will complain about the (PLT) left in str.  */
7149         str = input_line_pointer;
7150       }
7151     else
7152       {
7153         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
7154         inst.reloc.pc_rel = 1;
7155       }
7156     input_line_pointer = save_in;
7157   }
7158 #else
7159   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
7160   inst.reloc.pc_rel = 1;
7161 #endif /* OBJ_ELF  */
7162
7163   end_of_line (str);
7164 }
7165
7166 static void
7167 do_cdp (char * str)
7168 {
7169   /* Co-processor data operation.
7170      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
7171   skip_whitespace (str);
7172
7173   if (co_proc_number (&str) == FAIL)
7174     {
7175       if (!inst.error)
7176         inst.error = BAD_ARGS;
7177       return;
7178     }
7179
7180   if (skip_past_comma (&str) == FAIL
7181       || cp_opc_expr (&str, 20,4) == FAIL)
7182     {
7183       if (!inst.error)
7184         inst.error = BAD_ARGS;
7185       return;
7186     }
7187
7188   if (skip_past_comma (&str) == FAIL
7189       || cp_reg_required_here (&str, 12) == FAIL)
7190     {
7191       if (!inst.error)
7192         inst.error = BAD_ARGS;
7193       return;
7194     }
7195
7196   if (skip_past_comma (&str) == FAIL
7197       || cp_reg_required_here (&str, 16) == FAIL)
7198     {
7199       if (!inst.error)
7200         inst.error = BAD_ARGS;
7201       return;
7202     }
7203
7204   if (skip_past_comma (&str) == FAIL
7205       || cp_reg_required_here (&str, 0) == FAIL)
7206     {
7207       if (!inst.error)
7208         inst.error = BAD_ARGS;
7209       return;
7210     }
7211
7212   if (skip_past_comma (&str) == SUCCESS)
7213     {
7214       if (cp_opc_expr (&str, 5, 3) == FAIL)
7215         {
7216           if (!inst.error)
7217             inst.error = BAD_ARGS;
7218           return;
7219         }
7220     }
7221
7222   end_of_line (str);
7223 }
7224
7225 static void
7226 do_lstc (char * str)
7227 {
7228   /* Co-processor register load/store.
7229      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
7230
7231   skip_whitespace (str);
7232
7233   if (co_proc_number (&str) == FAIL)
7234     {
7235       if (!inst.error)
7236         inst.error = BAD_ARGS;
7237       return;
7238     }
7239
7240   if (skip_past_comma (&str) == FAIL
7241       || cp_reg_required_here (&str, 12) == FAIL)
7242     {
7243       if (!inst.error)
7244         inst.error = BAD_ARGS;
7245       return;
7246     }
7247
7248   if (skip_past_comma (&str) == FAIL
7249       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7250     {
7251       if (! inst.error)
7252         inst.error = BAD_ARGS;
7253       return;
7254     }
7255
7256   end_of_line (str);
7257 }
7258
7259 static void
7260 do_co_reg (char * str)
7261 {
7262   /* Co-processor register transfer.
7263      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
7264
7265   skip_whitespace (str);
7266
7267   if (co_proc_number (&str) == FAIL)
7268     {
7269       if (!inst.error)
7270         inst.error = BAD_ARGS;
7271       return;
7272     }
7273
7274   if (skip_past_comma (&str) == FAIL
7275       || cp_opc_expr (&str, 21, 3) == FAIL)
7276     {
7277       if (!inst.error)
7278         inst.error = BAD_ARGS;
7279       return;
7280     }
7281
7282   if (skip_past_comma (&str) == FAIL
7283       || reg_required_here (&str, 12) == FAIL)
7284     {
7285       if (!inst.error)
7286         inst.error = BAD_ARGS;
7287       return;
7288     }
7289
7290   if (skip_past_comma (&str) == FAIL
7291       || cp_reg_required_here (&str, 16) == FAIL)
7292     {
7293       if (!inst.error)
7294         inst.error = BAD_ARGS;
7295       return;
7296     }
7297
7298   if (skip_past_comma (&str) == FAIL
7299       || cp_reg_required_here (&str, 0) == FAIL)
7300     {
7301       if (!inst.error)
7302         inst.error = BAD_ARGS;
7303       return;
7304     }
7305
7306   if (skip_past_comma (&str) == SUCCESS)
7307     {
7308       if (cp_opc_expr (&str, 5, 3) == FAIL)
7309         {
7310           if (!inst.error)
7311             inst.error = BAD_ARGS;
7312           return;
7313         }
7314     }
7315
7316   end_of_line (str);
7317 }
7318
7319 static void
7320 do_fpa_ctrl (char * str)
7321 {
7322   /* FP control registers.
7323      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
7324
7325   skip_whitespace (str);
7326
7327   if (reg_required_here (&str, 12) == FAIL)
7328     {
7329       if (!inst.error)
7330         inst.error = BAD_ARGS;
7331       return;
7332     }
7333
7334   end_of_line (str);
7335 }
7336
7337 static void
7338 do_fpa_ldst (char * str)
7339 {
7340   skip_whitespace (str);
7341
7342   if (fp_reg_required_here (&str, 12) == FAIL)
7343     {
7344       if (!inst.error)
7345         inst.error = BAD_ARGS;
7346       return;
7347     }
7348
7349   if (skip_past_comma (&str) == FAIL
7350       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7351     {
7352       if (!inst.error)
7353         inst.error = BAD_ARGS;
7354       return;
7355     }
7356
7357   end_of_line (str);
7358 }
7359
7360 static void
7361 do_fpa_ldmstm (char * str)
7362 {
7363   int num_regs;
7364
7365   skip_whitespace (str);
7366
7367   if (fp_reg_required_here (&str, 12) == FAIL)
7368     {
7369       if (! inst.error)
7370         inst.error = BAD_ARGS;
7371       return;
7372     }
7373
7374   /* Get Number of registers to transfer.  */
7375   if (skip_past_comma (&str) == FAIL
7376       || my_get_expression (&inst.reloc.exp, &str))
7377     {
7378       if (! inst.error)
7379         inst.error = _("constant expression expected");
7380       return;
7381     }
7382
7383   if (inst.reloc.exp.X_op != O_constant)
7384     {
7385       inst.error = _("constant value required for number of registers");
7386       return;
7387     }
7388
7389   num_regs = inst.reloc.exp.X_add_number;
7390
7391   if (num_regs < 1 || num_regs > 4)
7392     {
7393       inst.error = _("number of registers must be in the range [1:4]");
7394       return;
7395     }
7396
7397   switch (num_regs)
7398     {
7399     case 1:
7400       inst.instruction |= CP_T_X;
7401       break;
7402     case 2:
7403       inst.instruction |= CP_T_Y;
7404       break;
7405     case 3:
7406       inst.instruction |= CP_T_Y | CP_T_X;
7407       break;
7408     case 4:
7409       break;
7410     default:
7411       abort ();
7412     }
7413
7414   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
7415     {
7416       int reg;
7417       int write_back;
7418       int offset;
7419
7420       /* The instruction specified "ea" or "fd", so we can only accept
7421          [Rn]{!}.  The instruction does not really support stacking or
7422          unstacking, so we have to emulate these by setting appropriate
7423          bits and offsets.  */
7424       if (skip_past_comma (&str) == FAIL
7425           || *str != '[')
7426         {
7427           if (! inst.error)
7428             inst.error = BAD_ARGS;
7429           return;
7430         }
7431
7432       str++;
7433       skip_whitespace (str);
7434
7435       if ((reg = reg_required_here (&str, 16)) == FAIL)
7436         return;
7437
7438       skip_whitespace (str);
7439
7440       if (*str != ']')
7441         {
7442           inst.error = BAD_ARGS;
7443           return;
7444         }
7445
7446       str++;
7447       if (*str == '!')
7448         {
7449           write_back = 1;
7450           str++;
7451           if (reg == REG_PC)
7452             {
7453               inst.error =
7454                 _("r15 not allowed as base register with write-back");
7455               return;
7456             }
7457         }
7458       else
7459         write_back = 0;
7460
7461       if (inst.instruction & CP_T_Pre)
7462         {
7463           /* Pre-decrement.  */
7464           offset = 3 * num_regs;
7465           if (write_back)
7466             inst.instruction |= CP_T_WB;
7467         }
7468       else
7469         {
7470           /* Post-increment.  */
7471           if (write_back)
7472             {
7473               inst.instruction |= CP_T_WB;
7474               offset = 3 * num_regs;
7475             }
7476           else
7477             {
7478               /* No write-back, so convert this into a standard pre-increment
7479                  instruction -- aesthetically more pleasing.  */
7480               inst.instruction |= CP_T_Pre | CP_T_UD;
7481               offset = 0;
7482             }
7483         }
7484
7485       inst.instruction |= offset;
7486     }
7487   else if (skip_past_comma (&str) == FAIL
7488            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7489     {
7490       if (! inst.error)
7491         inst.error = BAD_ARGS;
7492       return;
7493     }
7494
7495   end_of_line (str);
7496 }
7497
7498 static void
7499 do_fpa_dyadic (char * str)
7500 {
7501   skip_whitespace (str);
7502
7503   if (fp_reg_required_here (&str, 12) == FAIL)
7504     {
7505       if (! inst.error)
7506         inst.error = BAD_ARGS;
7507       return;
7508     }
7509
7510   if (skip_past_comma (&str) == FAIL
7511       || fp_reg_required_here (&str, 16) == FAIL)
7512     {
7513       if (! inst.error)
7514         inst.error = BAD_ARGS;
7515       return;
7516     }
7517
7518   if (skip_past_comma (&str) == FAIL
7519       || fp_op2 (&str) == FAIL)
7520     {
7521       if (! inst.error)
7522         inst.error = BAD_ARGS;
7523       return;
7524     }
7525
7526   end_of_line (str);
7527 }
7528
7529 static void
7530 do_fpa_monadic (char * str)
7531 {
7532   skip_whitespace (str);
7533
7534   if (fp_reg_required_here (&str, 12) == FAIL)
7535     {
7536       if (! inst.error)
7537         inst.error = BAD_ARGS;
7538       return;
7539     }
7540
7541   if (skip_past_comma (&str) == FAIL
7542       || fp_op2 (&str) == FAIL)
7543     {
7544       if (! inst.error)
7545         inst.error = BAD_ARGS;
7546       return;
7547     }
7548
7549   end_of_line (str);
7550 }
7551
7552 static void
7553 do_fpa_cmp (char * str)
7554 {
7555   skip_whitespace (str);
7556
7557   if (fp_reg_required_here (&str, 16) == FAIL)
7558     {
7559       if (! inst.error)
7560         inst.error = BAD_ARGS;
7561       return;
7562     }
7563
7564   if (skip_past_comma (&str) == FAIL
7565       || fp_op2 (&str) == FAIL)
7566     {
7567       if (! inst.error)
7568         inst.error = BAD_ARGS;
7569       return;
7570     }
7571
7572   end_of_line (str);
7573 }
7574
7575 static void
7576 do_fpa_from_reg (char * str)
7577 {
7578   skip_whitespace (str);
7579
7580   if (fp_reg_required_here (&str, 16) == FAIL)
7581     {
7582       if (! inst.error)
7583         inst.error = BAD_ARGS;
7584       return;
7585     }
7586
7587   if (skip_past_comma (&str) == FAIL
7588       || reg_required_here (&str, 12) == FAIL)
7589     {
7590       if (! inst.error)
7591         inst.error = BAD_ARGS;
7592       return;
7593     }
7594
7595   end_of_line (str);
7596 }
7597
7598 static void
7599 do_fpa_to_reg (char * str)
7600 {
7601   skip_whitespace (str);
7602
7603   if (reg_required_here (&str, 12) == FAIL)
7604     return;
7605
7606   if (skip_past_comma (&str) == FAIL
7607       || fp_reg_required_here (&str, 0) == FAIL)
7608     {
7609       if (! inst.error)
7610         inst.error = BAD_ARGS;
7611       return;
7612     }
7613
7614   end_of_line (str);
7615 }
7616
7617 /* Encode a VFP SP register number.  */
7618
7619 static void
7620 vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
7621 {
7622   switch (pos)
7623     {
7624     case VFP_REG_Sd:
7625       inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7626       break;
7627
7628     case VFP_REG_Sn:
7629       inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7630       break;
7631
7632     case VFP_REG_Sm:
7633       inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7634       break;
7635
7636     default:
7637       abort ();
7638     }
7639 }
7640
7641 static int
7642 vfp_sp_reg_required_here (char ** str,
7643                           enum vfp_sp_reg_pos pos)
7644 {
7645   int    reg;
7646   char * start = *str;
7647
7648   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7649     {
7650       vfp_sp_encode_reg (reg, pos);
7651       return reg;
7652     }
7653
7654   /* In the few cases where we might be able to accept something else
7655      this error can be overridden.  */
7656   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7657
7658   /* Restore the start point.  */
7659   *str = start;
7660   return FAIL;
7661 }
7662
7663 static int
7664 vfp_dp_reg_required_here (char ** str,
7665                           enum vfp_dp_reg_pos pos)
7666 {
7667   int    reg;
7668   char * start = *str;
7669
7670   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7671     {
7672       switch (pos)
7673         {
7674         case VFP_REG_Dd:
7675           inst.instruction |= reg << 12;
7676           break;
7677
7678         case VFP_REG_Dn:
7679           inst.instruction |= reg << 16;
7680           break;
7681
7682         case VFP_REG_Dm:
7683           inst.instruction |= reg << 0;
7684           break;
7685
7686         default:
7687           abort ();
7688         }
7689       return reg;
7690     }
7691
7692   /* In the few cases where we might be able to accept something else
7693      this error can be overridden.  */
7694   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7695
7696   /* Restore the start point.  */
7697   *str = start;
7698   return FAIL;
7699 }
7700
7701 static void
7702 do_vfp_sp_monadic (char * str)
7703 {
7704   skip_whitespace (str);
7705
7706   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7707     return;
7708
7709   if (skip_past_comma (&str) == FAIL
7710       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7711     {
7712       if (! inst.error)
7713         inst.error = BAD_ARGS;
7714       return;
7715     }
7716
7717   end_of_line (str);
7718 }
7719
7720 static void
7721 do_vfp_dp_monadic (char * str)
7722 {
7723   skip_whitespace (str);
7724
7725   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7726     return;
7727
7728   if (skip_past_comma (&str) == FAIL
7729       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7730     {
7731       if (! inst.error)
7732         inst.error = BAD_ARGS;
7733       return;
7734     }
7735
7736   end_of_line (str);
7737 }
7738
7739 static void
7740 do_vfp_sp_dyadic (char * str)
7741 {
7742   skip_whitespace (str);
7743
7744   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7745     return;
7746
7747   if (skip_past_comma (&str) == FAIL
7748       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7749       || skip_past_comma (&str) == FAIL
7750       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7751     {
7752       if (! inst.error)
7753         inst.error = BAD_ARGS;
7754       return;
7755     }
7756
7757   end_of_line (str);
7758 }
7759
7760 static void
7761 do_vfp_dp_dyadic (char * str)
7762 {
7763   skip_whitespace (str);
7764
7765   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7766     return;
7767
7768   if (skip_past_comma (&str) == FAIL
7769       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7770       || skip_past_comma (&str) == FAIL
7771       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7772     {
7773       if (! inst.error)
7774         inst.error = BAD_ARGS;
7775       return;
7776     }
7777
7778   end_of_line (str);
7779 }
7780
7781 static void
7782 do_vfp_reg_from_sp (char * str)
7783 {
7784   skip_whitespace (str);
7785
7786   if (reg_required_here (&str, 12) == FAIL)
7787     return;
7788
7789   if (skip_past_comma (&str) == FAIL
7790       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7791     {
7792       if (! inst.error)
7793         inst.error = BAD_ARGS;
7794       return;
7795     }
7796
7797   end_of_line (str);
7798 }
7799
7800 /* Parse a VFP register list.  If the string is invalid return FAIL.
7801    Otherwise return the number of registers, and set PBASE to the first
7802    register.  Double precision registers are matched if DP is nonzero.  */
7803
7804 static int
7805 vfp_parse_reg_list (char **str, int *pbase, int dp)
7806 {
7807   int base_reg;
7808   int new_base;
7809   int regtype;
7810   int max_regs;
7811   int count = 0;
7812   int warned = 0;
7813   unsigned long mask = 0;
7814   int i;
7815
7816   if (**str != '{')
7817     return FAIL;
7818
7819   (*str)++;
7820   skip_whitespace (*str);
7821
7822   if (dp)
7823     {
7824       regtype = REG_TYPE_DN;
7825       max_regs = 16;
7826     }
7827   else
7828     {
7829       regtype = REG_TYPE_SN;
7830       max_regs = 32;
7831     }
7832
7833   base_reg = max_regs;
7834
7835   do
7836     {
7837       new_base = arm_reg_parse (str, all_reg_maps[regtype].htab);
7838       if (new_base == FAIL)
7839         {
7840           inst.error = _(all_reg_maps[regtype].expected);
7841           return FAIL;
7842         }
7843
7844       if (new_base < base_reg)
7845         base_reg = new_base;
7846
7847       if (mask & (1 << new_base))
7848         {
7849           inst.error = _("invalid register list");
7850           return FAIL;
7851         }
7852
7853       if ((mask >> new_base) != 0 && ! warned)
7854         {
7855           as_tsktsk (_("register list not in ascending order"));
7856           warned = 1;
7857         }
7858
7859       mask |= 1 << new_base;
7860       count++;
7861
7862       skip_whitespace (*str);
7863
7864       if (**str == '-') /* We have the start of a range expression */
7865         {
7866           int high_range;
7867
7868           (*str)++;
7869
7870           if ((high_range
7871                = arm_reg_parse (str, all_reg_maps[regtype].htab))
7872               == FAIL)
7873             {
7874               inst.error = _(all_reg_maps[regtype].expected);
7875               return FAIL;
7876             }
7877
7878           if (high_range <= new_base)
7879             {
7880               inst.error = _("register range not in ascending order");
7881               return FAIL;
7882             }
7883
7884           for (new_base++; new_base <= high_range; new_base++)
7885             {
7886               if (mask & (1 << new_base))
7887                 {
7888                   inst.error = _("invalid register list");
7889                   return FAIL;
7890                 }
7891
7892               mask |= 1 << new_base;
7893               count++;
7894             }
7895         }
7896     }
7897   while (skip_past_comma (str) != FAIL);
7898
7899   (*str)++;
7900
7901   /* Sanity check -- should have raised a parse error above.  */
7902   if (count == 0 || count > max_regs)
7903     abort ();
7904
7905   *pbase = base_reg;
7906
7907   /* Final test -- the registers must be consecutive.  */
7908   mask >>= base_reg;
7909   for (i = 0; i < count; i++)
7910     {
7911       if ((mask & (1u << i)) == 0)
7912         {
7913           inst.error = _("non-contiguous register range");
7914           return FAIL;
7915         }
7916     }
7917
7918   return count;
7919 }
7920
7921 static void
7922 do_vfp_reg2_from_sp2 (char * str)
7923 {
7924   int reg;
7925
7926   skip_whitespace (str);
7927
7928   if (reg_required_here (&str, 12) == FAIL
7929       || skip_past_comma (&str) == FAIL
7930       || reg_required_here (&str, 16) == FAIL
7931       || skip_past_comma (&str) == FAIL)
7932     {
7933       if (! inst.error)
7934         inst.error = BAD_ARGS;
7935       return;
7936     }
7937
7938   /* We require exactly two consecutive SP registers.  */
7939   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7940     {
7941       if (! inst.error)
7942         inst.error = _("only two consecutive VFP SP registers allowed here");
7943     }
7944   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7945
7946   end_of_line (str);
7947 }
7948
7949 static void
7950 do_vfp_sp_from_reg (char * str)
7951 {
7952   skip_whitespace (str);
7953
7954   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7955     return;
7956
7957   if (skip_past_comma (&str) == FAIL
7958       || reg_required_here (&str, 12) == FAIL)
7959     {
7960       if (! inst.error)
7961         inst.error = BAD_ARGS;
7962       return;
7963     }
7964
7965   end_of_line (str);
7966 }
7967
7968 static void
7969 do_vfp_sp2_from_reg2 (char * str)
7970 {
7971   int reg;
7972
7973   skip_whitespace (str);
7974
7975   /* We require exactly two consecutive SP registers.  */
7976   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7977     {
7978       if (! inst.error)
7979         inst.error = _("only two consecutive VFP SP registers allowed here");
7980     }
7981   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7982
7983   if (skip_past_comma (&str) == FAIL
7984       || reg_required_here (&str, 12) == FAIL
7985       || skip_past_comma (&str) == FAIL
7986       || reg_required_here (&str, 16) == FAIL)
7987     {
7988       if (! inst.error)
7989         inst.error = BAD_ARGS;
7990       return;
7991     }
7992
7993   end_of_line (str);
7994 }
7995
7996 static void
7997 do_vfp_reg_from_dp (char * str)
7998 {
7999   skip_whitespace (str);
8000
8001   if (reg_required_here (&str, 12) == FAIL)
8002     return;
8003
8004   if (skip_past_comma (&str) == FAIL
8005       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
8006     {
8007       if (! inst.error)
8008         inst.error = BAD_ARGS;
8009       return;
8010     }
8011
8012   end_of_line (str);
8013 }
8014
8015 static void
8016 do_vfp_reg2_from_dp (char * str)
8017 {
8018   skip_whitespace (str);
8019
8020   if (reg_required_here (&str, 12) == FAIL)
8021     return;
8022
8023   if (skip_past_comma (&str) == FAIL
8024       || reg_required_here (&str, 16) == FAIL
8025       || skip_past_comma (&str) == FAIL
8026       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8027     {
8028       if (! inst.error)
8029         inst.error = BAD_ARGS;
8030       return;
8031     }
8032
8033   end_of_line (str);
8034 }
8035
8036 static void
8037 do_vfp_dp_from_reg (char * str)
8038 {
8039   skip_whitespace (str);
8040
8041   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
8042     return;
8043
8044   if (skip_past_comma (&str) == FAIL
8045       || reg_required_here (&str, 12) == FAIL)
8046     {
8047       if (! inst.error)
8048         inst.error = BAD_ARGS;
8049       return;
8050     }
8051
8052   end_of_line (str);
8053 }
8054
8055 static void
8056 do_vfp_dp_from_reg2 (char * str)
8057 {
8058   skip_whitespace (str);
8059
8060   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8061     return;
8062
8063   if (skip_past_comma (&str) == FAIL
8064       || reg_required_here (&str, 12) == FAIL
8065       || skip_past_comma (&str) == FAIL
8066       || reg_required_here (&str, 16) == FAIL)
8067     {
8068       if (! inst.error)
8069         inst.error = BAD_ARGS;
8070       return;
8071     }
8072
8073   end_of_line (str);
8074 }
8075
8076 static const struct vfp_reg *
8077 vfp_psr_parse (char ** str)
8078 {
8079   char *start = *str;
8080   char  c;
8081   char *p;
8082   const struct vfp_reg *vreg;
8083
8084   p = start;
8085
8086   /* Find the end of the current token.  */
8087   do
8088     {
8089       c = *p++;
8090     }
8091   while (ISALPHA (c));
8092
8093   /* Mark it.  */
8094   *--p = 0;
8095
8096   for (vreg = vfp_regs + 0;
8097        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
8098        vreg++)
8099     {
8100       if (streq (start, vreg->name))
8101         {
8102           *p = c;
8103           *str = p;
8104           return vreg;
8105         }
8106     }
8107
8108   *p = c;
8109   return NULL;
8110 }
8111
8112 static int
8113 vfp_psr_required_here (char ** str)
8114 {
8115   char *start = *str;
8116   const struct vfp_reg *vreg;
8117
8118   vreg = vfp_psr_parse (str);
8119
8120   if (vreg)
8121     {
8122       inst.instruction |= vreg->regno;
8123       return SUCCESS;
8124     }
8125
8126   inst.error = _("VFP system register expected");
8127
8128   *str = start;
8129   return FAIL;
8130 }
8131
8132 static void
8133 do_vfp_reg_from_ctrl (char * str)
8134 {
8135   skip_whitespace (str);
8136
8137   if (reg_required_here (&str, 12) == FAIL)
8138     return;
8139
8140   if (skip_past_comma (&str) == FAIL
8141       || vfp_psr_required_here (&str) == FAIL)
8142     {
8143       if (! inst.error)
8144         inst.error = BAD_ARGS;
8145       return;
8146     }
8147
8148   end_of_line (str);
8149 }
8150
8151 static void
8152 do_vfp_ctrl_from_reg (char * str)
8153 {
8154   skip_whitespace (str);
8155
8156   if (vfp_psr_required_here (&str) == FAIL)
8157     return;
8158
8159   if (skip_past_comma (&str) == FAIL
8160       || reg_required_here (&str, 12) == FAIL)
8161     {
8162       if (! inst.error)
8163         inst.error = BAD_ARGS;
8164       return;
8165     }
8166
8167   end_of_line (str);
8168 }
8169
8170 static void
8171 do_vfp_sp_ldst (char * str)
8172 {
8173   skip_whitespace (str);
8174
8175   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8176     {
8177       if (!inst.error)
8178         inst.error = BAD_ARGS;
8179       return;
8180     }
8181
8182   if (skip_past_comma (&str) == FAIL
8183       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8184     {
8185       if (!inst.error)
8186         inst.error = BAD_ARGS;
8187       return;
8188     }
8189
8190   end_of_line (str);
8191 }
8192
8193 static void
8194 do_vfp_dp_ldst (char * str)
8195 {
8196   skip_whitespace (str);
8197
8198   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8199     {
8200       if (!inst.error)
8201         inst.error = BAD_ARGS;
8202       return;
8203     }
8204
8205   if (skip_past_comma (&str) == FAIL
8206       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
8207     {
8208       if (!inst.error)
8209         inst.error = BAD_ARGS;
8210       return;
8211     }
8212
8213   end_of_line (str);
8214 }
8215
8216
8217 static void
8218 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
8219 {
8220   int count;
8221   int reg;
8222
8223   skip_whitespace (str);
8224
8225   if (reg_required_here (&str, 16) == FAIL)
8226     return;
8227
8228   skip_whitespace (str);
8229
8230   if (*str == '!')
8231     {
8232       inst.instruction |= WRITE_BACK;
8233       str++;
8234     }
8235   else if (ldstm_type != VFP_LDSTMIA)
8236     {
8237       inst.error = _("this addressing mode requires base-register writeback");
8238       return;
8239     }
8240
8241   if (skip_past_comma (&str) == FAIL
8242       || (count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
8243     {
8244       if (!inst.error)
8245         inst.error = BAD_ARGS;
8246       return;
8247     }
8248   vfp_sp_encode_reg (reg, VFP_REG_Sd);
8249
8250   inst.instruction |= count;
8251   end_of_line (str);
8252 }
8253
8254 static void
8255 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
8256 {
8257   int count;
8258   int reg;
8259
8260   skip_whitespace (str);
8261
8262   if (reg_required_here (&str, 16) == FAIL)
8263     return;
8264
8265   skip_whitespace (str);
8266
8267   if (*str == '!')
8268     {
8269       inst.instruction |= WRITE_BACK;
8270       str++;
8271     }
8272   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
8273     {
8274       inst.error = _("this addressing mode requires base-register writeback");
8275       return;
8276     }
8277
8278   if (skip_past_comma (&str) == FAIL
8279       || (count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
8280     {
8281       if (!inst.error)
8282         inst.error = BAD_ARGS;
8283       return;
8284     }
8285
8286   count <<= 1;
8287   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
8288     count += 1;
8289
8290   inst.instruction |= (reg << 12) | count;
8291   end_of_line (str);
8292 }
8293
8294 static void
8295 do_vfp_sp_ldstmia (char * str)
8296 {
8297   vfp_sp_ldstm (str, VFP_LDSTMIA);
8298 }
8299
8300 static void
8301 do_vfp_sp_ldstmdb (char * str)
8302 {
8303   vfp_sp_ldstm (str, VFP_LDSTMDB);
8304 }
8305
8306 static void
8307 do_vfp_dp_ldstmia (char * str)
8308 {
8309   vfp_dp_ldstm (str, VFP_LDSTMIA);
8310 }
8311
8312 static void
8313 do_vfp_dp_ldstmdb (char * str)
8314 {
8315   vfp_dp_ldstm (str, VFP_LDSTMDB);
8316 }
8317
8318 static void
8319 do_vfp_xp_ldstmia (char *str)
8320 {
8321   vfp_dp_ldstm (str, VFP_LDSTMIAX);
8322 }
8323
8324 static void
8325 do_vfp_xp_ldstmdb (char * str)
8326 {
8327   vfp_dp_ldstm (str, VFP_LDSTMDBX);
8328 }
8329
8330 static void
8331 do_vfp_sp_compare_z (char * str)
8332 {
8333   skip_whitespace (str);
8334
8335   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8336     {
8337       if (!inst.error)
8338         inst.error = BAD_ARGS;
8339       return;
8340     }
8341
8342   end_of_line (str);
8343 }
8344
8345 static void
8346 do_vfp_dp_compare_z (char * str)
8347 {
8348   skip_whitespace (str);
8349
8350   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8351     {
8352       if (!inst.error)
8353         inst.error = BAD_ARGS;
8354       return;
8355     }
8356
8357   end_of_line (str);
8358 }
8359
8360 static void
8361 do_vfp_dp_sp_cvt (char * str)
8362 {
8363   skip_whitespace (str);
8364
8365   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8366     return;
8367
8368   if (skip_past_comma (&str) == FAIL
8369       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8370     {
8371       if (! inst.error)
8372         inst.error = BAD_ARGS;
8373       return;
8374     }
8375
8376   end_of_line (str);
8377 }
8378
8379 static void
8380 do_vfp_sp_dp_cvt (char * str)
8381 {
8382   skip_whitespace (str);
8383
8384   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8385     return;
8386
8387   if (skip_past_comma (&str) == FAIL
8388       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8389     {
8390       if (! inst.error)
8391         inst.error = BAD_ARGS;
8392       return;
8393     }
8394
8395   end_of_line (str);
8396 }
8397
8398 /* Thumb specific routines.  */
8399
8400 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8401    was SUB.  */
8402
8403 static void
8404 thumb_add_sub (char * str, int subtract)
8405 {
8406   int Rd, Rs, Rn = FAIL;
8407
8408   skip_whitespace (str);
8409
8410   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8411       || skip_past_comma (&str) == FAIL)
8412     {
8413       if (! inst.error)
8414         inst.error = BAD_ARGS;
8415       return;
8416     }
8417
8418   if (is_immediate_prefix (*str))
8419     {
8420       Rs = Rd;
8421       str++;
8422       if (my_get_expression (&inst.reloc.exp, &str))
8423         return;
8424     }
8425   else
8426     {
8427       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8428         return;
8429
8430       if (skip_past_comma (&str) == FAIL)
8431         {
8432           /* Two operand format, shuffle the registers
8433              and pretend there are 3.  */
8434           Rn = Rs;
8435           Rs = Rd;
8436         }
8437       else if (is_immediate_prefix (*str))
8438         {
8439           str++;
8440           if (my_get_expression (&inst.reloc.exp, &str))
8441             return;
8442         }
8443       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8444         return;
8445     }
8446
8447   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8448      for the latter case, EXPR contains the immediate that was found.  */
8449   if (Rn != FAIL)
8450     {
8451       /* All register format.  */
8452       if (Rd > 7 || Rs > 7 || Rn > 7)
8453         {
8454           if (Rs != Rd)
8455             {
8456               inst.error = _("dest and source1 must be the same register");
8457               return;
8458             }
8459
8460           /* Can't do this for SUB.  */
8461           if (subtract)
8462             {
8463               inst.error = _("subtract valid only on lo regs");
8464               return;
8465             }
8466
8467           inst.instruction = (T_OPCODE_ADD_HI
8468                               | (Rd > 7 ? THUMB_H1 : 0)
8469                               | (Rn > 7 ? THUMB_H2 : 0));
8470           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8471         }
8472       else
8473         {
8474           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8475           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8476         }
8477     }
8478   else
8479     {
8480       /* Immediate expression, now things start to get nasty.  */
8481
8482       /* First deal with HI regs, only very restricted cases allowed:
8483          Adjusting SP, and using PC or SP to get an address.  */
8484       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8485           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8486         {
8487           inst.error = _("invalid Hi register with immediate");
8488           return;
8489         }
8490
8491       if (inst.reloc.exp.X_op != O_constant)
8492         {
8493           /* Value isn't known yet, all we can do is store all the fragments
8494              we know about in the instruction and let the reloc hacking
8495              work it all out.  */
8496           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8497           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8498         }
8499       else
8500         {
8501           int offset = inst.reloc.exp.X_add_number;
8502
8503           if (subtract)
8504             offset = - offset;
8505
8506           if (offset < 0)
8507             {
8508               offset = - offset;
8509               subtract = 1;
8510
8511               /* Quick check, in case offset is MIN_INT.  */
8512               if (offset < 0)
8513                 {
8514                   inst.error = _("immediate value out of range");
8515                   return;
8516                 }
8517             }
8518           /* Note - you cannot convert a subtract of 0 into an
8519              add of 0 because the carry flag is set differently.  */
8520           else if (offset > 0)
8521             subtract = 0;
8522
8523           if (Rd == REG_SP)
8524             {
8525               if (offset & ~0x1fc)
8526                 {
8527                   inst.error = _("invalid immediate value for stack adjust");
8528                   return;
8529                 }
8530               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8531               inst.instruction |= offset >> 2;
8532             }
8533           else if (Rs == REG_PC || Rs == REG_SP)
8534             {
8535               if (subtract
8536                   || (offset & ~0x3fc))
8537                 {
8538                   inst.error = _("invalid immediate for address calculation");
8539                   return;
8540                 }
8541               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8542                                   : T_OPCODE_ADD_SP);
8543               inst.instruction |= (Rd << 8) | (offset >> 2);
8544             }
8545           else if (Rs == Rd)
8546             {
8547               if (offset & ~0xff)
8548                 {
8549                   inst.error = _("immediate value out of range");
8550                   return;
8551                 }
8552               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8553               inst.instruction |= (Rd << 8) | offset;
8554             }
8555           else
8556             {
8557               if (offset & ~0x7)
8558                 {
8559                   inst.error = _("immediate value out of range");
8560                   return;
8561                 }
8562               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8563               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8564             }
8565         }
8566     }
8567
8568   end_of_line (str);
8569 }
8570
8571 static void
8572 thumb_shift (char * str, int shift)
8573 {
8574   int Rd, Rs, Rn = FAIL;
8575
8576   skip_whitespace (str);
8577
8578   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8579       || skip_past_comma (&str) == FAIL)
8580     {
8581       if (! inst.error)
8582         inst.error = BAD_ARGS;
8583       return;
8584     }
8585
8586   if (is_immediate_prefix (*str))
8587     {
8588       /* Two operand immediate format, set Rs to Rd.  */
8589       Rs = Rd;
8590       str ++;
8591       if (my_get_expression (&inst.reloc.exp, &str))
8592         return;
8593     }
8594   else
8595     {
8596       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8597         return;
8598
8599       if (skip_past_comma (&str) == FAIL)
8600         {
8601           /* Two operand format, shuffle the registers
8602              and pretend there are 3.  */
8603           Rn = Rs;
8604           Rs = Rd;
8605         }
8606       else if (is_immediate_prefix (*str))
8607         {
8608           str++;
8609           if (my_get_expression (&inst.reloc.exp, &str))
8610             return;
8611         }
8612       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8613         return;
8614     }
8615
8616   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8617      for the latter case, EXPR contains the immediate that was found.  */
8618
8619   if (Rn != FAIL)
8620     {
8621       if (Rs != Rd)
8622         {
8623           inst.error = _("source1 and dest must be same register");
8624           return;
8625         }
8626
8627       switch (shift)
8628         {
8629         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8630         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8631         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8632         }
8633
8634       inst.instruction |= Rd | (Rn << 3);
8635     }
8636   else
8637     {
8638       switch (shift)
8639         {
8640         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8641         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8642         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8643         }
8644
8645       if (inst.reloc.exp.X_op != O_constant)
8646         {
8647           /* Value isn't known yet, create a dummy reloc and let reloc
8648              hacking fix it up.  */
8649           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8650         }
8651       else
8652         {
8653           unsigned shift_value = inst.reloc.exp.X_add_number;
8654
8655           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8656             {
8657               inst.error = _("invalid immediate for shift");
8658               return;
8659             }
8660
8661           /* Shifts of zero are handled by converting to LSL.  */
8662           if (shift_value == 0)
8663             inst.instruction = T_OPCODE_LSL_I;
8664
8665           /* Shifts of 32 are encoded as a shift of zero.  */
8666           if (shift_value == 32)
8667             shift_value = 0;
8668
8669           inst.instruction |= shift_value << 6;
8670         }
8671
8672       inst.instruction |= Rd | (Rs << 3);
8673     }
8674
8675   end_of_line (str);
8676 }
8677
8678 static void
8679 thumb_load_store (char * str, int load_store, int size)
8680 {
8681   int Rd, Rb, Ro = FAIL;
8682
8683   skip_whitespace (str);
8684
8685   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8686       || skip_past_comma (&str) == FAIL)
8687     {
8688       if (! inst.error)
8689         inst.error = BAD_ARGS;
8690       return;
8691     }
8692
8693   if (*str == '[')
8694     {
8695       str++;
8696       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8697         return;
8698
8699       if (skip_past_comma (&str) != FAIL)
8700         {
8701           if (is_immediate_prefix (*str))
8702             {
8703               str++;
8704               if (my_get_expression (&inst.reloc.exp, &str))
8705                 return;
8706             }
8707           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8708             return;
8709         }
8710       else
8711         {
8712           inst.reloc.exp.X_op = O_constant;
8713           inst.reloc.exp.X_add_number = 0;
8714         }
8715
8716       if (*str != ']')
8717         {
8718           inst.error = _("expected ']'");
8719           return;
8720         }
8721       str++;
8722     }
8723   else if (*str == '=')
8724     {
8725       if (load_store != THUMB_LOAD)
8726         {
8727           inst.error = _("invalid pseudo operation");
8728           return;
8729         }
8730
8731       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
8732       str++;
8733
8734       skip_whitespace (str);
8735
8736       if (my_get_expression (& inst.reloc.exp, & str))
8737         return;
8738
8739       end_of_line (str);
8740
8741       if (   inst.reloc.exp.X_op != O_constant
8742           && inst.reloc.exp.X_op != O_symbol)
8743         {
8744           inst.error = "Constant expression expected";
8745           return;
8746         }
8747
8748       if (inst.reloc.exp.X_op == O_constant
8749           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8750         {
8751           /* This can be done with a mov instruction.  */
8752
8753           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
8754           inst.instruction |= inst.reloc.exp.X_add_number;
8755           return;
8756         }
8757
8758       /* Insert into literal pool.  */
8759       if (add_to_lit_pool () == FAIL)
8760         {
8761           if (!inst.error)
8762             inst.error = "literal pool insertion failed";
8763           return;
8764         }
8765
8766       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
8767       inst.reloc.pc_rel = 1;
8768       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
8769       /* Adjust ARM pipeline offset to Thumb.  */
8770       inst.reloc.exp.X_add_number += 4;
8771
8772       return;
8773     }
8774   else
8775     {
8776       if (my_get_expression (&inst.reloc.exp, &str))
8777         return;
8778
8779       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8780       inst.reloc.pc_rel = 1;
8781       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
8782       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8783       end_of_line (str);
8784       return;
8785     }
8786
8787   if (Rb == REG_PC || Rb == REG_SP)
8788     {
8789       if (size != THUMB_WORD)
8790         {
8791           inst.error = _("byte or halfword not valid for base register");
8792           return;
8793         }
8794       else if (Rb == REG_PC && load_store != THUMB_LOAD)
8795         {
8796           inst.error = _("r15 based store not allowed");
8797           return;
8798         }
8799       else if (Ro != FAIL)
8800         {
8801           inst.error = _("invalid base register for register offset");
8802           return;
8803         }
8804
8805       if (Rb == REG_PC)
8806         inst.instruction = T_OPCODE_LDR_PC;
8807       else if (load_store == THUMB_LOAD)
8808         inst.instruction = T_OPCODE_LDR_SP;
8809       else
8810         inst.instruction = T_OPCODE_STR_SP;
8811
8812       inst.instruction |= Rd << 8;
8813       if (inst.reloc.exp.X_op == O_constant)
8814         {
8815           unsigned offset = inst.reloc.exp.X_add_number;
8816
8817           if (offset & ~0x3fc)
8818             {
8819               inst.error = _("invalid offset");
8820               return;
8821             }
8822
8823           inst.instruction |= offset >> 2;
8824         }
8825       else
8826         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8827     }
8828   else if (Rb > 7)
8829     {
8830       inst.error = _("invalid base register in load/store");
8831       return;
8832     }
8833   else if (Ro == FAIL)
8834     {
8835       /* Immediate offset.  */
8836       if (size == THUMB_WORD)
8837         inst.instruction = (load_store == THUMB_LOAD
8838                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8839       else if (size == THUMB_HALFWORD)
8840         inst.instruction = (load_store == THUMB_LOAD
8841                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8842       else
8843         inst.instruction = (load_store == THUMB_LOAD
8844                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8845
8846       inst.instruction |= Rd | (Rb << 3);
8847
8848       if (inst.reloc.exp.X_op == O_constant)
8849         {
8850           unsigned offset = inst.reloc.exp.X_add_number;
8851
8852           if (offset & ~(0x1f << size))
8853             {
8854               inst.error = _("invalid offset");
8855               return;
8856             }
8857           inst.instruction |= (offset >> size) << 6;
8858         }
8859       else
8860         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8861     }
8862   else
8863     {
8864       /* Register offset.  */
8865       if (size == THUMB_WORD)
8866         inst.instruction = (load_store == THUMB_LOAD
8867                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8868       else if (size == THUMB_HALFWORD)
8869         inst.instruction = (load_store == THUMB_LOAD
8870                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8871       else
8872         inst.instruction = (load_store == THUMB_LOAD
8873                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8874
8875       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8876     }
8877
8878   end_of_line (str);
8879 }
8880
8881 /* A register must be given at this point.
8882
8883    Shift is the place to put it in inst.instruction.
8884
8885    Restores input start point on err.
8886    Returns the reg#, or FAIL.  */
8887
8888 static int
8889 mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
8890 {
8891   int   reg;
8892   char *start = *str;
8893
8894   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8895     {
8896       if (shift >= 0)
8897         inst.instruction |= reg << shift;
8898
8899       return reg;
8900     }
8901
8902   /* Restore the start point.  */
8903   *str = start;
8904
8905   /* Try generic coprocessor name if applicable.  */
8906   if (regtype == REG_TYPE_MVF ||
8907       regtype == REG_TYPE_MVD ||
8908       regtype == REG_TYPE_MVFX ||
8909       regtype == REG_TYPE_MVDX)
8910     {
8911       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
8912         {
8913           if (shift >= 0)
8914             inst.instruction |= reg << shift;
8915
8916           return reg;
8917         }
8918
8919       /* Restore the start point.  */
8920       *str = start;
8921     }
8922
8923   /* In the few cases where we might be able to accept something else
8924      this error can be overridden.  */
8925   inst.error = _(all_reg_maps[regtype].expected);
8926
8927   return FAIL;
8928 }
8929
8930 /* Cirrus Maverick Instructions.  */
8931
8932 /* Isnsn like "foo X,Y".  */
8933
8934 static void
8935 do_mav_binops (char * str,
8936                int mode,
8937                enum arm_reg_type reg0,
8938                enum arm_reg_type reg1)
8939 {
8940   int shift0, shift1;
8941
8942   shift0 = mode & 0xff;
8943   shift1 = (mode >> 8) & 0xff;
8944
8945   skip_whitespace (str);
8946
8947   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8948       || skip_past_comma (&str) == FAIL
8949       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8950     {
8951       if (!inst.error)
8952         inst.error = BAD_ARGS;
8953     }
8954   else
8955     end_of_line (str);
8956 }
8957
8958 /* Isnsn like "foo X,Y,Z".  */
8959
8960 static void
8961 do_mav_triple (char * str,
8962                int mode,
8963                enum arm_reg_type reg0,
8964                enum arm_reg_type reg1,
8965                enum arm_reg_type reg2)
8966 {
8967   int shift0, shift1, shift2;
8968
8969   shift0 = mode & 0xff;
8970   shift1 = (mode >> 8) & 0xff;
8971   shift2 = (mode >> 16) & 0xff;
8972
8973   skip_whitespace (str);
8974
8975   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8976       || skip_past_comma (&str) == FAIL
8977       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8978       || skip_past_comma (&str) == FAIL
8979       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8980     {
8981       if (!inst.error)
8982         inst.error = BAD_ARGS;
8983     }
8984   else
8985     end_of_line (str);
8986 }
8987
8988 /* Wrapper functions.  */
8989
8990 static void
8991 do_mav_binops_1a (char * str)
8992 {
8993   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8994 }
8995
8996 static void
8997 do_mav_binops_1b (char * str)
8998 {
8999   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
9000 }
9001
9002 static void
9003 do_mav_binops_1c (char * str)
9004 {
9005   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
9006 }
9007
9008 static void
9009 do_mav_binops_1d (char * str)
9010 {
9011   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
9012 }
9013
9014 static void
9015 do_mav_binops_1e (char * str)
9016 {
9017   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
9018 }
9019
9020 static void
9021 do_mav_binops_1f (char * str)
9022 {
9023   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
9024 }
9025
9026 static void
9027 do_mav_binops_1g (char * str)
9028 {
9029   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
9030 }
9031
9032 static void
9033 do_mav_binops_1h (char * str)
9034 {
9035   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
9036 }
9037
9038 static void
9039 do_mav_binops_1i (char * str)
9040 {
9041   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
9042 }
9043
9044 static void
9045 do_mav_binops_1j (char * str)
9046 {
9047   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
9048 }
9049
9050 static void
9051 do_mav_binops_1k (char * str)
9052 {
9053   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
9054 }
9055
9056 static void
9057 do_mav_binops_1l (char * str)
9058 {
9059   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
9060 }
9061
9062 static void
9063 do_mav_binops_1m (char * str)
9064 {
9065   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
9066 }
9067
9068 static void
9069 do_mav_binops_1n (char * str)
9070 {
9071   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
9072 }
9073
9074 static void
9075 do_mav_binops_1o (char * str)
9076 {
9077   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
9078 }
9079
9080 static void
9081 do_mav_binops_2a (char * str)
9082 {
9083   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
9084 }
9085
9086 static void
9087 do_mav_binops_2b (char * str)
9088 {
9089   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
9090 }
9091
9092 static void
9093 do_mav_binops_2c (char * str)
9094 {
9095   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
9096 }
9097
9098 static void
9099 do_mav_binops_3a (char * str)
9100 {
9101   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
9102 }
9103
9104 static void
9105 do_mav_binops_3b (char * str)
9106 {
9107   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
9108 }
9109
9110 static void
9111 do_mav_binops_3c (char * str)
9112 {
9113   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
9114 }
9115
9116 static void
9117 do_mav_binops_3d (char * str)
9118 {
9119   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
9120 }
9121
9122 static void
9123 do_mav_triple_4a (char * str)
9124 {
9125   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
9126 }
9127
9128 static void
9129 do_mav_triple_4b (char * str)
9130 {
9131   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
9132 }
9133
9134 static void
9135 do_mav_triple_5a (char * str)
9136 {
9137   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
9138 }
9139
9140 static void
9141 do_mav_triple_5b (char * str)
9142 {
9143   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
9144 }
9145
9146 static void
9147 do_mav_triple_5c (char * str)
9148 {
9149   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
9150 }
9151
9152 static void
9153 do_mav_triple_5d (char * str)
9154 {
9155   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
9156 }
9157
9158 static void
9159 do_mav_triple_5e (char * str)
9160 {
9161   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
9162 }
9163
9164 static void
9165 do_mav_triple_5f (char * str)
9166 {
9167   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
9168 }
9169
9170 static void
9171 do_mav_triple_5g (char * str)
9172 {
9173   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
9174 }
9175
9176 static void
9177 do_mav_triple_5h (char * str)
9178 {
9179   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
9180 }
9181
9182 /* Isnsn like "foo W,X,Y,Z".
9183     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
9184
9185 static void
9186 do_mav_quad (char * str,
9187              int mode,
9188              enum arm_reg_type reg0,
9189              enum arm_reg_type reg1,
9190              enum arm_reg_type reg2,
9191              enum arm_reg_type reg3)
9192 {
9193   int shift0, shift1, shift2, shift3;
9194
9195   shift0= mode & 0xff;
9196   shift1 = (mode >> 8) & 0xff;
9197   shift2 = (mode >> 16) & 0xff;
9198   shift3 = (mode >> 24) & 0xff;
9199
9200   skip_whitespace (str);
9201
9202   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9203       || skip_past_comma (&str) == FAIL
9204       || mav_reg_required_here (&str, shift1, reg1) == FAIL
9205       || skip_past_comma (&str) == FAIL
9206       || mav_reg_required_here (&str, shift2, reg2) == FAIL
9207       || skip_past_comma (&str) == FAIL
9208       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
9209     {
9210       if (!inst.error)
9211         inst.error = BAD_ARGS;
9212     }
9213   else
9214     end_of_line (str);
9215 }
9216
9217 static void
9218 do_mav_quad_6a (char * str)
9219 {
9220   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
9221                REG_TYPE_MVFX);
9222 }
9223
9224 static void
9225 do_mav_quad_6b (char * str)
9226 {
9227   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
9228                REG_TYPE_MVFX);
9229 }
9230
9231 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
9232 static void
9233 do_mav_dspsc_1 (char * str)
9234 {
9235   skip_whitespace (str);
9236
9237   /* cfmvsc32.  */
9238   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
9239       || skip_past_comma (&str) == FAIL
9240       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
9241     {
9242       if (!inst.error)
9243         inst.error = BAD_ARGS;
9244
9245       return;
9246     }
9247
9248   end_of_line (str);
9249 }
9250
9251 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
9252 static void
9253 do_mav_dspsc_2 (char * str)
9254 {
9255   skip_whitespace (str);
9256
9257   /* cfmv32sc.  */
9258   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
9259       || skip_past_comma (&str) == FAIL
9260       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
9261     {
9262       if (!inst.error)
9263         inst.error = BAD_ARGS;
9264
9265       return;
9266     }
9267
9268   end_of_line (str);
9269 }
9270
9271 /* Maverick shift immediate instructions.
9272    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
9273    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
9274
9275 static void
9276 do_mav_shift (char * str,
9277               enum arm_reg_type reg0,
9278               enum arm_reg_type reg1)
9279 {
9280   int error;
9281   int imm, neg = 0;
9282
9283   skip_whitespace (str);
9284
9285   error = 0;
9286
9287   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9288       || skip_past_comma (&str) == FAIL
9289       || mav_reg_required_here (&str, 16, reg1) == FAIL
9290       || skip_past_comma  (&str) == FAIL)
9291     {
9292       if (!inst.error)
9293         inst.error = BAD_ARGS;
9294       return;
9295     }
9296
9297   /* Calculate the immediate operand.
9298      The operand is a 7bit signed number.  */
9299   skip_whitespace (str);
9300
9301   if (*str == '#')
9302     ++str;
9303
9304   if (!ISDIGIT (*str) && *str != '-')
9305     {
9306       inst.error = _("expecting immediate, 7bit operand");
9307       return;
9308     }
9309
9310   if (*str == '-')
9311     {
9312       neg = 1;
9313       ++str;
9314     }
9315
9316   for (imm = 0; *str && ISDIGIT (*str); ++str)
9317     imm = imm * 10 + *str - '0';
9318
9319   if (imm > 64)
9320     {
9321       inst.error = _("immediate out of range");
9322       return;
9323     }
9324
9325   /* Make negative imm's into 7bit signed numbers.  */
9326   if (neg)
9327     {
9328       imm = -imm;
9329       imm &= 0x0000007f;
9330     }
9331
9332   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9333      Bits 5-7 of the insn should have bits 4-6 of the immediate.
9334      Bit 4 should be 0.  */
9335   imm = (imm & 0xf) | ((imm & 0x70) << 1);
9336
9337   inst.instruction |= imm;
9338   end_of_line (str);
9339 }
9340
9341 static void
9342 do_mav_shift_1 (char * str)
9343 {
9344   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9345 }
9346
9347 static void
9348 do_mav_shift_2 (char * str)
9349 {
9350   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9351 }
9352
9353 static int
9354 mav_parse_offset (char ** str, int * negative)
9355 {
9356   char * p = *str;
9357   int offset;
9358
9359   *negative = 0;
9360
9361   skip_whitespace (p);
9362
9363   if (*p == '#')
9364     ++p;
9365
9366   if (*p == '-')
9367     {
9368       *negative = 1;
9369       ++p;
9370     }
9371
9372   if (!ISDIGIT (*p))
9373     {
9374       inst.error = _("offset expected");
9375       return 0;
9376     }
9377
9378   for (offset = 0; *p && ISDIGIT (*p); ++p)
9379     offset = offset * 10 + *p - '0';
9380
9381   if (offset > 0x3fc)
9382     {
9383       inst.error = _("offset out of range");
9384       return 0;
9385     }
9386   if (offset & 0x3)
9387     {
9388       inst.error = _("offset not a multiple of 4");
9389       return 0;
9390     }
9391
9392   *str = p;
9393
9394   return *negative ? -offset : offset;
9395 }
9396
9397 /* Maverick load/store instructions.
9398   <insn><cond> CRd,[Rn,<offset>]{!}.
9399   <insn><cond> CRd,[Rn],<offset>.  */
9400
9401 static void
9402 do_mav_ldst (char * str, enum arm_reg_type reg0)
9403 {
9404   int offset, negative;
9405
9406   skip_whitespace (str);
9407
9408   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9409       || skip_past_comma (&str) == FAIL
9410       || *str++ != '['
9411       || reg_required_here (&str, 16) == FAIL)
9412     goto fail_ldst;
9413
9414   if (skip_past_comma (&str) == SUCCESS)
9415     {
9416       /* You are here: "<offset>]{!}".  */
9417       inst.instruction |= PRE_INDEX;
9418
9419       offset = mav_parse_offset (&str, &negative);
9420
9421       if (inst.error)
9422         return;
9423
9424       if (*str++ != ']')
9425         {
9426           inst.error = _("missing ]");
9427           return;
9428         }
9429
9430       if (*str == '!')
9431         {
9432           inst.instruction |= WRITE_BACK;
9433           ++str;
9434         }
9435     }
9436   else
9437     {
9438       /* You are here: "], <offset>".  */
9439       if (*str++ != ']')
9440         {
9441           inst.error = _("missing ]");
9442           return;
9443         }
9444
9445       if (skip_past_comma (&str) == FAIL
9446           || (offset = mav_parse_offset (&str, &negative), inst.error))
9447         goto fail_ldst;
9448
9449       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
9450     }
9451
9452   if (negative)
9453     offset = -offset;
9454   else
9455     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
9456
9457   inst.instruction |= offset >> 2;
9458   end_of_line (str);
9459   return;
9460
9461 fail_ldst:
9462   if (!inst.error)
9463      inst.error = BAD_ARGS;
9464 }
9465
9466 static void
9467 do_mav_ldst_1 (char * str)
9468 {
9469   do_mav_ldst (str, REG_TYPE_MVF);
9470 }
9471
9472 static void
9473 do_mav_ldst_2 (char * str)
9474 {
9475   do_mav_ldst (str, REG_TYPE_MVD);
9476 }
9477
9478 static void
9479 do_mav_ldst_3 (char * str)
9480 {
9481   do_mav_ldst (str, REG_TYPE_MVFX);
9482 }
9483
9484 static void
9485 do_mav_ldst_4 (char * str)
9486 {
9487   do_mav_ldst (str, REG_TYPE_MVDX);
9488 }
9489
9490 static void
9491 do_t_nop (char * str)
9492 {
9493   /* Do nothing.  */
9494   end_of_line (str);
9495 }
9496
9497 /* Handle the Format 4 instructions that do not have equivalents in other
9498    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9499    BIC and MVN.  */
9500
9501 static void
9502 do_t_arit (char * str)
9503 {
9504   int Rd, Rs, Rn;
9505
9506   skip_whitespace (str);
9507
9508   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9509       || skip_past_comma (&str) == FAIL
9510       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9511     {
9512       inst.error = BAD_ARGS;
9513       return;
9514     }
9515
9516   if (skip_past_comma (&str) != FAIL)
9517     {
9518       /* Three operand format not allowed for TST, CMN, NEG and MVN.
9519          (It isn't allowed for CMP either, but that isn't handled by this
9520          function.)  */
9521       if (inst.instruction == T_OPCODE_TST
9522           || inst.instruction == T_OPCODE_CMN
9523           || inst.instruction == T_OPCODE_NEG
9524           || inst.instruction == T_OPCODE_MVN)
9525         {
9526           inst.error = BAD_ARGS;
9527           return;
9528         }
9529
9530       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9531         return;
9532
9533       if (Rs != Rd)
9534         {
9535           inst.error = _("dest and source1 must be the same register");
9536           return;
9537         }
9538       Rs = Rn;
9539     }
9540
9541   if (inst.instruction == T_OPCODE_MUL
9542       && Rs == Rd)
9543     as_tsktsk (_("Rs and Rd must be different in MUL"));
9544
9545   inst.instruction |= Rd | (Rs << 3);
9546   end_of_line (str);
9547 }
9548
9549 static void
9550 do_t_add (char * str)
9551 {
9552   thumb_add_sub (str, 0);
9553 }
9554
9555 static void
9556 do_t_asr (char * str)
9557 {
9558   thumb_shift (str, THUMB_ASR);
9559 }
9560
9561 static void
9562 do_t_branch9 (char * str)
9563 {
9564   if (my_get_expression (&inst.reloc.exp, &str))
9565     return;
9566   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9567   inst.reloc.pc_rel = 1;
9568   end_of_line (str);
9569 }
9570
9571 static void
9572 do_t_branch12 (char * str)
9573 {
9574   if (my_get_expression (&inst.reloc.exp, &str))
9575     return;
9576   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9577   inst.reloc.pc_rel = 1;
9578   end_of_line (str);
9579 }
9580
9581 /* Find the real, Thumb encoded start of a Thumb function.  */
9582
9583 static symbolS *
9584 find_real_start (symbolS * symbolP)
9585 {
9586   char *       real_start;
9587   const char * name = S_GET_NAME (symbolP);
9588   symbolS *    new_target;
9589
9590   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
9591 #define STUB_NAME ".real_start_of"
9592
9593   if (name == NULL)
9594     abort ();
9595
9596   /* Names that start with '.' are local labels, not function entry points.
9597      The compiler may generate BL instructions to these labels because it
9598      needs to perform a branch to a far away location.  */
9599   if (name[0] == '.')
9600     return symbolP;
9601
9602   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9603   sprintf (real_start, "%s%s", STUB_NAME, name);
9604
9605   new_target = symbol_find (real_start);
9606
9607   if (new_target == NULL)
9608     {
9609       as_warn ("Failed to find real start of function: %s\n", name);
9610       new_target = symbolP;
9611     }
9612
9613   free (real_start);
9614
9615   return new_target;
9616 }
9617
9618 static void
9619 do_t_branch23 (char * str)
9620 {
9621   if (my_get_expression (& inst.reloc.exp, & str))
9622     return;
9623
9624   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
9625   inst.reloc.pc_rel = 1;
9626   end_of_line (str);
9627
9628   /* If the destination of the branch is a defined symbol which does not have
9629      the THUMB_FUNC attribute, then we must be calling a function which has
9630      the (interfacearm) attribute.  We look for the Thumb entry point to that
9631      function and change the branch to refer to that function instead.  */
9632   if (   inst.reloc.exp.X_op == O_symbol
9633       && inst.reloc.exp.X_add_symbol != NULL
9634       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9635       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9636     inst.reloc.exp.X_add_symbol =
9637       find_real_start (inst.reloc.exp.X_add_symbol);
9638 }
9639
9640 static void
9641 do_t_bx (char * str)
9642 {
9643   int reg;
9644
9645   skip_whitespace (str);
9646
9647   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9648     return;
9649
9650   /* This sets THUMB_H2 from the top bit of reg.  */
9651   inst.instruction |= reg << 3;
9652
9653   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
9654      should cause the alignment to be checked once it is known.  This is
9655      because BX PC only works if the instruction is word aligned.  */
9656
9657   end_of_line (str);
9658 }
9659
9660 static void
9661 do_t_compare (char * str)
9662 {
9663   thumb_mov_compare (str, THUMB_COMPARE);
9664 }
9665
9666 static void
9667 do_t_ldmstm (char * str)
9668 {
9669   int Rb;
9670   long range;
9671
9672   skip_whitespace (str);
9673
9674   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9675     return;
9676
9677   if (*str != '!')
9678     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9679   else
9680     str++;
9681
9682   if (skip_past_comma (&str) == FAIL
9683       || (range = reg_list (&str)) == FAIL)
9684     {
9685       if (! inst.error)
9686         inst.error = BAD_ARGS;
9687       return;
9688     }
9689
9690   if (inst.reloc.type != BFD_RELOC_UNUSED)
9691     {
9692       /* This really doesn't seem worth it.  */
9693       inst.reloc.type = BFD_RELOC_UNUSED;
9694       inst.error = _("expression too complex");
9695       return;
9696     }
9697
9698   if (range & ~0xff)
9699     {
9700       inst.error = _("only lo-regs valid in load/store multiple");
9701       return;
9702     }
9703
9704   inst.instruction |= (Rb << 8) | range;
9705   end_of_line (str);
9706 }
9707
9708 static void
9709 do_t_ldr (char * str)
9710 {
9711   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9712 }
9713
9714 static void
9715 do_t_ldrb (char * str)
9716 {
9717   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9718 }
9719
9720 static void
9721 do_t_ldrh (char * str)
9722 {
9723   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9724 }
9725
9726 static void
9727 do_t_lds (char * str)
9728 {
9729   int Rd, Rb, Ro;
9730
9731   skip_whitespace (str);
9732
9733   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9734       || skip_past_comma (&str) == FAIL
9735       || *str++ != '['
9736       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9737       || skip_past_comma (&str) == FAIL
9738       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9739       || *str++ != ']')
9740     {
9741       if (! inst.error)
9742         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9743       return;
9744     }
9745
9746   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9747   end_of_line (str);
9748 }
9749
9750 static void
9751 do_t_lsl (char * str)
9752 {
9753   thumb_shift (str, THUMB_LSL);
9754 }
9755
9756 static void
9757 do_t_lsr (char * str)
9758 {
9759   thumb_shift (str, THUMB_LSR);
9760 }
9761
9762 static void
9763 do_t_mov (char * str)
9764 {
9765   thumb_mov_compare (str, THUMB_MOVE);
9766 }
9767
9768 static void
9769 do_t_push_pop (char * str)
9770 {
9771   long range;
9772
9773   skip_whitespace (str);
9774
9775   if ((range = reg_list (&str)) == FAIL)
9776     {
9777       if (! inst.error)
9778         inst.error = BAD_ARGS;
9779       return;
9780     }
9781
9782   if (inst.reloc.type != BFD_RELOC_UNUSED)
9783     {
9784       /* This really doesn't seem worth it.  */
9785       inst.reloc.type = BFD_RELOC_UNUSED;
9786       inst.error = _("expression too complex");
9787       return;
9788     }
9789
9790   if (range & ~0xff)
9791     {
9792       if ((inst.instruction == T_OPCODE_PUSH
9793            && (range & ~0xff) == 1 << REG_LR)
9794           || (inst.instruction == T_OPCODE_POP
9795               && (range & ~0xff) == 1 << REG_PC))
9796         {
9797           inst.instruction |= THUMB_PP_PC_LR;
9798           range &= 0xff;
9799         }
9800       else
9801         {
9802           inst.error = _("invalid register list to push/pop instruction");
9803           return;
9804         }
9805     }
9806
9807   inst.instruction |= range;
9808   end_of_line (str);
9809 }
9810
9811 static void
9812 do_t_str (char * str)
9813 {
9814   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9815 }
9816
9817 static void
9818 do_t_strb (char * str)
9819 {
9820   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9821 }
9822
9823 static void
9824 do_t_strh (char * str)
9825 {
9826   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9827 }
9828
9829 static void
9830 do_t_sub (char * str)
9831 {
9832   thumb_add_sub (str, 1);
9833 }
9834
9835 static void
9836 do_t_swi (char * str)
9837 {
9838   skip_whitespace (str);
9839
9840   if (my_get_expression (&inst.reloc.exp, &str))
9841     return;
9842
9843   inst.reloc.type = BFD_RELOC_ARM_SWI;
9844   end_of_line (str);
9845 }
9846
9847 static void
9848 do_t_adr (char * str)
9849 {
9850   int reg;
9851
9852   /* This is a pseudo-op of the form "adr rd, label" to be converted
9853      into a relative address of the form "add rd, pc, #label-.-4".  */
9854   skip_whitespace (str);
9855
9856   /* Store Rd in temporary location inside instruction.  */
9857   if ((reg = reg_required_here (&str, 4)) == FAIL
9858       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
9859       || skip_past_comma (&str) == FAIL
9860       || my_get_expression (&inst.reloc.exp, &str))
9861     {
9862       if (!inst.error)
9863         inst.error = BAD_ARGS;
9864       return;
9865     }
9866
9867   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9868   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
9869   inst.reloc.pc_rel = 1;
9870   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
9871
9872   end_of_line (str);
9873 }
9874
9875 static void
9876 insert_reg (const struct reg_entry * r,
9877             struct hash_control * htab)
9878 {
9879   int    len  = strlen (r->name) + 2;
9880   char * buf  = xmalloc (len);
9881   char * buf2 = xmalloc (len);
9882   int    i    = 0;
9883
9884 #ifdef REGISTER_PREFIX
9885   buf[i++] = REGISTER_PREFIX;
9886 #endif
9887
9888   strcpy (buf + i, r->name);
9889
9890   for (i = 0; buf[i]; i++)
9891     buf2[i] = TOUPPER (buf[i]);
9892
9893   buf2[i] = '\0';
9894
9895   hash_insert (htab, buf,  (PTR) r);
9896   hash_insert (htab, buf2, (PTR) r);
9897 }
9898
9899 static void
9900 build_reg_hsh (struct reg_map * map)
9901 {
9902   const struct reg_entry *r;
9903
9904   if ((map->htab = hash_new ()) == NULL)
9905     as_fatal (_("virtual memory exhausted"));
9906
9907   for (r = map->names; r->name != NULL; r++)
9908     insert_reg (r, map->htab);
9909 }
9910
9911 static void
9912 insert_reg_alias (char * str,
9913                   int regnum,
9914                   struct hash_control *htab)
9915 {
9916   const char * error;
9917   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
9918   const char * name = xmalloc (strlen (str) + 1);
9919
9920   strcpy ((char *) name, str);
9921
9922   new->name = name;
9923   new->number = regnum;
9924   new->builtin = FALSE;
9925
9926   error = hash_insert (htab, name, (PTR) new);
9927   if (error)
9928     {
9929       as_bad (_("failed to create an alias for %s, reason: %s"),
9930             str, error);
9931       free ((char *) name);
9932       free (new);
9933     }
9934 }
9935
9936 /* Look for the .req directive.  This is of the form:
9937
9938         new_register_name .req existing_register_name
9939
9940    If we find one, or if it looks sufficiently like one that we want to
9941    handle any error here, return non-zero.  Otherwise return zero.  */
9942
9943 static int
9944 create_register_alias (char * newname, char * p)
9945 {
9946   char * q;
9947   char c;
9948
9949   q = p;
9950   skip_whitespace (q);
9951
9952   c = *p;
9953   *p = '\0';
9954
9955   if (*q && !strncmp (q, ".req ", 5))
9956     {
9957       char *copy_of_str;
9958       char *r;
9959
9960 #ifndef IGNORE_OPCODE_CASE
9961       newname = original_case_string;
9962 #endif
9963       copy_of_str = newname;
9964
9965       q += 4;
9966       skip_whitespace (q);
9967
9968       for (r = q; *r != '\0'; r++)
9969         if (*r == ' ')
9970           break;
9971
9972       if (r != q)
9973         {
9974           enum arm_reg_type new_type, old_type;
9975           int old_regno;
9976           char d = *r;
9977
9978           *r = '\0';
9979           old_type = arm_reg_parse_any (q);
9980           *r = d;
9981
9982           new_type = arm_reg_parse_any (newname);
9983
9984           if (new_type == REG_TYPE_MAX)
9985             {
9986               if (old_type != REG_TYPE_MAX)
9987                 {
9988                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9989                   insert_reg_alias (newname, old_regno,
9990                                     all_reg_maps[old_type].htab);
9991                 }
9992               else
9993                 as_warn (_("register '%s' does not exist\n"), q);
9994             }
9995           else if (old_type == REG_TYPE_MAX)
9996             {
9997               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9998                        copy_of_str, q);
9999             }
10000           else
10001             {
10002               /* Do not warn about redefinitions to the same alias.  */
10003               if (new_type != old_type
10004                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
10005                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
10006                 as_warn (_("ignoring redefinition of register alias '%s'"),
10007                          copy_of_str);
10008
10009             }
10010         }
10011       else
10012         as_warn (_("ignoring incomplete .req pseuso op"));
10013
10014       *p = c;
10015       return 1;
10016     }
10017
10018   *p = c;
10019   return 0;
10020 }
10021
10022 static void
10023 set_constant_flonums (void)
10024 {
10025   int i;
10026
10027   for (i = 0; i < NUM_FLOAT_VALS; i++)
10028     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
10029       abort ();
10030 }
10031
10032 \f
10033 static const struct asm_opcode insns[] =
10034 {
10035   /* Core ARM Instructions.  */
10036   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
10037   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
10038   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
10039   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
10040   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
10041   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
10042   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
10043   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
10044   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
10045   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
10046   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
10047   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
10048   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
10049   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
10050   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
10051   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
10052   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
10053   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
10054   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
10055   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
10056
10057   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
10058   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
10059   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
10060   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
10061   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
10062   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
10063   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
10064   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
10065   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
10066   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
10067   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
10068   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
10069
10070   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
10071   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
10072   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
10073   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
10074
10075   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
10076   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
10077   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
10078   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
10079   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
10080   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
10081   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
10082   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
10083
10084   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
10085   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
10086   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
10087   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
10088   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
10089   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
10090   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
10091   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
10092
10093   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
10094   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
10095   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
10096   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
10097   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
10098   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
10099   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
10100   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
10101
10102   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
10103 #ifdef TE_WINCE
10104   /* XXX This is the wrong place to do this.  Think multi-arch.  */
10105   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
10106   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
10107 #else
10108   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
10109   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
10110 #endif
10111
10112   /* Pseudo ops.  */
10113   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
10114   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
10115   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_nop},
10116
10117   /* ARM 2 multiplies.  */
10118   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
10119   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
10120   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
10121   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
10122
10123   /* Generic coprocessor instructions.  */
10124   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
10125   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
10126   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
10127   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
10128   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
10129   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
10130   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
10131
10132   /* ARM 3 - swp instructions.  */
10133   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
10134   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
10135
10136   /* ARM 6 Status register instructions.  */
10137   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
10138   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
10139   /* ScottB: our code uses     0xe128f000 for msr.
10140      NickC:  but this is wrong because the bits 16 through 19 are
10141              handled by the PSR_xxx defines above.  */
10142
10143   /* ARM 7M long multiplies.  */
10144   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
10145   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
10146   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
10147   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
10148   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
10149   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
10150   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
10151   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
10152
10153   /* ARM Architecture 4.  */
10154   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
10155   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
10156   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
10157   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
10158
10159   /* ARM Architecture 4T.  */
10160   /* Note: bx (and blx) are required on V5, even if the processor does
10161      not support Thumb.  */
10162   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
10163
10164   /*  ARM Architecture 5T.  */
10165   /* Note: blx has 2 variants, so the .value is set dynamically.
10166      Only one of the variants has conditional execution.  */
10167   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
10168   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
10169   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
10170   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
10171   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
10172   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
10173   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
10174   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
10175   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
10176   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
10177
10178   /*  ARM Architecture 5TExP.  */
10179   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
10180   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
10181   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
10182   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
10183
10184   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
10185   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
10186
10187   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
10188   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
10189   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
10190   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
10191
10192   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
10193   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
10194   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
10195   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
10196
10197   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
10198   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
10199
10200   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
10201   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
10202   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
10203   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
10204
10205   /*  ARM Architecture 5TE.  */
10206   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
10207   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
10208   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
10209
10210   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
10211   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
10212
10213   /*  ARM Architecture 5TEJ.  */
10214   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
10215
10216   /*  ARM V6.  */
10217   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
10218   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
10219   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
10220   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
10221   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
10222   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
10223   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
10224   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
10225   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
10226   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
10227   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
10228   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
10229   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
10230   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
10231   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
10232   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
10233   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
10234   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
10235   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
10236   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
10237   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
10238   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
10239   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
10240   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
10241   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
10242   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
10243   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
10244   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
10245   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
10246   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
10247   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
10248   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
10249   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
10250   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
10251   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
10252   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
10253   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
10254   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
10255   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
10256   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
10257   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
10258   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
10259   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
10260   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
10261   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
10262   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
10263   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
10264   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
10265   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
10266   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
10267   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
10268   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
10269   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
10270   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
10271   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
10272   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
10273   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
10274   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
10275   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
10276   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
10277   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
10278   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
10279   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
10280   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
10281   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
10282   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
10283   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
10284   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
10285   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
10286   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
10287   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
10288   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
10289   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
10290   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
10291   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
10292   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
10293   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
10294   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
10295   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
10296   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
10297   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
10298   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
10299   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
10300   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
10301   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
10302   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
10303   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
10304   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
10305   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
10306   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
10307   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
10308   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
10309   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
10310   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
10311   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
10312   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
10313   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
10314   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
10315   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
10316
10317   /*  ARM V6K.  */
10318   { "clrex",     0xf57ff01f, 0,  ARM_EXT_V6K,      do_empty},
10319   { "ldrexb",    0xe1d00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10320   { "ldrexd",    0xe1b00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10321   { "ldrexh",    0xe1f00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10322   { "sev",       0xe320f004, 3,  ARM_EXT_V6K,      do_empty},
10323   { "strexb",    0xe1c00f90, 6,  ARM_EXT_V6K,      do_strex},
10324   { "strexd",    0xe1a00f90, 6,  ARM_EXT_V6K,      do_strex},
10325   { "strexh",    0xe1e00f90, 6,  ARM_EXT_V6K,      do_strex},
10326   { "wfe",       0xe320f002, 3,  ARM_EXT_V6K,      do_empty},
10327   { "wfi",       0xe320f003, 3,  ARM_EXT_V6K,      do_empty},
10328   { "yield",     0xe320f001, 5,  ARM_EXT_V6K,      do_empty},
10329
10330   /*  ARM V6Z.  */
10331   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
10332
10333   /*  ARM V6T2.  */
10334   { "bfc",       0xe7c0001f, 3,  ARM_EXT_V6T2,     do_bfc},
10335   { "bfi",       0xe7c00010, 3,  ARM_EXT_V6T2,     do_bfi},
10336   { "mls",       0xe0600090, 3,  ARM_EXT_V6T2,     do_mls},
10337   { "movw",      0xe3000000, 4,  ARM_EXT_V6T2,     do_mov16},
10338   { "movt",      0xe3400000, 4,  ARM_EXT_V6T2,     do_mov16},
10339   { "rbit",      0xe3ff0f30, 4,  ARM_EXT_V6T2,     do_rbit},
10340   { "sbfx",      0xe7a00050, 4,  ARM_EXT_V6T2,     do_bfx},
10341   { "ubfx",      0xe7e00050, 4,  ARM_EXT_V6T2,     do_bfx},
10342
10343   { "ldrht",     0xe03000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10344   { "ldrsht",    0xe03000f0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10345   { "ldrsbt",    0xe03000d0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10346   { "strht",     0xe02000b0, 3,  ARM_EXT_V6T2,     do_ldsttv4},
10347
10348   /* Core FPA instruction set (V1).  */
10349   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10350   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10351   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10352   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10353
10354   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10355   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10356   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10357   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10358
10359   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10360   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10361   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10362   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10363
10364   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10365   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10366   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10367   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10368   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10369   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10370   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10371   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10372   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10373   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10374   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10375   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10376
10377   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10378   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10379   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10380   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10381   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10382   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10383   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10384   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10385   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10386   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10387   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10388   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10389
10390   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10391   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10392   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10393   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10394   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10395   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10396   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10397   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10398   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10399   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10400   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10401   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10402
10403   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10404   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10405   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10406   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10407   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10408   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10409   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10410   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10411   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10412   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10413   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10414   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10415
10416   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10417   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10418   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10419   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10420   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10421   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10422   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10423   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10424   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10425   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10426   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10427   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10428
10429   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10430   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10431   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10432   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10433   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10434   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10435   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10436   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10437   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10438   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10439   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10440   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10441
10442   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10443   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10444   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10445   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10446   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10447   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10448   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10449   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10450   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10451   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10452   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10453   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10454
10455   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10456   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10457   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10458   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10459   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10460   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10461   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10462   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10463   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10464   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10465   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10466   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10467
10468   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10469   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10470   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10471   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10472   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10473   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10474   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10475   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10476   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10477   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10478   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10479   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10480
10481   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10482   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10483   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10484   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10485   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10486   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10487   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10488   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10489   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10490   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10491   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10492   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10493
10494   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10495   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10496   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10497   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10498   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10499   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10500   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10501   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10502   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10503   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10504   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10505   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10506
10507   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10508   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10509   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10510   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10511   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10512   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10513   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10514   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10515   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10516   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10517   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10518   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10519
10520   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10521   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10522   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10523   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10524   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10525   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10526   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10527   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10528   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10529   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10530   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10531   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10532
10533   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10534   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10535   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10536   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10537   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10538   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10539   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10540   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10541   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10542   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10543   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10544   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10545
10546   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10547   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10548   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10549   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10550   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10551   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10552   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10553   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10554   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10555   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10556   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10557   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10558
10559   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10560   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10561   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10562   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10563   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10564   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10565   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10566   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10567   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10568   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10569   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10570   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10571
10572   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10573   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10574   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10575   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10576   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10577   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10578   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10579   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10580   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10581   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10582   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10583   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10584
10585   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10586   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10587   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10588   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10589   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10590   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10591   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10592   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10593   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10594   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10595   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10596   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10597
10598   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10599   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10600   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10601   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10602   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10603   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10604   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10605   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10606   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10607   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10608   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10609   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10610
10611   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10612   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10613   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10614   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10615   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10616   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10617   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10618   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10619   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10620   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10621   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10622   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10623
10624   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10625   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10626   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10627   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10628   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10629   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10630   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10631   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10632   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10633   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10634   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10635   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10636
10637   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10638   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10639   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10640   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10641   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10642   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10643   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10644   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10645   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10646   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10647   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10648   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10649
10650   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10651   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10652   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10653   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10654   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10655   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10656   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10657   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10658   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10659   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10660   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10661   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10662
10663   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10664   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10665   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10666   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10667   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10668   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10669   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10670   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10671   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10672   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10673   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10674   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10675
10676   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10677   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10678   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10679   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10680   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10681   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10682   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10683   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10684   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10685   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10686   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10687   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10688
10689   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10690   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10691   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10692   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10693   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10694   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10695   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10696   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10697   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10698   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10699   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10700   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10701
10702   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10703   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10704   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10705   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10706   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10707   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10708   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10709   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10710   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10711   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10712   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10713   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10714
10715   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10716   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10717   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10718   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10719   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10720   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10721   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10722   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10723   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10724   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10725   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10726   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10727
10728   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10729   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10730   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10731   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10732   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10733   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10734   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10735   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10736   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10737   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10738   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10739   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10740
10741   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10742   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10743   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10744   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10745   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
10746      not be an optional suffix, but part of the instruction.  To be
10747      compatible, we accept either.  */
10748   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10749   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10750
10751   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10752   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10753   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10754   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10755   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10756   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10757   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10758   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10759   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10760   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10761   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10762   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10763
10764   /* The implementation of the FIX instruction is broken on some
10765      assemblers, in that it accepts a precision specifier as well as a
10766      rounding specifier, despite the fact that this is meaningless.
10767      To be more compatible, we accept it as well, though of course it
10768      does not set any bits.  */
10769   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10770   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10771   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10772   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10773   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10774   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10775   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10776   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10777   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10778   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10779   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10780   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10781   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10782
10783   /* Instructions that were new with the real FPA, call them V2.  */
10784   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10785   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10786   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10787   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10788   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10789   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10790
10791   /* VFP V1xD (single precision).  */
10792   /* Moves and type conversions.  */
10793   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10794   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
10795   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
10796   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
10797   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10798   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10799   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10800   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10801   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10802   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10803   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
10804   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
10805
10806   /* Memory operations.  */
10807   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10808   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10809   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10810   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10811   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10812   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10813   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10814   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10815   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10816   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10817   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10818   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10819   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10820   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10821   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10822   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10823   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10824   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10825
10826   /* Monadic operations.  */
10827   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10828   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10829   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10830
10831   /* Dyadic operations.  */
10832   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10833   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10834   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10835   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10836   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10837   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10838   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10839   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10840   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10841
10842   /* Comparisons.  */
10843   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10844   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10845   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10846   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10847
10848   /* VFP V1 (Double precision).  */
10849   /* Moves and type conversions.  */
10850   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10851   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10852   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10853   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10854   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10855   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10856   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10857   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10858   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10859   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10860   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10861   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10862   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10863
10864   /* Memory operations.  */
10865   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10866   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10867   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10868   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10869   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10870   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10871   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10872   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10873   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10874   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10875
10876   /* Monadic operations.  */
10877   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10878   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10879   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10880
10881   /* Dyadic operations.  */
10882   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10883   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10884   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10885   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10886   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10887   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10888   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10889   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10890   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10891
10892   /* Comparisons.  */
10893   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10894   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10895   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10896   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10897
10898   /* VFP V2.  */
10899   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
10900   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
10901   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
10902   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
10903
10904   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
10905   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
10906   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10907   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10908   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10909   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10910   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10911   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
10912   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
10913
10914   /* Intel Wireless MMX technology instructions.  */
10915   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10916   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10917   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10918   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10919   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10920   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10921   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10922   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10923   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10924   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10925   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10926   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10927   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10928   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10929   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10930   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10931   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10932   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10933   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
10934   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
10935   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10936   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10937   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10938   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10939   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10940   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10941   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10942   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10943   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10944   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
10945   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
10946   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10947   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10948   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10949   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10950   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10951   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10952   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10953   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10954   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10955   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10956   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10957   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10958   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10959   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10960   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10961   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
10962   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10963   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10964   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10965   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10966   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10967   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10968   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10969   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10970   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10971   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10972   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10973   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10974   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10975   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10976   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10977   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10978   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10979   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10980   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10981   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10982   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10983   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10984   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10985   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10986   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10987   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10988   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10989   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10990   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10991   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10992   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10993   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10994   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10995   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10996   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10997   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10998   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10999   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11000   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11001   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11002   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11003   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
11004   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11005   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11006   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11007   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11008   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11009   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11010   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11011   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11012   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11013   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11014   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11015   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11016   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11017   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11018   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11019   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11020   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11021   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11022   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11023   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11024   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11025   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
11026   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11027   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11028   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11029   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11030   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11031   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11032   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11033   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11034   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11035   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11036   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11037   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11038   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11039   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11040   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11041   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11042   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11043   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
11044   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11045   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
11046   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11047   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
11048   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11049   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11050   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11051   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11052   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11053   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11054   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11055   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11056   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11057   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11058   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11059   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11060   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11061   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11062   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11063   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11064   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11065   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11066   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11067   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11068   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11069   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11070   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11071   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
11072   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11073   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11074   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11075   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
11076   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
11077
11078   /* Cirrus Maverick instructions.  */
11079   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
11080   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
11081   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
11082   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
11083   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
11084   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
11085   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
11086   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
11087   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
11088   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
11089   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
11090   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
11091   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
11092   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
11093   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
11094   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
11095   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
11096   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
11097   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11098   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11099   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11100   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11101   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11102   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11103   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
11104   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
11105   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
11106   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
11107   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
11108   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
11109   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11110   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11111   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
11112   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
11113   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
11114   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
11115   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
11116   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
11117   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
11118   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
11119   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
11120   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
11121   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
11122   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
11123   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
11124   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
11125   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
11126   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
11127   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
11128   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
11129   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11130   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11131   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
11132   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
11133   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11134   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11135   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11136   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11137   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
11138   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
11139   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
11140   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
11141   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
11142   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
11143   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11144   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11145   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11146   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11147   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11148   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
11149   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11150   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
11151   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
11152   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
11153   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
11154   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
11155 };
11156
11157 /* Iterate over the base tables to create the instruction patterns.  */
11158
11159 static void
11160 build_arm_ops_hsh (void)
11161 {
11162   unsigned int i;
11163   unsigned int j;
11164   static struct obstack insn_obstack;
11165
11166   obstack_begin (&insn_obstack, 4000);
11167
11168   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11169     {
11170       const struct asm_opcode *insn = insns + i;
11171
11172       if (insn->cond_offset != 0)
11173         {
11174           /* Insn supports conditional execution.  Build the varaints
11175              and insert them in the hash table.  */
11176           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11177             {
11178               unsigned len = strlen (insn->template);
11179               struct asm_opcode *new;
11180               char *template;
11181
11182               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11183               /* All condition codes are two characters.  */
11184               template = obstack_alloc (&insn_obstack, len + 3);
11185
11186               strncpy (template, insn->template, insn->cond_offset);
11187               strcpy (template + insn->cond_offset, conds[j].template);
11188               if (len > insn->cond_offset)
11189                 strcpy (template + insn->cond_offset + 2,
11190                         insn->template + insn->cond_offset);
11191               new->template = template;
11192               new->cond_offset = 0;
11193               new->variant = insn->variant;
11194               new->parms = insn->parms;
11195               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11196
11197               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11198             }
11199         }
11200       /* Finally, insert the unconditional insn in the table directly;
11201          no need to build a copy.  */
11202       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11203     }
11204 }
11205
11206 \f
11207 static const struct thumb_opcode tinsns[] =
11208 {
11209   /* Thumb v1 (ARMv4T).  */
11210   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
11211   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
11212   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
11213   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
11214   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
11215   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
11216   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
11217   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
11218   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
11219   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11220   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11221   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
11222   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
11223   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
11224   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
11225   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
11226   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
11227   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
11228   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
11229   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
11230   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
11231   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
11232   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
11233   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
11234   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
11235   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
11236   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
11237   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
11238   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
11239   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
11240   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
11241   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
11242   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
11243   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
11244   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
11245   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
11246   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
11247   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
11248   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
11249   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
11250   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
11251   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
11252   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
11253   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
11254   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
11255   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
11256   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
11257   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
11258   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
11259   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
11260   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
11261   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
11262   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
11263   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
11264   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
11265   /* Pseudo ops:  */
11266   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
11267   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
11268   /* Thumb v2 (ARMv5T).  */
11269   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
11270   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
11271
11272   /* ARM V6.  */
11273   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
11274   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
11275   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
11276   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
11277   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
11278   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
11279   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
11280   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
11281   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
11282   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
11283   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
11284
11285   /* ARM V6K.  */
11286   {"sev",       0xbf40,         2,      ARM_EXT_V6K, do_empty},
11287   {"wfe",       0xbf20,         2,      ARM_EXT_V6K, do_empty},
11288   {"wfi",       0xbf30,         2,      ARM_EXT_V6K, do_empty},
11289   {"yield",     0xbf10,         2,      ARM_EXT_V6K, do_empty},
11290 };
11291
11292 void
11293 md_begin (void)
11294 {
11295   unsigned mach;
11296   unsigned int i;
11297
11298   if (   (arm_ops_hsh = hash_new ()) == NULL
11299       || (arm_tops_hsh = hash_new ()) == NULL
11300       || (arm_cond_hsh = hash_new ()) == NULL
11301       || (arm_shift_hsh = hash_new ()) == NULL
11302       || (arm_psr_hsh = hash_new ()) == NULL)
11303     as_fatal (_("virtual memory exhausted"));
11304
11305   build_arm_ops_hsh ();
11306   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11307     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11308   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11309     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11310   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11311     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11312   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11313     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11314
11315   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11316     build_reg_hsh (all_reg_maps + i);
11317
11318   set_constant_flonums ();
11319
11320   /* Set the cpu variant based on the command-line options.  We prefer
11321      -mcpu= over -march= if both are set (as for GCC); and we prefer
11322      -mfpu= over any other way of setting the floating point unit.
11323      Use of legacy options with new options are faulted.  */
11324   if (legacy_cpu != -1)
11325     {
11326       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11327         as_bad (_("use of old and new-style options to set CPU type"));
11328
11329       mcpu_cpu_opt = legacy_cpu;
11330     }
11331   else if (mcpu_cpu_opt == -1)
11332     mcpu_cpu_opt = march_cpu_opt;
11333
11334   if (legacy_fpu != -1)
11335     {
11336       if (mfpu_opt != -1)
11337         as_bad (_("use of old and new-style options to set FPU type"));
11338
11339       mfpu_opt = legacy_fpu;
11340     }
11341   else if (mfpu_opt == -1)
11342     {
11343 #if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) 
11344       /* Some environments specify a default FPU.  If they don't, infer it
11345          from the processor.  */
11346       if (mcpu_fpu_opt != -1)
11347         mfpu_opt = mcpu_fpu_opt;
11348       else
11349         mfpu_opt = march_fpu_opt;
11350 #else
11351       mfpu_opt = FPU_DEFAULT;
11352 #endif
11353     }
11354
11355   if (mfpu_opt == -1)
11356     {
11357       if (mcpu_cpu_opt == -1)
11358         mfpu_opt = FPU_DEFAULT;
11359       else if (mcpu_cpu_opt & ARM_EXT_V5)
11360         mfpu_opt = FPU_ARCH_VFP_V2;
11361       else
11362         mfpu_opt = FPU_ARCH_FPA;
11363     }
11364
11365   if (mcpu_cpu_opt == -1)
11366     mcpu_cpu_opt = CPU_DEFAULT;
11367
11368   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11369
11370 #if defined OBJ_COFF || defined OBJ_ELF
11371   {
11372     unsigned int flags = 0;
11373
11374 #if defined OBJ_ELF
11375     flags = meabi_flags;
11376
11377     switch (meabi_flags)
11378       {
11379       case EF_ARM_EABI_UNKNOWN:
11380 #endif
11381         /* Set the flags in the private structure.  */
11382         if (uses_apcs_26)      flags |= F_APCS26;
11383         if (support_interwork) flags |= F_INTERWORK;
11384         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11385         if (pic_code)          flags |= F_PIC;
11386         if ((cpu_variant & FPU_ANY) == FPU_NONE
11387              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11388           flags |= F_SOFT_FLOAT;
11389
11390         switch (mfloat_abi_opt)
11391           {
11392           case ARM_FLOAT_ABI_SOFT:
11393           case ARM_FLOAT_ABI_SOFTFP:
11394             flags |= F_SOFT_FLOAT;
11395             break;
11396
11397           case ARM_FLOAT_ABI_HARD:
11398             if (flags & F_SOFT_FLOAT)
11399               as_bad (_("hard-float conflicts with specified fpu"));
11400             break;
11401           }
11402
11403         /* Using VFP conventions (even if soft-float).  */
11404         if (cpu_variant & FPU_VFP_EXT_NONE)
11405           flags |= F_VFP_FLOAT;
11406
11407 #if defined OBJ_ELF
11408         if (cpu_variant & FPU_ARCH_MAVERICK)
11409             flags |= EF_ARM_MAVERICK_FLOAT;
11410         break;
11411
11412       case EF_ARM_EABI_VER4:
11413         /* No additional flags to set.  */
11414         break;
11415
11416       default:
11417         abort ();
11418       }
11419 #endif
11420     bfd_set_private_flags (stdoutput, flags);
11421
11422     /* We have run out flags in the COFF header to encode the
11423        status of ATPCS support, so instead we create a dummy,
11424        empty, debug section called .arm.atpcs.  */
11425     if (atpcs)
11426       {
11427         asection * sec;
11428
11429         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11430
11431         if (sec != NULL)
11432           {
11433             bfd_set_section_flags
11434               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11435             bfd_set_section_size (stdoutput, sec, 0);
11436             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11437           }
11438       }
11439   }
11440 #endif
11441
11442   /* Record the CPU type as well.  */
11443   switch (cpu_variant & ARM_CPU_MASK)
11444     {
11445     case ARM_2:
11446       mach = bfd_mach_arm_2;
11447       break;
11448
11449     case ARM_3:                 /* Also ARM_250.  */
11450       mach = bfd_mach_arm_2a;
11451       break;
11452
11453     case ARM_6:                 /* Also ARM_7.  */
11454       mach = bfd_mach_arm_3;
11455       break;
11456
11457     default:
11458       mach = bfd_mach_arm_unknown;
11459       break;
11460     }
11461
11462   /* Catch special cases.  */
11463   if (cpu_variant & ARM_CEXT_IWMMXT)
11464     mach = bfd_mach_arm_iWMMXt;
11465   else if (cpu_variant & ARM_CEXT_XSCALE)
11466     mach = bfd_mach_arm_XScale;
11467   else if (cpu_variant & ARM_CEXT_MAVERICK)
11468     mach = bfd_mach_arm_ep9312;
11469   else if (cpu_variant & ARM_EXT_V5E)
11470     mach = bfd_mach_arm_5TE;
11471   else if (cpu_variant & ARM_EXT_V5)
11472     {
11473       if (cpu_variant & ARM_EXT_V4T)
11474         mach = bfd_mach_arm_5T;
11475       else
11476         mach = bfd_mach_arm_5;
11477     }
11478   else if (cpu_variant & ARM_EXT_V4)
11479     {
11480       if (cpu_variant & ARM_EXT_V4T)
11481         mach = bfd_mach_arm_4T;
11482       else
11483         mach = bfd_mach_arm_4;
11484     }
11485   else if (cpu_variant & ARM_EXT_V3M)
11486     mach = bfd_mach_arm_3M;
11487
11488   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11489 }
11490
11491 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11492    for use in the a.out file, and stores them in the array pointed to by buf.
11493    This knows about the endian-ness of the target machine and does
11494    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11495    2 (short) and 4 (long)  Floating numbers are put out as a series of
11496    LITTLENUMS (shorts, here at least).  */
11497
11498 void
11499 md_number_to_chars (char * buf, valueT val, int n)
11500 {
11501   if (target_big_endian)
11502     number_to_chars_bigendian (buf, val, n);
11503   else
11504     number_to_chars_littleendian (buf, val, n);
11505 }
11506
11507 static valueT
11508 md_chars_to_number (char * buf, int n)
11509 {
11510   valueT result = 0;
11511   unsigned char * where = (unsigned char *) buf;
11512
11513   if (target_big_endian)
11514     {
11515       while (n--)
11516         {
11517           result <<= 8;
11518           result |= (*where++ & 255);
11519         }
11520     }
11521   else
11522     {
11523       while (n--)
11524         {
11525           result <<= 8;
11526           result |= (where[n] & 255);
11527         }
11528     }
11529
11530   return result;
11531 }
11532
11533 /* Turn a string in input_line_pointer into a floating point constant
11534    of type TYPE, and store the appropriate bytes in *LITP.  The number
11535    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11536    returned, or NULL on OK.
11537
11538    Note that fp constants aren't represent in the normal way on the ARM.
11539    In big endian mode, things are as expected.  However, in little endian
11540    mode fp constants are big-endian word-wise, and little-endian byte-wise
11541    within the words.  For example, (double) 1.1 in big endian mode is
11542    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11543    the byte sequence 99 99 f1 3f 9a 99 99 99.
11544
11545    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11546
11547 char *
11548 md_atof (int type, char * litP, int * sizeP)
11549 {
11550   int prec;
11551   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11552   char *t;
11553   int i;
11554
11555   switch (type)
11556     {
11557     case 'f':
11558     case 'F':
11559     case 's':
11560     case 'S':
11561       prec = 2;
11562       break;
11563
11564     case 'd':
11565     case 'D':
11566     case 'r':
11567     case 'R':
11568       prec = 4;
11569       break;
11570
11571     case 'x':
11572     case 'X':
11573       prec = 6;
11574       break;
11575
11576     case 'p':
11577     case 'P':
11578       prec = 6;
11579       break;
11580
11581     default:
11582       *sizeP = 0;
11583       return _("bad call to MD_ATOF()");
11584     }
11585
11586   t = atof_ieee (input_line_pointer, type, words);
11587   if (t)
11588     input_line_pointer = t;
11589   *sizeP = prec * 2;
11590
11591   if (target_big_endian)
11592     {
11593       for (i = 0; i < prec; i++)
11594         {
11595           md_number_to_chars (litP, (valueT) words[i], 2);
11596           litP += 2;
11597         }
11598     }
11599   else
11600     {
11601       if (cpu_variant & FPU_ARCH_VFP)
11602         for (i = prec - 1; i >= 0; i--)
11603           {
11604             md_number_to_chars (litP, (valueT) words[i], 2);
11605             litP += 2;
11606           }
11607       else
11608         /* For a 4 byte float the order of elements in `words' is 1 0.
11609            For an 8 byte float the order is 1 0 3 2.  */
11610         for (i = 0; i < prec; i += 2)
11611           {
11612             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11613             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11614             litP += 4;
11615           }
11616     }
11617
11618   return 0;
11619 }
11620
11621 /* The knowledge of the PC's pipeline offset is built into the insns
11622    themselves.  */
11623
11624 long
11625 md_pcrel_from (fixS * fixP)
11626 {
11627   if (fixP->fx_addsy
11628       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11629       && fixP->fx_subsy == NULL)
11630     return 0;
11631
11632   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11633     {
11634       /* PC relative addressing on the Thumb is slightly odd
11635          as the bottom two bits of the PC are forced to zero
11636          for the calculation.  */
11637       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11638     }
11639
11640 #ifdef TE_WINCE
11641   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11642      so we un-adjust here to compensate for the accommodation.  */
11643   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11644 #else
11645   return fixP->fx_where + fixP->fx_frag->fr_address;
11646 #endif
11647 }
11648
11649 /* Round up a section size to the appropriate boundary.  */
11650
11651 valueT
11652 md_section_align (segT   segment ATTRIBUTE_UNUSED,
11653                   valueT size)
11654 {
11655 #ifdef OBJ_ELF
11656   return size;
11657 #else
11658   /* Round all sects to multiple of 4.  */
11659   return (size + 3) & ~3;
11660 #endif
11661 }
11662
11663 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
11664    Otherwise we have no need to default values of symbols.  */
11665
11666 symbolS *
11667 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
11668 {
11669 #ifdef OBJ_ELF
11670   if (name[0] == '_' && name[1] == 'G'
11671       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
11672     {
11673       if (!GOT_symbol)
11674         {
11675           if (symbol_find (name))
11676             as_bad ("GOT already in the symbol table");
11677
11678           GOT_symbol = symbol_new (name, undefined_section,
11679                                    (valueT) 0, & zero_address_frag);
11680         }
11681
11682       return GOT_symbol;
11683     }
11684 #endif
11685
11686   return 0;
11687 }
11688
11689 void
11690 md_apply_fix3 (fixS *   fixP,
11691                valueT * valP,
11692                segT     seg)
11693 {
11694   offsetT        value = * valP;
11695   offsetT        newval;
11696   unsigned int   newimm;
11697   unsigned long  temp;
11698   int            sign;
11699   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
11700   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
11701
11702   assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
11703
11704   /* Note whether this will delete the relocation.  */
11705   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11706     fixP->fx_done = 1;
11707
11708   /* If this symbol is in a different section then we need to leave it for
11709      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
11710      so we have to undo it's effects here.  */
11711   if (fixP->fx_pcrel)
11712     {
11713       if (fixP->fx_addsy != NULL
11714           && S_IS_DEFINED (fixP->fx_addsy)
11715           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11716         value += md_pcrel_from (fixP);
11717     }
11718
11719   /* Remember value for emit_reloc.  */
11720   fixP->fx_addnumber = value;
11721
11722   switch (fixP->fx_r_type)
11723     {
11724     case BFD_RELOC_NONE:
11725       /* This will need to go in the object file.  */
11726       fixP->fx_done = 0;
11727       break;
11728   
11729     case BFD_RELOC_ARM_IMMEDIATE:
11730       /* We claim that this fixup has been processed here,
11731          even if in fact we generate an error because we do
11732          not have a reloc for it, so tc_gen_reloc will reject it.  */
11733       fixP->fx_done = 1;
11734
11735       if (fixP->fx_addsy
11736           && ! S_IS_DEFINED (fixP->fx_addsy))
11737         {
11738           as_bad_where (fixP->fx_file, fixP->fx_line,
11739                         _("undefined symbol %s used as an immediate value"),
11740                         S_GET_NAME (fixP->fx_addsy));
11741           break;
11742         }
11743
11744       newimm = validate_immediate (value);
11745       temp = md_chars_to_number (buf, INSN_SIZE);
11746
11747       /* If the instruction will fail, see if we can fix things up by
11748          changing the opcode.  */
11749       if (newimm == (unsigned int) FAIL
11750           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11751         {
11752           as_bad_where (fixP->fx_file, fixP->fx_line,
11753                         _("invalid constant (%lx) after fixup"),
11754                         (unsigned long) value);
11755           break;
11756         }
11757
11758       newimm |= (temp & 0xfffff000);
11759       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11760       break;
11761
11762     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11763       {
11764         unsigned int highpart = 0;
11765         unsigned int newinsn  = 0xe1a00000; /* nop.  */
11766
11767         newimm = validate_immediate (value);
11768         temp = md_chars_to_number (buf, INSN_SIZE);
11769
11770         /* If the instruction will fail, see if we can fix things up by
11771            changing the opcode.  */
11772         if (newimm == (unsigned int) FAIL
11773             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11774           {
11775             /* No ?  OK - try using two ADD instructions to generate
11776                the value.  */
11777             newimm = validate_immediate_twopart (value, & highpart);
11778
11779             /* Yes - then make sure that the second instruction is
11780                also an add.  */
11781             if (newimm != (unsigned int) FAIL)
11782               newinsn = temp;
11783             /* Still No ?  Try using a negated value.  */
11784             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11785               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11786             /* Otherwise - give up.  */
11787             else
11788               {
11789                 as_bad_where (fixP->fx_file, fixP->fx_line,
11790                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11791                               (long) value);
11792                 break;
11793               }
11794
11795             /* Replace the first operand in the 2nd instruction (which
11796                is the PC) with the destination register.  We have
11797                already added in the PC in the first instruction and we
11798                do not want to do it again.  */
11799             newinsn &= ~ 0xf0000;
11800             newinsn |= ((newinsn & 0x0f000) << 4);
11801           }
11802
11803         newimm |= (temp & 0xfffff000);
11804         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11805
11806         highpart |= (newinsn & 0xfffff000);
11807         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11808       }
11809       break;
11810
11811     case BFD_RELOC_ARM_OFFSET_IMM:
11812       sign = value >= 0;
11813
11814       if (value < 0)
11815         value = - value;
11816
11817       if (validate_offset_imm (value, 0) == FAIL)
11818         {
11819           as_bad_where (fixP->fx_file, fixP->fx_line,
11820                         _("bad immediate value for offset (%ld)"),
11821                         (long) value);
11822           break;
11823         }
11824
11825       newval = md_chars_to_number (buf, INSN_SIZE);
11826       newval &= 0xff7ff000;
11827       newval |= value | (sign ? INDEX_UP : 0);
11828       md_number_to_chars (buf, newval, INSN_SIZE);
11829       break;
11830
11831     case BFD_RELOC_ARM_OFFSET_IMM8:
11832     case BFD_RELOC_ARM_HWLITERAL:
11833       sign = value >= 0;
11834
11835       if (value < 0)
11836         value = - value;
11837
11838       if (validate_offset_imm (value, 1) == FAIL)
11839         {
11840           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11841             as_bad_where (fixP->fx_file, fixP->fx_line,
11842                           _("invalid literal constant: pool needs to be closer"));
11843           else
11844             as_bad (_("bad immediate value for half-word offset (%ld)"),
11845                     (long) value);
11846           break;
11847         }
11848
11849       newval = md_chars_to_number (buf, INSN_SIZE);
11850       newval &= 0xff7ff0f0;
11851       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11852       md_number_to_chars (buf, newval, INSN_SIZE);
11853       break;
11854
11855     case BFD_RELOC_ARM_LITERAL:
11856       sign = value >= 0;
11857
11858       if (value < 0)
11859         value = - value;
11860
11861       if (validate_offset_imm (value, 0) == FAIL)
11862         {
11863           as_bad_where (fixP->fx_file, fixP->fx_line,
11864                         _("invalid literal constant: pool needs to be closer"));
11865           break;
11866         }
11867
11868       newval = md_chars_to_number (buf, INSN_SIZE);
11869       newval &= 0xff7ff000;
11870       newval |= value | (sign ? INDEX_UP : 0);
11871       md_number_to_chars (buf, newval, INSN_SIZE);
11872       break;
11873
11874     case BFD_RELOC_ARM_SHIFT_IMM:
11875       newval = md_chars_to_number (buf, INSN_SIZE);
11876       if (((unsigned long) value) > 32
11877           || (value == 32
11878               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11879         {
11880           as_bad_where (fixP->fx_file, fixP->fx_line,
11881                         _("shift expression is too large"));
11882           break;
11883         }
11884
11885       if (value == 0)
11886         /* Shifts of zero must be done as lsl.  */
11887         newval &= ~0x60;
11888       else if (value == 32)
11889         value = 0;
11890       newval &= 0xfffff07f;
11891       newval |= (value & 0x1f) << 7;
11892       md_number_to_chars (buf, newval, INSN_SIZE);
11893       break;
11894
11895     case BFD_RELOC_ARM_SMI:
11896       if (((unsigned long) value) > 0xffff)
11897         as_bad_where (fixP->fx_file, fixP->fx_line,
11898                       _("invalid smi expression"));
11899       newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0;
11900       newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11901       md_number_to_chars (buf, newval, INSN_SIZE);
11902       break;
11903
11904     case BFD_RELOC_ARM_SWI:
11905       if (arm_data->thumb_mode)
11906         {
11907           if (((unsigned long) value) > 0xff)
11908             as_bad_where (fixP->fx_file, fixP->fx_line,
11909                           _("invalid swi expression"));
11910           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11911           newval |= value;
11912           md_number_to_chars (buf, newval, THUMB_SIZE);
11913         }
11914       else
11915         {
11916           if (((unsigned long) value) > 0x00ffffff)
11917             as_bad_where (fixP->fx_file, fixP->fx_line,
11918                           _("invalid swi expression"));
11919           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11920           newval |= value;
11921           md_number_to_chars (buf, newval, INSN_SIZE);
11922         }
11923       break;
11924
11925     case BFD_RELOC_ARM_MULTI:
11926       if (((unsigned long) value) > 0xffff)
11927         as_bad_where (fixP->fx_file, fixP->fx_line,
11928                       _("invalid expression in load/store multiple"));
11929       newval = value | md_chars_to_number (buf, INSN_SIZE);
11930       md_number_to_chars (buf, newval, INSN_SIZE);
11931       break;
11932
11933     case BFD_RELOC_ARM_PCREL_BRANCH:
11934       newval = md_chars_to_number (buf, INSN_SIZE);
11935
11936       /* Sign-extend a 24-bit number.  */
11937 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11938
11939 #ifdef OBJ_ELF
11940       value = fixP->fx_offset;
11941 #endif
11942
11943       /* We are going to store value (shifted right by two) in the
11944          instruction, in a 24 bit, signed field.  Thus we need to check
11945          that none of the top 8 bits of the shifted value (top 7 bits of
11946          the unshifted, unsigned value) are set, or that they are all set.  */
11947       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
11948           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
11949         {
11950 #ifdef OBJ_ELF
11951           /* Normally we would be stuck at this point, since we cannot store
11952              the absolute address that is the destination of the branch in the
11953              24 bits of the branch instruction.  If however, we happen to know
11954              that the destination of the branch is in the same section as the
11955              branch instruction itself, then we can compute the relocation for
11956              ourselves and not have to bother the linker with it.
11957
11958              FIXME: The test for OBJ_ELF is only here because I have not
11959              worked out how to do this for OBJ_COFF.  */
11960           if (fixP->fx_addsy != NULL
11961               && S_IS_DEFINED (fixP->fx_addsy)
11962               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
11963             {
11964               /* Get pc relative value to go into the branch.  */
11965               value = * valP;
11966
11967               /* Permit a backward branch provided that enough bits
11968                  are set.  Allow a forwards branch, provided that
11969                  enough bits are clear.  */
11970               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
11971                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
11972                 fixP->fx_done = 1;
11973             }
11974
11975           if (! fixP->fx_done)
11976 #endif
11977             as_bad_where (fixP->fx_file, fixP->fx_line,
11978                           _("GAS can't handle same-section branch dest >= 0x04000000"));
11979         }
11980
11981       value >>= 2;
11982       value += SEXT24 (newval);
11983
11984       if (    (value & ~ ((offsetT) 0xffffff)) != 0
11985           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
11986         as_bad_where (fixP->fx_file, fixP->fx_line,
11987                       _("out of range branch"));
11988
11989       if (seg->use_rela_p && !fixP->fx_done)
11990         {
11991           /* Must unshift the value before storing it in the addend.  */
11992           value <<= 2;
11993 #ifdef OBJ_ELF
11994           fixP->fx_offset = value;
11995 #endif
11996           fixP->fx_addnumber = value;
11997           newval = newval & 0xff000000;
11998         }
11999       else
12000           newval = (value & 0x00ffffff) | (newval & 0xff000000);
12001       md_number_to_chars (buf, newval, INSN_SIZE);
12002       break;
12003
12004     case BFD_RELOC_ARM_PCREL_BLX:
12005       {
12006         offsetT hbit;
12007         newval = md_chars_to_number (buf, INSN_SIZE);
12008
12009 #ifdef OBJ_ELF
12010         value = fixP->fx_offset;
12011 #endif
12012         hbit   = (value >> 1) & 1;
12013         value  = (value >> 2) & 0x00ffffff;
12014         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12015
12016         if (seg->use_rela_p && !fixP->fx_done)
12017           {
12018             /* Must sign-extend and unshift the value before storing
12019                it in the addend.  */
12020             value = SEXT24 (value);
12021             value = (value << 2) | hbit;
12022 #ifdef OBJ_ELF
12023             fixP->fx_offset = value;
12024 #endif
12025             fixP->fx_addnumber = value;
12026             newval = newval & 0xfe000000;
12027           }
12028         else
12029           newval = value | (newval & 0xfe000000) | (hbit << 24);
12030         md_number_to_chars (buf, newval, INSN_SIZE);
12031       }
12032       break;
12033
12034     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12035       newval = md_chars_to_number (buf, THUMB_SIZE);
12036       {
12037         addressT diff = (newval & 0xff) << 1;
12038         if (diff & 0x100)
12039           diff |= ~0xff;
12040
12041         value += diff;
12042         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12043           as_bad_where (fixP->fx_file, fixP->fx_line,
12044                         _("branch out of range"));
12045         if (seg->use_rela_p && !fixP->fx_done)
12046           {
12047 #ifdef OBJ_ELF
12048             fixP->fx_offset = value;
12049 #endif
12050             fixP->fx_addnumber = value;
12051             newval = newval & 0xff00;
12052           }
12053         else
12054           newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12055       }
12056       md_number_to_chars (buf, newval, THUMB_SIZE);
12057       break;
12058
12059     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12060       newval = md_chars_to_number (buf, THUMB_SIZE);
12061       {
12062         addressT diff = (newval & 0x7ff) << 1;
12063         if (diff & 0x800)
12064           diff |= ~0x7ff;
12065
12066         value += diff;
12067         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12068           as_bad_where (fixP->fx_file, fixP->fx_line,
12069                         _("branch out of range"));
12070         if (seg->use_rela_p && !fixP->fx_done)
12071           {
12072 #ifdef OBJ_ELF
12073             fixP->fx_offset = value;
12074 #endif
12075             fixP->fx_addnumber = value;
12076             newval = newval & 0xf800;
12077           }
12078         else
12079           newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12080       }
12081       md_number_to_chars (buf, newval, THUMB_SIZE);
12082       break;
12083
12084     case BFD_RELOC_THUMB_PCREL_BLX:
12085     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12086       {
12087         offsetT newval2;
12088         addressT diff;
12089
12090         newval  = md_chars_to_number (buf, THUMB_SIZE);
12091         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12092         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12093         if (diff & 0x400000)
12094           diff |= ~0x3fffff;
12095 #ifdef OBJ_ELF
12096         value = fixP->fx_offset;
12097 #endif
12098         value += diff;
12099
12100         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12101           as_bad_where (fixP->fx_file, fixP->fx_line,
12102                         _("branch with link out of range"));
12103
12104         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12105           /* For a BLX instruction, make sure that the relocation is rounded up
12106              to a word boundary.  This follows the semantics of the instruction
12107              which specifies that bit 1 of the target address will come from bit
12108              1 of the base address.  */
12109           value = (value + 1) & ~ 1;
12110
12111         if (seg->use_rela_p && !fixP->fx_done)
12112           {
12113 #ifdef OBJ_ELF
12114             fixP->fx_offset = value;
12115 #endif
12116             fixP->fx_addnumber = value;
12117             newval = newval & 0xf800;
12118             newval2 = newval2 & 0xf800;
12119           }
12120         else
12121           {
12122             newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12123             newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12124           }
12125         md_number_to_chars (buf, newval, THUMB_SIZE);
12126         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12127       }
12128       break;
12129
12130     case BFD_RELOC_8:
12131       if (seg->use_rela_p && !fixP->fx_done)
12132         break;
12133       if (fixP->fx_done || fixP->fx_pcrel)
12134         md_number_to_chars (buf, value, 1);
12135 #ifdef OBJ_ELF
12136       else
12137         {
12138           value = fixP->fx_offset;
12139           md_number_to_chars (buf, value, 1);
12140         }
12141 #endif
12142       break;
12143
12144     case BFD_RELOC_16:
12145       if (seg->use_rela_p && !fixP->fx_done)
12146         break;
12147       if (fixP->fx_done || fixP->fx_pcrel)
12148         md_number_to_chars (buf, value, 2);
12149 #ifdef OBJ_ELF
12150       else
12151         {
12152           value = fixP->fx_offset;
12153           md_number_to_chars (buf, value, 2);
12154         }
12155 #endif
12156       break;
12157
12158 #ifdef OBJ_ELF
12159      case BFD_RELOC_ARM_TLS_GD32:
12160      case BFD_RELOC_ARM_TLS_LE32:
12161      case BFD_RELOC_ARM_TLS_IE32:
12162      case BFD_RELOC_ARM_TLS_LDM32:
12163      case BFD_RELOC_ARM_TLS_LDO32:
12164         S_SET_THREAD_LOCAL (fixP->fx_addsy);
12165         /* fall through */
12166
12167     case BFD_RELOC_ARM_GOT32:
12168     case BFD_RELOC_ARM_GOTOFF:
12169     case BFD_RELOC_ARM_TARGET2:
12170       if (seg->use_rela_p && !fixP->fx_done)
12171         break;
12172       md_number_to_chars (buf, 0, 4);
12173       break;
12174 #endif
12175
12176     case BFD_RELOC_RVA:
12177     case BFD_RELOC_32:
12178     case BFD_RELOC_ARM_TARGET1:
12179     case BFD_RELOC_ARM_ROSEGREL32:
12180     case BFD_RELOC_ARM_SBREL32:
12181     case BFD_RELOC_32_PCREL:
12182       if (seg->use_rela_p && !fixP->fx_done)
12183         break;
12184       if (fixP->fx_done || fixP->fx_pcrel)
12185         md_number_to_chars (buf, value, 4);
12186 #ifdef OBJ_ELF
12187       else
12188         {
12189           value = fixP->fx_offset;
12190           md_number_to_chars (buf, value, 4);
12191         }
12192 #endif
12193       break;
12194
12195 #ifdef OBJ_ELF
12196     case BFD_RELOC_ARM_PREL31:
12197       if (fixP->fx_done || fixP->fx_pcrel)
12198         {
12199           newval = md_chars_to_number (buf, 4) & 0x80000000;
12200           if ((value ^ (value >> 1)) & 0x40000000)
12201             {
12202               as_bad_where (fixP->fx_file, fixP->fx_line,
12203                             _("rel31 relocation overflow"));
12204             }
12205           newval |= value & 0x7fffffff;
12206           md_number_to_chars (buf, newval, 4);
12207         }
12208       break;
12209
12210     case BFD_RELOC_ARM_PLT32:
12211       /* It appears the instruction is fully prepared at this point.  */
12212       break;
12213 #endif
12214
12215     case BFD_RELOC_ARM_CP_OFF_IMM:
12216       sign = value >= 0;
12217       if (value < -1023 || value > 1023 || (value & 3))
12218         as_bad_where (fixP->fx_file, fixP->fx_line,
12219                       _("illegal value for co-processor offset"));
12220       if (value < 0)
12221         value = -value;
12222       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12223       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12224       md_number_to_chars (buf, newval, INSN_SIZE);
12225       break;
12226
12227     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12228       sign = value >= 0;
12229       if (value < -255 || value > 255)
12230         as_bad_where (fixP->fx_file, fixP->fx_line,
12231                       _("Illegal value for co-processor offset"));
12232       if (value < 0)
12233         value = -value;
12234       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12235       newval |= value | (sign ?  INDEX_UP : 0);
12236       md_number_to_chars (buf, newval , INSN_SIZE);
12237       break;
12238
12239     case BFD_RELOC_ARM_THUMB_OFFSET:
12240       newval = md_chars_to_number (buf, THUMB_SIZE);
12241       /* Exactly what ranges, and where the offset is inserted depends
12242          on the type of instruction, we can establish this from the
12243          top 4 bits.  */
12244       switch (newval >> 12)
12245         {
12246         case 4: /* PC load.  */
12247           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12248              forced to zero for these loads, so we will need to round
12249              up the offset if the instruction address is not word
12250              aligned (since the final address produced must be, and
12251              we can only describe word-aligned immediate offsets).  */
12252
12253           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12254             as_bad_where (fixP->fx_file, fixP->fx_line,
12255                           _("invalid offset, target not word aligned (0x%08X)"),
12256                           (unsigned int) (fixP->fx_frag->fr_address
12257                                           + fixP->fx_where + value));
12258
12259           if ((value + 2) & ~0x3fe)
12260             as_bad_where (fixP->fx_file, fixP->fx_line,
12261                           _("invalid offset, value too big (0x%08lX)"),
12262                           (long) value);
12263
12264           /* Round up, since pc will be rounded down.  */
12265           newval |= (value + 2) >> 2;
12266           break;
12267
12268         case 9: /* SP load/store.  */
12269           if (value & ~0x3fc)
12270             as_bad_where (fixP->fx_file, fixP->fx_line,
12271                           _("invalid offset, value too big (0x%08lX)"),
12272                           (long) value);
12273           newval |= value >> 2;
12274           break;
12275
12276         case 6: /* Word load/store.  */
12277           if (value & ~0x7c)
12278             as_bad_where (fixP->fx_file, fixP->fx_line,
12279                           _("invalid offset, value too big (0x%08lX)"),
12280                           (long) value);
12281           newval |= value << 4; /* 6 - 2.  */
12282           break;
12283
12284         case 7: /* Byte load/store.  */
12285           if (value & ~0x1f)
12286             as_bad_where (fixP->fx_file, fixP->fx_line,
12287                           _("invalid offset, value too big (0x%08lX)"),
12288                           (long) value);
12289           newval |= value << 6;
12290           break;
12291
12292         case 8: /* Halfword load/store.  */
12293           if (value & ~0x3e)
12294             as_bad_where (fixP->fx_file, fixP->fx_line,
12295                           _("invalid offset, value too big (0x%08lX)"),
12296                           (long) value);
12297           newval |= value << 5; /* 6 - 1.  */
12298           break;
12299
12300         default:
12301           as_bad_where (fixP->fx_file, fixP->fx_line,
12302                         "Unable to process relocation for thumb opcode: %lx",
12303                         (unsigned long) newval);
12304           break;
12305         }
12306       md_number_to_chars (buf, newval, THUMB_SIZE);
12307       break;
12308
12309     case BFD_RELOC_ARM_THUMB_ADD:
12310       /* This is a complicated relocation, since we use it for all of
12311          the following immediate relocations:
12312
12313             3bit ADD/SUB
12314             8bit ADD/SUB
12315             9bit ADD/SUB SP word-aligned
12316            10bit ADD PC/SP word-aligned
12317
12318          The type of instruction being processed is encoded in the
12319          instruction field:
12320
12321            0x8000  SUB
12322            0x00F0  Rd
12323            0x000F  Rs
12324       */
12325       newval = md_chars_to_number (buf, THUMB_SIZE);
12326       {
12327         int rd = (newval >> 4) & 0xf;
12328         int rs = newval & 0xf;
12329         int subtract = newval & 0x8000;
12330
12331         if (rd == REG_SP)
12332           {
12333             if (value & ~0x1fc)
12334               as_bad_where (fixP->fx_file, fixP->fx_line,
12335                             _("invalid immediate for stack address calculation"));
12336             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12337             newval |= value >> 2;
12338           }
12339         else if (rs == REG_PC || rs == REG_SP)
12340           {
12341             if (subtract ||
12342                 value & ~0x3fc)
12343               as_bad_where (fixP->fx_file, fixP->fx_line,
12344                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12345                             (unsigned long) value);
12346             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12347             newval |= rd << 8;
12348             newval |= value >> 2;
12349           }
12350         else if (rs == rd)
12351           {
12352             if (value & ~0xff)
12353               as_bad_where (fixP->fx_file, fixP->fx_line,
12354                             _("invalid 8bit immediate"));
12355             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12356             newval |= (rd << 8) | value;
12357           }
12358         else
12359           {
12360             if (value & ~0x7)
12361               as_bad_where (fixP->fx_file, fixP->fx_line,
12362                             _("invalid 3bit immediate"));
12363             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12364             newval |= rd | (rs << 3) | (value << 6);
12365           }
12366       }
12367       md_number_to_chars (buf, newval, THUMB_SIZE);
12368       break;
12369
12370     case BFD_RELOC_ARM_THUMB_IMM:
12371       newval = md_chars_to_number (buf, THUMB_SIZE);
12372       switch (newval >> 11)
12373         {
12374         case 0x04: /* 8bit immediate MOV.  */
12375         case 0x05: /* 8bit immediate CMP.  */
12376           if (value < 0 || value > 255)
12377             as_bad_where (fixP->fx_file, fixP->fx_line,
12378                           _("invalid immediate: %ld is too large"),
12379                           (long) value);
12380           newval |= value;
12381           break;
12382
12383         default:
12384           abort ();
12385         }
12386       md_number_to_chars (buf, newval, THUMB_SIZE);
12387       break;
12388
12389     case BFD_RELOC_ARM_THUMB_SHIFT:
12390       /* 5bit shift value (0..31).  */
12391       if (value < 0 || value > 31)
12392         as_bad_where (fixP->fx_file, fixP->fx_line,
12393                       _("illegal Thumb shift value: %ld"), (long) value);
12394       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12395       newval |= value << 6;
12396       md_number_to_chars (buf, newval, THUMB_SIZE);
12397       break;
12398
12399     case BFD_RELOC_VTABLE_INHERIT:
12400     case BFD_RELOC_VTABLE_ENTRY:
12401       fixP->fx_done = 0;
12402       return;
12403
12404     case BFD_RELOC_UNUSED:
12405     default:
12406       as_bad_where (fixP->fx_file, fixP->fx_line,
12407                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12408     }
12409 }
12410
12411 /* Translate internal representation of relocation info to BFD target
12412    format.  */
12413
12414 arelent *
12415 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
12416               fixS *     fixp)
12417 {
12418   arelent * reloc;
12419   bfd_reloc_code_real_type code;
12420
12421   reloc = xmalloc (sizeof (arelent));
12422
12423   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
12424   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12425   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12426
12427   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12428 #ifndef OBJ_ELF
12429   if (fixp->fx_pcrel == 0)
12430     reloc->addend = fixp->fx_offset;
12431   else
12432     reloc->addend = fixp->fx_offset = reloc->address;
12433 #else  /* OBJ_ELF */
12434   reloc->addend = fixp->fx_offset;
12435 #endif
12436
12437   switch (fixp->fx_r_type)
12438     {
12439     case BFD_RELOC_8:
12440       if (fixp->fx_pcrel)
12441         {
12442           code = BFD_RELOC_8_PCREL;
12443           break;
12444         }
12445
12446     case BFD_RELOC_16:
12447       if (fixp->fx_pcrel)
12448         {
12449           code = BFD_RELOC_16_PCREL;
12450           break;
12451         }
12452
12453     case BFD_RELOC_32:
12454       if (fixp->fx_pcrel)
12455         {
12456           code = BFD_RELOC_32_PCREL;
12457           break;
12458         }
12459
12460     case BFD_RELOC_NONE:
12461     case BFD_RELOC_ARM_PCREL_BRANCH:
12462     case BFD_RELOC_ARM_PCREL_BLX:
12463     case BFD_RELOC_RVA:
12464     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12465     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12466     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12467     case BFD_RELOC_THUMB_PCREL_BLX:
12468     case BFD_RELOC_VTABLE_ENTRY:
12469     case BFD_RELOC_VTABLE_INHERIT:
12470       code = fixp->fx_r_type;
12471       break;
12472
12473     case BFD_RELOC_ARM_LITERAL:
12474     case BFD_RELOC_ARM_HWLITERAL:
12475       /* If this is called then the a literal has
12476          been referenced across a section boundary.  */
12477       as_bad_where (fixp->fx_file, fixp->fx_line,
12478                     _("literal referenced across section boundary"));
12479       return NULL;
12480
12481 #ifdef OBJ_ELF
12482     case BFD_RELOC_ARM_GOT32:
12483     case BFD_RELOC_ARM_GOTOFF:
12484     case BFD_RELOC_ARM_PLT32:
12485     case BFD_RELOC_ARM_TARGET1:
12486     case BFD_RELOC_ARM_ROSEGREL32:
12487     case BFD_RELOC_ARM_SBREL32:
12488     case BFD_RELOC_ARM_PREL31:
12489     case BFD_RELOC_ARM_TARGET2:
12490     case BFD_RELOC_ARM_TLS_LE32:
12491     case BFD_RELOC_ARM_TLS_LDO32:
12492       code = fixp->fx_r_type;
12493       break;
12494
12495     case BFD_RELOC_ARM_TLS_GD32:
12496     case BFD_RELOC_ARM_TLS_IE32:
12497     case BFD_RELOC_ARM_TLS_LDM32:
12498       /* BFD will include the symbol's address in the addend.  
12499          But we don't want that, so subtract it out again here.  */
12500       if (!S_IS_COMMON (fixp->fx_addsy))
12501         reloc->addend -= (*reloc->sym_ptr_ptr)->value;
12502       code = fixp->fx_r_type;
12503       break;
12504 #endif
12505
12506     case BFD_RELOC_ARM_IMMEDIATE:
12507       as_bad_where (fixp->fx_file, fixp->fx_line,
12508                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12509       return NULL;
12510
12511     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12512       as_bad_where (fixp->fx_file, fixp->fx_line,
12513                     _("ADRL used for a symbol not defined in the same file"));
12514       return NULL;
12515
12516     case BFD_RELOC_ARM_OFFSET_IMM:
12517       if (fixp->fx_addsy != NULL
12518           && !S_IS_DEFINED (fixp->fx_addsy)
12519           && S_IS_LOCAL (fixp->fx_addsy))
12520         {
12521           as_bad_where (fixp->fx_file, fixp->fx_line,
12522                         _("undefined local label `%s'"),
12523                         S_GET_NAME (fixp->fx_addsy));
12524           return NULL;
12525         }
12526
12527       as_bad_where (fixp->fx_file, fixp->fx_line,
12528                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12529       return NULL;
12530
12531     default:
12532       {
12533         char * type;
12534
12535         switch (fixp->fx_r_type)
12536           {
12537           case BFD_RELOC_NONE:             type = "NONE";         break;
12538           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12539           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12540           case BFD_RELOC_ARM_SMI:          type = "SMI";          break;
12541           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12542           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12543           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12544           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12545           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12546           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12547           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12548           default:                         type = _("<unknown>"); break;
12549           }
12550         as_bad_where (fixp->fx_file, fixp->fx_line,
12551                       _("cannot represent %s relocation in this object file format"),
12552                       type);
12553         return NULL;
12554       }
12555     }
12556
12557 #ifdef OBJ_ELF
12558   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12559       && GOT_symbol
12560       && fixp->fx_addsy == GOT_symbol)
12561     {
12562       code = BFD_RELOC_ARM_GOTPC;
12563       reloc->addend = fixp->fx_offset = reloc->address;
12564     }
12565 #endif
12566
12567   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12568
12569   if (reloc->howto == NULL)
12570     {
12571       as_bad_where (fixp->fx_file, fixp->fx_line,
12572                     _("cannot represent %s relocation in this object file format"),
12573                     bfd_get_reloc_code_name (code));
12574       return NULL;
12575     }
12576
12577   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12578      vtable entry to be used in the relocation's section offset.  */
12579   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12580     reloc->address = fixp->fx_offset;
12581
12582   return reloc;
12583 }
12584
12585 int
12586 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
12587                                segT    segtype ATTRIBUTE_UNUSED)
12588 {
12589   as_fatal (_("md_estimate_size_before_relax\n"));
12590   return 1;
12591 }
12592
12593 /* We need to be able to fix up arbitrary expressions in some statements.
12594    This is so that we can handle symbols that are an arbitrary distance from
12595    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12596    which returns part of an address in a form which will be valid for
12597    a data instruction.  We do this by pushing the expression into a symbol
12598    in the expr_section, and creating a fix for that.  */
12599
12600 static void
12601 fix_new_arm (fragS *       frag,
12602              int           where,
12603              short int     size,
12604              expressionS * exp,
12605              int           pc_rel,
12606              int           reloc)
12607 {
12608   fixS *           new_fix;
12609   arm_fix_data *   arm_data;
12610
12611   switch (exp->X_op)
12612     {
12613     case O_constant:
12614     case O_symbol:
12615     case O_add:
12616     case O_subtract:
12617       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12618       break;
12619
12620     default:
12621       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12622                          pc_rel, reloc);
12623       break;
12624     }
12625
12626   /* Mark whether the fix is to a THUMB instruction, or an ARM
12627      instruction.  */
12628   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
12629   new_fix->tc_fix_data = (PTR) arm_data;
12630   arm_data->thumb_mode = thumb_mode;
12631 }
12632
12633 static void
12634 output_inst (const char * str)
12635 {
12636   char * to = NULL;
12637
12638   if (inst.error)
12639     {
12640       as_bad ("%s -- `%s'", inst.error, str);
12641       return;
12642     }
12643
12644   to = frag_more (inst.size);
12645
12646   if (thumb_mode && (inst.size > THUMB_SIZE))
12647     {
12648       assert (inst.size == (2 * THUMB_SIZE));
12649       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12650       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12651     }
12652   else if (inst.size > INSN_SIZE)
12653     {
12654       assert (inst.size == (2 * INSN_SIZE));
12655       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12656       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12657     }
12658   else
12659     md_number_to_chars (to, inst.instruction, inst.size);
12660
12661   if (inst.reloc.type != BFD_RELOC_UNUSED)
12662     fix_new_arm (frag_now, to - frag_now->fr_literal,
12663                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12664                  inst.reloc.type);
12665
12666 #ifdef OBJ_ELF
12667   dwarf2_emit_insn (inst.size);
12668 #endif
12669 }
12670
12671 void
12672 md_assemble (char * str)
12673 {
12674   char  c;
12675   char *p;
12676   char *start;
12677
12678   /* Align the previous label if needed.  */
12679   if (last_label_seen != NULL)
12680     {
12681       symbol_set_frag (last_label_seen, frag_now);
12682       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12683       S_SET_SEGMENT (last_label_seen, now_seg);
12684     }
12685
12686   memset (&inst, '\0', sizeof (inst));
12687   inst.reloc.type = BFD_RELOC_UNUSED;
12688
12689   skip_whitespace (str);
12690
12691   /* Scan up to the end of the op-code, which must end in white space or
12692      end of string.  */
12693   for (start = p = str; *p != '\0'; p++)
12694     if (*p == ' ')
12695       break;
12696
12697   if (p == str)
12698     {
12699       as_bad (_("no operator -- statement `%s'\n"), str);
12700       return;
12701     }
12702
12703   if (thumb_mode)
12704     {
12705       const struct thumb_opcode * opcode;
12706
12707       c = *p;
12708       *p = '\0';
12709       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12710       *p = c;
12711
12712       if (opcode)
12713         {
12714           /* Check that this instruction is supported for this CPU.  */
12715           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12716             {
12717               as_bad (_("selected processor does not support `%s'"), str);
12718               return;
12719             }
12720
12721           mapping_state (MAP_THUMB);
12722           inst.instruction = opcode->value;
12723           inst.size = opcode->size;
12724           opcode->parms (p);
12725           output_inst (str);
12726           return;
12727         }
12728     }
12729   else
12730     {
12731       const struct asm_opcode * opcode;
12732
12733       c = *p;
12734       *p = '\0';
12735       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12736       *p = c;
12737
12738       if (opcode)
12739         {
12740           /* Check that this instruction is supported for this CPU.  */
12741           if ((opcode->variant & cpu_variant) == 0)
12742             {
12743               as_bad (_("selected processor does not support `%s'"), str);
12744               return;
12745             }
12746
12747           mapping_state (MAP_ARM);
12748           inst.instruction = opcode->value;
12749           inst.size = INSN_SIZE;
12750           opcode->parms (p);
12751           output_inst (str);
12752           return;
12753         }
12754     }
12755
12756   /* It wasn't an instruction, but it might be a register alias of the form
12757      alias .req reg.  */
12758   if (create_register_alias (str, p))
12759     return;
12760
12761   as_bad (_("bad instruction `%s'"), start);
12762 }
12763
12764 /* md_parse_option
12765       Invocation line includes a switch not recognized by the base assembler.
12766       See if it's a processor-specific option.
12767
12768       This routine is somewhat complicated by the need for backwards
12769       compatibility (since older releases of gcc can't be changed).
12770       The new options try to make the interface as compatible as
12771       possible with GCC.
12772
12773       New options (supported) are:
12774
12775               -mcpu=<cpu name>           Assemble for selected processor
12776               -march=<architecture name> Assemble for selected architecture
12777               -mfpu=<fpu architecture>   Assemble for selected FPU.
12778               -EB/-mbig-endian           Big-endian
12779               -EL/-mlittle-endian        Little-endian
12780               -k                         Generate PIC code
12781               -mthumb                    Start in Thumb mode
12782               -mthumb-interwork          Code supports ARM/Thumb interworking
12783
12784       For now we will also provide support for:
12785
12786               -mapcs-32                  32-bit Program counter
12787               -mapcs-26                  26-bit Program counter
12788               -macps-float               Floats passed in FP registers
12789               -mapcs-reentrant           Reentrant code
12790               -matpcs
12791       (sometime these will probably be replaced with -mapcs=<list of options>
12792       and -matpcs=<list of options>)
12793
12794       The remaining options are only supported for back-wards compatibility.
12795       Cpu variants, the arm part is optional:
12796               -m[arm]1                Currently not supported.
12797               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
12798               -m[arm]3                Arm 3 processor
12799               -m[arm]6[xx],           Arm 6 processors
12800               -m[arm]7[xx][t][[d]m]   Arm 7 processors
12801               -m[arm]8[10]            Arm 8 processors
12802               -m[arm]9[20][tdmi]      Arm 9 processors
12803               -mstrongarm[110[0]]     StrongARM processors
12804               -mxscale                XScale processors
12805               -m[arm]v[2345[t[e]]]    Arm architectures
12806               -mall                   All (except the ARM1)
12807       FP variants:
12808               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
12809               -mfpe-old               (No float load/store multiples)
12810               -mvfpxd                 VFP Single precision
12811               -mvfp                   All VFP
12812               -mno-fpu                Disable all floating point instructions
12813
12814       The following CPU names are recognized:
12815               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12816               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12817               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12818               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12819               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12820               arm10t arm10e, arm1020t, arm1020e, arm10200e,
12821               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
12822
12823       */
12824
12825 const char * md_shortopts = "m:k";
12826
12827 #ifdef ARM_BI_ENDIAN
12828 #define OPTION_EB (OPTION_MD_BASE + 0)
12829 #define OPTION_EL (OPTION_MD_BASE + 1)
12830 #else
12831 #if TARGET_BYTES_BIG_ENDIAN
12832 #define OPTION_EB (OPTION_MD_BASE + 0)
12833 #else
12834 #define OPTION_EL (OPTION_MD_BASE + 1)
12835 #endif
12836 #endif
12837
12838 struct option md_longopts[] =
12839 {
12840 #ifdef OPTION_EB
12841   {"EB", no_argument, NULL, OPTION_EB},
12842 #endif
12843 #ifdef OPTION_EL
12844   {"EL", no_argument, NULL, OPTION_EL},
12845 #endif
12846   {NULL, no_argument, NULL, 0}
12847 };
12848
12849 size_t md_longopts_size = sizeof (md_longopts);
12850
12851 struct arm_option_table
12852 {
12853   char *option;         /* Option name to match.  */
12854   char *help;           /* Help information.  */
12855   int  *var;            /* Variable to change.  */
12856   int   value;          /* What to change it to.  */
12857   char *deprecated;     /* If non-null, print this message.  */
12858 };
12859
12860 struct arm_option_table arm_opts[] =
12861 {
12862   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
12863   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
12864   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12865    &support_interwork, 1, NULL},
12866   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12867   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12868   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12869    1, NULL},
12870   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12871   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12872   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12873   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
12874    NULL},
12875
12876   /* These are recognized by the assembler, but have no affect on code.  */
12877   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12878   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12879
12880   /* DON'T add any new processors to this list -- we want the whole list
12881      to go away...  Add them to the processors table instead.  */
12882   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12883   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12884   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12885   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12886   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12887   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12888   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12889   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12890   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12891   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12892   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12893   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12894   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12895   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12896   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12897   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12898   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12899   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12900   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12901   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12902   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12903   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12904   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12905   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12906   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12907   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12908   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12909   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12910   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12911   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12912   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12913   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12914   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12915   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12916   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12917   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12918   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12919   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12920   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12921   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12922   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12923   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12924   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12925   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12926   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12927   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12928   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12929   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12930   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12931   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12932   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12933   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12934   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12935   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12936   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12937   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12938   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12939   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12940   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12941   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12942   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12943   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12944   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12945   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12946   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12947   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12948   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12949   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12950   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
12951   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12952    N_("use -mcpu=strongarm110")},
12953   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12954    N_("use -mcpu=strongarm1100")},
12955   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12956    N_("use -mcpu=strongarm1110")},
12957   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12958   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12959   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
12960
12961   /* Architecture variants -- don't add any more to this list either.  */
12962   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12963   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12964   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12965   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12966   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12967   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12968   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12969   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12970   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12971   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12972   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12973   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12974   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12975   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12976   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12977   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12978   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12979   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12980
12981   /* Floating point variants -- don't add any more to this list either.  */
12982   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12983   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12984   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12985   {"mno-fpu",  NULL, &legacy_fpu, 0,
12986    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
12987
12988   {NULL, NULL, NULL, 0, NULL}
12989 };
12990
12991 struct arm_cpu_option_table
12992 {
12993   char *name;
12994   int   value;
12995   /* For some CPUs we assume an FPU unless the user explicitly sets
12996      -mfpu=...  */
12997   int   default_fpu;
12998 };
12999
13000 /* This list should, at a minimum, contain all the cpu names
13001    recognized by GCC.  */
13002 static struct arm_cpu_option_table arm_cpus[] =
13003 {
13004   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13005   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13006   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13007   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13008   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13009   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13010   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13011   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13012   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13013   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13014   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13015   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13016   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13017   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13018   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13019   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13020   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13021   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13022   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13023   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13024   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13025   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13026   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13027   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13028   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13029   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13030   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13031   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13032   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13033   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13034   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
13035   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13036   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13037   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13038   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13039   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13040   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13041   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13042   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13043   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13044   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13045   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13046   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13047   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13048   /* For V5 or later processors we default to using VFP; but the user
13049      should really set the FPU type explicitly.  */
13050   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13051   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13052   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13053   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13054   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13055   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13056   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13057   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13058   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13059   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13060   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13061   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13062   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13063   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13064   {"arm1026ejs",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13065   {"arm1026ej-s",       ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13066   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13067   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
13068   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13069   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13070   {"mpcore",            ARM_ARCH_V6K,    FPU_ARCH_VFP_V2},
13071   {"mpcorenovfp",       ARM_ARCH_V6K,    FPU_NONE},
13072   {"arm1176jz-s",       ARM_ARCH_V6ZK,   FPU_NONE},
13073   {"arm1176jzf-s",      ARM_ARCH_V6ZK,   FPU_ARCH_VFP_V2},
13074   /* ??? XSCALE is really an architecture.  */
13075   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13076   /* ??? iwmmxt is not a processor.  */
13077   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13078   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13079   /* Maverick */
13080   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13081   {NULL, 0, 0}
13082 };
13083
13084 struct arm_arch_option_table
13085 {
13086   char *name;
13087   int   value;
13088   int   default_fpu;
13089 };
13090
13091 /* This list should, at a minimum, contain all the architecture names
13092    recognized by GCC.  */
13093 static struct arm_arch_option_table arm_archs[] =
13094 {
13095   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13096   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13097   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13098   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13099   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13100   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13101   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13102   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13103   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13104   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13105   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13106   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13107   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13108   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13109   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13110   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13111   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13112   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13113   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13114   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
13115   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
13116   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
13117   {"armv6t2",           ARM_ARCH_V6T2,   FPU_ARCH_VFP},
13118   {"armv6kt2",          ARM_ARCH_V6KT2,  FPU_ARCH_VFP},
13119   {"armv6zt2",          ARM_ARCH_V6ZT2,  FPU_ARCH_VFP},
13120   {"armv6zkt2",         ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
13121   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13122   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13123   {NULL, 0, 0}
13124 };
13125
13126 /* ISA extensions in the co-processor space.  */
13127 struct arm_arch_extension_table
13128 {
13129   char *name;
13130   int value;
13131 };
13132
13133 static struct arm_arch_extension_table arm_extensions[] =
13134 {
13135   {"maverick",          ARM_CEXT_MAVERICK},
13136   {"xscale",            ARM_CEXT_XSCALE},
13137   {"iwmmxt",            ARM_CEXT_IWMMXT},
13138   {NULL,                0}
13139 };
13140
13141 struct arm_fpu_option_table
13142 {
13143   char *name;
13144   int   value;
13145 };
13146
13147 /* This list should, at a minimum, contain all the fpu names
13148    recognized by GCC.  */
13149 static struct arm_fpu_option_table arm_fpus[] =
13150 {
13151   {"softfpa",           FPU_NONE},
13152   {"fpe",               FPU_ARCH_FPE},
13153   {"fpe2",              FPU_ARCH_FPE},
13154   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13155   {"fpa",               FPU_ARCH_FPA},
13156   {"fpa10",             FPU_ARCH_FPA},
13157   {"fpa11",             FPU_ARCH_FPA},
13158   {"arm7500fe",         FPU_ARCH_FPA},
13159   {"softvfp",           FPU_ARCH_VFP},
13160   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13161   {"vfp",               FPU_ARCH_VFP_V2},
13162   {"vfp9",              FPU_ARCH_VFP_V2},
13163   {"vfp10",             FPU_ARCH_VFP_V2},
13164   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13165   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13166   {"arm1020t",          FPU_ARCH_VFP_V1},
13167   {"arm1020e",          FPU_ARCH_VFP_V2},
13168   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13169   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
13170   {"maverick",          FPU_ARCH_MAVERICK},
13171   {NULL, 0}
13172 };
13173
13174 struct arm_float_abi_option_table
13175 {
13176   char *name;
13177   int value;
13178 };
13179
13180 static struct arm_float_abi_option_table arm_float_abis[] =
13181 {
13182   {"hard",      ARM_FLOAT_ABI_HARD},
13183   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13184   {"soft",      ARM_FLOAT_ABI_SOFT},
13185   {NULL, 0}
13186 };
13187
13188 struct arm_eabi_option_table
13189 {
13190   char *name;
13191   unsigned int value;
13192 };
13193
13194 #ifdef OBJ_ELF
13195 /* We only know how to output GNU and ver 4 (AAELF) formats.  */
13196 static struct arm_eabi_option_table arm_eabis[] =
13197 {
13198   {"gnu",       EF_ARM_EABI_UNKNOWN},
13199   {"4",         EF_ARM_EABI_VER4},
13200   {NULL, 0}
13201 };
13202 #endif
13203
13204 struct arm_long_option_table
13205 {
13206   char * option;                /* Substring to match.  */
13207   char * help;                  /* Help information.  */
13208   int (* func) (char * subopt); /* Function to decode sub-option.  */
13209   char * deprecated;            /* If non-null, print this message.  */
13210 };
13211
13212 static int
13213 arm_parse_extension (char * str, int * opt_p)
13214 {
13215   while (str != NULL && *str != 0)
13216     {
13217       struct arm_arch_extension_table * opt;
13218       char * ext;
13219       int optlen;
13220
13221       if (*str != '+')
13222         {
13223           as_bad (_("invalid architectural extension"));
13224           return 0;
13225         }
13226
13227       str++;
13228       ext = strchr (str, '+');
13229
13230       if (ext != NULL)
13231         optlen = ext - str;
13232       else
13233         optlen = strlen (str);
13234
13235       if (optlen == 0)
13236         {
13237           as_bad (_("missing architectural extension"));
13238           return 0;
13239         }
13240
13241       for (opt = arm_extensions; opt->name != NULL; opt++)
13242         if (strncmp (opt->name, str, optlen) == 0)
13243           {
13244             *opt_p |= opt->value;
13245             break;
13246           }
13247
13248       if (opt->name == NULL)
13249         {
13250           as_bad (_("unknown architectural extnsion `%s'"), str);
13251           return 0;
13252         }
13253
13254       str = ext;
13255     };
13256
13257   return 1;
13258 }
13259
13260 static int
13261 arm_parse_cpu (char * str)
13262 {
13263   struct arm_cpu_option_table * opt;
13264   char * ext = strchr (str, '+');
13265   int optlen;
13266
13267   if (ext != NULL)
13268     optlen = ext - str;
13269   else
13270     optlen = strlen (str);
13271
13272   if (optlen == 0)
13273     {
13274       as_bad (_("missing cpu name `%s'"), str);
13275       return 0;
13276     }
13277
13278   for (opt = arm_cpus; opt->name != NULL; opt++)
13279     if (strncmp (opt->name, str, optlen) == 0)
13280       {
13281         mcpu_cpu_opt = opt->value;
13282         mcpu_fpu_opt = opt->default_fpu;
13283
13284         if (ext != NULL)
13285           return arm_parse_extension (ext, &mcpu_cpu_opt);
13286
13287         return 1;
13288       }
13289
13290   as_bad (_("unknown cpu `%s'"), str);
13291   return 0;
13292 }
13293
13294 static int
13295 arm_parse_arch (char * str)
13296 {
13297   struct arm_arch_option_table *opt;
13298   char *ext = strchr (str, '+');
13299   int optlen;
13300
13301   if (ext != NULL)
13302     optlen = ext - str;
13303   else
13304     optlen = strlen (str);
13305
13306   if (optlen == 0)
13307     {
13308       as_bad (_("missing architecture name `%s'"), str);
13309       return 0;
13310     }
13311
13312
13313   for (opt = arm_archs; opt->name != NULL; opt++)
13314     if (streq (opt->name, str))
13315       {
13316         march_cpu_opt = opt->value;
13317         march_fpu_opt = opt->default_fpu;
13318
13319         if (ext != NULL)
13320           return arm_parse_extension (ext, &march_cpu_opt);
13321
13322         return 1;
13323       }
13324
13325   as_bad (_("unknown architecture `%s'\n"), str);
13326   return 0;
13327 }
13328
13329 static int
13330 arm_parse_fpu (char * str)
13331 {
13332   struct arm_fpu_option_table * opt;
13333
13334   for (opt = arm_fpus; opt->name != NULL; opt++)
13335     if (streq (opt->name, str))
13336       {
13337         mfpu_opt = opt->value;
13338         return 1;
13339       }
13340
13341   as_bad (_("unknown floating point format `%s'\n"), str);
13342   return 0;
13343 }
13344
13345 static int
13346 arm_parse_float_abi (char * str)
13347 {
13348   struct arm_float_abi_option_table * opt;
13349
13350   for (opt = arm_float_abis; opt->name != NULL; opt++)
13351     if (streq (opt->name, str))
13352       {
13353         mfloat_abi_opt = opt->value;
13354         return 1;
13355       }
13356
13357   as_bad (_("unknown floating point abi `%s'\n"), str);
13358   return 0;
13359 }
13360
13361 #ifdef OBJ_ELF
13362 static int
13363 arm_parse_eabi (char * str)
13364 {
13365   struct arm_eabi_option_table *opt;
13366
13367   for (opt = arm_eabis; opt->name != NULL; opt++)
13368     if (streq (opt->name, str))
13369       {
13370         meabi_flags = opt->value;
13371         return 1;
13372       }
13373   as_bad (_("unknown EABI `%s'\n"), str);
13374   return 0;
13375 }
13376 #endif
13377
13378 struct arm_long_option_table arm_long_opts[] =
13379 {
13380   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13381    arm_parse_cpu, NULL},
13382   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13383    arm_parse_arch, NULL},
13384   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13385    arm_parse_fpu, NULL},
13386   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13387    arm_parse_float_abi, NULL},
13388 #ifdef OBJ_ELF
13389   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13390    arm_parse_eabi, NULL},
13391 #endif
13392   {NULL, NULL, 0, NULL}
13393 };
13394
13395 int
13396 md_parse_option (int c, char * arg)
13397 {
13398   struct arm_option_table *opt;
13399   struct arm_long_option_table *lopt;
13400
13401   switch (c)
13402     {
13403 #ifdef OPTION_EB
13404     case OPTION_EB:
13405       target_big_endian = 1;
13406       break;
13407 #endif
13408
13409 #ifdef OPTION_EL
13410     case OPTION_EL:
13411       target_big_endian = 0;
13412       break;
13413 #endif
13414
13415     case 'a':
13416       /* Listing option.  Just ignore these, we don't support additional
13417          ones.  */
13418       return 0;
13419
13420     default:
13421       for (opt = arm_opts; opt->option != NULL; opt++)
13422         {
13423           if (c == opt->option[0]
13424               && ((arg == NULL && opt->option[1] == 0)
13425                   || streq (arg, opt->option + 1)))
13426             {
13427 #if WARN_DEPRECATED
13428               /* If the option is deprecated, tell the user.  */
13429               if (opt->deprecated != NULL)
13430                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13431                            arg ? arg : "", _(opt->deprecated));
13432 #endif
13433
13434               if (opt->var != NULL)
13435                 *opt->var = opt->value;
13436
13437               return 1;
13438             }
13439         }
13440
13441       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13442         {
13443           /* These options are expected to have an argument.  */
13444           if (c == lopt->option[0]
13445               && arg != NULL
13446               && strncmp (arg, lopt->option + 1,
13447                           strlen (lopt->option + 1)) == 0)
13448             {
13449 #if WARN_DEPRECATED
13450               /* If the option is deprecated, tell the user.  */
13451               if (lopt->deprecated != NULL)
13452                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13453                            _(lopt->deprecated));
13454 #endif
13455
13456               /* Call the sup-option parser.  */
13457               return lopt->func (arg + strlen (lopt->option) - 1);
13458             }
13459         }
13460
13461       return 0;
13462     }
13463
13464   return 1;
13465 }
13466
13467 void
13468 md_show_usage (FILE * fp)
13469 {
13470   struct arm_option_table *opt;
13471   struct arm_long_option_table *lopt;
13472
13473   fprintf (fp, _(" ARM-specific assembler options:\n"));
13474
13475   for (opt = arm_opts; opt->option != NULL; opt++)
13476     if (opt->help != NULL)
13477       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13478
13479   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13480     if (lopt->help != NULL)
13481       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13482
13483 #ifdef OPTION_EB
13484   fprintf (fp, _("\
13485   -EB                     assemble code for a big-endian cpu\n"));
13486 #endif
13487
13488 #ifdef OPTION_EL
13489   fprintf (fp, _("\
13490   -EL                     assemble code for a little-endian cpu\n"));
13491 #endif
13492 }
13493
13494 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13495
13496 void
13497 cons_fix_new_arm (fragS *       frag,
13498                   int           where,
13499                   int           size,
13500                   expressionS * exp)
13501 {
13502   bfd_reloc_code_real_type type;
13503   int pcrel = 0;
13504
13505   /* Pick a reloc.
13506      FIXME: @@ Should look at CPU word size.  */
13507   switch (size)
13508     {
13509     case 1:
13510       type = BFD_RELOC_8;
13511       break;
13512     case 2:
13513       type = BFD_RELOC_16;
13514       break;
13515     case 4:
13516     default:
13517       type = BFD_RELOC_32;
13518       break;
13519     case 8:
13520       type = BFD_RELOC_64;
13521       break;
13522     }
13523
13524   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13525 }
13526
13527 /* A good place to do this, although this was probably not intended
13528    for this kind of use.  We need to dump the literal pool before
13529    references are made to a null symbol pointer.  */
13530
13531 void
13532 arm_cleanup (void)
13533 {
13534   literal_pool * pool;
13535
13536   for (pool = list_of_pools; pool; pool = pool->next)
13537     {
13538       /* Put it at the end of the relevent section.  */
13539       subseg_set (pool->section, pool->sub_section);
13540 #ifdef OBJ_ELF
13541       arm_elf_change_section ();
13542 #endif
13543       s_ltorg (0);
13544     }
13545 }
13546
13547 void
13548 arm_start_line_hook (void)
13549 {
13550   last_label_seen = NULL;
13551 }
13552
13553 void
13554 arm_frob_label (symbolS * sym)
13555 {
13556   last_label_seen = sym;
13557
13558   ARM_SET_THUMB (sym, thumb_mode);
13559
13560 #if defined OBJ_COFF || defined OBJ_ELF
13561   ARM_SET_INTERWORK (sym, support_interwork);
13562 #endif
13563
13564   /* Note - do not allow local symbols (.Lxxx) to be labeled
13565      as Thumb functions.  This is because these labels, whilst
13566      they exist inside Thumb code, are not the entry points for
13567      possible ARM->Thumb calls.  Also, these labels can be used
13568      as part of a computed goto or switch statement.  eg gcc
13569      can generate code that looks like this:
13570
13571                 ldr  r2, [pc, .Laaa]
13572                 lsl  r3, r3, #2
13573                 ldr  r2, [r3, r2]
13574                 mov  pc, r2
13575
13576        .Lbbb:  .word .Lxxx
13577        .Lccc:  .word .Lyyy
13578        ..etc...
13579        .Laaa:   .word Lbbb
13580
13581      The first instruction loads the address of the jump table.
13582      The second instruction converts a table index into a byte offset.
13583      The third instruction gets the jump address out of the table.
13584      The fourth instruction performs the jump.
13585
13586      If the address stored at .Laaa is that of a symbol which has the
13587      Thumb_Func bit set, then the linker will arrange for this address
13588      to have the bottom bit set, which in turn would mean that the
13589      address computation performed by the third instruction would end
13590      up with the bottom bit set.  Since the ARM is capable of unaligned
13591      word loads, the instruction would then load the incorrect address
13592      out of the jump table, and chaos would ensue.  */
13593   if (label_is_thumb_function_name
13594       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13595       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13596     {
13597       /* When the address of a Thumb function is taken the bottom
13598          bit of that address should be set.  This will allow
13599          interworking between Arm and Thumb functions to work
13600          correctly.  */
13601
13602       THUMB_SET_FUNC (sym, 1);
13603
13604       label_is_thumb_function_name = FALSE;
13605     }
13606 }
13607
13608 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13609    ARM ones.  */
13610
13611 void
13612 arm_adjust_symtab (void)
13613 {
13614 #ifdef OBJ_COFF
13615   symbolS * sym;
13616
13617   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13618     {
13619       if (ARM_IS_THUMB (sym))
13620         {
13621           if (THUMB_IS_FUNC (sym))
13622             {
13623               /* Mark the symbol as a Thumb function.  */
13624               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13625                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13626                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13627
13628               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13629                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13630               else
13631                 as_bad (_("%s: unexpected function type: %d"),
13632                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13633             }
13634           else switch (S_GET_STORAGE_CLASS (sym))
13635             {
13636             case C_EXT:
13637               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13638               break;
13639             case C_STAT:
13640               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13641               break;
13642             case C_LABEL:
13643               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13644               break;
13645             default:
13646               /* Do nothing.  */
13647               break;
13648             }
13649         }
13650
13651       if (ARM_IS_INTERWORK (sym))
13652         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13653     }
13654 #endif
13655 #ifdef OBJ_ELF
13656   symbolS * sym;
13657   char      bind;
13658
13659   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13660     {
13661       if (ARM_IS_THUMB (sym))
13662         {
13663           elf_symbol_type * elf_sym;
13664
13665           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13666           bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
13667
13668           if (! bfd_is_arm_mapping_symbol_name (elf_sym->symbol.name))
13669             { 
13670               /* If it's a .thumb_func, declare it as so,
13671                  otherwise tag label as .code 16.  */
13672               if (THUMB_IS_FUNC (sym))
13673                 elf_sym->internal_elf_sym.st_info =
13674                   ELF_ST_INFO (bind, STT_ARM_TFUNC);
13675               else
13676                 elf_sym->internal_elf_sym.st_info =
13677                   ELF_ST_INFO (bind, STT_ARM_16BIT);
13678             }
13679         }
13680     }
13681 #endif
13682 }
13683
13684 int
13685 arm_data_in_code (void)
13686 {
13687   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13688     {
13689       *input_line_pointer = '/';
13690       input_line_pointer += 5;
13691       *input_line_pointer = 0;
13692       return 1;
13693     }
13694
13695   return 0;
13696 }
13697
13698 char *
13699 arm_canonicalize_symbol_name (char * name)
13700 {
13701   int len;
13702
13703   if (thumb_mode && (len = strlen (name)) > 5
13704       && streq (name + len - 5, "/data"))
13705     *(name + len - 5) = 0;
13706
13707   return name;
13708 }
13709
13710 #if defined OBJ_COFF || defined OBJ_ELF
13711 void
13712 arm_validate_fix (fixS * fixP)
13713 {
13714   /* If the destination of the branch is a defined symbol which does not have
13715      the THUMB_FUNC attribute, then we must be calling a function which has
13716      the (interfacearm) attribute.  We look for the Thumb entry point to that
13717      function and change the branch to refer to that function instead.  */
13718   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13719       && fixP->fx_addsy != NULL
13720       && S_IS_DEFINED (fixP->fx_addsy)
13721       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13722     {
13723       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13724     }
13725 }
13726 #endif
13727
13728 int
13729 arm_force_relocation (struct fix * fixp)
13730 {
13731 #if defined (OBJ_COFF) && defined (TE_PE)
13732   if (fixp->fx_r_type == BFD_RELOC_RVA)
13733     return 1;
13734 #endif
13735 #ifdef OBJ_ELF
13736   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13737       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13738       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13739       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13740     return 1;
13741 #endif
13742
13743   /* Resolve these relocations even if the symbol is extern or weak.  */
13744   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13745       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13746       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13747     return 0;
13748
13749   return generic_force_reloc (fixp);
13750 }
13751
13752 #ifdef OBJ_COFF
13753 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13754    local labels from being added to the output symbol table when they
13755    are used with the ADRL pseudo op.  The ADRL relocation should always
13756    be resolved before the binbary is emitted, so it is safe to say that
13757    it is adjustable.  */
13758
13759 bfd_boolean
13760 arm_fix_adjustable (fixS * fixP)
13761 {
13762   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13763     return 1;
13764   return 0;
13765 }
13766 #endif
13767
13768 #ifdef OBJ_ELF
13769 /* Relocations against Thumb function names must be left unadjusted,
13770    so that the linker can use this information to correctly set the
13771    bottom bit of their addresses.  The MIPS version of this function
13772    also prevents relocations that are mips-16 specific, but I do not
13773    know why it does this.
13774
13775    FIXME:
13776    There is one other problem that ought to be addressed here, but
13777    which currently is not:  Taking the address of a label (rather
13778    than a function) and then later jumping to that address.  Such
13779    addresses also ought to have their bottom bit set (assuming that
13780    they reside in Thumb code), but at the moment they will not.  */
13781
13782 bfd_boolean
13783 arm_fix_adjustable (fixS * fixP)
13784 {
13785   if (fixP->fx_addsy == NULL)
13786     return 1;
13787
13788   if (THUMB_IS_FUNC (fixP->fx_addsy)
13789       && fixP->fx_subsy == NULL)
13790     return 0;
13791
13792   /* We need the symbol name for the VTABLE entries.  */
13793   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
13794       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
13795     return 0;
13796
13797   /* Don't allow symbols to be discarded on GOT related relocs.  */
13798   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
13799       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
13800       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
13801       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
13802       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
13803       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
13804       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
13805       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
13806       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
13807     return 0;
13808
13809   return 1;
13810 }
13811
13812 const char *
13813 elf32_arm_target_format (void)
13814 {
13815 #ifdef TE_SYMBIAN
13816   return (target_big_endian
13817           ? "elf32-bigarm-symbian"
13818           : "elf32-littlearm-symbian");
13819 #elif defined (TE_VXWORKS)
13820   return (target_big_endian
13821           ? "elf32-bigarm-vxworks"
13822           : "elf32-littlearm-vxworks");
13823 #else
13824   if (target_big_endian)
13825     return "elf32-bigarm";
13826   else
13827     return "elf32-littlearm";
13828 #endif
13829 }
13830
13831 void
13832 armelf_frob_symbol (symbolS * symp,
13833                     int *     puntp)
13834 {
13835   elf_frob_symbol (symp, puntp);
13836 }
13837
13838 static void
13839 s_arm_elf_cons (int nbytes)
13840 {
13841   expressionS exp;
13842
13843 #ifdef md_flush_pending_output
13844   md_flush_pending_output ();
13845 #endif
13846
13847   if (is_it_end_of_statement ())
13848     {
13849       demand_empty_rest_of_line ();
13850       return;
13851     }
13852
13853 #ifdef md_cons_align
13854   md_cons_align (nbytes);
13855 #endif
13856
13857   mapping_state (MAP_DATA);
13858   do
13859     {
13860       bfd_reloc_code_real_type reloc;
13861       char *sym_start;
13862       int sym_len;
13863
13864       sym_start = input_line_pointer;
13865       expression (& exp);
13866       sym_len = input_line_pointer - sym_start;
13867
13868       if (exp.X_op == O_symbol
13869           && * input_line_pointer == '('
13870           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
13871         {
13872           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13873           int size = bfd_get_reloc_size (howto);
13874
13875           if (size > nbytes)
13876             as_bad ("%s relocations do not fit in %d bytes",
13877                     howto->name, nbytes);
13878           else
13879             {
13880               char *p;
13881               int offset = nbytes - size;
13882               char *saved_buf = alloca (sym_len), *saved_input;
13883
13884               /* We've parsed an expression stopping at O_symbol.  But there
13885                  may be more expression left now that we have parsed the
13886                  relocation marker.  Parse it again.  */
13887               saved_input = input_line_pointer - sym_len;
13888               memcpy (saved_buf, saved_input, sym_len);
13889               memmove (saved_input, sym_start, sym_len);
13890               input_line_pointer = saved_input;
13891               expression (& exp);
13892               memcpy (saved_input, saved_buf, sym_len);
13893               assert (input_line_pointer >= saved_input + sym_len);
13894
13895               p = frag_more ((int) nbytes);
13896               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13897                            &exp, 0, reloc);
13898             }
13899         }
13900       else
13901         emit_expr (&exp, (unsigned int) nbytes);
13902     }
13903   while (*input_line_pointer++ == ',');
13904
13905   /* Put terminator back into stream.  */
13906   input_line_pointer --;
13907   demand_empty_rest_of_line ();
13908 }
13909
13910
13911 /* Parse a .rel31 directive.  */
13912
13913 static void
13914 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
13915 {
13916   expressionS exp;
13917   char *p;
13918   valueT highbit;
13919
13920   SKIP_WHITESPACE ();
13921
13922   highbit = 0;
13923   if (*input_line_pointer == '1')
13924     highbit = 0x80000000;
13925   else if (*input_line_pointer != '0')
13926     as_bad (_("expected 0 or 1"));
13927
13928   input_line_pointer++;
13929   SKIP_WHITESPACE ();
13930   if (*input_line_pointer != ',')
13931     as_bad (_("missing comma"));
13932   input_line_pointer++;
13933
13934 #ifdef md_flush_pending_output
13935   md_flush_pending_output ();
13936 #endif
13937
13938 #ifdef md_cons_align
13939   md_cons_align (4);
13940 #endif
13941
13942   mapping_state (MAP_DATA);
13943
13944   expression (&exp);
13945
13946   p = frag_more (4);
13947   md_number_to_chars (p, highbit, 4);
13948   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
13949                BFD_RELOC_ARM_PREL31);
13950
13951   demand_empty_rest_of_line ();
13952 }
13953 \f
13954 /* Code to deal with unwinding tables.  */
13955
13956 static void add_unwind_adjustsp (offsetT);
13957
13958 /* Switch to section NAME and create section if necessary.  It's
13959    rather ugly that we have to manipulate input_line_pointer but I
13960    don't see any other way to accomplish the same thing without
13961    changing obj-elf.c (which may be the Right Thing, in the end).
13962    Copied from tc-ia64.c.  */
13963
13964 static void
13965 set_section (char *name)
13966 {
13967   char *saved_input_line_pointer;
13968
13969   saved_input_line_pointer = input_line_pointer;
13970   input_line_pointer = name;
13971   obj_elf_section (0);
13972   input_line_pointer = saved_input_line_pointer;
13973 }
13974
13975 /* Cenerate and deferred unwind frame offset.  */
13976
13977 static void
13978 flush_pending_unwind (void)
13979 {
13980   offsetT offset;
13981
13982   offset = unwind.pending_offset;
13983   unwind.pending_offset = 0;
13984   if (offset != 0)
13985     add_unwind_adjustsp (offset);
13986 }
13987
13988 /* Add an opcode to this list for this function.  Two-byte opcodes should
13989    be passed as op[0] << 8 | op[1].  The list of opcodes is built in reverse
13990    order.  */
13991
13992 static void
13993 add_unwind_opcode (valueT op, int length)
13994 {
13995   /* Add any deferred stack adjustment.  */
13996   if (unwind.pending_offset)
13997     flush_pending_unwind ();
13998
13999   unwind.sp_restored = 0;
14000
14001   if (unwind.opcode_count + length > unwind.opcode_alloc)
14002     {
14003       unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
14004       if (unwind.opcodes)
14005         unwind.opcodes = xrealloc (unwind.opcodes,
14006                                    unwind.opcode_alloc);
14007       else
14008         unwind.opcodes = xmalloc (unwind.opcode_alloc);
14009     }
14010   while (length > 0)
14011     {
14012       length--;
14013       unwind.opcodes[unwind.opcode_count] = op & 0xff;
14014       op >>= 8;
14015       unwind.opcode_count++;
14016     }
14017 }
14018
14019 /* Add unwind opcodes to adjust the stack pointer.  */
14020
14021 static void
14022 add_unwind_adjustsp (offsetT offset)
14023 {
14024   valueT op;
14025
14026   if (offset > 0x200)
14027     {
14028       /* We need at most 5 bytes to hold a 32-bit value in a uleb128.  */
14029       char bytes[5];
14030       int n;
14031       valueT o;
14032
14033       /* Long form: 0xb2, uleb128.  */
14034       /* This might not fit in a word so add the individual bytes,
14035          remembering the list is built in reverse order.  */
14036       o = (valueT) ((offset - 0x204) >> 2);
14037       if (o == 0)
14038         add_unwind_opcode (0, 1);
14039
14040       /* Calculate the uleb128 encoding of the offset.  */
14041       n = 0;
14042       while (o)
14043         {
14044           bytes[n] = o & 0x7f;
14045           o >>= 7;
14046           if (o)
14047             bytes[n] |= 0x80;
14048           n++;
14049         }
14050       /* Add the insn.  */
14051       for (; n; n--)
14052         add_unwind_opcode (bytes[n - 1], 1);
14053       add_unwind_opcode (0xb2, 1);
14054     }
14055   else if (offset > 0x100)
14056     {
14057       /* Two short opcodes.  */
14058       add_unwind_opcode (0x3f, 1);
14059       op = (offset - 0x104) >> 2;
14060       add_unwind_opcode (op, 1);
14061     }
14062   else if (offset > 0)
14063     {
14064       /* Short opcode.  */
14065       op = (offset - 4) >> 2;
14066       add_unwind_opcode (op, 1);
14067     }
14068   else if (offset < 0)
14069     {
14070       offset = -offset;
14071       while (offset > 0x100)
14072         {
14073           add_unwind_opcode (0x7f, 1);
14074           offset -= 0x100;
14075         }
14076       op = ((offset - 4) >> 2) | 0x40;
14077       add_unwind_opcode (op, 1);
14078     }
14079 }
14080
14081 /* Finish the list of unwind opcodes for this function.  */
14082 static void
14083 finish_unwind_opcodes (void)
14084 {
14085   valueT op;
14086
14087   if (unwind.fp_used)
14088     {
14089       /* Adjust sp as neccessary.  */
14090       unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
14091       flush_pending_unwind ();
14092
14093       /* After restoring sp from the frame pointer.  */
14094       op = 0x90 | unwind.fp_reg;
14095       add_unwind_opcode (op, 1);
14096     }
14097   else
14098     flush_pending_unwind ();
14099 }
14100
14101
14102 /* Start an exception table entry.  If idx is nonzero this is an index table
14103    entry.  */
14104
14105 static void
14106 start_unwind_section (const segT text_seg, int idx)
14107 {
14108   const char * text_name;
14109   const char * prefix;
14110   const char * prefix_once;
14111   size_t prefix_len;
14112   size_t text_len;
14113   char * sec_name;
14114   size_t sec_name_len;
14115
14116   if (idx)
14117     {
14118       prefix = ELF_STRING_ARM_unwind;
14119       prefix_once = ELF_STRING_ARM_unwind_once;
14120     }
14121   else
14122     {
14123       prefix = ELF_STRING_ARM_unwind_info;
14124       prefix_once = ELF_STRING_ARM_unwind_info_once;
14125     }
14126
14127   text_name = segment_name (text_seg);
14128   if (streq (text_name, ".text"))
14129     text_name = "";
14130
14131   if (strncmp (text_name, ".gnu.linkonce.t.",
14132                strlen (".gnu.linkonce.t.")) == 0)
14133     {
14134       prefix = prefix_once;
14135       text_name += strlen (".gnu.linkonce.t.");
14136     }
14137
14138   prefix_len = strlen (prefix);
14139   text_len = strlen (text_name);
14140   sec_name_len = prefix_len + text_len;
14141   sec_name = alloca (sec_name_len + 1);
14142   memcpy (sec_name, prefix, prefix_len);
14143   memcpy (sec_name + prefix_len, text_name, text_len);
14144   sec_name[prefix_len + text_len] = '\0';
14145
14146   /* Handle COMDAT group.  */
14147   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
14148     {
14149       char *section;
14150       size_t len, group_name_len;
14151       const char *group_name = elf_group_name (text_seg);
14152
14153       if (group_name == NULL)
14154         {
14155           as_bad ("Group section `%s' has no group signature",
14156                   segment_name (text_seg));
14157           ignore_rest_of_line ();
14158           return;
14159         }
14160       /* We have to construct a fake section directive.  */
14161       group_name_len = strlen (group_name);
14162       if (idx)
14163         prefix_len = 13;
14164       else
14165         prefix_len = 16;
14166
14167       len = (sec_name_len
14168              + prefix_len             /* ,"aG",%sectiontype,  */
14169              + group_name_len         /* ,group_name  */
14170              + 7);                    /* ,comdat  */
14171
14172       section = alloca (len + 1);
14173       memcpy (section, sec_name, sec_name_len);
14174       if (idx)
14175           memcpy (section + sec_name_len, ",\"aG\",%exidx,", 13);
14176       else
14177           memcpy (section + sec_name_len, ",\"aG\",%progbits,", 16);
14178       memcpy (section + sec_name_len + prefix_len, group_name, group_name_len);
14179       memcpy (section + len - 7, ",comdat", 7);
14180       section [len] = '\0';
14181       set_section (section);
14182     }
14183   else
14184     {
14185       set_section (sec_name);
14186       bfd_set_section_flags (stdoutput, now_seg,
14187                              SEC_LOAD | SEC_ALLOC | SEC_READONLY);
14188     }
14189
14190   /* Set the setion link for index tables.  */
14191   if (idx)
14192     elf_linked_to_section (now_seg) = text_seg;
14193 }
14194
14195
14196 /* Start an unwind table entry.  HAVE_DATA is nonzero if we have additional
14197    personality routine data.  Returns zero, or the index table value for
14198    and inline entry.  */
14199
14200 static valueT
14201 create_unwind_entry (int have_data)
14202 {
14203   int size;
14204   addressT where;
14205   char *ptr;
14206   /* The current word of data.  */
14207   valueT data;
14208   /* The number of bytes left in this word.  */
14209   int n;
14210
14211   finish_unwind_opcodes ();
14212
14213   /* Remember the current text section.  */
14214   unwind.saved_seg = now_seg;
14215   unwind.saved_subseg = now_subseg;
14216
14217   start_unwind_section (now_seg, 0);
14218
14219   if (unwind.personality_routine == NULL)
14220     {
14221       if (unwind.personality_index == -2)
14222         {
14223           if (have_data)
14224             as_bad (_("handerdata in cantunwind frame"));
14225           return 1; /* EXIDX_CANTUNWIND.  */
14226         }
14227
14228       /* Use a default personality routine if none is specified.  */
14229       if (unwind.personality_index == -1)
14230         {
14231           if (unwind.opcode_count > 3)
14232             unwind.personality_index = 1;
14233           else
14234             unwind.personality_index = 0;
14235         }
14236
14237       /* Space for the personality routine entry.  */
14238       if (unwind.personality_index == 0)
14239         {
14240           if (unwind.opcode_count > 3)
14241             as_bad (_("too many unwind opcodes for personality routine 0"));
14242
14243           if (!have_data)
14244             {
14245               /* All the data is inline in the index table.  */
14246               data = 0x80;
14247               n = 3;
14248               while (unwind.opcode_count > 0)
14249                 {
14250                   unwind.opcode_count--;
14251                   data = (data << 8) | unwind.opcodes[unwind.opcode_count];
14252                   n--;
14253                 }
14254
14255               /* Pad with "finish" opcodes.  */
14256               while (n--)
14257                 data = (data << 8) | 0xb0;
14258
14259               return data;
14260             }
14261           size = 0;
14262         }
14263       else
14264         /* We get two opcodes "free" in the first word.  */
14265         size = unwind.opcode_count - 2;
14266     }
14267   else
14268     /* An extra byte is required for the opcode count.  */
14269     size = unwind.opcode_count + 1;
14270
14271   size = (size + 3) >> 2;
14272   if (size > 0xff)
14273     as_bad (_("too many unwind opcodes"));
14274
14275   frag_align (2, 0, 0);
14276   record_alignment (now_seg, 2);
14277   unwind.table_entry = expr_build_dot ();
14278
14279   /* Allocate the table entry.  */
14280   ptr = frag_more ((size << 2) + 4);
14281   where = frag_now_fix () - ((size << 2) + 4);
14282
14283   switch (unwind.personality_index)
14284     {
14285     case -1:
14286       /* ??? Should this be a PLT generating relocation?  */
14287       /* Custom personality routine.  */
14288       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
14289                BFD_RELOC_ARM_PREL31);
14290
14291       where += 4;
14292       ptr += 4;
14293
14294       /* Set the first byte to the number of additional words.  */
14295       data = size - 1;
14296       n = 3;
14297       break;
14298
14299     /* ABI defined personality routines.  */
14300     case 0:
14301       /* Three opcodes bytes are packed into the first word.  */
14302       data = 0x80;
14303       n = 3;
14304       break;
14305
14306     case 1:
14307     case 2:
14308       /* The size and first two opcode bytes go in the first word.  */
14309       data = ((0x80 + unwind.personality_index) << 8) | size;
14310       n = 2;
14311       break;
14312
14313     default:
14314       /* Should never happen.  */
14315       abort ();
14316     }
14317
14318   /* Pack the opcodes into words (MSB first), reversing the list at the same
14319      time.  */
14320   while (unwind.opcode_count > 0)
14321     {
14322       if (n == 0)
14323         {
14324           md_number_to_chars (ptr, data, 4);
14325           ptr += 4;
14326           n = 4;
14327           data = 0;
14328         }
14329       unwind.opcode_count--;
14330       n--;
14331       data = (data << 8) | unwind.opcodes[unwind.opcode_count];
14332     }
14333
14334   /* Finish off the last word.  */
14335   if (n < 4)
14336     {
14337       /* Pad with "finish" opcodes.  */
14338       while (n--)
14339         data = (data << 8) | 0xb0;
14340
14341       md_number_to_chars (ptr, data, 4);
14342     }
14343
14344   if (!have_data)
14345     {
14346       /* Add an empty descriptor if there is no user-specified data.   */
14347       ptr = frag_more (4);
14348       md_number_to_chars (ptr, 0, 4);
14349     }
14350
14351   return 0;
14352 }
14353
14354
14355 /* Parse an unwind_fnstart directive.  Simply records the current location.  */
14356
14357 static void
14358 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
14359 {
14360   demand_empty_rest_of_line ();
14361   /* Mark the start of the function.  */
14362   unwind.proc_start = expr_build_dot ();
14363
14364   /* Reset the rest of the unwind info.  */
14365   unwind.opcode_count = 0;
14366   unwind.table_entry = NULL;
14367   unwind.personality_routine = NULL;
14368   unwind.personality_index = -1;
14369   unwind.frame_size = 0;
14370   unwind.fp_offset = 0;
14371   unwind.fp_reg = 13;
14372   unwind.fp_used = 0;
14373   unwind.sp_restored = 0;
14374 }
14375
14376
14377 /* Parse a handlerdata directive.  Creates the exception handling table entry
14378    for the function.  */
14379
14380 static void
14381 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
14382 {
14383   demand_empty_rest_of_line ();
14384   if (unwind.table_entry)
14385     as_bad (_("dupicate .handlerdata directive"));
14386
14387   create_unwind_entry (1);
14388 }
14389
14390 /* Parse an unwind_fnend directive.  Generates the index table entry.  */
14391
14392 static void
14393 s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
14394 {
14395   long where;
14396   char *ptr;
14397   valueT val;
14398
14399   demand_empty_rest_of_line ();
14400
14401   /* Add eh table entry.  */
14402   if (unwind.table_entry == NULL)
14403     val = create_unwind_entry (0);
14404   else
14405     val = 0;
14406
14407   /* Add index table entry.  This is two words.  */
14408   start_unwind_section (unwind.saved_seg, 1);
14409   frag_align (2, 0, 0);
14410   record_alignment (now_seg, 2);
14411
14412   ptr = frag_more (8);
14413   where = frag_now_fix () - 8;
14414
14415   /* Self relative offset of the function start.  */
14416   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
14417            BFD_RELOC_ARM_PREL31);
14418
14419   /* Indicate dependency on EHABI-defined personality routines to the
14420      linker, if it hasn't been done already.  */
14421   if (unwind.personality_index >= 0 && unwind.personality_index < 3)
14422     {
14423       char *name[] = { "__aeabi_unwind_cpp_pr0",
14424                        "__aeabi_unwind_cpp_pr1",
14425                        "__aeabi_unwind_cpp_pr2" };
14426       if (!(marked_pr_dependency & (1 << unwind.personality_index)))
14427         {
14428           symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
14429           fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
14430           marked_pr_dependency |= 1 << unwind.personality_index;
14431           seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
14432             = marked_pr_dependency;
14433         }
14434     }
14435
14436   if (val)
14437     /* Inline exception table entry.  */
14438     md_number_to_chars (ptr + 4, val, 4);
14439   else
14440     /* Self relative offset of the table entry.  */
14441     fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
14442              BFD_RELOC_ARM_PREL31);
14443
14444   /* Restore the original section.  */
14445   subseg_set (unwind.saved_seg, unwind.saved_subseg);
14446 }
14447
14448
14449 /* Parse an unwind_cantunwind directive.  */
14450
14451 static void
14452 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
14453 {
14454   demand_empty_rest_of_line ();
14455   if (unwind.personality_routine || unwind.personality_index != -1)
14456     as_bad (_("personality routine specified for cantunwind frame"));
14457
14458   unwind.personality_index = -2;
14459 }
14460
14461
14462 /* Parse a personalityindex directive.  */
14463
14464 static void
14465 s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
14466 {
14467   expressionS exp;
14468
14469   if (unwind.personality_routine || unwind.personality_index != -1)
14470     as_bad (_("duplicate .personalityindex directive"));
14471
14472   SKIP_WHITESPACE ();
14473
14474   expression (&exp);
14475
14476   if (exp.X_op != O_constant
14477       || exp.X_add_number < 0 || exp.X_add_number > 15)
14478     {
14479       as_bad (_("bad personality routine number"));
14480       ignore_rest_of_line ();
14481       return;
14482     }
14483
14484   unwind.personality_index = exp.X_add_number;
14485
14486   demand_empty_rest_of_line ();
14487 }
14488
14489
14490 /* Parse a personality directive.  */
14491
14492 static void
14493 s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
14494 {
14495   char *name, *p, c;
14496
14497   if (unwind.personality_routine || unwind.personality_index != -1)
14498     as_bad (_("duplicate .personality directive"));
14499
14500   SKIP_WHITESPACE ();
14501   name = input_line_pointer;
14502   c = get_symbol_end ();
14503   p = input_line_pointer;
14504   unwind.personality_routine = symbol_find_or_make (name);
14505   *p = c;
14506   SKIP_WHITESPACE ();
14507   demand_empty_rest_of_line ();
14508 }
14509
14510
14511 /* Parse a directive saving core registers.  */
14512
14513 static void
14514 s_arm_unwind_save_core (void)
14515 {
14516   valueT op;
14517   long range;
14518   int n;
14519
14520   SKIP_WHITESPACE ();
14521   range = reg_list (&input_line_pointer);
14522   if (range == FAIL)
14523     {
14524       as_bad (_("expected register list"));
14525       ignore_rest_of_line ();
14526       return;
14527     }
14528
14529   demand_empty_rest_of_line ();
14530
14531   /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
14532      into .unwind_save {..., sp...}.  We aren't bothered about the value of
14533      ip because it is clobbered by calls.  */
14534   if (unwind.sp_restored && unwind.fp_reg == 12
14535       && (range & 0x3000) == 0x1000)
14536     {
14537       unwind.opcode_count--;
14538       unwind.sp_restored = 0;
14539       range = (range | 0x2000) & ~0x1000;
14540       unwind.pending_offset = 0;
14541     }
14542
14543   /* See if we can use the short opcodes.  These pop a block of upto 8
14544      registers starting with r4, plus maybe r14.  */
14545   for (n = 0; n < 8; n++)
14546     {
14547       /* Break at the first non-saved register.  */
14548       if ((range & (1 << (n + 4))) == 0)
14549         break;
14550     }
14551   /* See if there are any other bits set.  */
14552   if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
14553     {
14554       /* Use the long form.  */
14555       op = 0x8000 | ((range >> 4) & 0xfff);
14556       add_unwind_opcode (op, 2);
14557     }
14558   else
14559     {
14560       /* Use the short form.  */
14561       if (range & 0x4000)
14562         op = 0xa8; /* Pop r14.  */
14563       else
14564         op = 0xa0; /* Do not pop r14.  */
14565       op |= (n - 1);
14566       add_unwind_opcode (op, 1);
14567     }
14568
14569   /* Pop r0-r3.  */
14570   if (range & 0xf)
14571     {
14572       op = 0xb100 | (range & 0xf);
14573       add_unwind_opcode (op, 2);
14574     }
14575
14576   /* Record the number of bytes pushed.  */
14577   for (n = 0; n < 16; n++)
14578     {
14579       if (range & (1 << n))
14580         unwind.frame_size += 4;
14581     }
14582 }
14583
14584
14585 /* Parse a directive saving FPA registers.  */
14586
14587 static void
14588 s_arm_unwind_save_fpa (int reg)
14589 {
14590   expressionS exp;
14591   int num_regs;
14592   valueT op;
14593
14594   /* Get Number of registers to transfer.  */
14595   if (skip_past_comma (&input_line_pointer) != FAIL)
14596     expression (&exp);
14597   else
14598     exp.X_op = O_illegal;
14599
14600   if (exp.X_op != O_constant)
14601     {
14602       as_bad (_("expected , <constant>"));
14603       ignore_rest_of_line ();
14604       return;
14605     }
14606
14607   num_regs = exp.X_add_number;
14608
14609   if (num_regs < 1 || num_regs > 4)
14610     {
14611       as_bad (_("number of registers must be in the range [1:4]"));
14612       ignore_rest_of_line ();
14613       return;
14614     }
14615
14616   demand_empty_rest_of_line ();
14617
14618   if (reg == 4)
14619     {
14620       /* Short form.  */
14621       op = 0xb4 | (num_regs - 1);
14622       add_unwind_opcode (op, 1);
14623     }
14624   else
14625     {
14626       /* Long form.  */
14627       op = 0xc800 | (reg << 4) | (num_regs - 1);
14628       add_unwind_opcode (op, 2);
14629     }
14630   unwind.frame_size += num_regs * 12;
14631 }
14632
14633
14634 /* Parse a directive saving VFP registers.  */
14635
14636 static void
14637 s_arm_unwind_save_vfp (void)
14638 {
14639   int count;
14640   int reg;
14641   valueT op;
14642
14643   count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
14644   if (count == FAIL)
14645     {
14646       as_bad (_("expected register list"));
14647       ignore_rest_of_line ();
14648       return;
14649     }
14650
14651   demand_empty_rest_of_line ();
14652
14653   if (reg == 8)
14654     {
14655       /* Short form.  */
14656       op = 0xb8 | (count - 1);
14657       add_unwind_opcode (op, 1);
14658     }
14659   else
14660     {
14661       /* Long form.  */
14662       op = 0xb300 | (reg << 4) | (count - 1);
14663       add_unwind_opcode (op, 2);
14664     }
14665   unwind.frame_size += count * 8 + 4;
14666 }
14667
14668
14669 /* Parse a directive saving iWMMXt registers.  */
14670
14671 static void
14672 s_arm_unwind_save_wmmx (void)
14673 {
14674   int reg;
14675   int hi_reg;
14676   int i;
14677   unsigned wcg_mask;
14678   unsigned wr_mask;
14679   valueT op;
14680
14681   if (*input_line_pointer == '{')
14682     input_line_pointer++;
14683
14684   wcg_mask = 0;
14685   wr_mask = 0;
14686   do
14687     {
14688       reg = arm_reg_parse (&input_line_pointer,
14689                            all_reg_maps[REG_TYPE_IWMMXT].htab);
14690
14691       if (wr_register (reg))
14692         {
14693           i = reg & ~WR_PREFIX;
14694           if (wr_mask >> i)
14695             as_tsktsk (_("register list not in ascending order"));
14696           wr_mask |= 1 << i;
14697         }
14698       else if (wcg_register (reg))
14699         {
14700           i = (reg & ~WC_PREFIX) - 8;
14701           if (wcg_mask >> i)
14702             as_tsktsk (_("register list not in ascending order"));
14703           wcg_mask |= 1 << i;
14704         }
14705       else
14706         {
14707           as_bad (_("expected wr or wcgr"));
14708           goto error;
14709         }
14710
14711       SKIP_WHITESPACE ();
14712       if (*input_line_pointer == '-')
14713         {
14714           hi_reg = arm_reg_parse (&input_line_pointer,
14715                                   all_reg_maps[REG_TYPE_IWMMXT].htab);
14716           if (wr_register (reg) && wr_register (hi_reg))
14717             {
14718               for (; reg < hi_reg; reg++)
14719                 wr_mask |= 1 << (reg & ~WR_PREFIX);
14720             }
14721           else if (wcg_register (reg) && wcg_register (hi_reg))
14722             {
14723               for (; reg < hi_reg; reg++)
14724                 wcg_mask |= 1 << ((reg & ~WC_PREFIX) - 8);
14725             }
14726           else
14727             {
14728               as_bad (_("bad register range"));
14729               goto error;
14730             }
14731         }
14732     }
14733   while (skip_past_comma (&input_line_pointer) != FAIL);
14734
14735   SKIP_WHITESPACE ();
14736   if (*input_line_pointer == '}')
14737     input_line_pointer++;
14738
14739   demand_empty_rest_of_line ();
14740
14741   if (wr_mask && wcg_mask)
14742     {
14743       as_bad (_("inconsistent register types"));
14744       goto error;
14745     }
14746
14747   /* Generate any deferred opcodes becuuse we're going to be looking at
14748      the list.  */
14749   flush_pending_unwind ();
14750
14751   if (wcg_mask)
14752     {
14753       for (i = 0; i < 16; i++)
14754         {
14755           if (wcg_mask & (1 << i))
14756             unwind.frame_size += 4;
14757         }
14758       op = 0xc700 | wcg_mask;
14759       add_unwind_opcode (op, 2);
14760     }
14761   else
14762     {
14763       for (i = 0; i < 16; i++)
14764         {
14765           if (wr_mask & (1 << i))
14766             unwind.frame_size += 8;
14767         }
14768       /* Attempt to combine with a previous opcode.  We do this because gcc
14769          likes to output separate unwind directives for a single block of
14770          registers.  */
14771       if (unwind.opcode_count > 0)
14772         {
14773           i = unwind.opcodes[unwind.opcode_count - 1];
14774           if ((i & 0xf8) == 0xc0)
14775             {
14776               i &= 7;
14777               /* Only merge if the blocks are contiguous.  */
14778               if (i < 6)
14779                 {
14780                   if ((wr_mask & 0xfe00) == (1 << 9))
14781                     {
14782                       wr_mask |= ((1 << (i + 11)) - 1) & 0xfc00;
14783                       unwind.opcode_count--;
14784                     }
14785                 }
14786               else if (i == 6 && unwind.opcode_count >= 2)
14787                 {
14788                   i = unwind.opcodes[unwind.opcode_count - 2];
14789                   reg = i >> 4;
14790                   i &= 0xf;
14791
14792                   op = 0xffff << (reg - 1);
14793                   if (reg > 0
14794                       || ((wr_mask & op) == (1u << (reg - 1))))
14795                     {
14796                       op = (1 << (reg + i + 1)) - 1;
14797                       op &= ~((1 << reg) - 1);
14798                       wr_mask |= op;
14799                       unwind.opcode_count -= 2;
14800                     }
14801                 }
14802             }
14803         }
14804
14805       hi_reg = 15;
14806       /* We want to generate opcodes in the order the registers have been
14807          saved, ie. descending order.  */
14808       for (reg = 15; reg >= -1; reg--)
14809         {
14810           /* Save registers in blocks.  */
14811           if (reg < 0
14812               || !(wr_mask & (1 << reg)))
14813             {
14814               /* We found an unsaved reg.  Generate opcodes to save the
14815                  preceeding block.  */
14816               if (reg != hi_reg)
14817                 {
14818                   if (reg == 9)
14819                     {
14820                       /* Short form.  */
14821                       op = 0xc0 | (hi_reg - 10);
14822                       add_unwind_opcode (op, 1);
14823                     }
14824                   else
14825                     {
14826                       /* Long form.  */
14827                       op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
14828                       add_unwind_opcode (op, 2);
14829                     }
14830                 }
14831               hi_reg = reg - 1;
14832             }
14833         }
14834     }
14835   return;
14836 error:
14837   ignore_rest_of_line ();
14838 }
14839
14840
14841 /* Parse an unwind_save directive.  */
14842
14843 static void
14844 s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
14845 {
14846   char *saved_ptr;
14847   int reg;
14848
14849   /* Figure out what sort of save we have.  */
14850   SKIP_WHITESPACE ();
14851   saved_ptr = input_line_pointer;
14852
14853   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_FN].htab);
14854   if (reg != FAIL)
14855     {
14856       s_arm_unwind_save_fpa (reg);
14857       return;
14858     }
14859
14860   if (*input_line_pointer == '{')
14861     input_line_pointer++;
14862
14863   SKIP_WHITESPACE ();
14864
14865   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_RN].htab);
14866   if (reg != FAIL)
14867     {
14868       input_line_pointer = saved_ptr;
14869       s_arm_unwind_save_core ();
14870       return;
14871     }
14872
14873   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_DN].htab);
14874   if (reg != FAIL)
14875     {
14876       input_line_pointer = saved_ptr;
14877       s_arm_unwind_save_vfp ();
14878       return;
14879     }
14880
14881   reg = arm_reg_parse (&input_line_pointer,
14882                        all_reg_maps[REG_TYPE_IWMMXT].htab);
14883   if (reg != FAIL)
14884     {
14885       input_line_pointer = saved_ptr;
14886       s_arm_unwind_save_wmmx ();
14887       return;
14888     }
14889
14890   /* TODO: Maverick registers.  */
14891   as_bad (_("unrecognised register"));
14892 }
14893
14894
14895 /* Parse an unwind_movsp directive.  */
14896
14897 static void
14898 s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
14899 {
14900   int reg;
14901   valueT op;
14902
14903   SKIP_WHITESPACE ();
14904   reg = reg_required_here (&input_line_pointer, -1);
14905   if (reg == FAIL)
14906     {
14907       as_bad (_("ARM register expected"));
14908       ignore_rest_of_line ();
14909       return;
14910     }
14911
14912   if (reg == 13 || reg == 15)
14913     {
14914       as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
14915       ignore_rest_of_line ();
14916       return;
14917     }
14918
14919   if (unwind.fp_reg != 13)
14920     as_bad (_("unexpected .unwind_movsp directive"));
14921
14922   /* Generate opcode to restore the value.  */
14923   op = 0x90 | reg;
14924   add_unwind_opcode (op, 1);
14925
14926   /* Record the information for later.  */
14927   unwind.fp_reg = reg;
14928   unwind.fp_offset = unwind.frame_size;
14929   unwind.sp_restored = 1;
14930   demand_empty_rest_of_line ();
14931 }
14932
14933
14934 /* Parse #<number>.  */
14935
14936 static int
14937 require_hashconst (int * val)
14938 {
14939   expressionS exp;
14940
14941   SKIP_WHITESPACE ();
14942   if (*input_line_pointer == '#')
14943     {
14944       input_line_pointer++;
14945       expression (&exp);
14946     }
14947   else
14948     exp.X_op = O_illegal;
14949
14950   if (exp.X_op != O_constant)
14951     {
14952       as_bad (_("expected #constant"));
14953       ignore_rest_of_line ();
14954       return FAIL;
14955     }
14956   *val = exp.X_add_number;
14957   return SUCCESS;
14958 }
14959
14960 /* Parse an unwind_pad directive.  */
14961
14962 static void
14963 s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
14964 {
14965   int offset;
14966
14967   if (require_hashconst (&offset) == FAIL)
14968     return;
14969
14970   if (offset & 3)
14971     {
14972       as_bad (_("stack increment must be multiple of 4"));
14973       ignore_rest_of_line ();
14974       return;
14975     }
14976
14977   /* Don't generate any opcodes, just record the details for later.  */
14978   unwind.frame_size += offset;
14979   unwind.pending_offset += offset;
14980
14981   demand_empty_rest_of_line ();
14982 }
14983
14984 /* Parse an unwind_setfp directive.  */
14985
14986 static void
14987 s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
14988 {
14989   int sp_reg;
14990   int fp_reg;
14991   int offset;
14992
14993   fp_reg = reg_required_here (&input_line_pointer, -1);
14994   if (skip_past_comma (&input_line_pointer) == FAIL)
14995     sp_reg = FAIL;
14996   else
14997     sp_reg = reg_required_here (&input_line_pointer, -1);
14998
14999   if (fp_reg == FAIL || sp_reg == FAIL)
15000     {
15001       as_bad (_("expected <reg>, <reg>"));
15002       ignore_rest_of_line ();
15003       return;
15004     }
15005
15006   /* Optonal constant.  */
15007   if (skip_past_comma (&input_line_pointer) != FAIL)
15008     {
15009       if (require_hashconst (&offset) == FAIL)
15010         return;
15011     }
15012   else
15013     offset = 0;
15014
15015   demand_empty_rest_of_line ();
15016
15017   if (sp_reg != 13 && sp_reg != unwind.fp_reg)
15018     {
15019       as_bad (_("register must be either sp or set by a previous"
15020                 "unwind_movsp directive"));
15021       return;
15022     }
15023
15024   /* Don't generate any opcodes, just record the information for later.  */
15025   unwind.fp_reg = fp_reg;
15026   unwind.fp_used = 1;
15027   if (sp_reg == 13)
15028     unwind.fp_offset = unwind.frame_size - offset;
15029   else
15030     unwind.fp_offset -= offset;
15031 }
15032
15033 /* Parse an unwind_raw directive.  */
15034
15035 static void
15036 s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
15037 {
15038   expressionS exp;
15039   /* This is an arbitary limit.  */
15040   unsigned char op[16];
15041   int count;
15042
15043   SKIP_WHITESPACE ();
15044   expression (&exp);
15045   if (exp.X_op == O_constant
15046       && skip_past_comma (&input_line_pointer) != FAIL)
15047     {
15048       unwind.frame_size += exp.X_add_number;
15049       expression (&exp);
15050     }
15051   else
15052     exp.X_op = O_illegal;
15053
15054   if (exp.X_op != O_constant)
15055     {
15056       as_bad (_("expected <offset>, <opcode>"));
15057       ignore_rest_of_line ();
15058       return;
15059     }
15060
15061   count = 0;
15062
15063   /* Parse the opcode.  */
15064   for (;;)
15065     {
15066       if (count >= 16)
15067         {
15068           as_bad (_("unwind opcode too long"));
15069           ignore_rest_of_line ();
15070         }
15071       if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
15072         {
15073           as_bad (_("invalid unwind opcode"));
15074           ignore_rest_of_line ();
15075           return;
15076         }
15077       op[count++] = exp.X_add_number;
15078
15079       /* Parse the next byte.  */
15080       if (skip_past_comma (&input_line_pointer) == FAIL)
15081         break;
15082
15083       expression (&exp);
15084     }
15085
15086   /* Add the opcode bytes in reverse order.  */
15087   while (count--)
15088     add_unwind_opcode (op[count], 1);
15089
15090   demand_empty_rest_of_line ();
15091 }
15092
15093 #endif /* OBJ_ELF */
15094
15095 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
15096    of an rs_align_code fragment.  */
15097
15098 void
15099 arm_handle_align (fragS * fragP)
15100 {
15101   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
15102   static char const thumb_noop[2] = { 0xc0, 0x46 };
15103   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
15104   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
15105
15106   int bytes, fix, noop_size;
15107   char * p;
15108   const char * noop;
15109
15110   if (fragP->fr_type != rs_align_code)
15111     return;
15112
15113   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
15114   p = fragP->fr_literal + fragP->fr_fix;
15115   fix = 0;
15116
15117   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
15118     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
15119
15120   if (fragP->tc_frag_data)
15121     {
15122       if (target_big_endian)
15123         noop = thumb_bigend_noop;
15124       else
15125         noop = thumb_noop;
15126       noop_size = sizeof (thumb_noop);
15127     }
15128   else
15129     {
15130       if (target_big_endian)
15131         noop = arm_bigend_noop;
15132       else
15133         noop = arm_noop;
15134       noop_size = sizeof (arm_noop);
15135     }
15136
15137   if (bytes & (noop_size - 1))
15138     {
15139       fix = bytes & (noop_size - 1);
15140       memset (p, 0, fix);
15141       p += fix;
15142       bytes -= fix;
15143     }
15144
15145   while (bytes >= noop_size)
15146     {
15147       memcpy (p, noop, noop_size);
15148       p += noop_size;
15149       bytes -= noop_size;
15150       fix += noop_size;
15151     }
15152
15153   fragP->fr_fix += fix;
15154   fragP->fr_var = noop_size;
15155 }
15156
15157 /* Called from md_do_align.  Used to create an alignment
15158    frag in a code section.  */
15159
15160 void
15161 arm_frag_align_code (int n, int max)
15162 {
15163   char * p;
15164
15165   /* We assume that there will never be a requirement
15166      to support alignments greater than 32 bytes.  */
15167   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
15168     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
15169
15170   p = frag_var (rs_align_code,
15171                 MAX_MEM_FOR_RS_ALIGN_CODE,
15172                 1,
15173                 (relax_substateT) max,
15174                 (symbolS *) NULL,
15175                 (offsetT) n,
15176                 (char *) NULL);
15177   *p = 0;
15178 }
15179
15180 /* Perform target specific initialisation of a frag.  */
15181
15182 void
15183 arm_init_frag (fragS * fragP)
15184 {
15185   /* Record whether this frag is in an ARM or a THUMB area.  */
15186   fragP->tc_frag_data = thumb_mode;
15187 }
15188
15189 #ifdef OBJ_ELF
15190
15191 /* Convert REGNAME to a DWARF-2 register number.  */
15192
15193 int
15194 tc_arm_regname_to_dw2regnum (const char *regname)
15195 {
15196   unsigned int i;
15197
15198   for (i = 0; rn_table[i].name; i++)
15199     if (streq (regname, rn_table[i].name))
15200       return rn_table[i].number;
15201
15202   return -1;
15203 }
15204
15205 /* Initialize the DWARF-2 unwind information for this procedure.  */
15206
15207 void
15208 tc_arm_frame_initial_instructions (void)
15209 {
15210   cfi_add_CFA_def_cfa (REG_SP, 0);
15211 }
15212 #endif
15213
15214 /* This table describes all the machine specific pseudo-ops the assembler
15215    has to support.  The fields are:
15216      pseudo-op name without dot
15217      function to call to execute this pseudo-op
15218      Integer arg to pass to the function.  */
15219
15220 const pseudo_typeS md_pseudo_table[] =
15221 {
15222   /* Never called because '.req' does not start a line.  */
15223   { "req",         s_req,         0 },
15224   { "unreq",       s_unreq,       0 },
15225   { "bss",         s_bss,         0 },
15226   { "align",       s_align,       0 },
15227   { "arm",         s_arm,         0 },
15228   { "thumb",       s_thumb,       0 },
15229   { "code",        s_code,        0 },
15230   { "force_thumb", s_force_thumb, 0 },
15231   { "thumb_func",  s_thumb_func,  0 },
15232   { "thumb_set",   s_thumb_set,   0 },
15233   { "even",        s_even,        0 },
15234   { "ltorg",       s_ltorg,       0 },
15235   { "pool",        s_ltorg,       0 },
15236 #ifdef OBJ_ELF
15237   { "word",        s_arm_elf_cons, 4 },
15238   { "long",        s_arm_elf_cons, 4 },
15239   { "rel31",       s_arm_rel31,   0 },
15240   { "fnstart",          s_arm_unwind_fnstart,   0 },
15241   { "fnend",            s_arm_unwind_fnend,     0 },
15242   { "cantunwind",       s_arm_unwind_cantunwind, 0 },
15243   { "personality",      s_arm_unwind_personality, 0 },
15244   { "personalityindex", s_arm_unwind_personalityindex, 0 },
15245   { "handlerdata",      s_arm_unwind_handlerdata, 0 },
15246   { "save",             s_arm_unwind_save,      0 },
15247   { "movsp",            s_arm_unwind_movsp,     0 },
15248   { "pad",              s_arm_unwind_pad,       0 },
15249   { "setfp",            s_arm_unwind_setfp,     0 },
15250   { "unwind_raw",       s_arm_unwind_raw,       0 },
15251 #else
15252   { "word",        cons, 4},
15253 #endif
15254   { "extend",      float_cons, 'x' },
15255   { "ldouble",     float_cons, 'x' },
15256   { "packed",      float_cons, 'p' },
15257   { 0, 0, 0 }
15258 };