]> Git Repo - binutils.git/blob - gas/config/tc-arm.c
* config/atof-ieee.c, config/obj-coff.c, config/obj-elf.c,
[binutils.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005
4    Free Software Foundation, Inc.
5    Contributed by Richard Earnshaw ([email protected])
6         Modified by David Taylor ([email protected])
7         Cirrus coprocessor mods by Aldy Hernandez ([email protected])
8         Cirrus coprocessor fixes by Petko Manolov ([email protected])
9         Cirrus coprocessor fixes by Vladimir Ivanov ([email protected])
10
11    This file is part of GAS, the GNU Assembler.
12
13    GAS is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2, or (at your option)
16    any later version.
17
18    GAS is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with GAS; see the file COPYING.  If not, write to the Free
25    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26    02111-1307, USA.  */
27
28 #include <string.h>
29 #define  NO_RELOC 0
30 #include "as.h"
31 #include "safe-ctype.h"
32
33 /* Need TARGET_CPU.  */
34 #include "config.h"
35 #include "subsegs.h"
36 #include "obstack.h"
37 #include "symbols.h"
38 #include "listing.h"
39
40 #include "opcode/arm.h"
41
42 #ifdef OBJ_ELF
43 #include "elf/arm.h"
44 #include "dwarf2dbg.h"
45 #include "dw2gencfi.h"
46 #endif
47
48 /* XXX Set this to 1 after the next binutils release.  */
49 #define WARN_DEPRECATED 0
50
51 #ifdef OBJ_ELF
52 /* Must be at least the size of the largest unwind opcode (currently two).  */
53 #define ARM_OPCODE_CHUNK_SIZE 8
54
55 /* This structure holds the unwinding state.  */
56
57 static struct
58 {
59   symbolS *       proc_start;
60   symbolS *       table_entry;
61   symbolS *       personality_routine;
62   int             personality_index;
63   /* The segment containing the function.  */
64   segT            saved_seg;
65   subsegT         saved_subseg;
66   /* Opcodes generated from this function.  */
67   unsigned char * opcodes;
68   int             opcode_count;
69   int             opcode_alloc;
70   /* The number of bytes pushed to the stack.  */
71   offsetT         frame_size;
72   /* We don't add stack adjustment opcodes immediately so that we can merge
73      multiple adjustments.  We can also omit the final adjustment
74      when using a frame pointer.  */
75   offsetT         pending_offset;
76   /* These two fields are set by both unwind_movsp and unwind_setfp.  They
77      hold the reg+offset to use when restoring sp from a frame pointer.  */
78   offsetT         fp_offset;
79   int             fp_reg;
80   /* Nonzero if an unwind_setfp directive has been seen.  */
81   unsigned        fp_used:1;
82   /* Nonzero if the last opcode restores sp from fp_reg.  */
83   unsigned        sp_restored:1;
84 } unwind;
85
86 #endif /* OBJ_ELF */
87
88 enum arm_float_abi
89 {
90   ARM_FLOAT_ABI_HARD,
91   ARM_FLOAT_ABI_SOFTFP,
92   ARM_FLOAT_ABI_SOFT
93 };
94
95 /* Types of processor to assemble for.  */
96 #define ARM_1           ARM_ARCH_V1
97 #define ARM_2           ARM_ARCH_V2
98 #define ARM_3           ARM_ARCH_V2S
99 #define ARM_250         ARM_ARCH_V2S
100 #define ARM_6           ARM_ARCH_V3
101 #define ARM_7           ARM_ARCH_V3
102 #define ARM_8           ARM_ARCH_V4
103 #define ARM_9           ARM_ARCH_V4T
104 #define ARM_STRONG      ARM_ARCH_V4
105 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
106
107 #ifndef CPU_DEFAULT
108 #if defined __XSCALE__
109 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
110 #else
111 #if defined __thumb__
112 #define CPU_DEFAULT     (ARM_ARCH_V5T)
113 #else
114 #define CPU_DEFAULT     ARM_ANY
115 #endif
116 #endif
117 #endif
118
119 #ifndef FPU_DEFAULT
120 # ifdef TE_LINUX
121 #  define FPU_DEFAULT FPU_ARCH_FPA
122 # elif defined (TE_NetBSD)
123 #  ifdef OBJ_ELF
124 #   define FPU_DEFAULT FPU_ARCH_VFP     /* Soft-float, but VFP order.  */
125 #  else
126     /* Legacy a.out format.  */
127 #   define FPU_DEFAULT FPU_ARCH_FPA     /* Soft-float, but FPA order.  */
128 #  endif
129 # elif defined (TE_VXWORKS)
130 #  define FPU_DEFAULT FPU_ARCH_VFP      /* Soft-float, VFP order.  */
131 # else
132    /* For backwards compatibility, default to FPA.  */
133 #  define FPU_DEFAULT FPU_ARCH_FPA
134 # endif
135 #endif /* ifndef FPU_DEFAULT */
136
137 #define streq(a, b)           (strcmp (a, b) == 0)
138 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
139
140 static unsigned long cpu_variant;
141
142 /* Flags stored in private area of BFD structure.  */
143 static int uses_apcs_26      = FALSE;
144 static int atpcs             = FALSE;
145 static int support_interwork = FALSE;
146 static int uses_apcs_float   = FALSE;
147 static int pic_code          = FALSE;
148
149 /* Variables that we set while parsing command-line options.  Once all
150    options have been read we re-process these values to set the real
151    assembly flags.  */
152 static int legacy_cpu = -1;
153 static int legacy_fpu = -1;
154
155 static int mcpu_cpu_opt = -1;
156 static int mcpu_fpu_opt = -1;
157 static int march_cpu_opt = -1;
158 static int march_fpu_opt = -1;
159 static int mfpu_opt = -1;
160 static int mfloat_abi_opt = -1;
161 #ifdef OBJ_ELF
162 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
163 #endif
164
165 /* This array holds the chars that always start a comment.  If the
166    pre-processor is disabled, these aren't very useful.  */
167 const char comment_chars[] = "@";
168
169 /* This array holds the chars that only start a comment at the beginning of
170    a line.  If the line seems to have the form '# 123 filename'
171    .line and .file directives will appear in the pre-processed output.  */
172 /* Note that input_file.c hand checks for '#' at the beginning of the
173    first line of the input file.  This is because the compiler outputs
174    #NO_APP at the beginning of its output.  */
175 /* Also note that comments like this one will always work.  */
176 const char line_comment_chars[] = "#";
177
178 const char line_separator_chars[] = ";";
179
180 /* Chars that can be used to separate mant
181    from exp in floating point numbers.  */
182 const char EXP_CHARS[] = "eE";
183
184 /* Chars that mean this number is a floating point constant.  */
185 /* As in 0f12.456  */
186 /* or    0d1.2345e12  */
187
188 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
189
190 /* Prefix characters that indicate the start of an immediate
191    value.  */
192 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
193
194 #ifdef OBJ_ELF
195 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
196 symbolS * GOT_symbol;
197 #endif
198
199 /* Size of relocation record.  */
200 const int md_reloc_size = 8;
201
202 /* 0: assemble for ARM,
203    1: assemble for Thumb,
204    2: assemble for Thumb even though target CPU does not support thumb
205       instructions.  */
206 static int thumb_mode = 0;
207
208 typedef struct arm_fix
209 {
210   int thumb_mode;
211 } arm_fix_data;
212
213 struct arm_it
214 {
215   const char *  error;
216   unsigned long instruction;
217   int           size;
218   struct
219   {
220     bfd_reloc_code_real_type type;
221     expressionS              exp;
222     int                      pc_rel;
223   } reloc;
224 };
225
226 struct arm_it inst;
227
228 enum asm_shift_index
229 {
230   SHIFT_LSL = 0,
231   SHIFT_LSR,
232   SHIFT_ASR,
233   SHIFT_ROR,
234   SHIFT_RRX
235 };
236
237 struct asm_shift_properties
238 {
239   enum asm_shift_index index;
240   unsigned long        bit_field;
241   unsigned int         allows_0  : 1;
242   unsigned int         allows_32 : 1;
243 };
244
245 static const struct asm_shift_properties shift_properties [] =
246 {
247   { SHIFT_LSL, 0,    1, 0},
248   { SHIFT_LSR, 0x20, 0, 1},
249   { SHIFT_ASR, 0x40, 0, 1},
250   { SHIFT_ROR, 0x60, 0, 0},
251   { SHIFT_RRX, 0x60, 0, 0}
252 };
253
254 struct asm_shift_name
255 {
256   const char *                        name;
257   const struct asm_shift_properties * properties;
258 };
259
260 static const struct asm_shift_name shift_names [] =
261 {
262   { "asl", shift_properties + SHIFT_LSL },
263   { "lsl", shift_properties + SHIFT_LSL },
264   { "lsr", shift_properties + SHIFT_LSR },
265   { "asr", shift_properties + SHIFT_ASR },
266   { "ror", shift_properties + SHIFT_ROR },
267   { "rrx", shift_properties + SHIFT_RRX },
268   { "ASL", shift_properties + SHIFT_LSL },
269   { "LSL", shift_properties + SHIFT_LSL },
270   { "LSR", shift_properties + SHIFT_LSR },
271   { "ASR", shift_properties + SHIFT_ASR },
272   { "ROR", shift_properties + SHIFT_ROR },
273   { "RRX", shift_properties + SHIFT_RRX }
274 };
275
276 /* Any kind of shift is accepted.  */
277 #define NO_SHIFT_RESTRICT 1
278 /* The shift operand must be an immediate value, not a register.  */
279 #define SHIFT_IMMEDIATE   0
280 /* The shift must be LSL or ASR and the operand must be an immediate.  */
281 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
282 /* The shift must be ASR and the operand must be an immediate.  */
283 #define SHIFT_ASR_IMMEDIATE 3
284 /* The shift must be LSL and the operand must be an immediate.  */
285 #define SHIFT_LSL_IMMEDIATE 4
286
287 #define NUM_FLOAT_VALS 8
288
289 const char * fp_const[] =
290 {
291   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
292 };
293
294 /* Number of littlenums required to hold an extended precision number.  */
295 #define MAX_LITTLENUMS 6
296
297 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
298
299 #define FAIL    (-1)
300 #define SUCCESS (0)
301
302 /* Whether a Co-processor load/store operation accepts write-back forms.  */
303 #define CP_WB_OK 1
304 #define CP_NO_WB 0
305
306 #define SUFF_S 1
307 #define SUFF_D 2
308 #define SUFF_E 3
309 #define SUFF_P 4
310
311 #define CP_T_X   0x00008000
312 #define CP_T_Y   0x00400000
313 #define CP_T_Pre 0x01000000
314 #define CP_T_UD  0x00800000
315 #define CP_T_WB  0x00200000
316
317 #define CONDS_BIT        0x00100000
318 #define LOAD_BIT         0x00100000
319
320 #define DOUBLE_LOAD_FLAG 0x00000001
321
322 struct asm_cond
323 {
324   const char *  template;
325   unsigned long value;
326 };
327
328 #define COND_ALWAYS 0xe0000000
329 #define COND_MASK   0xf0000000
330
331 static const struct asm_cond conds[] =
332 {
333   {"eq", 0x00000000},
334   {"ne", 0x10000000},
335   {"cs", 0x20000000}, {"hs", 0x20000000},
336   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
337   {"mi", 0x40000000},
338   {"pl", 0x50000000},
339   {"vs", 0x60000000},
340   {"vc", 0x70000000},
341   {"hi", 0x80000000},
342   {"ls", 0x90000000},
343   {"ge", 0xa0000000},
344   {"lt", 0xb0000000},
345   {"gt", 0xc0000000},
346   {"le", 0xd0000000},
347   {"al", 0xe0000000},
348   {"nv", 0xf0000000}
349 };
350
351 struct asm_psr
352 {
353   const char *template;
354   bfd_boolean cpsr;
355   unsigned long field;
356 };
357
358 /* The bit that distinguishes CPSR and SPSR.  */
359 #define SPSR_BIT   (1 << 22)
360
361 /* How many bits to shift the PSR_xxx bits up by.  */
362 #define PSR_SHIFT  16
363
364 #define PSR_c   (1 << 0)
365 #define PSR_x   (1 << 1)
366 #define PSR_s   (1 << 2)
367 #define PSR_f   (1 << 3)
368
369 static const struct asm_psr psrs[] =
370 {
371   {"CPSR",      TRUE,  PSR_c | PSR_f},
372   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
373   {"SPSR",      FALSE, PSR_c | PSR_f},
374   {"SPSR_all",  FALSE, PSR_c | PSR_f},
375   {"CPSR_flg",  TRUE,  PSR_f},
376   {"CPSR_f",    TRUE,  PSR_f},
377   {"SPSR_flg",  FALSE, PSR_f},
378   {"SPSR_f",    FALSE, PSR_f},
379   {"CPSR_c",    TRUE,  PSR_c},
380   {"CPSR_ctl",  TRUE,  PSR_c},
381   {"SPSR_c",    FALSE, PSR_c},
382   {"SPSR_ctl",  FALSE, PSR_c},
383   {"CPSR_x",    TRUE,  PSR_x},
384   {"CPSR_s",    TRUE,  PSR_s},
385   {"SPSR_x",    FALSE, PSR_x},
386   {"SPSR_s",    FALSE, PSR_s},
387   /* Combinations of flags.  */
388   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
389   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
390   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
391   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
392   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
393   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
394   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
395   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
396   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
397   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
398   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
399   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
400   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
401   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
402   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
403   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
404   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
405   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
406   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
407   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
408   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
409   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
410   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
411   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
412   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
413   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
414   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
415   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
416   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
417   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
418   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
419   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
420   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
421   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
422   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
423   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
424   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
425   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
426   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
427   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
428   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
429   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
430   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
431   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
432   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
433   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
434   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
435   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
436   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
437   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
438   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
439   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
440   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
441   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
442   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
443   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
444   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
445   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
446   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
447   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
448   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
449   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
450   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
451   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
452   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
453   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
454   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
455   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
456   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
457   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
458   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
459   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
460   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
461   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
462   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
463   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
464   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
465   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
466   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
467   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
468   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
469   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
470   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
471   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
472   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
473   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
474   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
475   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
476   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
477   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
478   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
479   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
480   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
481   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
482   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
483   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
484   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
485   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
486   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
487   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
488   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
489   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
490   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
491   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
492   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
493   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
494   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
495   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
496   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
497   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
498   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
499   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
500   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
501   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
502   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
503   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
504   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
505   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
506   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
507   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
508 };
509
510 enum wreg_type
511   {
512     IWMMXT_REG_WR = 0,
513     IWMMXT_REG_WC = 1,
514     IWMMXT_REG_WR_OR_WC = 2,
515     IWMMXT_REG_WCG
516   };
517
518 enum iwmmxt_insn_type
519 {
520   check_rd,
521   check_wr,
522   check_wrwr,
523   check_wrwrwr,
524   check_wrwrwcg,
525   check_tbcst,
526   check_tmovmsk,
527   check_tmia,
528   check_tmcrr,
529   check_tmrrc,
530   check_tmcr,
531   check_tmrc,
532   check_tinsr,
533   check_textrc,
534   check_waligni,
535   check_textrm,
536   check_wshufh
537 };
538
539 enum vfp_dp_reg_pos
540 {
541   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
542 };
543
544 enum vfp_sp_reg_pos
545 {
546   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
547 };
548
549 enum vfp_ldstm_type
550 {
551   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
552 };
553
554 /* VFP system registers.  */
555 struct vfp_reg
556 {
557   const char *name;
558   unsigned long regno;
559 };
560
561 static const struct vfp_reg vfp_regs[] =
562 {
563   {"fpsid", 0x00000000},
564   {"FPSID", 0x00000000},
565   {"fpscr", 0x00010000},
566   {"FPSCR", 0x00010000},
567   {"fpexc", 0x00080000},
568   {"FPEXC", 0x00080000}
569 };
570
571 /* Structure for a hash table entry for a register.  */
572 struct reg_entry
573 {
574   const char * name;
575   int          number;
576   bfd_boolean  builtin;
577 };
578
579 /* Some well known registers that we refer to directly elsewhere.  */
580 #define REG_SP  13
581 #define REG_LR  14
582 #define REG_PC  15
583
584 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
585 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
586 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
587
588 /* These are the standard names.  Users can add aliases with .req.
589    and delete them with .unreq.  */
590
591 /* Integer Register Numbers.  */
592 static const struct reg_entry rn_table[] =
593 {
594   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
595   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
596   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
597   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
598   /* ATPCS Synonyms.  */
599   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
600   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
601   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
602   /* Well-known aliases.  */
603   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
604   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
605   {NULL, 0, TRUE}
606 };
607
608 #define WR_PREFIX 0x200
609 #define WC_PREFIX 0x400
610
611 static const struct reg_entry iwmmxt_table[] =
612 {
613   /* Intel Wireless MMX technology register names.  */
614   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
615   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
616   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
617   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
618   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
619   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
620   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
621   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
622   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
623   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
624   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
625   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
626
627   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
628   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
629   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
630   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
631   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
632   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
633   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
634   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
635   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
636   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
637   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
638   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
639   {NULL, 0, TRUE}
640 };
641
642 /* Co-processor Numbers.  */
643 static const struct reg_entry cp_table[] =
644 {
645   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
646   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
647   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
648   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
649   {NULL, 0, TRUE}
650 };
651
652 /* Co-processor Register Numbers.  */
653 static const struct reg_entry cn_table[] =
654 {
655   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
656   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
657   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
658   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
659   /* Not really valid, but kept for back-wards compatibility.  */
660   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
661   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
662   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
663   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
664   {NULL, 0, TRUE}
665 };
666
667 /* FPA Registers.  */
668 static const struct reg_entry fn_table[] =
669 {
670   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
671   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
672   {NULL, 0, TRUE}
673 };
674
675 /* VFP SP Registers.  */
676 static const struct reg_entry sn_table[] =
677 {
678   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
679   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
680   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
681   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
682   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
683   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
684   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
685   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
686   {NULL, 0, TRUE}
687 };
688
689 /* VFP DP Registers.  */
690 static const struct reg_entry dn_table[] =
691 {
692   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
693   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
694   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
695   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
696   {NULL, 0, TRUE}
697 };
698
699 /* Maverick DSP coprocessor registers.  */
700 static const struct reg_entry mav_mvf_table[] =
701 {
702   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
703   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
704   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
705   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
706   {NULL, 0, TRUE}
707 };
708
709 static const struct reg_entry mav_mvd_table[] =
710 {
711   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
712   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
713   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
714   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
715   {NULL, 0, TRUE}
716 };
717
718 static const struct reg_entry mav_mvfx_table[] =
719 {
720   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
721   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
722   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
723   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
724   {NULL, 0, TRUE}
725 };
726
727 static const struct reg_entry mav_mvdx_table[] =
728 {
729   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
730   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
731   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
732   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
733   {NULL, 0, TRUE}
734 };
735
736 static const struct reg_entry mav_mvax_table[] =
737 {
738   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
739   {NULL, 0, TRUE}
740 };
741
742 static const struct reg_entry mav_dspsc_table[] =
743 {
744   {"dspsc", 0, TRUE},
745   {NULL, 0, TRUE}
746 };
747
748 struct reg_map
749 {
750   const struct reg_entry * names;
751   int                      max_regno;
752   struct hash_control *    htab;
753   const char *             expected;
754 };
755
756 struct reg_map all_reg_maps[] =
757 {
758   {rn_table,        15, NULL, N_("ARM register expected")},
759   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
760   {cn_table,        15, NULL, N_("co-processor register expected")},
761   {fn_table,         7, NULL, N_("FPA register expected")},
762   {sn_table,        31, NULL, N_("VFP single precision register expected")},
763   {dn_table,        15, NULL, N_("VFP double precision register expected")},
764   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
765   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
766   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
767   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
768   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
769   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
770   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
771 };
772
773 /* Enumeration matching entries in table above.  */
774 enum arm_reg_type
775 {
776   REG_TYPE_RN = 0,
777 #define REG_TYPE_FIRST REG_TYPE_RN
778   REG_TYPE_CP = 1,
779   REG_TYPE_CN = 2,
780   REG_TYPE_FN = 3,
781   REG_TYPE_SN = 4,
782   REG_TYPE_DN = 5,
783   REG_TYPE_MVF = 6,
784   REG_TYPE_MVD = 7,
785   REG_TYPE_MVFX = 8,
786   REG_TYPE_MVDX = 9,
787   REG_TYPE_MVAX = 10,
788   REG_TYPE_DSPSC = 11,
789   REG_TYPE_IWMMXT = 12,
790
791   REG_TYPE_MAX = 13
792 };
793
794 /* ARM instructions take 4bytes in the object file, Thumb instructions
795    take 2:  */
796 #define INSN_SIZE       4
797
798 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
799 #define MAV_MODE1       0x100c
800
801 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
802 #define MAV_MODE2       0x0c10
803
804 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
805 #define MAV_MODE3       0x100c
806
807 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
808 #define MAV_MODE4       0x0c0010
809
810 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
811 #define MAV_MODE5       0x00100c
812
813 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
814 #define MAV_MODE6       0x00100c05
815
816 struct asm_opcode
817 {
818   /* Basic string to match.  */
819   const char * template;
820
821   /* Basic instruction code.  */
822   unsigned long value;
823
824   /* Offset into the template where the condition code (if any) will be.
825      If zero, then the instruction is never conditional.  */
826   unsigned cond_offset;
827
828   /* Which architecture variant provides this instruction.  */
829   unsigned long variant;
830
831   /* Function to call to parse args.  */
832   void (* parms) (char *);
833 };
834
835 /* Defines for various bits that we will want to toggle.  */
836 #define INST_IMMEDIATE  0x02000000
837 #define OFFSET_REG      0x02000000
838 #define HWOFFSET_IMM    0x00400000
839 #define SHIFT_BY_REG    0x00000010
840 #define PRE_INDEX       0x01000000
841 #define INDEX_UP        0x00800000
842 #define WRITE_BACK      0x00200000
843 #define LDM_TYPE_2_OR_3 0x00400000
844
845 #define LITERAL_MASK    0xf000f000
846 #define OPCODE_MASK     0xfe1fffff
847 #define V4_STR_BIT      0x00000020
848
849 #define DATA_OP_SHIFT   21
850
851 /* Codes to distinguish the arithmetic instructions.  */
852 #define OPCODE_AND      0
853 #define OPCODE_EOR      1
854 #define OPCODE_SUB      2
855 #define OPCODE_RSB      3
856 #define OPCODE_ADD      4
857 #define OPCODE_ADC      5
858 #define OPCODE_SBC      6
859 #define OPCODE_RSC      7
860 #define OPCODE_TST      8
861 #define OPCODE_TEQ      9
862 #define OPCODE_CMP      10
863 #define OPCODE_CMN      11
864 #define OPCODE_ORR      12
865 #define OPCODE_MOV      13
866 #define OPCODE_BIC      14
867 #define OPCODE_MVN      15
868
869 #define T_OPCODE_MUL 0x4340
870 #define T_OPCODE_TST 0x4200
871 #define T_OPCODE_CMN 0x42c0
872 #define T_OPCODE_NEG 0x4240
873 #define T_OPCODE_MVN 0x43c0
874
875 #define T_OPCODE_ADD_R3 0x1800
876 #define T_OPCODE_SUB_R3 0x1a00
877 #define T_OPCODE_ADD_HI 0x4400
878 #define T_OPCODE_ADD_ST 0xb000
879 #define T_OPCODE_SUB_ST 0xb080
880 #define T_OPCODE_ADD_SP 0xa800
881 #define T_OPCODE_ADD_PC 0xa000
882 #define T_OPCODE_ADD_I8 0x3000
883 #define T_OPCODE_SUB_I8 0x3800
884 #define T_OPCODE_ADD_I3 0x1c00
885 #define T_OPCODE_SUB_I3 0x1e00
886
887 #define T_OPCODE_ASR_R  0x4100
888 #define T_OPCODE_LSL_R  0x4080
889 #define T_OPCODE_LSR_R  0x40c0
890 #define T_OPCODE_ASR_I  0x1000
891 #define T_OPCODE_LSL_I  0x0000
892 #define T_OPCODE_LSR_I  0x0800
893
894 #define T_OPCODE_MOV_I8 0x2000
895 #define T_OPCODE_CMP_I8 0x2800
896 #define T_OPCODE_CMP_LR 0x4280
897 #define T_OPCODE_MOV_HR 0x4600
898 #define T_OPCODE_CMP_HR 0x4500
899
900 #define T_OPCODE_LDR_PC 0x4800
901 #define T_OPCODE_LDR_SP 0x9800
902 #define T_OPCODE_STR_SP 0x9000
903 #define T_OPCODE_LDR_IW 0x6800
904 #define T_OPCODE_STR_IW 0x6000
905 #define T_OPCODE_LDR_IH 0x8800
906 #define T_OPCODE_STR_IH 0x8000
907 #define T_OPCODE_LDR_IB 0x7800
908 #define T_OPCODE_STR_IB 0x7000
909 #define T_OPCODE_LDR_RW 0x5800
910 #define T_OPCODE_STR_RW 0x5000
911 #define T_OPCODE_LDR_RH 0x5a00
912 #define T_OPCODE_STR_RH 0x5200
913 #define T_OPCODE_LDR_RB 0x5c00
914 #define T_OPCODE_STR_RB 0x5400
915
916 #define T_OPCODE_PUSH   0xb400
917 #define T_OPCODE_POP    0xbc00
918
919 #define T_OPCODE_BRANCH 0xe7fe
920
921 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
922 #define THUMB_REG_LO    0x1
923 #define THUMB_REG_HI    0x2
924 #define THUMB_REG_ANY   0x3
925
926 #define THUMB_H1        0x0080
927 #define THUMB_H2        0x0040
928
929 #define THUMB_ASR 0
930 #define THUMB_LSL 1
931 #define THUMB_LSR 2
932
933 #define THUMB_MOVE 0
934 #define THUMB_COMPARE 1
935 #define THUMB_CPY 2
936
937 #define THUMB_LOAD 0
938 #define THUMB_STORE 1
939
940 #define THUMB_PP_PC_LR 0x0100
941
942 /* These three are used for immediate shifts, do not alter.  */
943 #define THUMB_WORD 2
944 #define THUMB_HALFWORD 1
945 #define THUMB_BYTE 0
946
947 struct thumb_opcode
948 {
949   /* Basic string to match.  */
950   const char * template;
951
952   /* Basic instruction code.  */
953   unsigned long value;
954
955   int size;
956
957   /* Which CPU variants this exists for.  */
958   unsigned long variant;
959
960   /* Function to call to parse args.  */
961   void (* parms) (char *);
962 };
963
964 #define BAD_ARGS        _("bad arguments to instruction")
965 #define BAD_PC          _("r15 not allowed here")
966 #define BAD_COND        _("instruction is not conditional")
967 #define ERR_NO_ACCUM    _("acc0 expected")
968
969 static struct hash_control * arm_ops_hsh   = NULL;
970 static struct hash_control * arm_tops_hsh  = NULL;
971 static struct hash_control * arm_cond_hsh  = NULL;
972 static struct hash_control * arm_shift_hsh = NULL;
973 static struct hash_control * arm_psr_hsh   = NULL;
974
975 /* Stuff needed to resolve the label ambiguity
976    As:
977      ...
978      label:   <insn>
979    may differ from:
980      ...
981      label:
982               <insn>
983 */
984
985 symbolS *  last_label_seen;
986 static int label_is_thumb_function_name = FALSE;
987 \f
988 /* Literal Pool stuff.  */
989
990 #define MAX_LITERAL_POOL_SIZE 1024
991
992 /* Literal pool structure.  Held on a per-section
993    and per-sub-section basis.  */
994
995 typedef struct literal_pool
996 {
997   expressionS    literals [MAX_LITERAL_POOL_SIZE];
998   unsigned int   next_free_entry;
999   unsigned int   id;
1000   symbolS *      symbol;
1001   segT           section;
1002   subsegT        sub_section;
1003   struct literal_pool * next;
1004 } literal_pool;
1005
1006 /* Pointer to a linked list of literal pools.  */
1007 literal_pool * list_of_pools = NULL;
1008
1009 static literal_pool *
1010 find_literal_pool (void)
1011 {
1012   literal_pool * pool;
1013
1014   for (pool = list_of_pools; pool != NULL; pool = pool->next)
1015     {
1016       if (pool->section == now_seg
1017           && pool->sub_section == now_subseg)
1018         break;
1019     }
1020
1021   return pool;
1022 }
1023
1024 static literal_pool *
1025 find_or_make_literal_pool (void)
1026 {
1027   /* Next literal pool ID number.  */
1028   static unsigned int latest_pool_num = 1;
1029   literal_pool *      pool;
1030
1031   pool = find_literal_pool ();
1032
1033   if (pool == NULL)
1034     {
1035       /* Create a new pool.  */
1036       pool = xmalloc (sizeof (* pool));
1037       if (! pool)
1038         return NULL;
1039
1040       pool->next_free_entry = 0;
1041       pool->section         = now_seg;
1042       pool->sub_section     = now_subseg;
1043       pool->next            = list_of_pools;
1044       pool->symbol          = NULL;
1045
1046       /* Add it to the list.  */
1047       list_of_pools = pool;
1048     }
1049
1050   /* New pools, and emptied pools, will have a NULL symbol.  */
1051   if (pool->symbol == NULL)
1052     {
1053       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
1054                                     (valueT) 0, &zero_address_frag);
1055       pool->id = latest_pool_num ++;
1056     }
1057
1058   /* Done.  */
1059   return pool;
1060 }
1061
1062 /* Add the literal in the global 'inst'
1063    structure to the relevent literal pool.  */
1064
1065 static int
1066 add_to_lit_pool (void)
1067 {
1068   literal_pool * pool;
1069   unsigned int entry;
1070
1071   pool = find_or_make_literal_pool ();
1072
1073   /* Check if this literal value is already in the pool.  */
1074   for (entry = 0; entry < pool->next_free_entry; entry ++)
1075     {
1076       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1077           && (inst.reloc.exp.X_op == O_constant)
1078           && (pool->literals[entry].X_add_number
1079               == inst.reloc.exp.X_add_number)
1080           && (pool->literals[entry].X_unsigned
1081               == inst.reloc.exp.X_unsigned))
1082         break;
1083
1084       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1085           && (inst.reloc.exp.X_op == O_symbol)
1086           && (pool->literals[entry].X_add_number
1087               == inst.reloc.exp.X_add_number)
1088           && (pool->literals[entry].X_add_symbol
1089               == inst.reloc.exp.X_add_symbol)
1090           && (pool->literals[entry].X_op_symbol
1091               == inst.reloc.exp.X_op_symbol))
1092         break;
1093     }
1094
1095   /* Do we need to create a new entry?  */
1096   if (entry == pool->next_free_entry)
1097     {
1098       if (entry >= MAX_LITERAL_POOL_SIZE)
1099         {
1100           inst.error = _("literal pool overflow");
1101           return FAIL;
1102         }
1103
1104       pool->literals[entry] = inst.reloc.exp;
1105       pool->next_free_entry += 1;
1106     }
1107
1108   inst.reloc.exp.X_op         = O_symbol;
1109   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
1110   inst.reloc.exp.X_add_symbol = pool->symbol;
1111
1112   return SUCCESS;
1113 }
1114
1115 /* Can't use symbol_new here, so have to create a symbol and then at
1116    a later date assign it a value. Thats what these functions do.  */
1117
1118 static void
1119 symbol_locate (symbolS *    symbolP,
1120                const char * name,       /* It is copied, the caller can modify.  */
1121                segT         segment,    /* Segment identifier (SEG_<something>).  */
1122                valueT       valu,       /* Symbol value.  */
1123                fragS *      frag)       /* Associated fragment.  */
1124 {
1125   unsigned int name_length;
1126   char * preserved_copy_of_name;
1127
1128   name_length = strlen (name) + 1;   /* +1 for \0.  */
1129   obstack_grow (&notes, name, name_length);
1130   preserved_copy_of_name = obstack_finish (&notes);
1131 #ifdef STRIP_UNDERSCORE
1132   if (preserved_copy_of_name[0] == '_')
1133     preserved_copy_of_name++;
1134 #endif
1135
1136 #ifdef tc_canonicalize_symbol_name
1137   preserved_copy_of_name =
1138     tc_canonicalize_symbol_name (preserved_copy_of_name);
1139 #endif
1140
1141   S_SET_NAME (symbolP, preserved_copy_of_name);
1142
1143   S_SET_SEGMENT (symbolP, segment);
1144   S_SET_VALUE (symbolP, valu);
1145   symbol_clear_list_pointers (symbolP);
1146
1147   symbol_set_frag (symbolP, frag);
1148
1149   /* Link to end of symbol chain.  */
1150   {
1151     extern int symbol_table_frozen;
1152
1153     if (symbol_table_frozen)
1154       abort ();
1155   }
1156
1157   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1158
1159   obj_symbol_new_hook (symbolP);
1160
1161 #ifdef tc_symbol_new_hook
1162   tc_symbol_new_hook (symbolP);
1163 #endif
1164
1165 #ifdef DEBUG_SYMS
1166   verify_symbol_chain (symbol_rootP, symbol_lastP);
1167 #endif /* DEBUG_SYMS  */
1168 }
1169
1170 /* Check that an immediate is valid.
1171    If so, convert it to the right format.  */
1172
1173 static unsigned int
1174 validate_immediate (unsigned int val)
1175 {
1176   unsigned int a;
1177   unsigned int i;
1178
1179 #define rotate_left(v, n) (v << n | v >> (32 - n))
1180
1181   for (i = 0; i < 32; i += 2)
1182     if ((a = rotate_left (val, i)) <= 0xff)
1183       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
1184
1185   return FAIL;
1186 }
1187
1188 /* Check to see if an immediate can be computed as two separate immediate
1189    values, added together.  We already know that this value cannot be
1190    computed by just one ARM instruction.  */
1191
1192 static unsigned int
1193 validate_immediate_twopart (unsigned int   val,
1194                             unsigned int * highpart)
1195 {
1196   unsigned int a;
1197   unsigned int i;
1198
1199   for (i = 0; i < 32; i += 2)
1200     if (((a = rotate_left (val, i)) & 0xff) != 0)
1201       {
1202         if (a & 0xff00)
1203           {
1204             if (a & ~ 0xffff)
1205               continue;
1206             * highpart = (a  >> 8) | ((i + 24) << 7);
1207           }
1208         else if (a & 0xff0000)
1209           {
1210             if (a & 0xff000000)
1211               continue;
1212             * highpart = (a >> 16) | ((i + 16) << 7);
1213           }
1214         else
1215           {
1216             assert (a & 0xff000000);
1217             * highpart = (a >> 24) | ((i + 8) << 7);
1218           }
1219
1220         return (a & 0xff) | (i << 7);
1221       }
1222
1223   return FAIL;
1224 }
1225
1226 static int
1227 validate_offset_imm (unsigned int val, int hwse)
1228 {
1229   if ((hwse && val > 255) || val > 4095)
1230     return FAIL;
1231   return val;
1232 }
1233
1234 \f
1235 #ifdef OBJ_ELF
1236 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
1237    (This text is taken from version B-02 of the spec):
1238
1239       4.4.7 Mapping and tagging symbols
1240
1241       A section of an ARM ELF file can contain a mixture of ARM code,
1242       Thumb code, and data.  There are inline transitions between code
1243       and data at literal pool boundaries. There can also be inline
1244       transitions between ARM code and Thumb code, for example in
1245       ARM-Thumb inter-working veneers.  Linkers, machine-level
1246       debuggers, profiling tools, and disassembly tools need to map
1247       images accurately. For example, setting an ARM breakpoint on a
1248       Thumb location, or in a literal pool, can crash the program
1249       being debugged, ruining the debugging session.
1250
1251       ARM ELF entities are mapped (see section 4.4.7.1 below) and
1252       tagged (see section 4.4.7.2 below) using local symbols (with
1253       binding STB_LOCAL).  To assist consumers, mapping and tagging
1254       symbols should be collated first in the symbol table, before
1255       other symbols with binding STB_LOCAL.
1256
1257       To allow properly collated mapping and tagging symbols to be
1258       skipped by consumers that have no interest in them, the first
1259       such symbol should have the name $m and its st_value field equal
1260       to the total number of mapping and tagging symbols (including
1261       the $m) in the symbol table.
1262
1263       4.4.7.1 Mapping symbols
1264
1265       $a    Labels the first byte of a sequence of ARM instructions.
1266             Its type is STT_FUNC.
1267
1268       $d    Labels the first byte of a sequence of data items.
1269             Its type is STT_OBJECT.
1270
1271       $t    Labels the first byte of a sequence of Thumb instructions.
1272             Its type is STT_FUNC.
1273
1274       This list of mapping symbols may be extended in the future.
1275
1276       Section-relative mapping symbols
1277
1278       Mapping symbols defined in a section define a sequence of
1279       half-open address intervals that cover the address range of the
1280       section. Each interval starts at the address defined by a
1281       mapping symbol, and continues up to, but not including, the
1282       address defined by the next (in address order) mapping symbol or
1283       the end of the section. A corollary is that there must be a
1284       mapping symbol defined at the beginning of each section.
1285       Consumers can ignore the size of a section-relative mapping
1286       symbol. Producers can set it to 0.
1287
1288       Absolute mapping symbols
1289
1290       Because of the need to crystallize a Thumb address with the
1291       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
1292       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
1293       or $t.
1294
1295       The extent of a mapping symbol defined in SHN_ABS is [st_value,
1296       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
1297       where [x, y) denotes the half-open address range from x,
1298       inclusive, to y, exclusive.
1299
1300       In the absence of a mapping symbol, a consumer can interpret a
1301       function symbol with an odd value as the Thumb code address
1302       obtained by clearing the least significant bit of the
1303       value. This interpretation is deprecated, and it may not work in
1304       the future.
1305
1306    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
1307    the EABI (which is still under development), so they are not
1308    implemented here.  */
1309
1310 static enum mstate mapstate = MAP_UNDEFINED;
1311
1312 static void
1313 mapping_state (enum mstate state)
1314 {
1315   symbolS * symbolP;
1316   const char * symname;
1317   int type;
1318
1319   if (mapstate == state)
1320     /* The mapping symbol has already been emitted.
1321        There is nothing else to do.  */
1322     return;
1323
1324   mapstate = state;
1325
1326   switch (state)
1327     {
1328     case MAP_DATA:
1329       symname = "$d";
1330       type = BSF_OBJECT;
1331       break;
1332     case MAP_ARM:
1333       symname = "$a";
1334       type = BSF_FUNCTION;
1335       break;
1336     case MAP_THUMB:
1337       symname = "$t";
1338       type = BSF_FUNCTION;
1339       break;
1340     case MAP_UNDEFINED:
1341       return;
1342     default:
1343       abort ();
1344     }
1345
1346   seg_info (now_seg)->tc_segment_info_data = state;
1347
1348   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
1349   symbol_table_insert (symbolP);
1350   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1351
1352   switch (state)
1353     {
1354     case MAP_ARM:
1355       THUMB_SET_FUNC (symbolP, 0);
1356       ARM_SET_THUMB (symbolP, 0);
1357       ARM_SET_INTERWORK (symbolP, support_interwork);
1358       break;
1359
1360     case MAP_THUMB:
1361       THUMB_SET_FUNC (symbolP, 1);
1362       ARM_SET_THUMB (symbolP, 1);
1363       ARM_SET_INTERWORK (symbolP, support_interwork);
1364       break;
1365
1366     case MAP_DATA:
1367     default:
1368       return;
1369     }
1370 }
1371
1372 /* When we change sections we need to issue a new mapping symbol.  */
1373
1374 void
1375 arm_elf_change_section (void)
1376 {
1377   flagword flags;
1378
1379   /* Link an unlinked unwind index table section to the .text section.  */
1380   if (elf_section_type (now_seg) == SHT_ARM_EXIDX
1381       && elf_linked_to_section (now_seg) == NULL)
1382     elf_linked_to_section (now_seg) = text_section;
1383
1384   if (!SEG_NORMAL (now_seg))
1385     return;
1386
1387   flags = bfd_get_section_flags (stdoutput, now_seg);
1388
1389   /* We can ignore sections that only contain debug info.  */
1390   if ((flags & SEC_ALLOC) == 0)
1391     return;
1392
1393   mapstate = seg_info (now_seg)->tc_segment_info_data;
1394 }
1395
1396 int
1397 arm_elf_section_type (const char * str, size_t len)
1398 {
1399   if (len == 5 && strncmp (str, "exidx", 5) == 0)
1400     return SHT_ARM_EXIDX;
1401
1402   return -1;
1403 }
1404 #else
1405 #define mapping_state(a)
1406 #endif /* OBJ_ELF */
1407 \f
1408 /* arm_reg_parse () := if it looks like a register, return its token and
1409    advance the pointer.  */
1410
1411 static int
1412 arm_reg_parse (char ** ccp, struct hash_control * htab)
1413 {
1414   char * start = * ccp;
1415   char   c;
1416   char * p;
1417   struct reg_entry * reg;
1418
1419 #ifdef REGISTER_PREFIX
1420   if (*start != REGISTER_PREFIX)
1421     return FAIL;
1422   p = start + 1;
1423 #else
1424   p = start;
1425 #ifdef OPTIONAL_REGISTER_PREFIX
1426   if (*p == OPTIONAL_REGISTER_PREFIX)
1427     p++, start++;
1428 #endif
1429 #endif
1430   if (!ISALPHA (*p) || !is_name_beginner (*p))
1431     return FAIL;
1432
1433   c = *p++;
1434   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
1435     c = *p++;
1436
1437   *--p = 0;
1438   reg = (struct reg_entry *) hash_find (htab, start);
1439   *p = c;
1440
1441   if (reg)
1442     {
1443       *ccp = p;
1444       return reg->number;
1445     }
1446
1447   return FAIL;
1448 }
1449
1450 /* Search for the following register name in each of the possible reg name
1451    tables.  Return the classification if found, or REG_TYPE_MAX if not
1452    present.  */
1453
1454 static enum arm_reg_type
1455 arm_reg_parse_any (char *cp)
1456 {
1457   int i;
1458
1459   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
1460     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
1461       return (enum arm_reg_type) i;
1462
1463   return REG_TYPE_MAX;
1464 }
1465
1466 static void
1467 opcode_select (int width)
1468 {
1469   switch (width)
1470     {
1471     case 16:
1472       if (! thumb_mode)
1473         {
1474           if (! (cpu_variant & ARM_EXT_V4T))
1475             as_bad (_("selected processor does not support THUMB opcodes"));
1476
1477           thumb_mode = 1;
1478           /* No need to force the alignment, since we will have been
1479              coming from ARM mode, which is word-aligned.  */
1480           record_alignment (now_seg, 1);
1481         }
1482       mapping_state (MAP_THUMB);
1483       break;
1484
1485     case 32:
1486       if (thumb_mode)
1487         {
1488           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
1489             as_bad (_("selected processor does not support ARM opcodes"));
1490
1491           thumb_mode = 0;
1492
1493           if (!need_pass_2)
1494             frag_align (2, 0, 0);
1495
1496           record_alignment (now_seg, 1);
1497         }
1498       mapping_state (MAP_ARM);
1499       break;
1500
1501     default:
1502       as_bad (_("invalid instruction size selected (%d)"), width);
1503     }
1504 }
1505
1506 static void
1507 s_req (int a ATTRIBUTE_UNUSED)
1508 {
1509   as_bad (_("invalid syntax for .req directive"));
1510 }
1511
1512 /* The .unreq directive deletes an alias which was previously defined
1513    by .req.  For example:
1514
1515        my_alias .req r11
1516        .unreq my_alias    */
1517
1518 static void
1519 s_unreq (int a ATTRIBUTE_UNUSED)
1520 {
1521   char * name;
1522   char saved_char;
1523
1524   skip_whitespace (input_line_pointer);
1525   name = input_line_pointer;
1526
1527   while (*input_line_pointer != 0
1528          && *input_line_pointer != ' '
1529          && *input_line_pointer != '\n')
1530     ++input_line_pointer;
1531
1532   saved_char = *input_line_pointer;
1533   *input_line_pointer = 0;
1534
1535   if (*name)
1536     {
1537       enum arm_reg_type req_type = arm_reg_parse_any (name);
1538
1539       if (req_type != REG_TYPE_MAX)
1540         {
1541           char *temp_name = name;
1542           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
1543
1544           if (req_no != FAIL)
1545             {
1546               struct reg_entry *req_entry;
1547
1548               /* Check to see if this alias is a builtin one.  */
1549               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
1550
1551               if (!req_entry)
1552                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
1553               else if (req_entry->builtin)
1554                 /* FIXME: We are deleting a built in register alias which
1555                    points to a const data structure, so we only need to
1556                    free up the memory used by the key in the hash table.
1557                    Unfortunately we have not recorded this value, so this
1558                    is a memory leak.  */
1559                   /* FIXME: Should we issue a warning message ?  */
1560                 ;
1561               else
1562                 {
1563                   /* Deleting a user defined alias.  We need to free the
1564                      key and the value, but fortunately the key is the same
1565                      as the value->name field.  */
1566                   free ((char *) req_entry->name);
1567                   free (req_entry);
1568                 }
1569             }
1570           else
1571             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1572         }
1573       else
1574         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1575     }
1576   else
1577     as_bad (_("invalid syntax for .unreq directive"));
1578
1579   *input_line_pointer = saved_char;
1580   demand_empty_rest_of_line ();
1581 }
1582
1583 static void
1584 s_bss (int ignore ATTRIBUTE_UNUSED)
1585 {
1586   /* We don't support putting frags in the BSS segment, we fake it by
1587      marking in_bss, then looking at s_skip for clues.  */
1588   subseg_set (bss_section, 0);
1589   demand_empty_rest_of_line ();
1590   mapping_state (MAP_DATA);
1591 }
1592
1593 static void
1594 s_even (int ignore ATTRIBUTE_UNUSED)
1595 {
1596   /* Never make frag if expect extra pass.  */
1597   if (!need_pass_2)
1598     frag_align (1, 0, 0);
1599
1600   record_alignment (now_seg, 1);
1601
1602   demand_empty_rest_of_line ();
1603 }
1604
1605 static void
1606 s_ltorg (int ignored ATTRIBUTE_UNUSED)
1607 {
1608   unsigned int entry;
1609   literal_pool * pool;
1610   char sym_name[20];
1611
1612   pool = find_literal_pool ();
1613   if (pool == NULL
1614       || pool->symbol == NULL
1615       || pool->next_free_entry == 0)
1616     return;
1617
1618   mapping_state (MAP_DATA);
1619
1620   /* Align pool as you have word accesses.
1621      Only make a frag if we have to.  */
1622   if (!need_pass_2)
1623     frag_align (2, 0, 0);
1624
1625   record_alignment (now_seg, 2);
1626
1627   sprintf (sym_name, "$$lit_\002%x", pool->id);
1628
1629   symbol_locate (pool->symbol, sym_name, now_seg,
1630                  (valueT) frag_now_fix (), frag_now);
1631   symbol_table_insert (pool->symbol);
1632
1633   ARM_SET_THUMB (pool->symbol, thumb_mode);
1634
1635 #if defined OBJ_COFF || defined OBJ_ELF
1636   ARM_SET_INTERWORK (pool->symbol, support_interwork);
1637 #endif
1638
1639   for (entry = 0; entry < pool->next_free_entry; entry ++)
1640     /* First output the expression in the instruction to the pool.  */
1641     emit_expr (&(pool->literals[entry]), 4); /* .word  */
1642
1643   /* Mark the pool as empty.  */
1644   pool->next_free_entry = 0;
1645   pool->symbol = NULL;
1646 }
1647
1648 /* Same as s_align_ptwo but align 0 => align 2.  */
1649
1650 static void
1651 s_align (int unused ATTRIBUTE_UNUSED)
1652 {
1653   int temp;
1654   long temp_fill;
1655   long max_alignment = 15;
1656
1657   temp = get_absolute_expression ();
1658   if (temp > max_alignment)
1659     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
1660   else if (temp < 0)
1661     {
1662       as_bad (_("alignment negative. 0 assumed."));
1663       temp = 0;
1664     }
1665
1666   if (*input_line_pointer == ',')
1667     {
1668       input_line_pointer++;
1669       temp_fill = get_absolute_expression ();
1670     }
1671   else
1672     temp_fill = 0;
1673
1674   if (!temp)
1675     temp = 2;
1676
1677   /* Only make a frag if we HAVE to.  */
1678   if (temp && !need_pass_2)
1679     frag_align (temp, (int) temp_fill, 0);
1680   demand_empty_rest_of_line ();
1681
1682   record_alignment (now_seg, temp);
1683 }
1684
1685 static void
1686 s_force_thumb (int ignore ATTRIBUTE_UNUSED)
1687 {
1688   /* If we are not already in thumb mode go into it, EVEN if
1689      the target processor does not support thumb instructions.
1690      This is used by gcc/config/arm/lib1funcs.asm for example
1691      to compile interworking support functions even if the
1692      target processor should not support interworking.  */
1693   if (! thumb_mode)
1694     {
1695       thumb_mode = 2;
1696
1697       record_alignment (now_seg, 1);
1698     }
1699
1700   demand_empty_rest_of_line ();
1701 }
1702
1703 static void
1704 s_thumb_func (int ignore ATTRIBUTE_UNUSED)
1705 {
1706   if (! thumb_mode)
1707     opcode_select (16);
1708
1709   /* The following label is the name/address of the start of a Thumb function.
1710      We need to know this for the interworking support.  */
1711   label_is_thumb_function_name = TRUE;
1712
1713   demand_empty_rest_of_line ();
1714 }
1715
1716 /* Perform a .set directive, but also mark the alias as
1717    being a thumb function.  */
1718
1719 static void
1720 s_thumb_set (int equiv)
1721 {
1722   /* XXX the following is a duplicate of the code for s_set() in read.c
1723      We cannot just call that code as we need to get at the symbol that
1724      is created.  */
1725   char *    name;
1726   char      delim;
1727   char *    end_name;
1728   symbolS * symbolP;
1729
1730   /* Especial apologies for the random logic:
1731      This just grew, and could be parsed much more simply!
1732      Dean - in haste.  */
1733   name      = input_line_pointer;
1734   delim     = get_symbol_end ();
1735   end_name  = input_line_pointer;
1736   *end_name = delim;
1737
1738   SKIP_WHITESPACE ();
1739
1740   if (*input_line_pointer != ',')
1741     {
1742       *end_name = 0;
1743       as_bad (_("expected comma after name \"%s\""), name);
1744       *end_name = delim;
1745       ignore_rest_of_line ();
1746       return;
1747     }
1748
1749   input_line_pointer++;
1750   *end_name = 0;
1751
1752   if (name[0] == '.' && name[1] == '\0')
1753     {
1754       /* XXX - this should not happen to .thumb_set.  */
1755       abort ();
1756     }
1757
1758   if ((symbolP = symbol_find (name)) == NULL
1759       && (symbolP = md_undefined_symbol (name)) == NULL)
1760     {
1761 #ifndef NO_LISTING
1762       /* When doing symbol listings, play games with dummy fragments living
1763          outside the normal fragment chain to record the file and line info
1764          for this symbol.  */
1765       if (listing & LISTING_SYMBOLS)
1766         {
1767           extern struct list_info_struct * listing_tail;
1768           fragS * dummy_frag = xmalloc (sizeof (fragS));
1769
1770           memset (dummy_frag, 0, sizeof (fragS));
1771           dummy_frag->fr_type = rs_fill;
1772           dummy_frag->line = listing_tail;
1773           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1774           dummy_frag->fr_symbol = symbolP;
1775         }
1776       else
1777 #endif
1778         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1779
1780 #ifdef OBJ_COFF
1781       /* "set" symbols are local unless otherwise specified.  */
1782       SF_SET_LOCAL (symbolP);
1783 #endif /* OBJ_COFF  */
1784     }                           /* Make a new symbol.  */
1785
1786   symbol_table_insert (symbolP);
1787
1788   * end_name = delim;
1789
1790   if (equiv
1791       && S_IS_DEFINED (symbolP)
1792       && S_GET_SEGMENT (symbolP) != reg_section)
1793     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1794
1795   pseudo_set (symbolP);
1796
1797   demand_empty_rest_of_line ();
1798
1799   /* XXX Now we come to the Thumb specific bit of code.  */
1800
1801   THUMB_SET_FUNC (symbolP, 1);
1802   ARM_SET_THUMB (symbolP, 1);
1803 #if defined OBJ_ELF || defined OBJ_COFF
1804   ARM_SET_INTERWORK (symbolP, support_interwork);
1805 #endif
1806 }
1807
1808 static void
1809 s_arm (int ignore ATTRIBUTE_UNUSED)
1810 {
1811   opcode_select (32);
1812   demand_empty_rest_of_line ();
1813 }
1814
1815 static void
1816 s_thumb (int ignore ATTRIBUTE_UNUSED)
1817 {
1818   opcode_select (16);
1819   demand_empty_rest_of_line ();
1820 }
1821
1822 static void
1823 s_code (int unused ATTRIBUTE_UNUSED)
1824 {
1825   int temp;
1826
1827   temp = get_absolute_expression ();
1828   switch (temp)
1829     {
1830     case 16:
1831     case 32:
1832       opcode_select (temp);
1833       break;
1834
1835     default:
1836       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1837     }
1838 }
1839
1840 static void
1841 end_of_line (char * str)
1842 {
1843   skip_whitespace (str);
1844
1845   if (*str != '\0' && !inst.error)
1846     inst.error = _("garbage following instruction");
1847 }
1848
1849 static int
1850 skip_past_comma (char ** str)
1851 {
1852   char * p = * str, c;
1853   int comma = 0;
1854
1855   while ((c = *p) == ' ' || c == ',')
1856     {
1857       p++;
1858       if (c == ',' && comma++)
1859         return FAIL;
1860     }
1861
1862   if (c == '\0')
1863     return FAIL;
1864
1865   *str = p;
1866   return comma ? SUCCESS : FAIL;
1867 }
1868
1869 /* Return TRUE if anything in the expression is a bignum.  */
1870
1871 static int
1872 walk_no_bignums (symbolS * sp)
1873 {
1874   if (symbol_get_value_expression (sp)->X_op == O_big)
1875     return 1;
1876
1877   if (symbol_get_value_expression (sp)->X_add_symbol)
1878     {
1879       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1880               || (symbol_get_value_expression (sp)->X_op_symbol
1881                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
1882     }
1883
1884   return 0;
1885 }
1886
1887 static int in_my_get_expression = 0;
1888
1889 static int
1890 my_get_expression (expressionS * ep, char ** str)
1891 {
1892   char * save_in;
1893   segT   seg;
1894
1895   save_in = input_line_pointer;
1896   input_line_pointer = *str;
1897   in_my_get_expression = 1;
1898   seg = expression (ep);
1899   in_my_get_expression = 0;
1900
1901   if (ep->X_op == O_illegal)
1902     {
1903       /* We found a bad expression in md_operand().  */
1904       *str = input_line_pointer;
1905       input_line_pointer = save_in;
1906       return 1;
1907     }
1908
1909 #ifdef OBJ_AOUT
1910   if (seg != absolute_section
1911       && seg != text_section
1912       && seg != data_section
1913       && seg != bss_section
1914       && seg != undefined_section)
1915     {
1916       inst.error = _("bad_segment");
1917       *str = input_line_pointer;
1918       input_line_pointer = save_in;
1919       return 1;
1920     }
1921 #endif
1922
1923   /* Get rid of any bignums now, so that we don't generate an error for which
1924      we can't establish a line number later on.  Big numbers are never valid
1925      in instructions, which is where this routine is always called.  */
1926   if (ep->X_op == O_big
1927       || (ep->X_add_symbol
1928           && (walk_no_bignums (ep->X_add_symbol)
1929               || (ep->X_op_symbol
1930                   && walk_no_bignums (ep->X_op_symbol)))))
1931     {
1932       inst.error = _("invalid constant");
1933       *str = input_line_pointer;
1934       input_line_pointer = save_in;
1935       return 1;
1936     }
1937
1938   *str = input_line_pointer;
1939   input_line_pointer = save_in;
1940   return 0;
1941 }
1942
1943 /* A standard register must be given at this point.
1944    SHIFT is the place to put it in inst.instruction.
1945    Restores input start point on error.
1946    Returns the reg#, or FAIL.  */
1947
1948 static int
1949 reg_required_here (char ** str, int shift)
1950 {
1951   static char buff [128]; /* XXX  */
1952   int         reg;
1953   char *      start = * str;
1954
1955   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
1956     {
1957       if (shift >= 0)
1958         inst.instruction |= reg << shift;
1959       return reg;
1960     }
1961
1962   /* Restore the start point, we may have got a reg of the wrong class.  */
1963   *str = start;
1964
1965   /* In the few cases where we might be able to accept something else
1966      this error can be overridden.  */
1967   sprintf (buff, _("register expected, not '%.100s'"), start);
1968   inst.error = buff;
1969
1970   return FAIL;
1971 }
1972
1973 /* A Intel Wireless MMX technology register
1974    must be given at this point.
1975    Shift is the place to put it in inst.instruction.
1976    Restores input start point on err.
1977    Returns the reg#, or FAIL.  */
1978
1979 static int
1980 wreg_required_here (char ** str,
1981                     int shift,
1982                     enum wreg_type reg_type)
1983 {
1984   static char buff [128];
1985   int    reg;
1986   char * start = *str;
1987
1988   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
1989     {
1990       if (wr_register (reg)
1991           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
1992         {
1993           if (shift >= 0)
1994             inst.instruction |= (reg ^ WR_PREFIX) << shift;
1995           return reg;
1996         }
1997       else if (wc_register (reg)
1998                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
1999         {
2000           if (shift >= 0)
2001             inst.instruction |= (reg ^ WC_PREFIX) << shift;
2002           return reg;
2003         }
2004       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
2005         {
2006           if (shift >= 0)
2007             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
2008           return reg;
2009         }
2010     }
2011
2012   /* Restore the start point, we may have got a reg of the wrong class.  */
2013   *str = start;
2014
2015   /* In the few cases where we might be able to accept
2016      something else this error can be overridden.  */
2017   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
2018   inst.error = buff;
2019
2020   return FAIL;
2021 }
2022
2023 static const struct asm_psr *
2024 arm_psr_parse (char ** ccp)
2025 {
2026   char * start = * ccp;
2027   char   c;
2028   char * p;
2029   const struct asm_psr * psr;
2030
2031   p = start;
2032
2033   /* Skip to the end of the next word in the input stream.  */
2034   do
2035     {
2036       c = *p++;
2037     }
2038   while (ISALPHA (c) || c == '_');
2039
2040   /* Terminate the word.  */
2041   *--p = 0;
2042
2043   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
2044      feature for ease of use and backwards compatibility.  */
2045   if (!strncmp (start, "cpsr", 4))
2046     strncpy (start, "CPSR", 4);
2047   else if (!strncmp (start, "spsr", 4))
2048     strncpy (start, "SPSR", 4);
2049
2050   /* Now locate the word in the psr hash table.  */
2051   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2052
2053   /* Restore the input stream.  */
2054   *p = c;
2055
2056   /* If we found a valid match, advance the
2057      stream pointer past the end of the word.  */
2058   *ccp = p;
2059
2060   return psr;
2061 }
2062
2063 /* Parse the input looking for a PSR flag.  */
2064
2065 static int
2066 psr_required_here (char ** str)
2067 {
2068   char * start = * str;
2069   const struct asm_psr * psr;
2070
2071   psr = arm_psr_parse (str);
2072
2073   if (psr)
2074     {
2075       /* If this is the SPSR that is being modified, set the R bit.  */
2076       if (! psr->cpsr)
2077         inst.instruction |= SPSR_BIT;
2078
2079       /* Set the psr flags in the MSR instruction.  */
2080       inst.instruction |= psr->field << PSR_SHIFT;
2081
2082       return SUCCESS;
2083     }
2084
2085   /* In the few cases where we might be able to accept
2086      something else this error can be overridden.  */
2087   inst.error = _("flag for {c}psr instruction expected");
2088
2089   /* Restore the start point.  */
2090   *str = start;
2091   return FAIL;
2092 }
2093
2094 static int
2095 co_proc_number (char ** str)
2096 {
2097   int processor, pchar;
2098   char *start;
2099
2100   skip_whitespace (*str);
2101   start = *str;
2102
2103   /* The data sheet seems to imply that just a number on its own is valid
2104      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
2105      accept either.  */
2106   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2107       == FAIL)
2108     {
2109       *str = start;
2110
2111       pchar = *(*str)++;
2112       if (pchar >= '0' && pchar <= '9')
2113         {
2114           processor = pchar - '0';
2115           if (**str >= '0' && **str <= '9')
2116             {
2117               processor = processor * 10 + *(*str)++ - '0';
2118               if (processor > 15)
2119                 {
2120                   inst.error = _("illegal co-processor number");
2121                   return FAIL;
2122                 }
2123             }
2124         }
2125       else
2126         {
2127           inst.error = all_reg_maps[REG_TYPE_CP].expected;
2128           return FAIL;
2129         }
2130     }
2131
2132   inst.instruction |= processor << 8;
2133   return SUCCESS;
2134 }
2135
2136 static int
2137 cp_opc_expr (char ** str, int where, int length)
2138 {
2139   expressionS expr;
2140
2141   skip_whitespace (* str);
2142
2143   memset (&expr, '\0', sizeof (expr));
2144
2145   if (my_get_expression (&expr, str))
2146     return FAIL;
2147   if (expr.X_op != O_constant)
2148     {
2149       inst.error = _("bad or missing expression");
2150       return FAIL;
2151     }
2152
2153   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2154     {
2155       inst.error = _("immediate co-processor expression too large");
2156       return FAIL;
2157     }
2158
2159   inst.instruction |= expr.X_add_number << where;
2160   return SUCCESS;
2161 }
2162
2163 static int
2164 cp_reg_required_here (char ** str, int where)
2165 {
2166   int    reg;
2167   char * start = *str;
2168
2169   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2170     {
2171       inst.instruction |= reg << where;
2172       return reg;
2173     }
2174
2175   /* In the few cases where we might be able to accept something else
2176      this error can be overridden.  */
2177   inst.error = all_reg_maps[REG_TYPE_CN].expected;
2178
2179   /* Restore the start point.  */
2180   *str = start;
2181   return FAIL;
2182 }
2183
2184 static int
2185 fp_reg_required_here (char ** str, int where)
2186 {
2187   int    reg;
2188   char * start = * str;
2189
2190   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2191     {
2192       inst.instruction |= reg << where;
2193       return reg;
2194     }
2195
2196   /* In the few cases where we might be able to accept something else
2197      this error can be overridden.  */
2198   inst.error = all_reg_maps[REG_TYPE_FN].expected;
2199
2200   /* Restore the start point.  */
2201   *str = start;
2202   return FAIL;
2203 }
2204
2205 static int
2206 cp_address_offset (char ** str)
2207 {
2208   int offset;
2209
2210   skip_whitespace (* str);
2211
2212   if (! is_immediate_prefix (**str))
2213     {
2214       inst.error = _("immediate expression expected");
2215       return FAIL;
2216     }
2217
2218   (*str)++;
2219
2220   if (my_get_expression (& inst.reloc.exp, str))
2221     return FAIL;
2222
2223   if (inst.reloc.exp.X_op == O_constant)
2224     {
2225       offset = inst.reloc.exp.X_add_number;
2226
2227       if (offset & 3)
2228         {
2229           inst.error = _("co-processor address must be word aligned");
2230           return FAIL;
2231         }
2232
2233       if (offset > 1023 || offset < -1023)
2234         {
2235           inst.error = _("offset too large");
2236           return FAIL;
2237         }
2238
2239       if (offset >= 0)
2240         inst.instruction |= INDEX_UP;
2241       else
2242         offset = -offset;
2243
2244       inst.instruction |= offset >> 2;
2245     }
2246   else
2247     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2248
2249   return SUCCESS;
2250 }
2251
2252 static int
2253 cp_address_required_here (char ** str, int wb_ok)
2254 {
2255   char * p = * str;
2256   int    pre_inc = 0;
2257   int    write_back = 0;
2258
2259   if (*p == '[')
2260     {
2261       int reg;
2262
2263       p++;
2264       skip_whitespace (p);
2265
2266       if ((reg = reg_required_here (& p, 16)) == FAIL)
2267         return FAIL;
2268
2269       skip_whitespace (p);
2270
2271       if (*p == ']')
2272         {
2273           p++;
2274
2275           skip_whitespace (p);
2276
2277           if (*p == '\0')
2278             {
2279               /* As an extension to the official ARM syntax we allow:
2280                    [Rn]
2281                  as a short hand for:
2282                    [Rn,#0]  */
2283               inst.instruction |= PRE_INDEX | INDEX_UP;
2284               *str = p;
2285               return SUCCESS;
2286             }
2287
2288           if (skip_past_comma (& p) == FAIL)
2289             {
2290               inst.error = _("comma expected after closing square bracket");
2291               return FAIL;
2292             }
2293
2294           skip_whitespace (p);
2295
2296           if (*p == '#')
2297             {
2298               if (wb_ok)
2299                 {
2300                   /* [Rn], #expr  */
2301                   write_back = WRITE_BACK;
2302
2303                   if (reg == REG_PC)
2304                     {
2305                       inst.error = _("pc may not be used in post-increment");
2306                       return FAIL;
2307                     }
2308
2309                   if (cp_address_offset (& p) == FAIL)
2310                     return FAIL;
2311                 }
2312               else
2313                 pre_inc = PRE_INDEX | INDEX_UP;
2314             }
2315           else if (*p == '{')
2316             {
2317               int option;
2318
2319               /* [Rn], {<expr>}  */
2320               p++;
2321
2322               skip_whitespace (p);
2323
2324               if (my_get_expression (& inst.reloc.exp, & p))
2325                 return FAIL;
2326
2327               if (inst.reloc.exp.X_op == O_constant)
2328                 {
2329                   option = inst.reloc.exp.X_add_number;
2330
2331                   if (option > 255 || option < 0)
2332                     {
2333                       inst.error = _("'option' field too large");
2334                       return FAIL;
2335                     }
2336
2337                   skip_whitespace (p);
2338
2339                   if (*p != '}')
2340                     {
2341                       inst.error = _("'}' expected at end of 'option' field");
2342                       return FAIL;
2343                     }
2344                   else
2345                     {
2346                       p++;
2347                       inst.instruction |= option;
2348                       inst.instruction |= INDEX_UP;
2349                     }
2350                 }
2351               else
2352                 {
2353                   inst.error = _("non-constant expressions for 'option' field not supported");
2354                   return FAIL;
2355                 }
2356             }
2357           else
2358             {
2359               inst.error = _("# or { expected after comma");
2360               return FAIL;
2361             }
2362         }
2363       else
2364         {
2365           /* '['Rn, #expr']'[!]  */
2366
2367           if (skip_past_comma (& p) == FAIL)
2368             {
2369               inst.error = _("pre-indexed expression expected");
2370               return FAIL;
2371             }
2372
2373           pre_inc = PRE_INDEX;
2374
2375           if (cp_address_offset (& p) == FAIL)
2376             return FAIL;
2377
2378           skip_whitespace (p);
2379
2380           if (*p++ != ']')
2381             {
2382               inst.error = _("missing ]");
2383               return FAIL;
2384             }
2385
2386           skip_whitespace (p);
2387
2388           if (wb_ok && *p == '!')
2389             {
2390               if (reg == REG_PC)
2391                 {
2392                   inst.error = _("pc may not be used with write-back");
2393                   return FAIL;
2394                 }
2395
2396               p++;
2397               write_back = WRITE_BACK;
2398             }
2399         }
2400     }
2401   else
2402     {
2403       if (my_get_expression (&inst.reloc.exp, &p))
2404         return FAIL;
2405
2406       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2407       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2408       inst.reloc.pc_rel = 1;
2409       inst.instruction |= (REG_PC << 16);
2410       pre_inc = PRE_INDEX;
2411     }
2412
2413   inst.instruction |= write_back | pre_inc;
2414   *str = p;
2415   return SUCCESS;
2416 }
2417
2418 static int
2419 cp_byte_address_offset (char ** str)
2420 {
2421   int offset;
2422
2423   skip_whitespace (* str);
2424
2425   if (! is_immediate_prefix (**str))
2426     {
2427       inst.error = _("immediate expression expected");
2428       return FAIL;
2429     }
2430
2431   (*str)++;
2432
2433   if (my_get_expression (& inst.reloc.exp, str))
2434     return FAIL;
2435
2436   if (inst.reloc.exp.X_op == O_constant)
2437     {
2438       offset = inst.reloc.exp.X_add_number;
2439
2440       if (offset > 255 || offset < -255)
2441         {
2442           inst.error = _("offset too large");
2443           return FAIL;
2444         }
2445
2446       if (offset >= 0)
2447         inst.instruction |= INDEX_UP;
2448       else
2449         offset = -offset;
2450
2451       inst.instruction |= offset;
2452     }
2453   else
2454     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2455
2456   return SUCCESS;
2457 }
2458
2459 static int
2460 cp_byte_address_required_here (char ** str)
2461 {
2462   char * p = * str;
2463   int    pre_inc = 0;
2464   int    write_back = 0;
2465
2466   if (*p == '[')
2467     {
2468       int reg;
2469
2470       p++;
2471       skip_whitespace (p);
2472
2473       if ((reg = reg_required_here (& p, 16)) == FAIL)
2474         return FAIL;
2475
2476       skip_whitespace (p);
2477
2478       if (*p == ']')
2479         {
2480           p++;
2481
2482           if (skip_past_comma (& p) == SUCCESS)
2483             {
2484               /* [Rn], #expr */
2485               write_back = WRITE_BACK;
2486
2487               if (reg == REG_PC)
2488                 {
2489                   inst.error = _("pc may not be used in post-increment");
2490                   return FAIL;
2491                 }
2492
2493               if (cp_byte_address_offset (& p) == FAIL)
2494                 return FAIL;
2495             }
2496           else
2497             pre_inc = PRE_INDEX | INDEX_UP;
2498         }
2499       else
2500         {
2501           /* '['Rn, #expr']'[!] */
2502
2503           if (skip_past_comma (& p) == FAIL)
2504             {
2505               inst.error = _("pre-indexed expression expected");
2506               return FAIL;
2507             }
2508
2509           pre_inc = PRE_INDEX;
2510
2511           if (cp_byte_address_offset (& p) == FAIL)
2512             return FAIL;
2513
2514           skip_whitespace (p);
2515
2516           if (*p++ != ']')
2517             {
2518               inst.error = _("missing ]");
2519               return FAIL;
2520             }
2521
2522           skip_whitespace (p);
2523
2524           if (*p == '!')
2525             {
2526               if (reg == REG_PC)
2527                 {
2528                   inst.error = _("pc may not be used with write-back");
2529                   return FAIL;
2530                 }
2531
2532               p++;
2533               write_back = WRITE_BACK;
2534             }
2535         }
2536     }
2537   else
2538     {
2539       if (my_get_expression (&inst.reloc.exp, &p))
2540         return FAIL;
2541
2542       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2543       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2544       inst.reloc.pc_rel = 1;
2545       inst.instruction |= (REG_PC << 16);
2546       pre_inc = PRE_INDEX;
2547     }
2548
2549   inst.instruction |= write_back | pre_inc;
2550   *str = p;
2551   return SUCCESS;
2552 }
2553
2554 static void
2555 do_nop (char * str)
2556 {
2557   skip_whitespace (str);
2558   if (*str == '{')
2559     {
2560       str++;
2561
2562       if (my_get_expression (&inst.reloc.exp, &str))
2563         inst.reloc.exp.X_op = O_illegal;
2564       else
2565         {
2566           skip_whitespace (str);
2567           if (*str == '}')
2568             str++;
2569           else
2570             inst.reloc.exp.X_op = O_illegal;
2571         }
2572
2573       if (inst.reloc.exp.X_op != O_constant
2574           || inst.reloc.exp.X_add_number > 255
2575           || inst.reloc.exp.X_add_number < 0)
2576         {
2577           inst.error = _("Invalid NOP hint");
2578           return;
2579         }
2580
2581       /* Arcitectural NOP hints are CPSR sets with no bits selected.  */
2582       inst.instruction &= 0xf0000000;
2583       inst.instruction |= 0x0320f000 + inst.reloc.exp.X_add_number;
2584     }
2585
2586   end_of_line (str);
2587 }
2588
2589 static void
2590 do_empty (char * str)
2591 {
2592   /* Do nothing really.  */
2593   end_of_line (str);
2594 }
2595
2596 static void
2597 do_mrs (char * str)
2598 {
2599   int skip = 0;
2600
2601   /* Only one syntax.  */
2602   skip_whitespace (str);
2603
2604   if (reg_required_here (&str, 12) == FAIL)
2605     {
2606       inst.error = BAD_ARGS;
2607       return;
2608     }
2609
2610   if (skip_past_comma (&str) == FAIL)
2611     {
2612       inst.error = _("comma expected after register name");
2613       return;
2614     }
2615
2616   skip_whitespace (str);
2617
2618   if (   streq (str, "CPSR")
2619       || streq (str, "SPSR")
2620          /* Lower case versions for backwards compatibility.  */
2621       || streq (str, "cpsr")
2622       || streq (str, "spsr"))
2623     skip = 4;
2624
2625   /* This is for backwards compatibility with older toolchains.  */
2626   else if (   streq (str, "cpsr_all")
2627            || streq (str, "spsr_all"))
2628     skip = 8;
2629   else
2630     {
2631       inst.error = _("CPSR or SPSR expected");
2632       return;
2633     }
2634
2635   if (* str == 's' || * str == 'S')
2636     inst.instruction |= SPSR_BIT;
2637   str += skip;
2638
2639   end_of_line (str);
2640 }
2641
2642 /* Two possible forms:
2643       "{C|S}PSR_<field>, Rm",
2644       "{C|S}PSR_f, #expression".  */
2645
2646 static void
2647 do_msr (char * str)
2648 {
2649   skip_whitespace (str);
2650
2651   if (psr_required_here (& str) == FAIL)
2652     return;
2653
2654   if (skip_past_comma (& str) == FAIL)
2655     {
2656       inst.error = _("comma missing after psr flags");
2657       return;
2658     }
2659
2660   skip_whitespace (str);
2661
2662   if (reg_required_here (& str, 0) != FAIL)
2663     {
2664       inst.error = NULL;
2665       end_of_line (str);
2666       return;
2667     }
2668
2669   if (! is_immediate_prefix (* str))
2670     {
2671       inst.error =
2672         _("only a register or immediate value can follow a psr flag");
2673       return;
2674     }
2675
2676   str ++;
2677   inst.error = NULL;
2678
2679   if (my_get_expression (& inst.reloc.exp, & str))
2680     {
2681       inst.error =
2682         _("only a register or immediate value can follow a psr flag");
2683       return;
2684     }
2685
2686   inst.instruction |= INST_IMMEDIATE;
2687
2688   if (inst.reloc.exp.X_add_symbol)
2689     {
2690       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2691       inst.reloc.pc_rel = 0;
2692     }
2693   else
2694     {
2695       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2696
2697       if (value == (unsigned) FAIL)
2698         {
2699           inst.error = _("invalid constant");
2700           return;
2701         }
2702
2703       inst.instruction |= value;
2704     }
2705
2706   inst.error = NULL;
2707   end_of_line (str);
2708 }
2709
2710 /* Long Multiply Parser
2711    UMULL RdLo, RdHi, Rm, Rs
2712    SMULL RdLo, RdHi, Rm, Rs
2713    UMLAL RdLo, RdHi, Rm, Rs
2714    SMLAL RdLo, RdHi, Rm, Rs.  */
2715
2716 static void
2717 do_mull (char * str)
2718 {
2719   int rdlo, rdhi, rm, rs;
2720
2721   /* Only one format "rdlo, rdhi, rm, rs".  */
2722   skip_whitespace (str);
2723
2724   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2725     {
2726       inst.error = BAD_ARGS;
2727       return;
2728     }
2729
2730   if (skip_past_comma (&str) == FAIL
2731       || (rdhi = reg_required_here (&str, 16)) == FAIL)
2732     {
2733       inst.error = BAD_ARGS;
2734       return;
2735     }
2736
2737   if (skip_past_comma (&str) == FAIL
2738       || (rm = reg_required_here (&str, 0)) == FAIL)
2739     {
2740       inst.error = BAD_ARGS;
2741       return;
2742     }
2743
2744   /* rdhi, rdlo and rm must all be different.  */
2745   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2746     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2747
2748   if (skip_past_comma (&str) == FAIL
2749       || (rs = reg_required_here (&str, 8)) == FAIL)
2750     {
2751       inst.error = BAD_ARGS;
2752       return;
2753     }
2754
2755   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2756     {
2757       inst.error = BAD_PC;
2758       return;
2759     }
2760
2761   end_of_line (str);
2762 }
2763
2764 static void
2765 do_mul (char * str)
2766 {
2767   int rd, rm;
2768
2769   /* Only one format "rd, rm, rs".  */
2770   skip_whitespace (str);
2771
2772   if ((rd = reg_required_here (&str, 16)) == FAIL)
2773     {
2774       inst.error = BAD_ARGS;
2775       return;
2776     }
2777
2778   if (rd == REG_PC)
2779     {
2780       inst.error = BAD_PC;
2781       return;
2782     }
2783
2784   if (skip_past_comma (&str) == FAIL
2785       || (rm = reg_required_here (&str, 0)) == FAIL)
2786     {
2787       inst.error = BAD_ARGS;
2788       return;
2789     }
2790
2791   if (rm == REG_PC)
2792     {
2793       inst.error = BAD_PC;
2794       return;
2795     }
2796
2797   if (rm == rd)
2798     as_tsktsk (_("rd and rm should be different in mul"));
2799
2800   if (skip_past_comma (&str) == FAIL
2801       || (rm = reg_required_here (&str, 8)) == FAIL)
2802     {
2803       inst.error = BAD_ARGS;
2804       return;
2805     }
2806
2807   if (rm == REG_PC)
2808     {
2809       inst.error = BAD_PC;
2810       return;
2811     }
2812
2813   end_of_line (str);
2814 }
2815
2816 static void
2817 do_mla (char * str)
2818 {
2819   int rd, rm;
2820
2821   /* Only one format "rd, rm, rs, rn".  */
2822   skip_whitespace (str);
2823
2824   if ((rd = reg_required_here (&str, 16)) == FAIL)
2825     {
2826       inst.error = BAD_ARGS;
2827       return;
2828     }
2829
2830   if (rd == REG_PC)
2831     {
2832       inst.error = BAD_PC;
2833       return;
2834     }
2835
2836   if (skip_past_comma (&str) == FAIL
2837       || (rm = reg_required_here (&str, 0)) == FAIL)
2838     {
2839       inst.error = BAD_ARGS;
2840       return;
2841     }
2842
2843   if (rm == REG_PC)
2844     {
2845       inst.error = BAD_PC;
2846       return;
2847     }
2848
2849   if (rm == rd)
2850     as_tsktsk (_("rd and rm should be different in mla"));
2851
2852   if (skip_past_comma (&str) == FAIL
2853       || (rd = reg_required_here (&str, 8)) == FAIL
2854       || skip_past_comma (&str) == FAIL
2855       || (rm = reg_required_here (&str, 12)) == FAIL)
2856     {
2857       inst.error = BAD_ARGS;
2858       return;
2859     }
2860
2861   if (rd == REG_PC || rm == REG_PC)
2862     {
2863       inst.error = BAD_PC;
2864       return;
2865     }
2866
2867   end_of_line (str);
2868 }
2869
2870 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2871    Advances *str to the next non-alphanumeric.
2872    Returns 0, or else FAIL (in which case sets inst.error).
2873
2874   (In a future XScale, there may be accumulators other than zero.
2875   At that time this routine and its callers can be upgraded to suit.)  */
2876
2877 static int
2878 accum0_required_here (char ** str)
2879 {
2880   static char buff [128];       /* Note the address is taken.  Hence, static.  */
2881   char * p = * str;
2882   char   c;
2883   int result = 0;               /* The accum number.  */
2884
2885   skip_whitespace (p);
2886
2887   *str = p;                     /* Advance caller's string pointer too.  */
2888   c = *p++;
2889   while (ISALNUM (c))
2890     c = *p++;
2891
2892   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
2893
2894   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2895     {
2896       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2897       inst.error = buff;
2898       result = FAIL;
2899     }
2900
2901   *p = c;                       /* Unzap.  */
2902   *str = p;                     /* Caller's string pointer to after match.  */
2903   return result;
2904 }
2905
2906 static int
2907 ldst_extend_v4 (char ** str)
2908 {
2909   int add = INDEX_UP;
2910
2911   switch (**str)
2912     {
2913     case '#':
2914     case '$':
2915       (*str)++;
2916       if (my_get_expression (& inst.reloc.exp, str))
2917         return FAIL;
2918
2919       if (inst.reloc.exp.X_op == O_constant)
2920         {
2921           int value = inst.reloc.exp.X_add_number;
2922
2923           if (value < -255 || value > 255)
2924             {
2925               inst.error = _("address offset too large");
2926               return FAIL;
2927             }
2928
2929           if (value < 0)
2930             {
2931               value = -value;
2932               add = 0;
2933             }
2934
2935           /* Halfword and signextension instructions have the
2936              immediate value split across bits 11..8 and bits 3..0.  */
2937           inst.instruction |= (add | HWOFFSET_IMM
2938                                | ((value >> 4) << 8) | (value & 0xF));
2939         }
2940       else
2941         {
2942           inst.instruction |= HWOFFSET_IMM;
2943           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2944           inst.reloc.pc_rel = 0;
2945         }
2946       return SUCCESS;
2947
2948     case '-':
2949       add = 0;
2950       /* Fall through.  */
2951
2952     case '+':
2953       (*str)++;
2954       /* Fall through.  */
2955
2956     default:
2957       if (reg_required_here (str, 0) == FAIL)
2958         return FAIL;
2959
2960       inst.instruction |= add;
2961       return SUCCESS;
2962     }
2963 }
2964
2965 /* Expects **str -> after a comma. May be leading blanks.
2966    Advances *str, recognizing a load  mode, and setting inst.instruction.
2967    Returns rn, or else FAIL (in which case may set inst.error
2968    and not advance str)
2969
2970    Note: doesn't know Rd, so no err checks that require such knowledge.  */
2971
2972 static int
2973 ld_mode_required_here (char ** string)
2974 {
2975   char * str = * string;
2976   int    rn;
2977   int    pre_inc = 0;
2978
2979   skip_whitespace (str);
2980
2981   if (* str == '[')
2982     {
2983       str++;
2984
2985       skip_whitespace (str);
2986
2987       if ((rn = reg_required_here (& str, 16)) == FAIL)
2988         return FAIL;
2989
2990       skip_whitespace (str);
2991
2992       if (* str == ']')
2993         {
2994           str ++;
2995
2996           if (skip_past_comma (& str) == SUCCESS)
2997             {
2998               /* [Rn],... (post inc) */
2999               if (ldst_extend_v4 (&str) == FAIL)
3000                 return FAIL;
3001             }
3002           else        /* [Rn] */
3003             {
3004               skip_whitespace (str);
3005
3006               if (* str == '!')
3007                 {
3008                   str ++;
3009                   inst.instruction |= WRITE_BACK;
3010                 }
3011
3012               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3013               pre_inc = 1;
3014             }
3015         }
3016       else        /* [Rn,...] */
3017         {
3018           if (skip_past_comma (& str) == FAIL)
3019             {
3020               inst.error = _("pre-indexed expression expected");
3021               return FAIL;
3022             }
3023
3024           pre_inc = 1;
3025
3026           if (ldst_extend_v4 (&str) == FAIL)
3027             return FAIL;
3028
3029           skip_whitespace (str);
3030
3031           if (* str ++ != ']')
3032             {
3033               inst.error = _("missing ]");
3034               return FAIL;
3035             }
3036
3037           skip_whitespace (str);
3038
3039           if (* str == '!')
3040             {
3041               str ++;
3042               inst.instruction |= WRITE_BACK;
3043             }
3044         }
3045     }
3046   else if (* str == '=')        /* ldr's "r,=label" syntax */
3047     /* We should never reach here, because <text> = <expression> is
3048        caught gas/read.c read_a_source_file() as a .set operation.  */
3049     return FAIL;
3050   else                          /* PC +- 8 bit immediate offset.  */
3051     {
3052       if (my_get_expression (& inst.reloc.exp, & str))
3053         return FAIL;
3054
3055       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3056       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3057       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3058       inst.reloc.pc_rel            = 1;
3059       inst.instruction            |= (REG_PC << 16);
3060
3061       rn = REG_PC;
3062       pre_inc = 1;
3063     }
3064
3065   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3066   * string = str;
3067
3068   return rn;
3069 }
3070
3071 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3072    SMLAxy{cond} Rd,Rm,Rs,Rn
3073    SMLAWy{cond} Rd,Rm,Rs,Rn
3074    Error if any register is R15.  */
3075
3076 static void
3077 do_smla (char * str)
3078 {
3079   int rd, rm, rs, rn;
3080
3081   skip_whitespace (str);
3082
3083   if ((rd = reg_required_here (& str, 16)) == FAIL
3084       || skip_past_comma (& str) == FAIL
3085       || (rm = reg_required_here (& str, 0)) == FAIL
3086       || skip_past_comma (& str) == FAIL
3087       || (rs = reg_required_here (& str, 8)) == FAIL
3088       || skip_past_comma (& str) == FAIL
3089       || (rn = reg_required_here (& str, 12)) == FAIL)
3090     inst.error = BAD_ARGS;
3091
3092   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3093     inst.error = BAD_PC;
3094
3095   else
3096     end_of_line (str);
3097 }
3098
3099 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3100    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3101    Error if any register is R15.
3102    Warning if Rdlo == Rdhi.  */
3103
3104 static void
3105 do_smlal (char * str)
3106 {
3107   int rdlo, rdhi, rm, rs;
3108
3109   skip_whitespace (str);
3110
3111   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3112       || skip_past_comma (& str) == FAIL
3113       || (rdhi = reg_required_here (& str, 16)) == FAIL
3114       || skip_past_comma (& str) == FAIL
3115       || (rm = reg_required_here (& str, 0)) == FAIL
3116       || skip_past_comma (& str) == FAIL
3117       || (rs = reg_required_here (& str, 8)) == FAIL)
3118     {
3119       inst.error = BAD_ARGS;
3120       return;
3121     }
3122
3123   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3124     {
3125       inst.error = BAD_PC;
3126       return;
3127     }
3128
3129   if (rdlo == rdhi)
3130     as_tsktsk (_("rdhi and rdlo must be different"));
3131
3132   end_of_line (str);
3133 }
3134
3135 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3136    SMULxy{cond} Rd,Rm,Rs
3137    Error if any register is R15.  */
3138
3139 static void
3140 do_smul (char * str)
3141 {
3142   int rd, rm, rs;
3143
3144   skip_whitespace (str);
3145
3146   if ((rd = reg_required_here (& str, 16)) == FAIL
3147       || skip_past_comma (& str) == FAIL
3148       || (rm = reg_required_here (& str, 0)) == FAIL
3149       || skip_past_comma (& str) == FAIL
3150       || (rs = reg_required_here (& str, 8)) == FAIL)
3151     inst.error = BAD_ARGS;
3152
3153   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3154     inst.error = BAD_PC;
3155
3156   else
3157     end_of_line (str);
3158 }
3159
3160 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3161    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3162    Error if any register is R15.  */
3163
3164 static void
3165 do_qadd (char * str)
3166 {
3167   int rd, rm, rn;
3168
3169   skip_whitespace (str);
3170
3171   if ((rd = reg_required_here (& str, 12)) == FAIL
3172       || skip_past_comma (& str) == FAIL
3173       || (rm = reg_required_here (& str, 0)) == FAIL
3174       || skip_past_comma (& str) == FAIL
3175       || (rn = reg_required_here (& str, 16)) == FAIL)
3176     inst.error = BAD_ARGS;
3177
3178   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3179     inst.error = BAD_PC;
3180
3181   else
3182     end_of_line (str);
3183 }
3184
3185 /* ARM V5E (el Segundo)
3186    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3187    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3188
3189    These are equivalent to the XScale instructions MAR and MRA,
3190    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3191
3192    Result unpredicatable if Rd or Rn is R15.  */
3193
3194 static void
3195 do_co_reg2c (char * str)
3196 {
3197   int rd, rn;
3198
3199   skip_whitespace (str);
3200
3201   if (co_proc_number (& str) == FAIL)
3202     {
3203       if (!inst.error)
3204         inst.error = BAD_ARGS;
3205       return;
3206     }
3207
3208   if (skip_past_comma (& str) == FAIL
3209       || cp_opc_expr (& str, 4, 4) == FAIL)
3210     {
3211       if (!inst.error)
3212         inst.error = BAD_ARGS;
3213       return;
3214     }
3215
3216   if (skip_past_comma (& str) == FAIL
3217       || (rd = reg_required_here (& str, 12)) == FAIL)
3218     {
3219       if (!inst.error)
3220         inst.error = BAD_ARGS;
3221       return;
3222     }
3223
3224   if (skip_past_comma (& str) == FAIL
3225       || (rn = reg_required_here (& str, 16)) == FAIL)
3226     {
3227       if (!inst.error)
3228         inst.error = BAD_ARGS;
3229       return;
3230     }
3231
3232   /* Unpredictable result if rd or rn is R15.  */
3233   if (rd == REG_PC || rn == REG_PC)
3234     as_tsktsk
3235       (_("Warning: instruction unpredictable when using r15"));
3236
3237   if (skip_past_comma (& str) == FAIL
3238       || cp_reg_required_here (& str, 0) == FAIL)
3239     {
3240       if (!inst.error)
3241         inst.error = BAD_ARGS;
3242       return;
3243     }
3244
3245   end_of_line (str);
3246 }
3247
3248 /* ARM V5 count-leading-zeroes instruction (argument parse)
3249      CLZ{<cond>} <Rd>, <Rm>
3250      Condition defaults to COND_ALWAYS.
3251      Error if Rd or Rm are R15.  */
3252
3253 static void
3254 do_clz (char * str)
3255 {
3256   int rd, rm;
3257
3258   skip_whitespace (str);
3259
3260   if (((rd = reg_required_here (& str, 12)) == FAIL)
3261       || (skip_past_comma (& str) == FAIL)
3262       || ((rm = reg_required_here (& str, 0)) == FAIL))
3263     inst.error = BAD_ARGS;
3264
3265   else if (rd == REG_PC || rm == REG_PC )
3266     inst.error = BAD_PC;
3267
3268   else
3269     end_of_line (str);
3270 }
3271
3272 /* ARM V5 (argument parse)
3273      LDC2{L} <coproc>, <CRd>, <addressing mode>
3274      STC2{L} <coproc>, <CRd>, <addressing mode>
3275      Instruction is not conditional, and has 0xf in the condition field.
3276      Otherwise, it's the same as LDC/STC.  */
3277
3278 static void
3279 do_lstc2 (char * str)
3280 {
3281   skip_whitespace (str);
3282
3283   if (co_proc_number (& str) == FAIL)
3284     {
3285       if (!inst.error)
3286         inst.error = BAD_ARGS;
3287     }
3288   else if (skip_past_comma (& str) == FAIL
3289            || cp_reg_required_here (& str, 12) == FAIL)
3290     {
3291       if (!inst.error)
3292         inst.error = BAD_ARGS;
3293     }
3294   else if (skip_past_comma (& str) == FAIL
3295            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3296     {
3297       if (! inst.error)
3298         inst.error = BAD_ARGS;
3299     }
3300   else
3301     end_of_line (str);
3302 }
3303
3304 /* ARM V5 (argument parse)
3305      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3306      Instruction is not conditional, and has 0xf in the condition field.
3307      Otherwise, it's the same as CDP.  */
3308
3309 static void
3310 do_cdp2 (char * str)
3311 {
3312   skip_whitespace (str);
3313
3314   if (co_proc_number (& str) == FAIL)
3315     {
3316       if (!inst.error)
3317         inst.error = BAD_ARGS;
3318       return;
3319     }
3320
3321   if (skip_past_comma (& str) == FAIL
3322       || cp_opc_expr (& str, 20,4) == FAIL)
3323     {
3324       if (!inst.error)
3325         inst.error = BAD_ARGS;
3326       return;
3327     }
3328
3329   if (skip_past_comma (& str) == FAIL
3330       || cp_reg_required_here (& str, 12) == FAIL)
3331     {
3332       if (!inst.error)
3333         inst.error = BAD_ARGS;
3334       return;
3335     }
3336
3337   if (skip_past_comma (& str) == FAIL
3338       || cp_reg_required_here (& str, 16) == FAIL)
3339     {
3340       if (!inst.error)
3341         inst.error = BAD_ARGS;
3342       return;
3343     }
3344
3345   if (skip_past_comma (& str) == FAIL
3346       || cp_reg_required_here (& str, 0) == FAIL)
3347     {
3348       if (!inst.error)
3349         inst.error = BAD_ARGS;
3350       return;
3351     }
3352
3353   if (skip_past_comma (& str) == SUCCESS)
3354     {
3355       if (cp_opc_expr (& str, 5, 3) == FAIL)
3356         {
3357           if (!inst.error)
3358             inst.error = BAD_ARGS;
3359           return;
3360         }
3361     }
3362
3363   end_of_line (str);
3364 }
3365
3366 /* ARM V5 (argument parse)
3367      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3368      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3369      Instruction is not conditional, and has 0xf in the condition field.
3370      Otherwise, it's the same as MCR/MRC.  */
3371
3372 static void
3373 do_co_reg2 (char * str)
3374 {
3375   skip_whitespace (str);
3376
3377   if (co_proc_number (& str) == FAIL)
3378     {
3379       if (!inst.error)
3380         inst.error = BAD_ARGS;
3381       return;
3382     }
3383
3384   if (skip_past_comma (& str) == FAIL
3385       || cp_opc_expr (& str, 21, 3) == FAIL)
3386     {
3387       if (!inst.error)
3388         inst.error = BAD_ARGS;
3389       return;
3390     }
3391
3392   if (skip_past_comma (& str) == FAIL
3393       || reg_required_here (& str, 12) == FAIL)
3394     {
3395       if (!inst.error)
3396         inst.error = BAD_ARGS;
3397       return;
3398     }
3399
3400   if (skip_past_comma (& str) == FAIL
3401       || cp_reg_required_here (& str, 16) == FAIL)
3402     {
3403       if (!inst.error)
3404         inst.error = BAD_ARGS;
3405       return;
3406     }
3407
3408   if (skip_past_comma (& str) == FAIL
3409       || cp_reg_required_here (& str, 0) == FAIL)
3410     {
3411       if (!inst.error)
3412         inst.error = BAD_ARGS;
3413       return;
3414     }
3415
3416   if (skip_past_comma (& str) == SUCCESS)
3417     {
3418       if (cp_opc_expr (& str, 5, 3) == FAIL)
3419         {
3420           if (!inst.error)
3421             inst.error = BAD_ARGS;
3422           return;
3423         }
3424     }
3425
3426   end_of_line (str);
3427 }
3428
3429 static void
3430 do_bx (char * str)
3431 {
3432   int reg;
3433
3434   skip_whitespace (str);
3435
3436   if ((reg = reg_required_here (&str, 0)) == FAIL)
3437     {
3438       inst.error = BAD_ARGS;
3439       return;
3440     }
3441
3442   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
3443   if (reg == REG_PC)
3444     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
3445
3446   end_of_line (str);
3447 }
3448
3449 /* ARM v5TEJ.  Jump to Jazelle code.  */
3450
3451 static void
3452 do_bxj (char * str)
3453 {
3454   int reg;
3455
3456   skip_whitespace (str);
3457
3458   if ((reg = reg_required_here (&str, 0)) == FAIL)
3459     {
3460       inst.error = BAD_ARGS;
3461       return;
3462     }
3463
3464   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3465   if (reg == REG_PC)
3466     as_tsktsk (_("use of r15 in bxj is not really useful"));
3467
3468   end_of_line (str);
3469 }
3470
3471 /* ARM V6 umaal (argument parse).  */
3472
3473 static void
3474 do_umaal (char * str)
3475 {
3476   int rdlo, rdhi, rm, rs;
3477
3478   skip_whitespace (str);
3479   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3480       || skip_past_comma (& str) == FAIL
3481       || (rdhi = reg_required_here (& str, 16)) == FAIL
3482       || skip_past_comma (& str) == FAIL
3483       || (rm = reg_required_here (& str, 0)) == FAIL
3484       || skip_past_comma (& str) == FAIL
3485       || (rs = reg_required_here (& str, 8)) == FAIL)
3486     {
3487       inst.error = BAD_ARGS;
3488       return;
3489     }
3490
3491   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3492     {
3493       inst.error = BAD_PC;
3494       return;
3495     }
3496
3497   end_of_line (str);
3498 }
3499
3500 /* ARM V6 strex (argument parse).  */
3501
3502 static void
3503 do_strex (char * str)
3504 {
3505   int rd, rm, rn;
3506
3507   /* Parse Rd, Rm,.  */
3508   skip_whitespace (str);
3509   if ((rd = reg_required_here (& str, 12)) == FAIL
3510       || skip_past_comma (& str) == FAIL
3511       || (rm = reg_required_here (& str, 0)) == FAIL
3512       || skip_past_comma (& str) == FAIL)
3513     {
3514       inst.error = BAD_ARGS;
3515       return;
3516     }
3517   if (rd == REG_PC || rm == REG_PC)
3518     {
3519       inst.error = BAD_PC;
3520       return;
3521     }
3522   if (rd == rm)
3523     {
3524       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3525       return;
3526     }
3527
3528   /* Skip past '['.  */
3529   if ((strlen (str) >= 1)
3530       && strncmp (str, "[", 1) == 0)
3531     str += 1;
3532
3533   skip_whitespace (str);
3534
3535   /* Parse Rn.  */
3536   if ((rn = reg_required_here (& str, 16)) == FAIL)
3537     {
3538       inst.error = BAD_ARGS;
3539       return;
3540     }
3541   else if (rn == REG_PC)
3542     {
3543       inst.error = BAD_PC;
3544       return;
3545     }
3546   if (rd == rn)
3547     {
3548       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3549       return;
3550     }
3551   skip_whitespace (str);
3552
3553   /* Skip past ']'.  */
3554   if ((strlen (str) >= 1)
3555       && strncmp (str, "]", 1) == 0)
3556     str += 1;
3557
3558   end_of_line (str);
3559 }
3560
3561 /* KIND indicates what kind of shifts are accepted.  */
3562
3563 static int
3564 decode_shift (char ** str, int kind)
3565 {
3566   const struct asm_shift_name * shift;
3567   char * p;
3568   char   c;
3569
3570   skip_whitespace (* str);
3571
3572   for (p = * str; ISALPHA (* p); p ++)
3573     ;
3574
3575   if (p == * str)
3576     {
3577       inst.error = _("shift expression expected");
3578       return FAIL;
3579     }
3580
3581   c = * p;
3582   * p = '\0';
3583   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3584   * p = c;
3585
3586   if (shift == NULL)
3587     {
3588       inst.error = _("shift expression expected");
3589       return FAIL;
3590     }
3591
3592   assert (shift->properties->index == shift_properties[shift->properties->index].index);
3593
3594   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
3595       && shift->properties->index != SHIFT_LSL
3596       && shift->properties->index != SHIFT_ASR)
3597     {
3598       inst.error = _("'LSL' or 'ASR' required");
3599       return FAIL;
3600     }
3601   else if (kind == SHIFT_LSL_IMMEDIATE
3602            && shift->properties->index != SHIFT_LSL)
3603     {
3604       inst.error = _("'LSL' required");
3605       return FAIL;
3606     }
3607   else if (kind == SHIFT_ASR_IMMEDIATE
3608            && shift->properties->index != SHIFT_ASR)
3609     {
3610       inst.error = _("'ASR' required");
3611       return FAIL;
3612     }
3613
3614   if (shift->properties->index == SHIFT_RRX)
3615     {
3616       * str = p;
3617       inst.instruction |= shift->properties->bit_field;
3618       return SUCCESS;
3619     }
3620
3621   skip_whitespace (p);
3622
3623   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
3624     {
3625       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3626       * str = p;
3627       return SUCCESS;
3628     }
3629   else if (! is_immediate_prefix (* p))
3630     {
3631       inst.error = (NO_SHIFT_RESTRICT
3632                     ? _("shift requires register or #expression")
3633                     : _("shift requires #expression"));
3634       * str = p;
3635       return FAIL;
3636     }
3637
3638   inst.error = NULL;
3639   p ++;
3640
3641   if (my_get_expression (& inst.reloc.exp, & p))
3642     return FAIL;
3643
3644   /* Validate some simple #expressions.  */
3645   if (inst.reloc.exp.X_op == O_constant)
3646     {
3647       unsigned num = inst.reloc.exp.X_add_number;
3648
3649       /* Reject operations greater than 32.  */
3650       if (num > 32
3651           /* Reject a shift of 0 unless the mode allows it.  */
3652           || (num == 0 && shift->properties->allows_0 == 0)
3653           /* Reject a shift of 32 unless the mode allows it.  */
3654           || (num == 32 && shift->properties->allows_32 == 0)
3655           )
3656         {
3657           /* As a special case we allow a shift of zero for
3658              modes that do not support it to be recoded as an
3659              logical shift left of zero (ie nothing).  We warn
3660              about this though.  */
3661           if (num == 0)
3662             {
3663               as_warn (_("shift of 0 ignored."));
3664               shift = & shift_names[0];
3665               assert (shift->properties->index == SHIFT_LSL);
3666             }
3667           else
3668             {
3669               inst.error = _("invalid immediate shift");
3670               return FAIL;
3671             }
3672         }
3673
3674       /* Shifts of 32 are encoded as 0, for those shifts that
3675          support it.  */
3676       if (num == 32)
3677         num = 0;
3678
3679       inst.instruction |= (num << 7) | shift->properties->bit_field;
3680     }
3681   else
3682     {
3683       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
3684       inst.reloc.pc_rel = 0;
3685       inst.instruction |= shift->properties->bit_field;
3686     }
3687
3688   * str = p;
3689   return SUCCESS;
3690 }
3691
3692 static void
3693 do_sat (char ** str, int bias)
3694 {
3695   int rd, rm;
3696   expressionS expr;
3697
3698   skip_whitespace (*str);
3699
3700   /* Parse <Rd>, field.  */
3701   if ((rd = reg_required_here (str, 12)) == FAIL
3702       || skip_past_comma (str) == FAIL)
3703     {
3704       inst.error = BAD_ARGS;
3705       return;
3706     }
3707   if (rd == REG_PC)
3708     {
3709       inst.error = BAD_PC;
3710       return;
3711     }
3712
3713   /* Parse #<immed>,  field.  */
3714   if (is_immediate_prefix (**str))
3715     (*str)++;
3716   else
3717     {
3718       inst.error = _("immediate expression expected");
3719       return;
3720     }
3721   if (my_get_expression (&expr, str))
3722     {
3723       inst.error = _("bad expression");
3724       return;
3725     }
3726   if (expr.X_op != O_constant)
3727     {
3728       inst.error = _("constant expression expected");
3729       return;
3730     }
3731   if (expr.X_add_number + bias < 0
3732       || expr.X_add_number + bias > 31)
3733     {
3734       inst.error = _("immediate value out of range");
3735       return;
3736     }
3737   inst.instruction |= (expr.X_add_number + bias) << 16;
3738   if (skip_past_comma (str) == FAIL)
3739     {
3740       inst.error = BAD_ARGS;
3741       return;
3742     }
3743
3744   /* Parse <Rm> field.  */
3745   if ((rm = reg_required_here (str, 0)) == FAIL)
3746     {
3747       inst.error = BAD_ARGS;
3748       return;
3749     }
3750   if (rm == REG_PC)
3751     {
3752       inst.error = BAD_PC;
3753       return;
3754     }
3755
3756   if (skip_past_comma (str) == SUCCESS)
3757     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
3758 }
3759
3760 /* ARM V6 ssat (argument parse).  */
3761
3762 static void
3763 do_ssat (char * str)
3764 {
3765   do_sat (&str, /*bias=*/-1);
3766   end_of_line (str);
3767 }
3768
3769 /* ARM V6 usat (argument parse).  */
3770
3771 static void
3772 do_usat (char * str)
3773 {
3774   do_sat (&str, /*bias=*/0);
3775   end_of_line (str);
3776 }
3777
3778 static void
3779 do_sat16 (char ** str, int bias)
3780 {
3781   int rd, rm;
3782   expressionS expr;
3783
3784   skip_whitespace (*str);
3785
3786   /* Parse the <Rd> field.  */
3787   if ((rd = reg_required_here (str, 12)) == FAIL
3788       || skip_past_comma (str) == FAIL)
3789     {
3790       inst.error = BAD_ARGS;
3791       return;
3792     }
3793   if (rd == REG_PC)
3794     {
3795       inst.error = BAD_PC;
3796       return;
3797     }
3798
3799   /* Parse #<immed>, field.  */
3800   if (is_immediate_prefix (**str))
3801     (*str)++;
3802   else
3803     {
3804       inst.error = _("immediate expression expected");
3805       return;
3806     }
3807   if (my_get_expression (&expr, str))
3808     {
3809       inst.error = _("bad expression");
3810       return;
3811     }
3812   if (expr.X_op != O_constant)
3813     {
3814       inst.error = _("constant expression expected");
3815       return;
3816     }
3817   if (expr.X_add_number + bias < 0
3818       || expr.X_add_number + bias > 15)
3819     {
3820       inst.error = _("immediate value out of range");
3821       return;
3822     }
3823   inst.instruction |= (expr.X_add_number + bias) << 16;
3824   if (skip_past_comma (str) == FAIL)
3825     {
3826       inst.error = BAD_ARGS;
3827       return;
3828     }
3829
3830   /* Parse <Rm> field.  */
3831   if ((rm = reg_required_here (str, 0)) == FAIL)
3832     {
3833       inst.error = BAD_ARGS;
3834       return;
3835     }
3836   if (rm == REG_PC)
3837     {
3838       inst.error = BAD_PC;
3839       return;
3840     }
3841 }
3842
3843 /* ARM V6 ssat16 (argument parse).  */
3844
3845 static void
3846 do_ssat16 (char * str)
3847 {
3848   do_sat16 (&str, /*bias=*/-1);
3849   end_of_line (str);
3850 }
3851
3852 static void
3853 do_usat16 (char * str)
3854 {
3855   do_sat16 (&str, /*bias=*/0);
3856   end_of_line (str);
3857 }
3858
3859 static void
3860 do_cps_mode (char ** str)
3861 {
3862   expressionS expr;
3863
3864   skip_whitespace (*str);
3865
3866   if (! is_immediate_prefix (**str))
3867     {
3868       inst.error = _("immediate expression expected");
3869       return;
3870     }
3871
3872   (*str)++; /* Strip off the immediate signifier.  */
3873   if (my_get_expression (&expr, str))
3874     {
3875       inst.error = _("bad expression");
3876       return;
3877     }
3878
3879   if (expr.X_op != O_constant)
3880     {
3881       inst.error = _("constant expression expected");
3882       return;
3883     }
3884
3885   /* The mode is a 5 bit field.  Valid values are 0-31.  */
3886   if (((unsigned) expr.X_add_number) > 31
3887       || (inst.reloc.exp.X_add_number) < 0)
3888     {
3889       inst.error = _("invalid constant");
3890       return;
3891     }
3892
3893   inst.instruction |= expr.X_add_number;
3894 }
3895
3896 /* ARM V6 srs (argument parse).  */
3897
3898 static void
3899 do_srs (char * str)
3900 {
3901   char *exclam;
3902   skip_whitespace (str);
3903   exclam = strchr (str, '!');
3904   if (exclam)
3905     *exclam = '\0';
3906   do_cps_mode (&str);
3907   if (exclam)
3908     *exclam = '!';
3909   if (*str == '!')
3910     {
3911       inst.instruction |= WRITE_BACK;
3912       str++;
3913     }
3914   end_of_line (str);
3915 }
3916
3917 /* ARM V6 SMMUL (argument parse).  */
3918
3919 static void
3920 do_smmul (char * str)
3921 {
3922   int rd, rm, rs;
3923
3924   skip_whitespace (str);
3925   if ((rd = reg_required_here (&str, 16)) == FAIL
3926       || skip_past_comma (&str) == FAIL
3927       || (rm = reg_required_here (&str, 0)) == FAIL
3928       || skip_past_comma (&str) == FAIL
3929       || (rs = reg_required_here (&str, 8)) == FAIL)
3930     {
3931       inst.error = BAD_ARGS;
3932       return;
3933     }
3934
3935   if (   rd == REG_PC
3936       || rm == REG_PC
3937       || rs == REG_PC)
3938     {
3939       inst.error = BAD_PC;
3940       return;
3941     }
3942
3943   end_of_line (str);
3944 }
3945
3946 /* ARM V6 SMLALD (argument parse).  */
3947
3948 static void
3949 do_smlald (char * str)
3950 {
3951   int rdlo, rdhi, rm, rs;
3952
3953   skip_whitespace (str);
3954   if ((rdlo = reg_required_here (&str, 12)) == FAIL
3955       || skip_past_comma (&str) == FAIL
3956       || (rdhi = reg_required_here (&str, 16)) == FAIL
3957       || skip_past_comma (&str) == FAIL
3958       || (rm = reg_required_here (&str, 0)) == FAIL
3959       || skip_past_comma (&str) == FAIL
3960       || (rs = reg_required_here (&str, 8)) == FAIL)
3961     {
3962       inst.error = BAD_ARGS;
3963       return;
3964     }
3965
3966   if (   rdlo == REG_PC
3967       || rdhi == REG_PC
3968       || rm == REG_PC
3969       || rs == REG_PC)
3970     {
3971       inst.error = BAD_PC;
3972       return;
3973     }
3974
3975   end_of_line (str);
3976 }
3977
3978 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
3979    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
3980
3981 static void
3982 do_smlad (char * str)
3983 {
3984   int rd, rm, rs, rn;
3985
3986   skip_whitespace (str);
3987   if ((rd = reg_required_here (&str, 16)) == FAIL
3988       || skip_past_comma (&str) == FAIL
3989       || (rm = reg_required_here (&str, 0)) == FAIL
3990       || skip_past_comma (&str) == FAIL
3991       || (rs = reg_required_here (&str, 8)) == FAIL
3992       || skip_past_comma (&str) == FAIL
3993       || (rn = reg_required_here (&str, 12)) == FAIL)
3994     {
3995       inst.error = BAD_ARGS;
3996       return;
3997     }
3998
3999   if (   rd == REG_PC
4000       || rn == REG_PC
4001       || rs == REG_PC
4002       || rm == REG_PC)
4003     {
4004       inst.error = BAD_PC;
4005       return;
4006     }
4007
4008   end_of_line (str);
4009 }
4010
4011 /* Returns true if the endian-specifier indicates big-endianness.  */
4012
4013 static int
4014 do_endian_specifier (char * str)
4015 {
4016   int big_endian = 0;
4017
4018   skip_whitespace (str);
4019   if (strlen (str) < 2)
4020     inst.error = _("missing endian specifier");
4021   else if (strncasecmp (str, "BE", 2) == 0)
4022     {
4023       str += 2;
4024       big_endian = 1;
4025     }
4026   else if (strncasecmp (str, "LE", 2) == 0)
4027     str += 2;
4028   else
4029     inst.error = _("valid endian specifiers are be or le");
4030
4031   end_of_line (str);
4032
4033   return big_endian;
4034 }
4035
4036 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
4037    preserving the other bits.
4038
4039    setend <endian_specifier>, where <endian_specifier> is either
4040    BE or LE.  */
4041
4042 static void
4043 do_setend (char * str)
4044 {
4045   if (do_endian_specifier (str))
4046     inst.instruction |= 0x200;
4047 }
4048
4049 /* ARM V6 SXTH.
4050
4051    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
4052    Condition defaults to COND_ALWAYS.
4053    Error if any register uses R15.  */
4054
4055 static void
4056 do_sxth (char * str)
4057 {
4058   int rd, rm;
4059   expressionS expr;
4060   int rotation_clear_mask = 0xfffff3ff;
4061   int rotation_eight_mask = 0x00000400;
4062   int rotation_sixteen_mask = 0x00000800;
4063   int rotation_twenty_four_mask = 0x00000c00;
4064
4065   skip_whitespace (str);
4066   if ((rd = reg_required_here (&str, 12)) == FAIL
4067       || skip_past_comma (&str) == FAIL
4068       || (rm = reg_required_here (&str, 0)) == FAIL)
4069     {
4070       inst.error = BAD_ARGS;
4071       return;
4072     }
4073
4074   else if (rd == REG_PC || rm == REG_PC)
4075     {
4076       inst.error = BAD_PC;
4077       return;
4078     }
4079
4080   /* Zero out the rotation field.  */
4081   inst.instruction &= rotation_clear_mask;
4082
4083   /* Check for lack of optional rotation field.  */
4084   if (skip_past_comma (&str) == FAIL)
4085     {
4086       end_of_line (str);
4087       return;
4088     }
4089
4090   /* Move past 'ROR'.  */
4091   skip_whitespace (str);
4092   if (strncasecmp (str, "ROR", 3) == 0)
4093     str += 3;
4094   else
4095     {
4096       inst.error = _("missing rotation field after comma");
4097       return;
4098     }
4099
4100   /* Get the immediate constant.  */
4101   skip_whitespace (str);
4102   if (is_immediate_prefix (* str))
4103     str++;
4104   else
4105     {
4106       inst.error = _("immediate expression expected");
4107       return;
4108     }
4109
4110   if (my_get_expression (&expr, &str))
4111     {
4112       inst.error = _("bad expression");
4113       return;
4114     }
4115
4116   if (expr.X_op != O_constant)
4117     {
4118       inst.error = _("constant expression expected");
4119       return;
4120     }
4121
4122   switch (expr.X_add_number)
4123     {
4124     case 0:
4125       /* Rotation field has already been zeroed.  */
4126       break;
4127     case 8:
4128       inst.instruction |= rotation_eight_mask;
4129       break;
4130
4131     case 16:
4132       inst.instruction |= rotation_sixteen_mask;
4133       break;
4134
4135     case 24:
4136       inst.instruction |= rotation_twenty_four_mask;
4137       break;
4138
4139     default:
4140       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4141       break;
4142     }
4143
4144   end_of_line (str);
4145 }
4146
4147 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
4148    extends it to 32-bits, and adds the result to a value in another
4149    register.  You can specify a rotation by 0, 8, 16, or 24 bits
4150    before extracting the 16-bit value.
4151    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
4152    Condition defaults to COND_ALWAYS.
4153    Error if any register uses R15.  */
4154
4155 static void
4156 do_sxtah (char * str)
4157 {
4158   int rd, rn, rm;
4159   expressionS expr;
4160   int rotation_clear_mask = 0xfffff3ff;
4161   int rotation_eight_mask = 0x00000400;
4162   int rotation_sixteen_mask = 0x00000800;
4163   int rotation_twenty_four_mask = 0x00000c00;
4164
4165   skip_whitespace (str);
4166   if ((rd = reg_required_here (&str, 12)) == FAIL
4167       || skip_past_comma (&str) == FAIL
4168       || (rn = reg_required_here (&str, 16)) == FAIL
4169       || skip_past_comma (&str) == FAIL
4170       || (rm = reg_required_here (&str, 0)) == FAIL)
4171     {
4172       inst.error = BAD_ARGS;
4173       return;
4174     }
4175
4176   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4177     {
4178       inst.error = BAD_PC;
4179       return;
4180     }
4181
4182   /* Zero out the rotation field.  */
4183   inst.instruction &= rotation_clear_mask;
4184
4185   /* Check for lack of optional rotation field.  */
4186   if (skip_past_comma (&str) == FAIL)
4187     {
4188       end_of_line (str);
4189       return;
4190     }
4191
4192   /* Move past 'ROR'.  */
4193   skip_whitespace (str);
4194   if (strncasecmp (str, "ROR", 3) == 0)
4195     str += 3;
4196   else
4197     {
4198       inst.error = _("missing rotation field after comma");
4199       return;
4200     }
4201
4202   /* Get the immediate constant.  */
4203   skip_whitespace (str);
4204   if (is_immediate_prefix (* str))
4205     str++;
4206   else
4207     {
4208       inst.error = _("immediate expression expected");
4209       return;
4210     }
4211
4212   if (my_get_expression (&expr, &str))
4213     {
4214       inst.error = _("bad expression");
4215       return;
4216     }
4217
4218   if (expr.X_op != O_constant)
4219     {
4220       inst.error = _("constant expression expected");
4221       return;
4222     }
4223
4224   switch (expr.X_add_number)
4225     {
4226     case 0:
4227       /* Rotation field has already been zeroed.  */
4228       break;
4229
4230     case 8:
4231       inst.instruction |= rotation_eight_mask;
4232       break;
4233
4234     case 16:
4235       inst.instruction |= rotation_sixteen_mask;
4236       break;
4237
4238     case 24:
4239       inst.instruction |= rotation_twenty_four_mask;
4240       break;
4241
4242     default:
4243       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4244       break;
4245     }
4246
4247   end_of_line (str);
4248 }
4249
4250
4251 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
4252    word at the specified address and the following word
4253    respectively.
4254    Unconditionally executed.
4255    Error if Rn is R15.  */
4256
4257 static void
4258 do_rfe (char * str)
4259 {
4260   int rn;
4261
4262   skip_whitespace (str);
4263
4264   if ((rn = reg_required_here (&str, 16)) == FAIL)
4265     return;
4266
4267   if (rn == REG_PC)
4268     {
4269       inst.error = BAD_PC;
4270       return;
4271     }
4272
4273   skip_whitespace (str);
4274
4275   if (*str == '!')
4276     {
4277       inst.instruction |= WRITE_BACK;
4278       str++;
4279     }
4280   end_of_line (str);
4281 }
4282
4283 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
4284    register (argument parse).
4285    REV{<cond>} Rd, Rm.
4286    Condition defaults to COND_ALWAYS.
4287    Error if Rd or Rm are R15.  */
4288
4289 static void
4290 do_rev (char * str)
4291 {
4292   int rd, rm;
4293
4294   skip_whitespace (str);
4295
4296   if ((rd = reg_required_here (&str, 12)) == FAIL
4297       || skip_past_comma (&str) == FAIL
4298       || (rm = reg_required_here (&str, 0)) == FAIL)
4299     inst.error = BAD_ARGS;
4300
4301   else if (rd == REG_PC || rm == REG_PC)
4302     inst.error = BAD_PC;
4303
4304   else
4305     end_of_line (str);
4306 }
4307
4308 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
4309    QADD16{<cond>} <Rd>, <Rn>, <Rm>
4310    Condition defaults to COND_ALWAYS.
4311    Error if Rd, Rn or Rm are R15.  */
4312
4313 static void
4314 do_qadd16 (char * str)
4315 {
4316   int rd, rm, rn;
4317
4318   skip_whitespace (str);
4319
4320   if ((rd = reg_required_here (&str, 12)) == FAIL
4321       || skip_past_comma (&str) == FAIL
4322       || (rn = reg_required_here (&str, 16)) == FAIL
4323       || skip_past_comma (&str) == FAIL
4324       || (rm = reg_required_here (&str, 0)) == FAIL)
4325     inst.error = BAD_ARGS;
4326
4327   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4328     inst.error = BAD_PC;
4329
4330   else
4331     end_of_line (str);
4332 }
4333
4334 static void
4335 do_pkh_core (char * str, int shift)
4336 {
4337   int rd, rn, rm;
4338
4339   skip_whitespace (str);
4340   if (((rd = reg_required_here (&str, 12)) == FAIL)
4341       || (skip_past_comma (&str) == FAIL)
4342       || ((rn = reg_required_here (&str, 16)) == FAIL)
4343       || (skip_past_comma (&str) == FAIL)
4344       || ((rm = reg_required_here (&str, 0)) == FAIL))
4345     {
4346       inst.error = BAD_ARGS;
4347       return;
4348     }
4349
4350   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4351     {
4352       inst.error = BAD_PC;
4353       return;
4354     }
4355
4356   /* Check for optional shift immediate constant.  */
4357   if (skip_past_comma (&str) == FAIL)
4358     {
4359       if (shift == SHIFT_ASR_IMMEDIATE)
4360         {
4361           /* If the shift specifier is ommited, turn the instruction
4362              into pkhbt rd, rm, rn.  First, switch the instruction
4363              code, and clear the rn and rm fields.  */
4364           inst.instruction &= 0xfff0f010;
4365           /* Now, re-encode the registers.  */
4366           inst.instruction |= (rm << 16) | rn;
4367         }
4368       return;
4369     }
4370
4371   decode_shift (&str, shift);
4372 }
4373
4374 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
4375    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
4376    Condition defaults to COND_ALWAYS.
4377    Error if Rd, Rn or Rm are R15.  */
4378
4379 static void
4380 do_pkhbt (char * str)
4381 {
4382   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
4383 }
4384
4385 /* ARM V6 PKHTB (Argument Parse).  */
4386
4387 static void
4388 do_pkhtb (char * str)
4389 {
4390   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
4391 }
4392
4393 /* ARM V6 Load Register Exclusive instruction (argument parse).
4394    LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
4395    Condition defaults to COND_ALWAYS.
4396    Error if Rd or Rn are R15.
4397    See ARMARMv6 A4.1.27: LDREX.  */
4398
4399 static void
4400 do_ldrex (char * str)
4401 {
4402   int rd, rn;
4403
4404   skip_whitespace (str);
4405
4406   /* Parse Rd.  */
4407   if (((rd = reg_required_here (&str, 12)) == FAIL)
4408       || (skip_past_comma (&str) == FAIL))
4409     {
4410       inst.error = BAD_ARGS;
4411       return;
4412     }
4413   else if (rd == REG_PC)
4414     {
4415       inst.error = BAD_PC;
4416       return;
4417     }
4418   skip_whitespace (str);
4419
4420   /* Skip past '['.  */
4421   if ((strlen (str) >= 1)
4422       &&strncmp (str, "[", 1) == 0)
4423     str += 1;
4424   skip_whitespace (str);
4425
4426   /* Parse Rn.  */
4427   if ((rn = reg_required_here (&str, 16)) == FAIL)
4428     {
4429       inst.error = BAD_ARGS;
4430       return;
4431     }
4432   else if (rn == REG_PC)
4433     {
4434       inst.error = BAD_PC;
4435       return;
4436     }
4437   skip_whitespace (str);
4438
4439   /* Skip past ']'.  */
4440   if ((strlen (str) >= 1)
4441       && strncmp (str, "]", 1) == 0)
4442     str += 1;
4443
4444   end_of_line (str);
4445 }
4446
4447 /* ARM V6 change processor state instruction (argument parse)
4448       CPS, CPSIE, CSPID .  */
4449
4450 static void
4451 do_cps (char * str)
4452 {
4453   do_cps_mode (&str);
4454   end_of_line (str);
4455 }
4456
4457 static void
4458 do_cps_flags (char ** str, int thumb_p)
4459 {
4460   struct cps_flag
4461   {
4462     char character;
4463     unsigned long arm_value;
4464     unsigned long thumb_value;
4465   };
4466   static struct cps_flag flag_table[] =
4467   {
4468     {'a', 0x100, 0x4 },
4469     {'i', 0x080, 0x2 },
4470     {'f', 0x040, 0x1 }
4471   };
4472
4473   int saw_a_flag = 0;
4474
4475   skip_whitespace (*str);
4476
4477   /* Get the a, f and i flags.  */
4478   while (**str && **str != ',')
4479     {
4480       struct cps_flag *p;
4481       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
4482
4483       for (p = flag_table; p < q; ++p)
4484         if (strncasecmp (*str, &p->character, 1) == 0)
4485           {
4486             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
4487             saw_a_flag = 1;
4488             break;
4489           }
4490       if (p == q)
4491         {
4492           inst.error = _("unrecognized flag");
4493           return;
4494         }
4495       (*str)++;
4496     }
4497
4498   if (!saw_a_flag)
4499     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
4500 }
4501
4502 static void
4503 do_cpsi (char * str)
4504 {
4505   do_cps_flags (&str, /*thumb_p=*/0);
4506
4507   if (skip_past_comma (&str) == SUCCESS)
4508     {
4509       skip_whitespace (str);
4510       do_cps_mode (&str);
4511     }
4512   end_of_line (str);
4513 }
4514
4515 /* THUMB V5 breakpoint instruction (argument parse)
4516         BKPT <immed_8>.  */
4517
4518 static void
4519 do_t_bkpt (char * str)
4520 {
4521   expressionS expr;
4522   unsigned long number;
4523
4524   skip_whitespace (str);
4525
4526   /* Allow optional leading '#'.  */
4527   if (is_immediate_prefix (*str))
4528     str ++;
4529
4530   memset (& expr, '\0', sizeof (expr));
4531   if (my_get_expression (& expr, & str)
4532       || (expr.X_op != O_constant
4533           /* As a convenience we allow 'bkpt' without an operand.  */
4534           && expr.X_op != O_absent))
4535     {
4536       inst.error = _("bad expression");
4537       return;
4538     }
4539
4540   number = expr.X_add_number;
4541
4542   /* Check it fits an 8 bit unsigned.  */
4543   if (number != (number & 0xff))
4544     {
4545       inst.error = _("immediate value out of range");
4546       return;
4547     }
4548
4549   inst.instruction |= number;
4550
4551   end_of_line (str);
4552 }
4553
4554 static bfd_reloc_code_real_type
4555 arm_parse_reloc (void)
4556 {
4557   char         id [16];
4558   char *       ip;
4559   unsigned int i;
4560   static struct
4561   {
4562     char * str;
4563     int    len;
4564     bfd_reloc_code_real_type reloc;
4565   }
4566   reloc_map[] =
4567   {
4568 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
4569     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
4570     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
4571     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
4572        branch instructions generated by GCC for PLT relocs.  */
4573     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
4574     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
4575     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
4576     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
4577     { NULL, 0,         BFD_RELOC_UNUSED }
4578 #undef MAP
4579   };
4580
4581   for (i = 0, ip = input_line_pointer;
4582        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
4583        i++, ip++)
4584     id[i] = TOLOWER (*ip);
4585
4586   for (i = 0; reloc_map[i].str; i++)
4587     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
4588       break;
4589
4590   input_line_pointer += reloc_map[i].len;
4591
4592   return reloc_map[i].reloc;
4593 }
4594
4595 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4596    Expects inst.instruction is set for BLX(1).
4597    Note: this is cloned from do_branch, and the reloc changed to be a
4598         new one that can cope with setting one extra bit (the H bit).  */
4599
4600 static void
4601 do_branch25 (char * str)
4602 {
4603   if (my_get_expression (& inst.reloc.exp, & str))
4604     return;
4605
4606 #ifdef OBJ_ELF
4607   {
4608     char * save_in;
4609
4610     /* ScottB: February 5, 1998 */
4611     /* Check to see of PLT32 reloc required for the instruction.  */
4612
4613     /* arm_parse_reloc() works on input_line_pointer.
4614        We actually want to parse the operands to the branch instruction
4615        passed in 'str'.  Save the input pointer and restore it later.  */
4616     save_in = input_line_pointer;
4617     input_line_pointer = str;
4618
4619     if (inst.reloc.exp.X_op == O_symbol
4620         && *str == '('
4621         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4622       {
4623         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
4624         inst.reloc.pc_rel = 0;
4625         /* Modify str to point to after parsed operands, otherwise
4626            end_of_line() will complain about the (PLT) left in str.  */
4627         str = input_line_pointer;
4628       }
4629     else
4630       {
4631         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4632         inst.reloc.pc_rel = 1;
4633       }
4634
4635     input_line_pointer = save_in;
4636   }
4637 #else
4638   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4639   inst.reloc.pc_rel = 1;
4640 #endif /* OBJ_ELF */
4641
4642   end_of_line (str);
4643 }
4644
4645 /* ARM V5 branch-link-exchange instruction (argument parse)
4646      BLX <target_addr>          ie BLX(1)
4647      BLX{<condition>} <Rm>      ie BLX(2)
4648    Unfortunately, there are two different opcodes for this mnemonic.
4649    So, the insns[].value is not used, and the code here zaps values
4650         into inst.instruction.
4651    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4652
4653 static void
4654 do_blx (char * str)
4655 {
4656   char * mystr = str;
4657   int rm;
4658
4659   skip_whitespace (mystr);
4660   rm = reg_required_here (& mystr, 0);
4661
4662   /* The above may set inst.error.  Ignore his opinion.  */
4663   inst.error = 0;
4664
4665   if (rm != FAIL)
4666     {
4667       /* Arg is a register.
4668          Use the condition code our caller put in inst.instruction.
4669          Pass ourselves off as a BX with a funny opcode.  */
4670       inst.instruction |= 0x012fff30;
4671       do_bx (str);
4672     }
4673   else
4674     {
4675       /* This must be is BLX <target address>, no condition allowed.  */
4676       if (inst.instruction != COND_ALWAYS)
4677         {
4678           inst.error = BAD_COND;
4679           return;
4680         }
4681
4682       inst.instruction = 0xfafffffe;
4683
4684       /* Process like a B/BL, but with a different reloc.
4685          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4686       do_branch25 (str);
4687     }
4688 }
4689
4690 /* ARM V5 Thumb BLX (argument parse)
4691         BLX <target_addr>       which is BLX(1)
4692         BLX <Rm>                which is BLX(2)
4693    Unfortunately, there are two different opcodes for this mnemonic.
4694    So, the tinsns[].value is not used, and the code here zaps values
4695         into inst.instruction.  */
4696
4697 static void
4698 do_t_blx (char * str)
4699 {
4700   char * mystr = str;
4701   int rm;
4702
4703   skip_whitespace (mystr);
4704   inst.instruction = 0x4780;
4705
4706   /* Note that this call is to the ARM register recognizer.  BLX(2)
4707      uses the ARM register space, not the Thumb one, so a call to
4708      thumb_reg() would be wrong.  */
4709   rm = reg_required_here (& mystr, 3);
4710   inst.error = 0;
4711
4712   if (rm != FAIL)
4713     {
4714       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
4715       inst.size = 2;
4716     }
4717   else
4718     {
4719       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
4720       inst.instruction = 0xf7ffeffe;
4721       inst.size = 4;
4722
4723       if (my_get_expression (& inst.reloc.exp, & mystr))
4724         return;
4725
4726       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
4727       inst.reloc.pc_rel = 1;
4728     }
4729
4730   end_of_line (mystr);
4731 }
4732
4733 /* ARM V5 breakpoint instruction (argument parse)
4734      BKPT <16 bit unsigned immediate>
4735      Instruction is not conditional.
4736         The bit pattern given in insns[] has the COND_ALWAYS condition,
4737         and it is an error if the caller tried to override that.  */
4738
4739 static void
4740 do_bkpt (char * str)
4741 {
4742   expressionS expr;
4743   unsigned long number;
4744
4745   skip_whitespace (str);
4746
4747   /* Allow optional leading '#'.  */
4748   if (is_immediate_prefix (* str))
4749     str++;
4750
4751   memset (& expr, '\0', sizeof (expr));
4752
4753   if (my_get_expression (& expr, & str)
4754       || (expr.X_op != O_constant
4755           /* As a convenience we allow 'bkpt' without an operand.  */
4756           && expr.X_op != O_absent))
4757     {
4758       inst.error = _("bad expression");
4759       return;
4760     }
4761
4762   number = expr.X_add_number;
4763
4764   /* Check it fits a 16 bit unsigned.  */
4765   if (number != (number & 0xffff))
4766     {
4767       inst.error = _("immediate value out of range");
4768       return;
4769     }
4770
4771   /* Top 12 of 16 bits to bits 19:8.  */
4772   inst.instruction |= (number & 0xfff0) << 4;
4773
4774   /* Bottom 4 of 16 bits to bits 3:0.  */
4775   inst.instruction |= number & 0xf;
4776
4777   end_of_line (str);
4778 }
4779
4780 /* THUMB CPS instruction (argument parse).  */
4781
4782 static void
4783 do_t_cps (char * str)
4784 {
4785   do_cps_flags (&str, /*thumb_p=*/1);
4786   end_of_line (str);
4787 }
4788
4789 /* Parse and validate that a register is of the right form, this saves
4790    repeated checking of this information in many similar cases.
4791    Unlike the 32-bit case we do not insert the register into the opcode
4792    here, since the position is often unknown until the full instruction
4793    has been parsed.  */
4794
4795 static int
4796 thumb_reg (char ** strp, int hi_lo)
4797 {
4798   int reg;
4799
4800   if ((reg = reg_required_here (strp, -1)) == FAIL)
4801     return FAIL;
4802
4803   switch (hi_lo)
4804     {
4805     case THUMB_REG_LO:
4806       if (reg > 7)
4807         {
4808           inst.error = _("lo register required");
4809           return FAIL;
4810         }
4811       break;
4812
4813     case THUMB_REG_HI:
4814       if (reg < 8)
4815         {
4816           inst.error = _("hi register required");
4817           return FAIL;
4818         }
4819       break;
4820
4821     default:
4822       break;
4823     }
4824
4825   return reg;
4826 }
4827
4828 static void
4829 thumb_mov_compare (char * str, int move)
4830 {
4831   int Rd, Rs = FAIL;
4832
4833   skip_whitespace (str);
4834
4835   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4836       || skip_past_comma (&str) == FAIL)
4837     {
4838       if (! inst.error)
4839         inst.error = BAD_ARGS;
4840       return;
4841     }
4842
4843   if (move != THUMB_CPY && is_immediate_prefix (*str))
4844     {
4845       str++;
4846       if (my_get_expression (&inst.reloc.exp, &str))
4847         return;
4848     }
4849   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4850     return;
4851
4852   if (Rs != FAIL)
4853     {
4854       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
4855         {
4856           if (move == THUMB_MOVE)
4857             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4858                since a MOV instruction produces unpredictable results.  */
4859             inst.instruction = T_OPCODE_ADD_I3;
4860           else
4861             inst.instruction = T_OPCODE_CMP_LR;
4862           inst.instruction |= Rd | (Rs << 3);
4863         }
4864       else
4865         {
4866           if (move == THUMB_MOVE)
4867             inst.instruction = T_OPCODE_MOV_HR;
4868           else if (move != THUMB_CPY)
4869             inst.instruction = T_OPCODE_CMP_HR;
4870
4871           if (Rd > 7)
4872             inst.instruction |= THUMB_H1;
4873
4874           if (Rs > 7)
4875             inst.instruction |= THUMB_H2;
4876
4877           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4878         }
4879     }
4880   else
4881     {
4882       if (Rd > 7)
4883         {
4884           inst.error = _("only lo regs allowed with immediate");
4885           return;
4886         }
4887
4888       if (move == THUMB_MOVE)
4889         inst.instruction = T_OPCODE_MOV_I8;
4890       else
4891         inst.instruction = T_OPCODE_CMP_I8;
4892
4893       inst.instruction |= Rd << 8;
4894
4895       if (inst.reloc.exp.X_op != O_constant)
4896         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4897       else
4898         {
4899           unsigned value = inst.reloc.exp.X_add_number;
4900
4901           if (value > 255)
4902             {
4903               inst.error = _("invalid immediate");
4904               return;
4905             }
4906
4907           inst.instruction |= value;
4908         }
4909     }
4910
4911   end_of_line (str);
4912 }
4913
4914 /* THUMB CPY instruction (argument parse).  */
4915
4916 static void
4917 do_t_cpy (char * str)
4918 {
4919   thumb_mov_compare (str, THUMB_CPY);
4920 }
4921
4922 /* THUMB SETEND instruction (argument parse).  */
4923
4924 static void
4925 do_t_setend (char * str)
4926 {
4927   if (do_endian_specifier (str))
4928     inst.instruction |= 0x8;
4929 }
4930
4931 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
4932
4933 static unsigned long
4934 check_iwmmxt_insn (char * str,
4935                    enum iwmmxt_insn_type insn_type,
4936                    int immediate_size)
4937 {
4938   int reg = 0;
4939   const char *  inst_error;
4940   expressionS expr;
4941   unsigned long number;
4942
4943   inst_error = inst.error;
4944   if (!inst.error)
4945     inst.error = BAD_ARGS;
4946   skip_whitespace (str);
4947
4948   switch (insn_type)
4949     {
4950     case check_rd:
4951       if ((reg = reg_required_here (&str, 12)) == FAIL)
4952         return FAIL;
4953       break;
4954
4955     case check_wr:
4956        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4957          return FAIL;
4958        break;
4959
4960     case check_wrwr:
4961       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4962            || skip_past_comma (&str) == FAIL
4963            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4964         return FAIL;
4965       break;
4966
4967     case check_wrwrwr:
4968       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4969            || skip_past_comma (&str) == FAIL
4970            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4971            || skip_past_comma (&str) == FAIL
4972            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4973         return FAIL;
4974       break;
4975
4976     case check_wrwrwcg:
4977       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4978            || skip_past_comma (&str) == FAIL
4979            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4980            || skip_past_comma (&str) == FAIL
4981            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4982         return FAIL;
4983       break;
4984
4985     case check_tbcst:
4986       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4987            || skip_past_comma (&str) == FAIL
4988            || reg_required_here (&str, 12) == FAIL))
4989         return FAIL;
4990       break;
4991
4992     case check_tmovmsk:
4993       if ((reg_required_here (&str, 12) == FAIL
4994            || skip_past_comma (&str) == FAIL
4995            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4996         return FAIL;
4997       break;
4998
4999     case check_tmia:
5000       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5001            || skip_past_comma (&str) == FAIL
5002            || reg_required_here (&str, 0) == FAIL
5003            || skip_past_comma (&str) == FAIL
5004            || reg_required_here (&str, 12) == FAIL))
5005         return FAIL;
5006       break;
5007
5008     case check_tmcrr:
5009       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5010            || skip_past_comma (&str) == FAIL
5011            || reg_required_here (&str, 12) == FAIL
5012            || skip_past_comma (&str) == FAIL
5013            || reg_required_here (&str, 16) == FAIL))
5014         return FAIL;
5015       break;
5016
5017     case check_tmrrc:
5018       if ((reg_required_here (&str, 12) == FAIL
5019            || skip_past_comma (&str) == FAIL
5020            || reg_required_here (&str, 16) == FAIL
5021            || skip_past_comma (&str) == FAIL
5022            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5023         return FAIL;
5024       break;
5025
5026     case check_tmcr:
5027       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5028            || skip_past_comma (&str) == FAIL
5029            || reg_required_here (&str, 12) == FAIL))
5030         return FAIL;
5031       break;
5032
5033     case check_tmrc:
5034       if ((reg_required_here (&str, 12) == FAIL
5035            || skip_past_comma (&str) == FAIL
5036            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5037         return FAIL;
5038       break;
5039
5040     case check_tinsr:
5041       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5042            || skip_past_comma (&str) == FAIL
5043            || reg_required_here (&str, 12) == FAIL
5044            || skip_past_comma (&str) == FAIL))
5045         return FAIL;
5046       break;
5047
5048     case check_textrc:
5049       if ((reg_required_here (&str, 12) == FAIL
5050            || skip_past_comma (&str) == FAIL))
5051         return FAIL;
5052       break;
5053
5054     case check_waligni:
5055       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5056            || skip_past_comma (&str) == FAIL
5057            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5058            || skip_past_comma (&str) == FAIL
5059            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5060            || skip_past_comma (&str) == FAIL))
5061         return FAIL;
5062       break;
5063
5064     case check_textrm:
5065       if ((reg_required_here (&str, 12) == FAIL
5066            || skip_past_comma (&str) == FAIL
5067            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5068            || skip_past_comma (&str) == FAIL))
5069         return FAIL;
5070       break;
5071
5072     case check_wshufh:
5073       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5074            || skip_past_comma (&str) == FAIL
5075            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5076            || skip_past_comma (&str) == FAIL))
5077         return FAIL;
5078       break;
5079     }
5080
5081   if (immediate_size == 0)
5082     {
5083       end_of_line (str);
5084       inst.error = inst_error;
5085       return reg;
5086     }
5087   else
5088     {
5089       skip_whitespace (str);
5090
5091       /* Allow optional leading '#'.  */
5092       if (is_immediate_prefix (* str))
5093         str++;
5094
5095       memset (& expr, '\0', sizeof (expr));
5096
5097       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5098         {
5099           inst.error = _("bad or missing expression");
5100           return FAIL;
5101         }
5102
5103       number = expr.X_add_number;
5104
5105       if (number != (number & immediate_size))
5106         {
5107           inst.error = _("immediate value out of range");
5108           return FAIL;
5109         }
5110       end_of_line (str);
5111       inst.error = inst_error;
5112       return number;
5113     }
5114 }
5115
5116 static void
5117 do_iwmmxt_byte_addr (char * str)
5118 {
5119   int op = (inst.instruction & 0x300) >> 8;
5120   int reg;
5121
5122   inst.instruction &= ~0x300;
5123   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5124
5125   skip_whitespace (str);
5126
5127   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5128       || skip_past_comma (& str) == FAIL
5129       || cp_byte_address_required_here (&str) == FAIL)
5130     {
5131       if (! inst.error)
5132         inst.error = BAD_ARGS;
5133     }
5134   else
5135     end_of_line (str);
5136
5137   if (wc_register (reg))
5138     {
5139       as_bad (_("non-word size not supported with control register"));
5140       inst.instruction |=  0xf0000100;
5141       inst.instruction &= ~0x00400000;
5142     }
5143 }
5144
5145 static void
5146 do_iwmmxt_tandc (char * str)
5147 {
5148   int reg;
5149
5150   reg = check_iwmmxt_insn (str, check_rd, 0);
5151
5152   if (reg != REG_PC && !inst.error)
5153     inst.error = _("only r15 allowed here");
5154 }
5155
5156 static void
5157 do_iwmmxt_tbcst (char * str)
5158 {
5159   check_iwmmxt_insn (str, check_tbcst, 0);
5160 }
5161
5162 static void
5163 do_iwmmxt_textrc (char * str)
5164 {
5165   unsigned long number;
5166
5167   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5168     return;
5169
5170   inst.instruction |= number & 0x7;
5171 }
5172
5173 static void
5174 do_iwmmxt_textrm (char * str)
5175 {
5176   unsigned long number;
5177
5178   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5179     return;
5180
5181   inst.instruction |= number & 0x7;
5182 }
5183
5184 static void
5185 do_iwmmxt_tinsr (char * str)
5186 {
5187   unsigned long number;
5188
5189   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5190     return;
5191
5192   inst.instruction |= number & 0x7;
5193 }
5194
5195 static void
5196 do_iwmmxt_tmcr (char * str)
5197 {
5198   check_iwmmxt_insn (str, check_tmcr, 0);
5199 }
5200
5201 static void
5202 do_iwmmxt_tmcrr (char * str)
5203 {
5204   check_iwmmxt_insn (str, check_tmcrr, 0);
5205 }
5206
5207 static void
5208 do_iwmmxt_tmia (char * str)
5209 {
5210   check_iwmmxt_insn (str, check_tmia, 0);
5211 }
5212
5213 static void
5214 do_iwmmxt_tmovmsk (char * str)
5215 {
5216   check_iwmmxt_insn (str, check_tmovmsk, 0);
5217 }
5218
5219 static void
5220 do_iwmmxt_tmrc (char * str)
5221 {
5222   check_iwmmxt_insn (str, check_tmrc, 0);
5223 }
5224
5225 static void
5226 do_iwmmxt_tmrrc (char * str)
5227 {
5228   check_iwmmxt_insn (str, check_tmrrc, 0);
5229 }
5230
5231 static void
5232 do_iwmmxt_torc (char * str)
5233 {
5234   check_iwmmxt_insn (str, check_rd, 0);
5235 }
5236
5237 static void
5238 do_iwmmxt_waligni (char * str)
5239 {
5240   unsigned long number;
5241
5242   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5243     return;
5244
5245   inst.instruction |= ((number & 0x7) << 20);
5246 }
5247
5248 static void
5249 do_iwmmxt_wmov (char * str)
5250 {
5251   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5252     return;
5253
5254   inst.instruction |= ((inst.instruction >> 16) & 0xf);
5255 }
5256
5257 static void
5258 do_iwmmxt_word_addr (char * str)
5259 {
5260   int op = (inst.instruction & 0x300) >> 8;
5261   int reg;
5262
5263   inst.instruction &= ~0x300;
5264   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5265
5266   skip_whitespace (str);
5267
5268   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5269       || skip_past_comma (& str) == FAIL
5270       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5271     {
5272       if (! inst.error)
5273         inst.error = BAD_ARGS;
5274     }
5275   else
5276     end_of_line (str);
5277
5278   if (wc_register (reg))
5279     {
5280       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5281         as_bad (_("conditional execution not supported with control register"));
5282       if (op != 2)
5283         as_bad (_("non-word size not supported with control register"));
5284       inst.instruction |=  0xf0000100;
5285       inst.instruction &= ~0x00400000;
5286     }
5287 }
5288
5289 static void
5290 do_iwmmxt_wrwr (char * str)
5291 {
5292   check_iwmmxt_insn (str, check_wrwr, 0);
5293 }
5294
5295 static void
5296 do_iwmmxt_wrwrwcg (char * str)
5297 {
5298   check_iwmmxt_insn (str, check_wrwrwcg, 0);
5299 }
5300
5301 static void
5302 do_iwmmxt_wrwrwr (char * str)
5303 {
5304   check_iwmmxt_insn (str, check_wrwrwr, 0);
5305 }
5306
5307 static void
5308 do_iwmmxt_wshufh (char * str)
5309 {
5310   unsigned long number;
5311
5312   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5313     return;
5314
5315   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5316 }
5317
5318 static void
5319 do_iwmmxt_wzero (char * str)
5320 {
5321   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5322     return;
5323
5324   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5325 }
5326
5327 /* Xscale multiply-accumulate (argument parse)
5328      MIAcc   acc0,Rm,Rs
5329      MIAPHcc acc0,Rm,Rs
5330      MIAxycc acc0,Rm,Rs.  */
5331
5332 static void
5333 do_xsc_mia (char * str)
5334 {
5335   int rs;
5336   int rm;
5337
5338   if (accum0_required_here (& str) == FAIL)
5339     inst.error = ERR_NO_ACCUM;
5340
5341   else if (skip_past_comma (& str) == FAIL
5342            || (rm = reg_required_here (& str, 0)) == FAIL)
5343     inst.error = BAD_ARGS;
5344
5345   else if (skip_past_comma (& str) == FAIL
5346            || (rs = reg_required_here (& str, 12)) == FAIL)
5347     inst.error = BAD_ARGS;
5348
5349   /* inst.instruction has now been zapped with both rm and rs.  */
5350   else if (rm == REG_PC || rs == REG_PC)
5351     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
5352
5353   else
5354     end_of_line (str);
5355 }
5356
5357 /* Xscale move-accumulator-register (argument parse)
5358
5359      MARcc   acc0,RdLo,RdHi.  */
5360
5361 static void
5362 do_xsc_mar (char * str)
5363 {
5364   int rdlo, rdhi;
5365
5366   if (accum0_required_here (& str) == FAIL)
5367     inst.error = ERR_NO_ACCUM;
5368
5369   else if (skip_past_comma (& str) == FAIL
5370            || (rdlo = reg_required_here (& str, 12)) == FAIL)
5371     inst.error = BAD_ARGS;
5372
5373   else if (skip_past_comma (& str) == FAIL
5374            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5375     inst.error = BAD_ARGS;
5376
5377   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5378   else if (rdlo == REG_PC || rdhi == REG_PC)
5379     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5380
5381   else
5382     end_of_line (str);
5383 }
5384
5385 /* Xscale move-register-accumulator (argument parse)
5386
5387      MRAcc   RdLo,RdHi,acc0.  */
5388
5389 static void
5390 do_xsc_mra (char * str)
5391 {
5392   int rdlo;
5393   int rdhi;
5394
5395   skip_whitespace (str);
5396
5397   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5398     inst.error = BAD_ARGS;
5399
5400   else if (skip_past_comma (& str) == FAIL
5401            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5402     inst.error = BAD_ARGS;
5403
5404   else if  (skip_past_comma (& str) == FAIL
5405             || accum0_required_here (& str) == FAIL)
5406     inst.error = ERR_NO_ACCUM;
5407
5408   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5409   else if (rdlo == rdhi)
5410     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
5411
5412   else if (rdlo == REG_PC || rdhi == REG_PC)
5413     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5414   else
5415     end_of_line (str);
5416 }
5417
5418 static int
5419 ldst_extend (char ** str)
5420 {
5421   int add = INDEX_UP;
5422
5423   switch (**str)
5424     {
5425     case '#':
5426     case '$':
5427       (*str)++;
5428       if (my_get_expression (& inst.reloc.exp, str))
5429         return FAIL;
5430
5431       if (inst.reloc.exp.X_op == O_constant)
5432         {
5433           int value = inst.reloc.exp.X_add_number;
5434
5435           if (value < -4095 || value > 4095)
5436             {
5437               inst.error = _("address offset too large");
5438               return FAIL;
5439             }
5440
5441           if (value < 0)
5442             {
5443               value = -value;
5444               add = 0;
5445             }
5446
5447           inst.instruction |= add | value;
5448         }
5449       else
5450         {
5451           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5452           inst.reloc.pc_rel = 0;
5453         }
5454       return SUCCESS;
5455
5456     case '-':
5457       add = 0;
5458       /* Fall through.  */
5459
5460     case '+':
5461       (*str)++;
5462       /* Fall through.  */
5463
5464     default:
5465       if (reg_required_here (str, 0) == FAIL)
5466         return FAIL;
5467
5468       inst.instruction |= add | OFFSET_REG;
5469       if (skip_past_comma (str) == SUCCESS)
5470         return decode_shift (str, SHIFT_IMMEDIATE);
5471
5472       return SUCCESS;
5473     }
5474 }
5475
5476 /* ARMv5TE: Preload-Cache
5477
5478     PLD <addr_mode>
5479
5480   Syntactically, like LDR with B=1, W=0, L=1.  */
5481
5482 static void
5483 do_pld (char * str)
5484 {
5485   int rd;
5486
5487   skip_whitespace (str);
5488
5489   if (* str != '[')
5490     {
5491       inst.error = _("'[' expected after PLD mnemonic");
5492       return;
5493     }
5494
5495   ++str;
5496   skip_whitespace (str);
5497
5498   if ((rd = reg_required_here (& str, 16)) == FAIL)
5499     return;
5500
5501   skip_whitespace (str);
5502
5503   if (*str == ']')
5504     {
5505       /* [Rn], ... ?  */
5506       ++str;
5507       skip_whitespace (str);
5508
5509       /* Post-indexed addressing is not allowed with PLD.  */
5510       if (skip_past_comma (&str) == SUCCESS)
5511         {
5512           inst.error
5513             = _("post-indexed expression used in preload instruction");
5514           return;
5515         }
5516       else if (*str == '!') /* [Rn]! */
5517         {
5518           inst.error = _("writeback used in preload instruction");
5519           ++str;
5520         }
5521       else /* [Rn] */
5522         inst.instruction |= INDEX_UP | PRE_INDEX;
5523     }
5524   else /* [Rn, ...] */
5525     {
5526       if (skip_past_comma (& str) == FAIL)
5527         {
5528           inst.error = _("pre-indexed expression expected");
5529           return;
5530         }
5531
5532       if (ldst_extend (&str) == FAIL)
5533         return;
5534
5535       skip_whitespace (str);
5536
5537       if (* str != ']')
5538         {
5539           inst.error = _("missing ]");
5540           return;
5541         }
5542
5543       ++ str;
5544       skip_whitespace (str);
5545
5546       if (* str == '!') /* [Rn]! */
5547         {
5548           inst.error = _("writeback used in preload instruction");
5549           ++ str;
5550         }
5551
5552       inst.instruction |= PRE_INDEX;
5553     }
5554
5555   end_of_line (str);
5556 }
5557
5558 /* ARMv5TE load-consecutive (argument parse)
5559    Mode is like LDRH.
5560
5561      LDRccD R, mode
5562      STRccD R, mode.  */
5563
5564 static void
5565 do_ldrd (char * str)
5566 {
5567   int rd;
5568   int rn;
5569
5570   skip_whitespace (str);
5571
5572   if ((rd = reg_required_here (& str, 12)) == FAIL)
5573     {
5574       inst.error = BAD_ARGS;
5575       return;
5576     }
5577
5578   if (skip_past_comma (& str) == FAIL
5579       || (rn = ld_mode_required_here (& str)) == FAIL)
5580     {
5581       if (!inst.error)
5582         inst.error = BAD_ARGS;
5583       return;
5584     }
5585
5586   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
5587   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
5588     {
5589       inst.error = _("destination register must be even");
5590       return;
5591     }
5592
5593   if (rd == REG_LR)
5594     {
5595       inst.error = _("r14 not allowed here");
5596       return;
5597     }
5598
5599   if (((rd == rn) || (rd + 1 == rn))
5600       && ((inst.instruction & WRITE_BACK)
5601           || (!(inst.instruction & PRE_INDEX))))
5602     as_warn (_("pre/post-indexing used when modified address register is destination"));
5603
5604   /* For an index-register load, the index register must not overlap the
5605      destination (even if not write-back).  */
5606   if ((inst.instruction & V4_STR_BIT) == 0
5607       && (inst.instruction & HWOFFSET_IMM) == 0)
5608     {
5609       int rm = inst.instruction & 0x0000000f;
5610
5611       if (rm == rd || (rm == rd + 1))
5612         as_warn (_("ldrd destination registers must not overlap index register"));
5613     }
5614
5615   end_of_line (str);
5616 }
5617
5618 /* Returns the index into fp_values of a floating point number,
5619    or -1 if not in the table.  */
5620
5621 static int
5622 my_get_float_expression (char ** str)
5623 {
5624   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5625   char *         save_in;
5626   expressionS    exp;
5627   int            i;
5628   int            j;
5629
5630   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5631
5632   /* Look for a raw floating point number.  */
5633   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5634       && is_end_of_line[(unsigned char) *save_in])
5635     {
5636       for (i = 0; i < NUM_FLOAT_VALS; i++)
5637         {
5638           for (j = 0; j < MAX_LITTLENUMS; j++)
5639             {
5640               if (words[j] != fp_values[i][j])
5641                 break;
5642             }
5643
5644           if (j == MAX_LITTLENUMS)
5645             {
5646               *str = save_in;
5647               return i;
5648             }
5649         }
5650     }
5651
5652   /* Try and parse a more complex expression, this will probably fail
5653      unless the code uses a floating point prefix (eg "0f").  */
5654   save_in = input_line_pointer;
5655   input_line_pointer = *str;
5656   if (expression (&exp) == absolute_section
5657       && exp.X_op == O_big
5658       && exp.X_add_number < 0)
5659     {
5660       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5661          Ditto for 15.  */
5662       if (gen_to_words (words, 5, (long) 15) == 0)
5663         {
5664           for (i = 0; i < NUM_FLOAT_VALS; i++)
5665             {
5666               for (j = 0; j < MAX_LITTLENUMS; j++)
5667                 {
5668                   if (words[j] != fp_values[i][j])
5669                     break;
5670                 }
5671
5672               if (j == MAX_LITTLENUMS)
5673                 {
5674                   *str = input_line_pointer;
5675                   input_line_pointer = save_in;
5676                   return i;
5677                 }
5678             }
5679         }
5680     }
5681
5682   *str = input_line_pointer;
5683   input_line_pointer = save_in;
5684   return -1;
5685 }
5686
5687 /* We handle all bad expressions here, so that we can report the faulty
5688    instruction in the error message.  */
5689 void
5690 md_operand (expressionS * expr)
5691 {
5692   if (in_my_get_expression)
5693     {
5694       expr->X_op = O_illegal;
5695       if (inst.error == NULL)
5696         inst.error = _("bad expression");
5697     }
5698 }
5699
5700 /* Do those data_ops which can take a negative immediate constant
5701    by altering the instruction.  A bit of a hack really.
5702         MOV <-> MVN
5703         AND <-> BIC
5704         ADC <-> SBC
5705         by inverting the second operand, and
5706         ADD <-> SUB
5707         CMP <-> CMN
5708         by negating the second operand.  */
5709
5710 static int
5711 negate_data_op (unsigned long * instruction,
5712                 unsigned long   value)
5713 {
5714   int op, new_inst;
5715   unsigned long negated, inverted;
5716
5717   negated = validate_immediate (-value);
5718   inverted = validate_immediate (~value);
5719
5720   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5721   switch (op)
5722     {
5723       /* First negates.  */
5724     case OPCODE_SUB:             /* ADD <-> SUB  */
5725       new_inst = OPCODE_ADD;
5726       value = negated;
5727       break;
5728
5729     case OPCODE_ADD:
5730       new_inst = OPCODE_SUB;
5731       value = negated;
5732       break;
5733
5734     case OPCODE_CMP:             /* CMP <-> CMN  */
5735       new_inst = OPCODE_CMN;
5736       value = negated;
5737       break;
5738
5739     case OPCODE_CMN:
5740       new_inst = OPCODE_CMP;
5741       value = negated;
5742       break;
5743
5744       /* Now Inverted ops.  */
5745     case OPCODE_MOV:             /* MOV <-> MVN  */
5746       new_inst = OPCODE_MVN;
5747       value = inverted;
5748       break;
5749
5750     case OPCODE_MVN:
5751       new_inst = OPCODE_MOV;
5752       value = inverted;
5753       break;
5754
5755     case OPCODE_AND:             /* AND <-> BIC  */
5756       new_inst = OPCODE_BIC;
5757       value = inverted;
5758       break;
5759
5760     case OPCODE_BIC:
5761       new_inst = OPCODE_AND;
5762       value = inverted;
5763       break;
5764
5765     case OPCODE_ADC:              /* ADC <-> SBC  */
5766       new_inst = OPCODE_SBC;
5767       value = inverted;
5768       break;
5769
5770     case OPCODE_SBC:
5771       new_inst = OPCODE_ADC;
5772       value = inverted;
5773       break;
5774
5775       /* We cannot do anything.  */
5776     default:
5777       return FAIL;
5778     }
5779
5780   if (value == (unsigned) FAIL)
5781     return FAIL;
5782
5783   *instruction &= OPCODE_MASK;
5784   *instruction |= new_inst << DATA_OP_SHIFT;
5785   return value;
5786 }
5787
5788 static int
5789 data_op2 (char ** str)
5790 {
5791   int value;
5792   expressionS expr;
5793
5794   skip_whitespace (* str);
5795
5796   if (reg_required_here (str, 0) != FAIL)
5797     {
5798       if (skip_past_comma (str) == SUCCESS)
5799         /* Shift operation on register.  */
5800         return decode_shift (str, NO_SHIFT_RESTRICT);
5801
5802       return SUCCESS;
5803     }
5804   else
5805     {
5806       /* Immediate expression.  */
5807       if (is_immediate_prefix (**str))
5808         {
5809           (*str)++;
5810           inst.error = NULL;
5811
5812           if (my_get_expression (&inst.reloc.exp, str))
5813             return FAIL;
5814
5815           if (inst.reloc.exp.X_add_symbol)
5816             {
5817               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5818               inst.reloc.pc_rel = 0;
5819             }
5820           else
5821             {
5822               if (skip_past_comma (str) == SUCCESS)
5823                 {
5824                   /* #x, y -- ie explicit rotation by Y.  */
5825                   if (my_get_expression (&expr, str))
5826                     return FAIL;
5827
5828                   if (expr.X_op != O_constant)
5829                     {
5830                       inst.error = _("constant expression expected");
5831                       return FAIL;
5832                     }
5833
5834                   /* Rotate must be a multiple of 2.  */
5835                   if (((unsigned) expr.X_add_number) > 30
5836                       || (expr.X_add_number & 1) != 0
5837                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
5838                     {
5839                       inst.error = _("invalid constant");
5840                       return FAIL;
5841                     }
5842                   inst.instruction |= INST_IMMEDIATE;
5843                   inst.instruction |= inst.reloc.exp.X_add_number;
5844                   inst.instruction |= expr.X_add_number << 7;
5845                   return SUCCESS;
5846                 }
5847
5848               /* Implicit rotation, select a suitable one.  */
5849               value = validate_immediate (inst.reloc.exp.X_add_number);
5850
5851               if (value == FAIL)
5852                 {
5853                   /* Can't be done.  Perhaps the code reads something like
5854                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
5855                   if ((value = negate_data_op (&inst.instruction,
5856                                                inst.reloc.exp.X_add_number))
5857                       == FAIL)
5858                     {
5859                       inst.error = _("invalid constant");
5860                       return FAIL;
5861                     }
5862                 }
5863
5864               inst.instruction |= value;
5865             }
5866
5867           inst.instruction |= INST_IMMEDIATE;
5868           return SUCCESS;
5869         }
5870
5871       (*str)++;
5872       inst.error = _("register or shift expression expected");
5873       return FAIL;
5874     }
5875 }
5876
5877 static int
5878 fp_op2 (char ** str)
5879 {
5880   skip_whitespace (* str);
5881
5882   if (fp_reg_required_here (str, 0) != FAIL)
5883     return SUCCESS;
5884   else
5885     {
5886       /* Immediate expression.  */
5887       if (*((*str)++) == '#')
5888         {
5889           int i;
5890
5891           inst.error = NULL;
5892
5893           skip_whitespace (* str);
5894
5895           /* First try and match exact strings, this is to guarantee
5896              that some formats will work even for cross assembly.  */
5897
5898           for (i = 0; fp_const[i]; i++)
5899             {
5900               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
5901                 {
5902                   char *start = *str;
5903
5904                   *str += strlen (fp_const[i]);
5905                   if (is_end_of_line[(unsigned char) **str])
5906                     {
5907                       inst.instruction |= i + 8;
5908                       return SUCCESS;
5909                     }
5910                   *str = start;
5911                 }
5912             }
5913
5914           /* Just because we didn't get a match doesn't mean that the
5915              constant isn't valid, just that it is in a format that we
5916              don't automatically recognize.  Try parsing it with
5917              the standard expression routines.  */
5918           if ((i = my_get_float_expression (str)) >= 0)
5919             {
5920               inst.instruction |= i + 8;
5921               return SUCCESS;
5922             }
5923
5924           inst.error = _("invalid floating point immediate expression");
5925           return FAIL;
5926         }
5927       inst.error =
5928         _("floating point register or immediate expression expected");
5929       return FAIL;
5930     }
5931 }
5932
5933 static void
5934 do_arit (char * str)
5935 {
5936   skip_whitespace (str);
5937
5938   if (reg_required_here (&str, 12) == FAIL
5939       || skip_past_comma (&str) == FAIL
5940       || reg_required_here (&str, 16) == FAIL
5941       || skip_past_comma (&str) == FAIL
5942       || data_op2 (&str) == FAIL)
5943     {
5944       if (!inst.error)
5945         inst.error = BAD_ARGS;
5946       return;
5947     }
5948
5949   end_of_line (str);
5950 }
5951
5952 static void
5953 do_adr (char * str)
5954 {
5955   /* This is a pseudo-op of the form "adr rd, label" to be converted
5956      into a relative address of the form "add rd, pc, #label-.-8".  */
5957   skip_whitespace (str);
5958
5959   if (reg_required_here (&str, 12) == FAIL
5960       || skip_past_comma (&str) == FAIL
5961       || my_get_expression (&inst.reloc.exp, &str))
5962     {
5963       if (!inst.error)
5964         inst.error = BAD_ARGS;
5965       return;
5966     }
5967
5968   /* Frag hacking will turn this into a sub instruction if the offset turns
5969      out to be negative.  */
5970   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5971 #ifndef TE_WINCE
5972   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
5973 #endif
5974   inst.reloc.pc_rel = 1;
5975
5976   end_of_line (str);
5977 }
5978
5979 static void
5980 do_adrl (char * str)
5981 {
5982   /* This is a pseudo-op of the form "adrl rd, label" to be converted
5983      into a relative address of the form:
5984      add rd, pc, #low(label-.-8)"
5985      add rd, rd, #high(label-.-8)"  */
5986
5987   skip_whitespace (str);
5988
5989   if (reg_required_here (&str, 12) == FAIL
5990       || skip_past_comma (&str) == FAIL
5991       || my_get_expression (&inst.reloc.exp, &str))
5992     {
5993       if (!inst.error)
5994         inst.error = BAD_ARGS;
5995
5996       return;
5997     }
5998
5999   end_of_line (str);
6000   /* Frag hacking will turn this into a sub instruction if the offset turns
6001      out to be negative.  */
6002   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6003 #ifndef TE_WINCE
6004   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
6005 #endif
6006   inst.reloc.pc_rel            = 1;
6007   inst.size                    = INSN_SIZE * 2;
6008 }
6009
6010 static void
6011 do_cmp (char * str)
6012 {
6013   skip_whitespace (str);
6014
6015   if (reg_required_here (&str, 16) == FAIL)
6016     {
6017       if (!inst.error)
6018         inst.error = BAD_ARGS;
6019       return;
6020     }
6021
6022   if (skip_past_comma (&str) == FAIL
6023       || data_op2 (&str) == FAIL)
6024     {
6025       if (!inst.error)
6026         inst.error = BAD_ARGS;
6027       return;
6028     }
6029
6030   end_of_line (str);
6031 }
6032
6033 static void
6034 do_mov (char * str)
6035 {
6036   skip_whitespace (str);
6037
6038   if (reg_required_here (&str, 12) == FAIL)
6039     {
6040       if (!inst.error)
6041         inst.error = BAD_ARGS;
6042       return;
6043     }
6044
6045   if (skip_past_comma (&str) == FAIL
6046       || data_op2 (&str) == FAIL)
6047     {
6048       if (!inst.error)
6049         inst.error = BAD_ARGS;
6050       return;
6051     }
6052
6053   end_of_line (str);
6054 }
6055
6056 static void
6057 do_ldst (char * str)
6058 {
6059   int pre_inc = 0;
6060   int conflict_reg;
6061   int value;
6062
6063   skip_whitespace (str);
6064
6065   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6066     {
6067       if (!inst.error)
6068         inst.error = BAD_ARGS;
6069       return;
6070     }
6071
6072   if (skip_past_comma (&str) == FAIL)
6073     {
6074       inst.error = _("address expected");
6075       return;
6076     }
6077
6078   if (*str == '[')
6079     {
6080       int reg;
6081
6082       str++;
6083
6084       skip_whitespace (str);
6085
6086       if ((reg = reg_required_here (&str, 16)) == FAIL)
6087         return;
6088
6089       /* Conflicts can occur on stores as well as loads.  */
6090       conflict_reg = (conflict_reg == reg);
6091
6092       skip_whitespace (str);
6093
6094       if (*str == ']')
6095         {
6096           str ++;
6097
6098           if (skip_past_comma (&str) == SUCCESS)
6099             {
6100               /* [Rn],... (post inc)  */
6101               if (ldst_extend (&str) == FAIL)
6102                 return;
6103               if (conflict_reg)
6104                 as_warn (_("%s register same as write-back base"),
6105                          ((inst.instruction & LOAD_BIT)
6106                           ? _("destination") : _("source")));
6107             }
6108           else
6109             {
6110               /* [Rn]  */
6111               skip_whitespace (str);
6112
6113               if (*str == '!')
6114                 {
6115                   if (conflict_reg)
6116                     as_warn (_("%s register same as write-back base"),
6117                              ((inst.instruction & LOAD_BIT)
6118                               ? _("destination") : _("source")));
6119                   str++;
6120                   inst.instruction |= WRITE_BACK;
6121                 }
6122
6123               inst.instruction |= INDEX_UP;
6124               pre_inc = 1;
6125             }
6126         }
6127       else
6128         {
6129           /* [Rn,...]  */
6130           if (skip_past_comma (&str) == FAIL)
6131             {
6132               inst.error = _("pre-indexed expression expected");
6133               return;
6134             }
6135
6136           pre_inc = 1;
6137           if (ldst_extend (&str) == FAIL)
6138             return;
6139
6140           skip_whitespace (str);
6141
6142           if (*str++ != ']')
6143             {
6144               inst.error = _("missing ]");
6145               return;
6146             }
6147
6148           skip_whitespace (str);
6149
6150           if (*str == '!')
6151             {
6152               if (conflict_reg)
6153                 as_warn (_("%s register same as write-back base"),
6154                          ((inst.instruction & LOAD_BIT)
6155                           ? _("destination") : _("source")));
6156               str++;
6157               inst.instruction |= WRITE_BACK;
6158             }
6159         }
6160     }
6161   else if (*str == '=')
6162     {
6163       if ((inst.instruction & LOAD_BIT) == 0)
6164         {
6165           inst.error = _("invalid pseudo operation");
6166           return;
6167         }
6168
6169       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6170       str++;
6171
6172       skip_whitespace (str);
6173
6174       if (my_get_expression (&inst.reloc.exp, &str))
6175         return;
6176
6177       if (inst.reloc.exp.X_op != O_constant
6178           && inst.reloc.exp.X_op != O_symbol)
6179         {
6180           inst.error = _("constant expression expected");
6181           return;
6182         }
6183
6184       if (inst.reloc.exp.X_op == O_constant)
6185         {
6186           value = validate_immediate (inst.reloc.exp.X_add_number);
6187
6188           if (value != FAIL)
6189             {
6190               /* This can be done with a mov instruction.  */
6191               inst.instruction &= LITERAL_MASK;
6192               inst.instruction |= (INST_IMMEDIATE
6193                                    | (OPCODE_MOV << DATA_OP_SHIFT));
6194               inst.instruction |= value & 0xfff;
6195               end_of_line (str);
6196               return;
6197             }
6198
6199           value = validate_immediate (~inst.reloc.exp.X_add_number);
6200
6201           if (value != FAIL)
6202             {
6203               /* This can be done with a mvn instruction.  */
6204               inst.instruction &= LITERAL_MASK;
6205               inst.instruction |= (INST_IMMEDIATE
6206                                    | (OPCODE_MVN << DATA_OP_SHIFT));
6207               inst.instruction |= value & 0xfff;
6208               end_of_line (str);
6209               return;
6210             }
6211         }
6212
6213       /* Insert into literal pool.  */
6214       if (add_to_lit_pool () == FAIL)
6215         {
6216           if (!inst.error)
6217             inst.error = _("literal pool insertion failed");
6218           return;
6219         }
6220
6221       /* Change the instruction exp to point to the pool.  */
6222       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6223       inst.reloc.pc_rel = 1;
6224       inst.instruction |= (REG_PC << 16);
6225       pre_inc = 1;
6226     }
6227   else
6228     {
6229       if (my_get_expression (&inst.reloc.exp, &str))
6230         return;
6231
6232       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6233 #ifndef TE_WINCE
6234       /* PC rel adjust.  */
6235       inst.reloc.exp.X_add_number -= 8;
6236 #endif
6237       inst.reloc.pc_rel = 1;
6238       inst.instruction |= (REG_PC << 16);
6239       pre_inc = 1;
6240     }
6241
6242   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6243   end_of_line (str);
6244 }
6245
6246 static void
6247 do_ldstt (char * str)
6248 {
6249   int conflict_reg;
6250
6251   skip_whitespace (str);
6252
6253   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6254     {
6255       if (!inst.error)
6256         inst.error = BAD_ARGS;
6257       return;
6258     }
6259
6260   if (skip_past_comma (& str) == FAIL)
6261     {
6262       inst.error = _("address expected");
6263       return;
6264     }
6265
6266   if (*str == '[')
6267     {
6268       int reg;
6269
6270       str++;
6271
6272       skip_whitespace (str);
6273
6274       if ((reg = reg_required_here (&str, 16)) == FAIL)
6275         return;
6276
6277       /* ldrt/strt always use post-indexed addressing, so if the base is
6278          the same as Rd, we warn.  */
6279       if (conflict_reg == reg)
6280         as_warn (_("%s register same as write-back base"),
6281                  ((inst.instruction & LOAD_BIT)
6282                   ? _("destination") : _("source")));
6283
6284       skip_whitespace (str);
6285
6286       if (*str == ']')
6287         {
6288           str ++;
6289
6290           if (skip_past_comma (&str) == SUCCESS)
6291             {
6292               /* [Rn],... (post inc)  */
6293               if (ldst_extend (&str) == FAIL)
6294                 return;
6295             }
6296           else
6297             {
6298               /* [Rn]  */
6299               skip_whitespace (str);
6300
6301               /* Skip a write-back '!'.  */
6302               if (*str == '!')
6303                 str++;
6304
6305               inst.instruction |= INDEX_UP;
6306             }
6307         }
6308       else
6309         {
6310           inst.error = _("post-indexed expression expected");
6311           return;
6312         }
6313     }
6314   else
6315     {
6316       inst.error = _("post-indexed expression expected");
6317       return;
6318     }
6319
6320   end_of_line (str);
6321 }
6322
6323 /* Halfword and signed-byte load/store operations.  */
6324
6325 static void
6326 do_ldstv4 (char * str)
6327 {
6328   int pre_inc = 0;
6329   int conflict_reg;
6330   int value;
6331
6332   skip_whitespace (str);
6333
6334   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6335     {
6336       if (!inst.error)
6337         inst.error = BAD_ARGS;
6338       return;
6339     }
6340
6341   if (skip_past_comma (& str) == FAIL)
6342     {
6343       inst.error = _("address expected");
6344       return;
6345     }
6346
6347   if (*str == '[')
6348     {
6349       int reg;
6350
6351       str++;
6352
6353       skip_whitespace (str);
6354
6355       if ((reg = reg_required_here (&str, 16)) == FAIL)
6356         return;
6357
6358       /* Conflicts can occur on stores as well as loads.  */
6359       conflict_reg = (conflict_reg == reg);
6360
6361       skip_whitespace (str);
6362
6363       if (*str == ']')
6364         {
6365           str ++;
6366
6367           if (skip_past_comma (&str) == SUCCESS)
6368             {
6369               /* [Rn],... (post inc)  */
6370               if (ldst_extend_v4 (&str) == FAIL)
6371                 return;
6372               if (conflict_reg)
6373                 as_warn (_("%s register same as write-back base"),
6374                          ((inst.instruction & LOAD_BIT)
6375                           ? _("destination") : _("source")));
6376             }
6377           else
6378             {
6379               /* [Rn]  */
6380               inst.instruction |= HWOFFSET_IMM;
6381
6382               skip_whitespace (str);
6383
6384               if (*str == '!')
6385                 {
6386                   if (conflict_reg)
6387                     as_warn (_("%s register same as write-back base"),
6388                              ((inst.instruction & LOAD_BIT)
6389                               ? _("destination") : _("source")));
6390                   str++;
6391                   inst.instruction |= WRITE_BACK;
6392                 }
6393
6394               inst.instruction |= INDEX_UP;
6395               pre_inc = 1;
6396             }
6397         }
6398       else
6399         {
6400           /* [Rn,...]  */
6401           if (skip_past_comma (&str) == FAIL)
6402             {
6403               inst.error = _("pre-indexed expression expected");
6404               return;
6405             }
6406
6407           pre_inc = 1;
6408           if (ldst_extend_v4 (&str) == FAIL)
6409             return;
6410
6411           skip_whitespace (str);
6412
6413           if (*str++ != ']')
6414             {
6415               inst.error = _("missing ]");
6416               return;
6417             }
6418
6419           skip_whitespace (str);
6420
6421           if (*str == '!')
6422             {
6423               if (conflict_reg)
6424                 as_warn (_("%s register same as write-back base"),
6425                          ((inst.instruction & LOAD_BIT)
6426                           ? _("destination") : _("source")));
6427               str++;
6428               inst.instruction |= WRITE_BACK;
6429             }
6430         }
6431     }
6432   else if (*str == '=')
6433     {
6434       if ((inst.instruction & LOAD_BIT) == 0)
6435         {
6436           inst.error = _("invalid pseudo operation");
6437           return;
6438         }
6439
6440       /* XXX Does this work correctly for half-word/byte ops?  */
6441       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6442       str++;
6443
6444       skip_whitespace (str);
6445
6446       if (my_get_expression (&inst.reloc.exp, &str))
6447         return;
6448
6449       if (inst.reloc.exp.X_op != O_constant
6450           && inst.reloc.exp.X_op != O_symbol)
6451         {
6452           inst.error = _("constant expression expected");
6453           return;
6454         }
6455
6456       if (inst.reloc.exp.X_op == O_constant)
6457         {
6458           value = validate_immediate (inst.reloc.exp.X_add_number);
6459
6460           if (value != FAIL)
6461             {
6462               /* This can be done with a mov instruction.  */
6463               inst.instruction &= LITERAL_MASK;
6464               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6465               inst.instruction |= value & 0xfff;
6466               end_of_line (str);
6467               return;
6468             }
6469
6470           value = validate_immediate (~ inst.reloc.exp.X_add_number);
6471
6472           if (value != FAIL)
6473             {
6474               /* This can be done with a mvn instruction.  */
6475               inst.instruction &= LITERAL_MASK;
6476               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6477               inst.instruction |= value & 0xfff;
6478               end_of_line (str);
6479               return;
6480             }
6481         }
6482
6483       /* Insert into literal pool.  */
6484       if (add_to_lit_pool () == FAIL)
6485         {
6486           if (!inst.error)
6487             inst.error = _("literal pool insertion failed");
6488           return;
6489         }
6490
6491       /* Change the instruction exp to point to the pool.  */
6492       inst.instruction |= HWOFFSET_IMM;
6493       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6494       inst.reloc.pc_rel = 1;
6495       inst.instruction |= (REG_PC << 16);
6496       pre_inc = 1;
6497     }
6498   else
6499     {
6500       if (my_get_expression (&inst.reloc.exp, &str))
6501         return;
6502
6503       inst.instruction |= HWOFFSET_IMM;
6504       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6505 #ifndef TE_WINCE
6506       /* PC rel adjust.  */
6507       inst.reloc.exp.X_add_number -= 8;
6508 #endif
6509       inst.reloc.pc_rel = 1;
6510       inst.instruction |= (REG_PC << 16);
6511       pre_inc = 1;
6512     }
6513
6514   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6515   end_of_line (str);
6516 }
6517
6518 static long
6519 reg_list (char ** strp)
6520 {
6521   char * str = * strp;
6522   long   range = 0;
6523   int    another_range;
6524
6525   /* We come back here if we get ranges concatenated by '+' or '|'.  */
6526   do
6527     {
6528       another_range = 0;
6529
6530       if (*str == '{')
6531         {
6532           int in_range = 0;
6533           int cur_reg = -1;
6534
6535           str++;
6536           do
6537             {
6538               int reg;
6539
6540               skip_whitespace (str);
6541
6542               if ((reg = reg_required_here (& str, -1)) == FAIL)
6543                 return FAIL;
6544
6545               if (in_range)
6546                 {
6547                   int i;
6548
6549                   if (reg <= cur_reg)
6550                     {
6551                       inst.error = _("bad range in register list");
6552                       return FAIL;
6553                     }
6554
6555                   for (i = cur_reg + 1; i < reg; i++)
6556                     {
6557                       if (range & (1 << i))
6558                         as_tsktsk
6559                           (_("Warning: duplicated register (r%d) in register list"),
6560                            i);
6561                       else
6562                         range |= 1 << i;
6563                     }
6564                   in_range = 0;
6565                 }
6566
6567               if (range & (1 << reg))
6568                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6569                            reg);
6570               else if (reg <= cur_reg)
6571                 as_tsktsk (_("Warning: register range not in ascending order"));
6572
6573               range |= 1 << reg;
6574               cur_reg = reg;
6575             }
6576           while (skip_past_comma (&str) != FAIL
6577                  || (in_range = 1, *str++ == '-'));
6578           str--;
6579           skip_whitespace (str);
6580
6581           if (*str++ != '}')
6582             {
6583               inst.error = _("missing `}'");
6584               return FAIL;
6585             }
6586         }
6587       else
6588         {
6589           expressionS expr;
6590
6591           if (my_get_expression (&expr, &str))
6592             return FAIL;
6593
6594           if (expr.X_op == O_constant)
6595             {
6596               if (expr.X_add_number
6597                   != (expr.X_add_number & 0x0000ffff))
6598                 {
6599                   inst.error = _("invalid register mask");
6600                   return FAIL;
6601                 }
6602
6603               if ((range & expr.X_add_number) != 0)
6604                 {
6605                   int regno = range & expr.X_add_number;
6606
6607                   regno &= -regno;
6608                   regno = (1 << regno) - 1;
6609                   as_tsktsk
6610                     (_("Warning: duplicated register (r%d) in register list"),
6611                      regno);
6612                 }
6613
6614               range |= expr.X_add_number;
6615             }
6616           else
6617             {
6618               if (inst.reloc.type != 0)
6619                 {
6620                   inst.error = _("expression too complex");
6621                   return FAIL;
6622                 }
6623
6624               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6625               inst.reloc.type = BFD_RELOC_ARM_MULTI;
6626               inst.reloc.pc_rel = 0;
6627             }
6628         }
6629
6630       skip_whitespace (str);
6631
6632       if (*str == '|' || *str == '+')
6633         {
6634           str++;
6635           another_range = 1;
6636         }
6637     }
6638   while (another_range);
6639
6640   *strp = str;
6641   return range;
6642 }
6643
6644 static void
6645 do_ldmstm (char * str)
6646 {
6647   int base_reg;
6648   long range;
6649
6650   skip_whitespace (str);
6651
6652   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6653     return;
6654
6655   if (base_reg == REG_PC)
6656     {
6657       inst.error = _("r15 not allowed as base register");
6658       return;
6659     }
6660
6661   skip_whitespace (str);
6662
6663   if (*str == '!')
6664     {
6665       inst.instruction |= WRITE_BACK;
6666       str++;
6667     }
6668
6669   if (skip_past_comma (&str) == FAIL
6670       || (range = reg_list (&str)) == FAIL)
6671     {
6672       if (! inst.error)
6673         inst.error = BAD_ARGS;
6674       return;
6675     }
6676
6677   if (*str == '^')
6678     {
6679       str++;
6680       inst.instruction |= LDM_TYPE_2_OR_3;
6681     }
6682
6683   if (inst.instruction & WRITE_BACK)
6684     {
6685       /* Check for unpredictable uses of writeback.  */
6686       if (inst.instruction & LOAD_BIT)
6687         {
6688           /* Not allowed in LDM type 2.  */
6689           if ((inst.instruction & LDM_TYPE_2_OR_3)
6690               && ((range & (1 << REG_PC)) == 0))
6691             as_warn (_("writeback of base register is UNPREDICTABLE"));
6692           /* Only allowed if base reg not in list for other types.  */
6693           else if (range & (1 << base_reg))
6694             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
6695         }
6696       else /* STM.  */
6697         {
6698           /* Not allowed for type 2.  */
6699           if (inst.instruction & LDM_TYPE_2_OR_3)
6700             as_warn (_("writeback of base register is UNPREDICTABLE"));
6701           /* Only allowed if base reg not in list, or first in list.  */
6702           else if ((range & (1 << base_reg))
6703                    && (range & ((1 << base_reg) - 1)))
6704             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
6705         }
6706     }
6707
6708   inst.instruction |= range;
6709   end_of_line (str);
6710 }
6711
6712 static void
6713 do_smi (char * str)
6714 {
6715   skip_whitespace (str);
6716
6717   /* Allow optional leading '#'.  */
6718   if (is_immediate_prefix (*str))
6719     str++;
6720
6721   if (my_get_expression (& inst.reloc.exp, & str))
6722     return;
6723
6724   inst.reloc.type = BFD_RELOC_ARM_SMI;
6725   inst.reloc.pc_rel = 0;
6726   end_of_line (str);
6727 }
6728
6729 static void
6730 do_swi (char * str)
6731 {
6732   skip_whitespace (str);
6733
6734   /* Allow optional leading '#'.  */
6735   if (is_immediate_prefix (*str))
6736     str++;
6737
6738   if (my_get_expression (& inst.reloc.exp, & str))
6739     return;
6740
6741   inst.reloc.type = BFD_RELOC_ARM_SWI;
6742   inst.reloc.pc_rel = 0;
6743   end_of_line (str);
6744 }
6745
6746 static void
6747 do_swap (char * str)
6748 {
6749   int reg;
6750
6751   skip_whitespace (str);
6752
6753   if ((reg = reg_required_here (&str, 12)) == FAIL)
6754     return;
6755
6756   if (reg == REG_PC)
6757     {
6758       inst.error = _("r15 not allowed in swap");
6759       return;
6760     }
6761
6762   if (skip_past_comma (&str) == FAIL
6763       || (reg = reg_required_here (&str, 0)) == FAIL)
6764     {
6765       if (!inst.error)
6766         inst.error = BAD_ARGS;
6767       return;
6768     }
6769
6770   if (reg == REG_PC)
6771     {
6772       inst.error = _("r15 not allowed in swap");
6773       return;
6774     }
6775
6776   if (skip_past_comma (&str) == FAIL
6777       || *str++ != '[')
6778     {
6779       inst.error = BAD_ARGS;
6780       return;
6781     }
6782
6783   skip_whitespace (str);
6784
6785   if ((reg = reg_required_here (&str, 16)) == FAIL)
6786     return;
6787
6788   if (reg == REG_PC)
6789     {
6790       inst.error = BAD_PC;
6791       return;
6792     }
6793
6794   skip_whitespace (str);
6795
6796   if (*str++ != ']')
6797     {
6798       inst.error = _("missing ]");
6799       return;
6800     }
6801
6802   end_of_line (str);
6803 }
6804
6805 static void
6806 do_branch (char * str)
6807 {
6808   if (my_get_expression (&inst.reloc.exp, &str))
6809     return;
6810
6811 #ifdef OBJ_ELF
6812   {
6813     char * save_in;
6814
6815     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
6816        required for the instruction.  */
6817
6818     /* arm_parse_reloc () works on input_line_pointer.
6819        We actually want to parse the operands to the branch instruction
6820        passed in 'str'.  Save the input pointer and restore it later.  */
6821     save_in = input_line_pointer;
6822     input_line_pointer = str;
6823     if (inst.reloc.exp.X_op == O_symbol
6824         && *str == '('
6825         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
6826       {
6827         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
6828         inst.reloc.pc_rel = 0;
6829         /* Modify str to point to after parsed operands, otherwise
6830            end_of_line() will complain about the (PLT) left in str.  */
6831         str = input_line_pointer;
6832       }
6833     else
6834       {
6835         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6836         inst.reloc.pc_rel = 1;
6837       }
6838     input_line_pointer = save_in;
6839   }
6840 #else
6841   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6842   inst.reloc.pc_rel = 1;
6843 #endif /* OBJ_ELF  */
6844
6845   end_of_line (str);
6846 }
6847
6848 static void
6849 do_cdp (char * str)
6850 {
6851   /* Co-processor data operation.
6852      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
6853   skip_whitespace (str);
6854
6855   if (co_proc_number (&str) == FAIL)
6856     {
6857       if (!inst.error)
6858         inst.error = BAD_ARGS;
6859       return;
6860     }
6861
6862   if (skip_past_comma (&str) == FAIL
6863       || cp_opc_expr (&str, 20,4) == FAIL)
6864     {
6865       if (!inst.error)
6866         inst.error = BAD_ARGS;
6867       return;
6868     }
6869
6870   if (skip_past_comma (&str) == FAIL
6871       || cp_reg_required_here (&str, 12) == FAIL)
6872     {
6873       if (!inst.error)
6874         inst.error = BAD_ARGS;
6875       return;
6876     }
6877
6878   if (skip_past_comma (&str) == FAIL
6879       || cp_reg_required_here (&str, 16) == FAIL)
6880     {
6881       if (!inst.error)
6882         inst.error = BAD_ARGS;
6883       return;
6884     }
6885
6886   if (skip_past_comma (&str) == FAIL
6887       || cp_reg_required_here (&str, 0) == FAIL)
6888     {
6889       if (!inst.error)
6890         inst.error = BAD_ARGS;
6891       return;
6892     }
6893
6894   if (skip_past_comma (&str) == SUCCESS)
6895     {
6896       if (cp_opc_expr (&str, 5, 3) == FAIL)
6897         {
6898           if (!inst.error)
6899             inst.error = BAD_ARGS;
6900           return;
6901         }
6902     }
6903
6904   end_of_line (str);
6905 }
6906
6907 static void
6908 do_lstc (char * str)
6909 {
6910   /* Co-processor register load/store.
6911      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
6912
6913   skip_whitespace (str);
6914
6915   if (co_proc_number (&str) == FAIL)
6916     {
6917       if (!inst.error)
6918         inst.error = BAD_ARGS;
6919       return;
6920     }
6921
6922   if (skip_past_comma (&str) == FAIL
6923       || cp_reg_required_here (&str, 12) == FAIL)
6924     {
6925       if (!inst.error)
6926         inst.error = BAD_ARGS;
6927       return;
6928     }
6929
6930   if (skip_past_comma (&str) == FAIL
6931       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6932     {
6933       if (! inst.error)
6934         inst.error = BAD_ARGS;
6935       return;
6936     }
6937
6938   end_of_line (str);
6939 }
6940
6941 static void
6942 do_co_reg (char * str)
6943 {
6944   /* Co-processor register transfer.
6945      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
6946
6947   skip_whitespace (str);
6948
6949   if (co_proc_number (&str) == FAIL)
6950     {
6951       if (!inst.error)
6952         inst.error = BAD_ARGS;
6953       return;
6954     }
6955
6956   if (skip_past_comma (&str) == FAIL
6957       || cp_opc_expr (&str, 21, 3) == FAIL)
6958     {
6959       if (!inst.error)
6960         inst.error = BAD_ARGS;
6961       return;
6962     }
6963
6964   if (skip_past_comma (&str) == FAIL
6965       || reg_required_here (&str, 12) == FAIL)
6966     {
6967       if (!inst.error)
6968         inst.error = BAD_ARGS;
6969       return;
6970     }
6971
6972   if (skip_past_comma (&str) == FAIL
6973       || cp_reg_required_here (&str, 16) == FAIL)
6974     {
6975       if (!inst.error)
6976         inst.error = BAD_ARGS;
6977       return;
6978     }
6979
6980   if (skip_past_comma (&str) == FAIL
6981       || cp_reg_required_here (&str, 0) == FAIL)
6982     {
6983       if (!inst.error)
6984         inst.error = BAD_ARGS;
6985       return;
6986     }
6987
6988   if (skip_past_comma (&str) == SUCCESS)
6989     {
6990       if (cp_opc_expr (&str, 5, 3) == FAIL)
6991         {
6992           if (!inst.error)
6993             inst.error = BAD_ARGS;
6994           return;
6995         }
6996     }
6997
6998   end_of_line (str);
6999 }
7000
7001 static void
7002 do_fpa_ctrl (char * str)
7003 {
7004   /* FP control registers.
7005      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
7006
7007   skip_whitespace (str);
7008
7009   if (reg_required_here (&str, 12) == FAIL)
7010     {
7011       if (!inst.error)
7012         inst.error = BAD_ARGS;
7013       return;
7014     }
7015
7016   end_of_line (str);
7017 }
7018
7019 static void
7020 do_fpa_ldst (char * str)
7021 {
7022   skip_whitespace (str);
7023
7024   if (fp_reg_required_here (&str, 12) == FAIL)
7025     {
7026       if (!inst.error)
7027         inst.error = BAD_ARGS;
7028       return;
7029     }
7030
7031   if (skip_past_comma (&str) == FAIL
7032       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7033     {
7034       if (!inst.error)
7035         inst.error = BAD_ARGS;
7036       return;
7037     }
7038
7039   end_of_line (str);
7040 }
7041
7042 static void
7043 do_fpa_ldmstm (char * str)
7044 {
7045   int num_regs;
7046
7047   skip_whitespace (str);
7048
7049   if (fp_reg_required_here (&str, 12) == FAIL)
7050     {
7051       if (! inst.error)
7052         inst.error = BAD_ARGS;
7053       return;
7054     }
7055
7056   /* Get Number of registers to transfer.  */
7057   if (skip_past_comma (&str) == FAIL
7058       || my_get_expression (&inst.reloc.exp, &str))
7059     {
7060       if (! inst.error)
7061         inst.error = _("constant expression expected");
7062       return;
7063     }
7064
7065   if (inst.reloc.exp.X_op != O_constant)
7066     {
7067       inst.error = _("constant value required for number of registers");
7068       return;
7069     }
7070
7071   num_regs = inst.reloc.exp.X_add_number;
7072
7073   if (num_regs < 1 || num_regs > 4)
7074     {
7075       inst.error = _("number of registers must be in the range [1:4]");
7076       return;
7077     }
7078
7079   switch (num_regs)
7080     {
7081     case 1:
7082       inst.instruction |= CP_T_X;
7083       break;
7084     case 2:
7085       inst.instruction |= CP_T_Y;
7086       break;
7087     case 3:
7088       inst.instruction |= CP_T_Y | CP_T_X;
7089       break;
7090     case 4:
7091       break;
7092     default:
7093       abort ();
7094     }
7095
7096   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
7097     {
7098       int reg;
7099       int write_back;
7100       int offset;
7101
7102       /* The instruction specified "ea" or "fd", so we can only accept
7103          [Rn]{!}.  The instruction does not really support stacking or
7104          unstacking, so we have to emulate these by setting appropriate
7105          bits and offsets.  */
7106       if (skip_past_comma (&str) == FAIL
7107           || *str != '[')
7108         {
7109           if (! inst.error)
7110             inst.error = BAD_ARGS;
7111           return;
7112         }
7113
7114       str++;
7115       skip_whitespace (str);
7116
7117       if ((reg = reg_required_here (&str, 16)) == FAIL)
7118         return;
7119
7120       skip_whitespace (str);
7121
7122       if (*str != ']')
7123         {
7124           inst.error = BAD_ARGS;
7125           return;
7126         }
7127
7128       str++;
7129       if (*str == '!')
7130         {
7131           write_back = 1;
7132           str++;
7133           if (reg == REG_PC)
7134             {
7135               inst.error =
7136                 _("r15 not allowed as base register with write-back");
7137               return;
7138             }
7139         }
7140       else
7141         write_back = 0;
7142
7143       if (inst.instruction & CP_T_Pre)
7144         {
7145           /* Pre-decrement.  */
7146           offset = 3 * num_regs;
7147           if (write_back)
7148             inst.instruction |= CP_T_WB;
7149         }
7150       else
7151         {
7152           /* Post-increment.  */
7153           if (write_back)
7154             {
7155               inst.instruction |= CP_T_WB;
7156               offset = 3 * num_regs;
7157             }
7158           else
7159             {
7160               /* No write-back, so convert this into a standard pre-increment
7161                  instruction -- aesthetically more pleasing.  */
7162               inst.instruction |= CP_T_Pre | CP_T_UD;
7163               offset = 0;
7164             }
7165         }
7166
7167       inst.instruction |= offset;
7168     }
7169   else if (skip_past_comma (&str) == FAIL
7170            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7171     {
7172       if (! inst.error)
7173         inst.error = BAD_ARGS;
7174       return;
7175     }
7176
7177   end_of_line (str);
7178 }
7179
7180 static void
7181 do_fpa_dyadic (char * str)
7182 {
7183   skip_whitespace (str);
7184
7185   if (fp_reg_required_here (&str, 12) == FAIL)
7186     {
7187       if (! inst.error)
7188         inst.error = BAD_ARGS;
7189       return;
7190     }
7191
7192   if (skip_past_comma (&str) == FAIL
7193       || fp_reg_required_here (&str, 16) == FAIL)
7194     {
7195       if (! inst.error)
7196         inst.error = BAD_ARGS;
7197       return;
7198     }
7199
7200   if (skip_past_comma (&str) == FAIL
7201       || fp_op2 (&str) == FAIL)
7202     {
7203       if (! inst.error)
7204         inst.error = BAD_ARGS;
7205       return;
7206     }
7207
7208   end_of_line (str);
7209 }
7210
7211 static void
7212 do_fpa_monadic (char * str)
7213 {
7214   skip_whitespace (str);
7215
7216   if (fp_reg_required_here (&str, 12) == FAIL)
7217     {
7218       if (! inst.error)
7219         inst.error = BAD_ARGS;
7220       return;
7221     }
7222
7223   if (skip_past_comma (&str) == FAIL
7224       || fp_op2 (&str) == FAIL)
7225     {
7226       if (! inst.error)
7227         inst.error = BAD_ARGS;
7228       return;
7229     }
7230
7231   end_of_line (str);
7232 }
7233
7234 static void
7235 do_fpa_cmp (char * str)
7236 {
7237   skip_whitespace (str);
7238
7239   if (fp_reg_required_here (&str, 16) == FAIL)
7240     {
7241       if (! inst.error)
7242         inst.error = BAD_ARGS;
7243       return;
7244     }
7245
7246   if (skip_past_comma (&str) == FAIL
7247       || fp_op2 (&str) == FAIL)
7248     {
7249       if (! inst.error)
7250         inst.error = BAD_ARGS;
7251       return;
7252     }
7253
7254   end_of_line (str);
7255 }
7256
7257 static void
7258 do_fpa_from_reg (char * str)
7259 {
7260   skip_whitespace (str);
7261
7262   if (fp_reg_required_here (&str, 16) == FAIL)
7263     {
7264       if (! inst.error)
7265         inst.error = BAD_ARGS;
7266       return;
7267     }
7268
7269   if (skip_past_comma (&str) == FAIL
7270       || reg_required_here (&str, 12) == FAIL)
7271     {
7272       if (! inst.error)
7273         inst.error = BAD_ARGS;
7274       return;
7275     }
7276
7277   end_of_line (str);
7278 }
7279
7280 static void
7281 do_fpa_to_reg (char * str)
7282 {
7283   skip_whitespace (str);
7284
7285   if (reg_required_here (&str, 12) == FAIL)
7286     return;
7287
7288   if (skip_past_comma (&str) == FAIL
7289       || fp_reg_required_here (&str, 0) == FAIL)
7290     {
7291       if (! inst.error)
7292         inst.error = BAD_ARGS;
7293       return;
7294     }
7295
7296   end_of_line (str);
7297 }
7298
7299 /* Encode a VFP SP register number.  */
7300
7301 static void
7302 vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
7303 {
7304   switch (pos)
7305     {
7306     case VFP_REG_Sd:
7307       inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7308       break;
7309
7310     case VFP_REG_Sn:
7311       inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7312       break;
7313
7314     case VFP_REG_Sm:
7315       inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7316       break;
7317
7318     default:
7319       abort ();
7320     }
7321 }
7322
7323 static int
7324 vfp_sp_reg_required_here (char ** str,
7325                           enum vfp_sp_reg_pos pos)
7326 {
7327   int    reg;
7328   char * start = *str;
7329
7330   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7331     {
7332       vfp_sp_encode_reg (reg, pos);
7333       return reg;
7334     }
7335
7336   /* In the few cases where we might be able to accept something else
7337      this error can be overridden.  */
7338   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7339
7340   /* Restore the start point.  */
7341   *str = start;
7342   return FAIL;
7343 }
7344
7345 static int
7346 vfp_dp_reg_required_here (char ** str,
7347                           enum vfp_dp_reg_pos pos)
7348 {
7349   int    reg;
7350   char * start = *str;
7351
7352   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7353     {
7354       switch (pos)
7355         {
7356         case VFP_REG_Dd:
7357           inst.instruction |= reg << 12;
7358           break;
7359
7360         case VFP_REG_Dn:
7361           inst.instruction |= reg << 16;
7362           break;
7363
7364         case VFP_REG_Dm:
7365           inst.instruction |= reg << 0;
7366           break;
7367
7368         default:
7369           abort ();
7370         }
7371       return reg;
7372     }
7373
7374   /* In the few cases where we might be able to accept something else
7375      this error can be overridden.  */
7376   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7377
7378   /* Restore the start point.  */
7379   *str = start;
7380   return FAIL;
7381 }
7382
7383 static void
7384 do_vfp_sp_monadic (char * str)
7385 {
7386   skip_whitespace (str);
7387
7388   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7389     return;
7390
7391   if (skip_past_comma (&str) == FAIL
7392       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7393     {
7394       if (! inst.error)
7395         inst.error = BAD_ARGS;
7396       return;
7397     }
7398
7399   end_of_line (str);
7400 }
7401
7402 static void
7403 do_vfp_dp_monadic (char * str)
7404 {
7405   skip_whitespace (str);
7406
7407   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7408     return;
7409
7410   if (skip_past_comma (&str) == FAIL
7411       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7412     {
7413       if (! inst.error)
7414         inst.error = BAD_ARGS;
7415       return;
7416     }
7417
7418   end_of_line (str);
7419 }
7420
7421 static void
7422 do_vfp_sp_dyadic (char * str)
7423 {
7424   skip_whitespace (str);
7425
7426   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7427     return;
7428
7429   if (skip_past_comma (&str) == FAIL
7430       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7431       || skip_past_comma (&str) == FAIL
7432       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7433     {
7434       if (! inst.error)
7435         inst.error = BAD_ARGS;
7436       return;
7437     }
7438
7439   end_of_line (str);
7440 }
7441
7442 static void
7443 do_vfp_dp_dyadic (char * str)
7444 {
7445   skip_whitespace (str);
7446
7447   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7448     return;
7449
7450   if (skip_past_comma (&str) == FAIL
7451       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7452       || skip_past_comma (&str) == FAIL
7453       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7454     {
7455       if (! inst.error)
7456         inst.error = BAD_ARGS;
7457       return;
7458     }
7459
7460   end_of_line (str);
7461 }
7462
7463 static void
7464 do_vfp_reg_from_sp (char * str)
7465 {
7466   skip_whitespace (str);
7467
7468   if (reg_required_here (&str, 12) == FAIL)
7469     return;
7470
7471   if (skip_past_comma (&str) == FAIL
7472       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7473     {
7474       if (! inst.error)
7475         inst.error = BAD_ARGS;
7476       return;
7477     }
7478
7479   end_of_line (str);
7480 }
7481
7482 /* Parse a VFP register list.  If the string is invalid return FAIL.
7483    Otherwise return the number of registers, and set PBASE to the first
7484    register.  Double precision registers are matched if DP is nonzero.  */
7485
7486 static int
7487 vfp_parse_reg_list (char **str, int *pbase, int dp)
7488 {
7489   int base_reg;
7490   int new_base;
7491   int regtype;
7492   int max_regs;
7493   int count = 0;
7494   int warned = 0;
7495   unsigned long mask = 0;
7496   int i;
7497
7498   if (**str != '{')
7499     return FAIL;
7500
7501   (*str)++;
7502   skip_whitespace (*str);
7503
7504   if (dp)
7505     {
7506       regtype = REG_TYPE_DN;
7507       max_regs = 16;
7508     }
7509   else
7510     {
7511       regtype = REG_TYPE_SN;
7512       max_regs = 32;
7513     }
7514
7515   base_reg = max_regs;
7516
7517   do
7518     {
7519       new_base = arm_reg_parse (str, all_reg_maps[regtype].htab);
7520       if (new_base == FAIL)
7521         {
7522           inst.error = _(all_reg_maps[regtype].expected);
7523           return FAIL;
7524         }
7525
7526       if (new_base < base_reg)
7527         base_reg = new_base;
7528
7529       if (mask & (1 << new_base))
7530         {
7531           inst.error = _("invalid register list");
7532           return FAIL;
7533         }
7534
7535       if ((mask >> new_base) != 0 && ! warned)
7536         {
7537           as_tsktsk (_("register list not in ascending order"));
7538           warned = 1;
7539         }
7540
7541       mask |= 1 << new_base;
7542       count++;
7543
7544       skip_whitespace (*str);
7545
7546       if (**str == '-') /* We have the start of a range expression */
7547         {
7548           int high_range;
7549
7550           (*str)++;
7551
7552           if ((high_range
7553                = arm_reg_parse (str, all_reg_maps[regtype].htab))
7554               == FAIL)
7555             {
7556               inst.error = _(all_reg_maps[regtype].expected);
7557               return FAIL;
7558             }
7559
7560           if (high_range <= new_base)
7561             {
7562               inst.error = _("register range not in ascending order");
7563               return FAIL;
7564             }
7565
7566           for (new_base++; new_base <= high_range; new_base++)
7567             {
7568               if (mask & (1 << new_base))
7569                 {
7570                   inst.error = _("invalid register list");
7571                   return FAIL;
7572                 }
7573
7574               mask |= 1 << new_base;
7575               count++;
7576             }
7577         }
7578     }
7579   while (skip_past_comma (str) != FAIL);
7580
7581   (*str)++;
7582
7583   /* Sanity check -- should have raised a parse error above.  */
7584   if (count == 0 || count > max_regs)
7585     abort ();
7586
7587   *pbase = base_reg;
7588
7589   /* Final test -- the registers must be consecutive.  */
7590   mask >>= base_reg;
7591   for (i = 0; i < count; i++)
7592     {
7593       if ((mask & (1u << i)) == 0)
7594         {
7595           inst.error = _("non-contiguous register range");
7596           return FAIL;
7597         }
7598     }
7599
7600   return count;
7601 }
7602
7603 static void
7604 do_vfp_reg2_from_sp2 (char * str)
7605 {
7606   int reg;
7607
7608   skip_whitespace (str);
7609
7610   if (reg_required_here (&str, 12) == FAIL
7611       || skip_past_comma (&str) == FAIL
7612       || reg_required_here (&str, 16) == FAIL
7613       || skip_past_comma (&str) == FAIL)
7614     {
7615       if (! inst.error)
7616         inst.error = BAD_ARGS;
7617       return;
7618     }
7619
7620   /* We require exactly two consecutive SP registers.  */
7621   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7622     {
7623       if (! inst.error)
7624         inst.error = _("only two consecutive VFP SP registers allowed here");
7625     }
7626   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7627
7628   end_of_line (str);
7629 }
7630
7631 static void
7632 do_vfp_sp_from_reg (char * str)
7633 {
7634   skip_whitespace (str);
7635
7636   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7637     return;
7638
7639   if (skip_past_comma (&str) == FAIL
7640       || reg_required_here (&str, 12) == FAIL)
7641     {
7642       if (! inst.error)
7643         inst.error = BAD_ARGS;
7644       return;
7645     }
7646
7647   end_of_line (str);
7648 }
7649
7650 static void
7651 do_vfp_sp2_from_reg2 (char * str)
7652 {
7653   int reg;
7654
7655   skip_whitespace (str);
7656
7657   /* We require exactly two consecutive SP registers.  */
7658   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7659     {
7660       if (! inst.error)
7661         inst.error = _("only two consecutive VFP SP registers allowed here");
7662     }
7663   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7664
7665   if (skip_past_comma (&str) == FAIL
7666       || reg_required_here (&str, 12) == FAIL
7667       || skip_past_comma (&str) == FAIL
7668       || reg_required_here (&str, 16) == FAIL)
7669     {
7670       if (! inst.error)
7671         inst.error = BAD_ARGS;
7672       return;
7673     }
7674
7675   end_of_line (str);
7676 }
7677
7678 static void
7679 do_vfp_reg_from_dp (char * str)
7680 {
7681   skip_whitespace (str);
7682
7683   if (reg_required_here (&str, 12) == FAIL)
7684     return;
7685
7686   if (skip_past_comma (&str) == FAIL
7687       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7688     {
7689       if (! inst.error)
7690         inst.error = BAD_ARGS;
7691       return;
7692     }
7693
7694   end_of_line (str);
7695 }
7696
7697 static void
7698 do_vfp_reg2_from_dp (char * str)
7699 {
7700   skip_whitespace (str);
7701
7702   if (reg_required_here (&str, 12) == FAIL)
7703     return;
7704
7705   if (skip_past_comma (&str) == FAIL
7706       || reg_required_here (&str, 16) == FAIL
7707       || skip_past_comma (&str) == FAIL
7708       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7709     {
7710       if (! inst.error)
7711         inst.error = BAD_ARGS;
7712       return;
7713     }
7714
7715   end_of_line (str);
7716 }
7717
7718 static void
7719 do_vfp_dp_from_reg (char * str)
7720 {
7721   skip_whitespace (str);
7722
7723   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7724     return;
7725
7726   if (skip_past_comma (&str) == FAIL
7727       || reg_required_here (&str, 12) == FAIL)
7728     {
7729       if (! inst.error)
7730         inst.error = BAD_ARGS;
7731       return;
7732     }
7733
7734   end_of_line (str);
7735 }
7736
7737 static void
7738 do_vfp_dp_from_reg2 (char * str)
7739 {
7740   skip_whitespace (str);
7741
7742   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7743     return;
7744
7745   if (skip_past_comma (&str) == FAIL
7746       || reg_required_here (&str, 12) == FAIL
7747       || skip_past_comma (&str) == FAIL
7748       || reg_required_here (&str, 16) == FAIL)
7749     {
7750       if (! inst.error)
7751         inst.error = BAD_ARGS;
7752       return;
7753     }
7754
7755   end_of_line (str);
7756 }
7757
7758 static const struct vfp_reg *
7759 vfp_psr_parse (char ** str)
7760 {
7761   char *start = *str;
7762   char  c;
7763   char *p;
7764   const struct vfp_reg *vreg;
7765
7766   p = start;
7767
7768   /* Find the end of the current token.  */
7769   do
7770     {
7771       c = *p++;
7772     }
7773   while (ISALPHA (c));
7774
7775   /* Mark it.  */
7776   *--p = 0;
7777
7778   for (vreg = vfp_regs + 0;
7779        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
7780        vreg++)
7781     {
7782       if (streq (start, vreg->name))
7783         {
7784           *p = c;
7785           *str = p;
7786           return vreg;
7787         }
7788     }
7789
7790   *p = c;
7791   return NULL;
7792 }
7793
7794 static int
7795 vfp_psr_required_here (char ** str)
7796 {
7797   char *start = *str;
7798   const struct vfp_reg *vreg;
7799
7800   vreg = vfp_psr_parse (str);
7801
7802   if (vreg)
7803     {
7804       inst.instruction |= vreg->regno;
7805       return SUCCESS;
7806     }
7807
7808   inst.error = _("VFP system register expected");
7809
7810   *str = start;
7811   return FAIL;
7812 }
7813
7814 static void
7815 do_vfp_reg_from_ctrl (char * str)
7816 {
7817   skip_whitespace (str);
7818
7819   if (reg_required_here (&str, 12) == FAIL)
7820     return;
7821
7822   if (skip_past_comma (&str) == FAIL
7823       || vfp_psr_required_here (&str) == FAIL)
7824     {
7825       if (! inst.error)
7826         inst.error = BAD_ARGS;
7827       return;
7828     }
7829
7830   end_of_line (str);
7831 }
7832
7833 static void
7834 do_vfp_ctrl_from_reg (char * str)
7835 {
7836   skip_whitespace (str);
7837
7838   if (vfp_psr_required_here (&str) == FAIL)
7839     return;
7840
7841   if (skip_past_comma (&str) == FAIL
7842       || reg_required_here (&str, 12) == FAIL)
7843     {
7844       if (! inst.error)
7845         inst.error = BAD_ARGS;
7846       return;
7847     }
7848
7849   end_of_line (str);
7850 }
7851
7852 static void
7853 do_vfp_sp_ldst (char * str)
7854 {
7855   skip_whitespace (str);
7856
7857   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7858     {
7859       if (!inst.error)
7860         inst.error = BAD_ARGS;
7861       return;
7862     }
7863
7864   if (skip_past_comma (&str) == FAIL
7865       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7866     {
7867       if (!inst.error)
7868         inst.error = BAD_ARGS;
7869       return;
7870     }
7871
7872   end_of_line (str);
7873 }
7874
7875 static void
7876 do_vfp_dp_ldst (char * str)
7877 {
7878   skip_whitespace (str);
7879
7880   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7881     {
7882       if (!inst.error)
7883         inst.error = BAD_ARGS;
7884       return;
7885     }
7886
7887   if (skip_past_comma (&str) == FAIL
7888       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7889     {
7890       if (!inst.error)
7891         inst.error = BAD_ARGS;
7892       return;
7893     }
7894
7895   end_of_line (str);
7896 }
7897
7898
7899 static void
7900 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7901 {
7902   int count;
7903   int reg;
7904
7905   skip_whitespace (str);
7906
7907   if (reg_required_here (&str, 16) == FAIL)
7908     return;
7909
7910   skip_whitespace (str);
7911
7912   if (*str == '!')
7913     {
7914       inst.instruction |= WRITE_BACK;
7915       str++;
7916     }
7917   else if (ldstm_type != VFP_LDSTMIA)
7918     {
7919       inst.error = _("this addressing mode requires base-register writeback");
7920       return;
7921     }
7922
7923   if (skip_past_comma (&str) == FAIL
7924       || (count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
7925     {
7926       if (!inst.error)
7927         inst.error = BAD_ARGS;
7928       return;
7929     }
7930   vfp_sp_encode_reg (reg, VFP_REG_Sd);
7931
7932   inst.instruction |= count;
7933   end_of_line (str);
7934 }
7935
7936 static void
7937 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7938 {
7939   int count;
7940   int reg;
7941
7942   skip_whitespace (str);
7943
7944   if (reg_required_here (&str, 16) == FAIL)
7945     return;
7946
7947   skip_whitespace (str);
7948
7949   if (*str == '!')
7950     {
7951       inst.instruction |= WRITE_BACK;
7952       str++;
7953     }
7954   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7955     {
7956       inst.error = _("this addressing mode requires base-register writeback");
7957       return;
7958     }
7959
7960   if (skip_past_comma (&str) == FAIL
7961       || (count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
7962     {
7963       if (!inst.error)
7964         inst.error = BAD_ARGS;
7965       return;
7966     }
7967
7968   count <<= 1;
7969   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7970     count += 1;
7971
7972   inst.instruction |= (reg << 12) | count;
7973   end_of_line (str);
7974 }
7975
7976 static void
7977 do_vfp_sp_ldstmia (char * str)
7978 {
7979   vfp_sp_ldstm (str, VFP_LDSTMIA);
7980 }
7981
7982 static void
7983 do_vfp_sp_ldstmdb (char * str)
7984 {
7985   vfp_sp_ldstm (str, VFP_LDSTMDB);
7986 }
7987
7988 static void
7989 do_vfp_dp_ldstmia (char * str)
7990 {
7991   vfp_dp_ldstm (str, VFP_LDSTMIA);
7992 }
7993
7994 static void
7995 do_vfp_dp_ldstmdb (char * str)
7996 {
7997   vfp_dp_ldstm (str, VFP_LDSTMDB);
7998 }
7999
8000 static void
8001 do_vfp_xp_ldstmia (char *str)
8002 {
8003   vfp_dp_ldstm (str, VFP_LDSTMIAX);
8004 }
8005
8006 static void
8007 do_vfp_xp_ldstmdb (char * str)
8008 {
8009   vfp_dp_ldstm (str, VFP_LDSTMDBX);
8010 }
8011
8012 static void
8013 do_vfp_sp_compare_z (char * str)
8014 {
8015   skip_whitespace (str);
8016
8017   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8018     {
8019       if (!inst.error)
8020         inst.error = BAD_ARGS;
8021       return;
8022     }
8023
8024   end_of_line (str);
8025 }
8026
8027 static void
8028 do_vfp_dp_compare_z (char * str)
8029 {
8030   skip_whitespace (str);
8031
8032   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8033     {
8034       if (!inst.error)
8035         inst.error = BAD_ARGS;
8036       return;
8037     }
8038
8039   end_of_line (str);
8040 }
8041
8042 static void
8043 do_vfp_dp_sp_cvt (char * str)
8044 {
8045   skip_whitespace (str);
8046
8047   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8048     return;
8049
8050   if (skip_past_comma (&str) == FAIL
8051       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8052     {
8053       if (! inst.error)
8054         inst.error = BAD_ARGS;
8055       return;
8056     }
8057
8058   end_of_line (str);
8059 }
8060
8061 static void
8062 do_vfp_sp_dp_cvt (char * str)
8063 {
8064   skip_whitespace (str);
8065
8066   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8067     return;
8068
8069   if (skip_past_comma (&str) == FAIL
8070       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8071     {
8072       if (! inst.error)
8073         inst.error = BAD_ARGS;
8074       return;
8075     }
8076
8077   end_of_line (str);
8078 }
8079
8080 /* Thumb specific routines.  */
8081
8082 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8083    was SUB.  */
8084
8085 static void
8086 thumb_add_sub (char * str, int subtract)
8087 {
8088   int Rd, Rs, Rn = FAIL;
8089
8090   skip_whitespace (str);
8091
8092   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8093       || skip_past_comma (&str) == FAIL)
8094     {
8095       if (! inst.error)
8096         inst.error = BAD_ARGS;
8097       return;
8098     }
8099
8100   if (is_immediate_prefix (*str))
8101     {
8102       Rs = Rd;
8103       str++;
8104       if (my_get_expression (&inst.reloc.exp, &str))
8105         return;
8106     }
8107   else
8108     {
8109       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8110         return;
8111
8112       if (skip_past_comma (&str) == FAIL)
8113         {
8114           /* Two operand format, shuffle the registers
8115              and pretend there are 3.  */
8116           Rn = Rs;
8117           Rs = Rd;
8118         }
8119       else if (is_immediate_prefix (*str))
8120         {
8121           str++;
8122           if (my_get_expression (&inst.reloc.exp, &str))
8123             return;
8124         }
8125       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8126         return;
8127     }
8128
8129   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8130      for the latter case, EXPR contains the immediate that was found.  */
8131   if (Rn != FAIL)
8132     {
8133       /* All register format.  */
8134       if (Rd > 7 || Rs > 7 || Rn > 7)
8135         {
8136           if (Rs != Rd)
8137             {
8138               inst.error = _("dest and source1 must be the same register");
8139               return;
8140             }
8141
8142           /* Can't do this for SUB.  */
8143           if (subtract)
8144             {
8145               inst.error = _("subtract valid only on lo regs");
8146               return;
8147             }
8148
8149           inst.instruction = (T_OPCODE_ADD_HI
8150                               | (Rd > 7 ? THUMB_H1 : 0)
8151                               | (Rn > 7 ? THUMB_H2 : 0));
8152           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8153         }
8154       else
8155         {
8156           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8157           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8158         }
8159     }
8160   else
8161     {
8162       /* Immediate expression, now things start to get nasty.  */
8163
8164       /* First deal with HI regs, only very restricted cases allowed:
8165          Adjusting SP, and using PC or SP to get an address.  */
8166       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8167           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8168         {
8169           inst.error = _("invalid Hi register with immediate");
8170           return;
8171         }
8172
8173       if (inst.reloc.exp.X_op != O_constant)
8174         {
8175           /* Value isn't known yet, all we can do is store all the fragments
8176              we know about in the instruction and let the reloc hacking
8177              work it all out.  */
8178           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8179           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8180         }
8181       else
8182         {
8183           int offset = inst.reloc.exp.X_add_number;
8184
8185           if (subtract)
8186             offset = - offset;
8187
8188           if (offset < 0)
8189             {
8190               offset = - offset;
8191               subtract = 1;
8192
8193               /* Quick check, in case offset is MIN_INT.  */
8194               if (offset < 0)
8195                 {
8196                   inst.error = _("immediate value out of range");
8197                   return;
8198                 }
8199             }
8200           /* Note - you cannot convert a subtract of 0 into an
8201              add of 0 because the carry flag is set differently.  */
8202           else if (offset > 0)
8203             subtract = 0;
8204
8205           if (Rd == REG_SP)
8206             {
8207               if (offset & ~0x1fc)
8208                 {
8209                   inst.error = _("invalid immediate value for stack adjust");
8210                   return;
8211                 }
8212               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8213               inst.instruction |= offset >> 2;
8214             }
8215           else if (Rs == REG_PC || Rs == REG_SP)
8216             {
8217               if (subtract
8218                   || (offset & ~0x3fc))
8219                 {
8220                   inst.error = _("invalid immediate for address calculation");
8221                   return;
8222                 }
8223               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8224                                   : T_OPCODE_ADD_SP);
8225               inst.instruction |= (Rd << 8) | (offset >> 2);
8226             }
8227           else if (Rs == Rd)
8228             {
8229               if (offset & ~0xff)
8230                 {
8231                   inst.error = _("immediate value out of range");
8232                   return;
8233                 }
8234               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8235               inst.instruction |= (Rd << 8) | offset;
8236             }
8237           else
8238             {
8239               if (offset & ~0x7)
8240                 {
8241                   inst.error = _("immediate value out of range");
8242                   return;
8243                 }
8244               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8245               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8246             }
8247         }
8248     }
8249
8250   end_of_line (str);
8251 }
8252
8253 static void
8254 thumb_shift (char * str, int shift)
8255 {
8256   int Rd, Rs, Rn = FAIL;
8257
8258   skip_whitespace (str);
8259
8260   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8261       || skip_past_comma (&str) == FAIL)
8262     {
8263       if (! inst.error)
8264         inst.error = BAD_ARGS;
8265       return;
8266     }
8267
8268   if (is_immediate_prefix (*str))
8269     {
8270       /* Two operand immediate format, set Rs to Rd.  */
8271       Rs = Rd;
8272       str ++;
8273       if (my_get_expression (&inst.reloc.exp, &str))
8274         return;
8275     }
8276   else
8277     {
8278       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8279         return;
8280
8281       if (skip_past_comma (&str) == FAIL)
8282         {
8283           /* Two operand format, shuffle the registers
8284              and pretend there are 3.  */
8285           Rn = Rs;
8286           Rs = Rd;
8287         }
8288       else if (is_immediate_prefix (*str))
8289         {
8290           str++;
8291           if (my_get_expression (&inst.reloc.exp, &str))
8292             return;
8293         }
8294       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8295         return;
8296     }
8297
8298   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8299      for the latter case, EXPR contains the immediate that was found.  */
8300
8301   if (Rn != FAIL)
8302     {
8303       if (Rs != Rd)
8304         {
8305           inst.error = _("source1 and dest must be same register");
8306           return;
8307         }
8308
8309       switch (shift)
8310         {
8311         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8312         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8313         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8314         }
8315
8316       inst.instruction |= Rd | (Rn << 3);
8317     }
8318   else
8319     {
8320       switch (shift)
8321         {
8322         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8323         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8324         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8325         }
8326
8327       if (inst.reloc.exp.X_op != O_constant)
8328         {
8329           /* Value isn't known yet, create a dummy reloc and let reloc
8330              hacking fix it up.  */
8331           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8332         }
8333       else
8334         {
8335           unsigned shift_value = inst.reloc.exp.X_add_number;
8336
8337           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8338             {
8339               inst.error = _("invalid immediate for shift");
8340               return;
8341             }
8342
8343           /* Shifts of zero are handled by converting to LSL.  */
8344           if (shift_value == 0)
8345             inst.instruction = T_OPCODE_LSL_I;
8346
8347           /* Shifts of 32 are encoded as a shift of zero.  */
8348           if (shift_value == 32)
8349             shift_value = 0;
8350
8351           inst.instruction |= shift_value << 6;
8352         }
8353
8354       inst.instruction |= Rd | (Rs << 3);
8355     }
8356
8357   end_of_line (str);
8358 }
8359
8360 static void
8361 thumb_load_store (char * str, int load_store, int size)
8362 {
8363   int Rd, Rb, Ro = FAIL;
8364
8365   skip_whitespace (str);
8366
8367   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8368       || skip_past_comma (&str) == FAIL)
8369     {
8370       if (! inst.error)
8371         inst.error = BAD_ARGS;
8372       return;
8373     }
8374
8375   if (*str == '[')
8376     {
8377       str++;
8378       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8379         return;
8380
8381       if (skip_past_comma (&str) != FAIL)
8382         {
8383           if (is_immediate_prefix (*str))
8384             {
8385               str++;
8386               if (my_get_expression (&inst.reloc.exp, &str))
8387                 return;
8388             }
8389           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8390             return;
8391         }
8392       else
8393         {
8394           inst.reloc.exp.X_op = O_constant;
8395           inst.reloc.exp.X_add_number = 0;
8396         }
8397
8398       if (*str != ']')
8399         {
8400           inst.error = _("expected ']'");
8401           return;
8402         }
8403       str++;
8404     }
8405   else if (*str == '=')
8406     {
8407       if (load_store != THUMB_LOAD)
8408         {
8409           inst.error = _("invalid pseudo operation");
8410           return;
8411         }
8412
8413       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
8414       str++;
8415
8416       skip_whitespace (str);
8417
8418       if (my_get_expression (& inst.reloc.exp, & str))
8419         return;
8420
8421       end_of_line (str);
8422
8423       if (   inst.reloc.exp.X_op != O_constant
8424           && inst.reloc.exp.X_op != O_symbol)
8425         {
8426           inst.error = "Constant expression expected";
8427           return;
8428         }
8429
8430       if (inst.reloc.exp.X_op == O_constant
8431           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8432         {
8433           /* This can be done with a mov instruction.  */
8434
8435           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
8436           inst.instruction |= inst.reloc.exp.X_add_number;
8437           return;
8438         }
8439
8440       /* Insert into literal pool.  */
8441       if (add_to_lit_pool () == FAIL)
8442         {
8443           if (!inst.error)
8444             inst.error = "literal pool insertion failed";
8445           return;
8446         }
8447
8448       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
8449       inst.reloc.pc_rel = 1;
8450       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
8451       /* Adjust ARM pipeline offset to Thumb.  */
8452       inst.reloc.exp.X_add_number += 4;
8453
8454       return;
8455     }
8456   else
8457     {
8458       if (my_get_expression (&inst.reloc.exp, &str))
8459         return;
8460
8461       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8462       inst.reloc.pc_rel = 1;
8463       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
8464       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8465       end_of_line (str);
8466       return;
8467     }
8468
8469   if (Rb == REG_PC || Rb == REG_SP)
8470     {
8471       if (size != THUMB_WORD)
8472         {
8473           inst.error = _("byte or halfword not valid for base register");
8474           return;
8475         }
8476       else if (Rb == REG_PC && load_store != THUMB_LOAD)
8477         {
8478           inst.error = _("r15 based store not allowed");
8479           return;
8480         }
8481       else if (Ro != FAIL)
8482         {
8483           inst.error = _("invalid base register for register offset");
8484           return;
8485         }
8486
8487       if (Rb == REG_PC)
8488         inst.instruction = T_OPCODE_LDR_PC;
8489       else if (load_store == THUMB_LOAD)
8490         inst.instruction = T_OPCODE_LDR_SP;
8491       else
8492         inst.instruction = T_OPCODE_STR_SP;
8493
8494       inst.instruction |= Rd << 8;
8495       if (inst.reloc.exp.X_op == O_constant)
8496         {
8497           unsigned offset = inst.reloc.exp.X_add_number;
8498
8499           if (offset & ~0x3fc)
8500             {
8501               inst.error = _("invalid offset");
8502               return;
8503             }
8504
8505           inst.instruction |= offset >> 2;
8506         }
8507       else
8508         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8509     }
8510   else if (Rb > 7)
8511     {
8512       inst.error = _("invalid base register in load/store");
8513       return;
8514     }
8515   else if (Ro == FAIL)
8516     {
8517       /* Immediate offset.  */
8518       if (size == THUMB_WORD)
8519         inst.instruction = (load_store == THUMB_LOAD
8520                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8521       else if (size == THUMB_HALFWORD)
8522         inst.instruction = (load_store == THUMB_LOAD
8523                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8524       else
8525         inst.instruction = (load_store == THUMB_LOAD
8526                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8527
8528       inst.instruction |= Rd | (Rb << 3);
8529
8530       if (inst.reloc.exp.X_op == O_constant)
8531         {
8532           unsigned offset = inst.reloc.exp.X_add_number;
8533
8534           if (offset & ~(0x1f << size))
8535             {
8536               inst.error = _("invalid offset");
8537               return;
8538             }
8539           inst.instruction |= (offset >> size) << 6;
8540         }
8541       else
8542         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8543     }
8544   else
8545     {
8546       /* Register offset.  */
8547       if (size == THUMB_WORD)
8548         inst.instruction = (load_store == THUMB_LOAD
8549                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8550       else if (size == THUMB_HALFWORD)
8551         inst.instruction = (load_store == THUMB_LOAD
8552                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8553       else
8554         inst.instruction = (load_store == THUMB_LOAD
8555                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8556
8557       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8558     }
8559
8560   end_of_line (str);
8561 }
8562
8563 /* A register must be given at this point.
8564
8565    Shift is the place to put it in inst.instruction.
8566
8567    Restores input start point on err.
8568    Returns the reg#, or FAIL.  */
8569
8570 static int
8571 mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
8572 {
8573   int   reg;
8574   char *start = *str;
8575
8576   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8577     {
8578       if (shift >= 0)
8579         inst.instruction |= reg << shift;
8580
8581       return reg;
8582     }
8583
8584   /* Restore the start point.  */
8585   *str = start;
8586
8587   /* Try generic coprocessor name if applicable.  */
8588   if (regtype == REG_TYPE_MVF ||
8589       regtype == REG_TYPE_MVD ||
8590       regtype == REG_TYPE_MVFX ||
8591       regtype == REG_TYPE_MVDX)
8592     {
8593       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
8594         {
8595           if (shift >= 0)
8596             inst.instruction |= reg << shift;
8597
8598           return reg;
8599         }
8600
8601       /* Restore the start point.  */
8602       *str = start;
8603     }
8604
8605   /* In the few cases where we might be able to accept something else
8606      this error can be overridden.  */
8607   inst.error = _(all_reg_maps[regtype].expected);
8608
8609   return FAIL;
8610 }
8611
8612 /* Cirrus Maverick Instructions.  */
8613
8614 /* Isnsn like "foo X,Y".  */
8615
8616 static void
8617 do_mav_binops (char * str,
8618                int mode,
8619                enum arm_reg_type reg0,
8620                enum arm_reg_type reg1)
8621 {
8622   int shift0, shift1;
8623
8624   shift0 = mode & 0xff;
8625   shift1 = (mode >> 8) & 0xff;
8626
8627   skip_whitespace (str);
8628
8629   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8630       || skip_past_comma (&str) == FAIL
8631       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8632     {
8633       if (!inst.error)
8634         inst.error = BAD_ARGS;
8635     }
8636   else
8637     end_of_line (str);
8638 }
8639
8640 /* Isnsn like "foo X,Y,Z".  */
8641
8642 static void
8643 do_mav_triple (char * str,
8644                int mode,
8645                enum arm_reg_type reg0,
8646                enum arm_reg_type reg1,
8647                enum arm_reg_type reg2)
8648 {
8649   int shift0, shift1, shift2;
8650
8651   shift0 = mode & 0xff;
8652   shift1 = (mode >> 8) & 0xff;
8653   shift2 = (mode >> 16) & 0xff;
8654
8655   skip_whitespace (str);
8656
8657   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8658       || skip_past_comma (&str) == FAIL
8659       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8660       || skip_past_comma (&str) == FAIL
8661       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8662     {
8663       if (!inst.error)
8664         inst.error = BAD_ARGS;
8665     }
8666   else
8667     end_of_line (str);
8668 }
8669
8670 /* Wrapper functions.  */
8671
8672 static void
8673 do_mav_binops_1a (char * str)
8674 {
8675   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8676 }
8677
8678 static void
8679 do_mav_binops_1b (char * str)
8680 {
8681   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
8682 }
8683
8684 static void
8685 do_mav_binops_1c (char * str)
8686 {
8687   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8688 }
8689
8690 static void
8691 do_mav_binops_1d (char * str)
8692 {
8693   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8694 }
8695
8696 static void
8697 do_mav_binops_1e (char * str)
8698 {
8699   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8700 }
8701
8702 static void
8703 do_mav_binops_1f (char * str)
8704 {
8705   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8706 }
8707
8708 static void
8709 do_mav_binops_1g (char * str)
8710 {
8711   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8712 }
8713
8714 static void
8715 do_mav_binops_1h (char * str)
8716 {
8717   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8718 }
8719
8720 static void
8721 do_mav_binops_1i (char * str)
8722 {
8723   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8724 }
8725
8726 static void
8727 do_mav_binops_1j (char * str)
8728 {
8729   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8730 }
8731
8732 static void
8733 do_mav_binops_1k (char * str)
8734 {
8735   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8736 }
8737
8738 static void
8739 do_mav_binops_1l (char * str)
8740 {
8741   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8742 }
8743
8744 static void
8745 do_mav_binops_1m (char * str)
8746 {
8747   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8748 }
8749
8750 static void
8751 do_mav_binops_1n (char * str)
8752 {
8753   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8754 }
8755
8756 static void
8757 do_mav_binops_1o (char * str)
8758 {
8759   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8760 }
8761
8762 static void
8763 do_mav_binops_2a (char * str)
8764 {
8765   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8766 }
8767
8768 static void
8769 do_mav_binops_2b (char * str)
8770 {
8771   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8772 }
8773
8774 static void
8775 do_mav_binops_2c (char * str)
8776 {
8777   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8778 }
8779
8780 static void
8781 do_mav_binops_3a (char * str)
8782 {
8783   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8784 }
8785
8786 static void
8787 do_mav_binops_3b (char * str)
8788 {
8789   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8790 }
8791
8792 static void
8793 do_mav_binops_3c (char * str)
8794 {
8795   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8796 }
8797
8798 static void
8799 do_mav_binops_3d (char * str)
8800 {
8801   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8802 }
8803
8804 static void
8805 do_mav_triple_4a (char * str)
8806 {
8807   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8808 }
8809
8810 static void
8811 do_mav_triple_4b (char * str)
8812 {
8813   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8814 }
8815
8816 static void
8817 do_mav_triple_5a (char * str)
8818 {
8819   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8820 }
8821
8822 static void
8823 do_mav_triple_5b (char * str)
8824 {
8825   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8826 }
8827
8828 static void
8829 do_mav_triple_5c (char * str)
8830 {
8831   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8832 }
8833
8834 static void
8835 do_mav_triple_5d (char * str)
8836 {
8837   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8838 }
8839
8840 static void
8841 do_mav_triple_5e (char * str)
8842 {
8843   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8844 }
8845
8846 static void
8847 do_mav_triple_5f (char * str)
8848 {
8849   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8850 }
8851
8852 static void
8853 do_mav_triple_5g (char * str)
8854 {
8855   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8856 }
8857
8858 static void
8859 do_mav_triple_5h (char * str)
8860 {
8861   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8862 }
8863
8864 /* Isnsn like "foo W,X,Y,Z".
8865     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
8866
8867 static void
8868 do_mav_quad (char * str,
8869              int mode,
8870              enum arm_reg_type reg0,
8871              enum arm_reg_type reg1,
8872              enum arm_reg_type reg2,
8873              enum arm_reg_type reg3)
8874 {
8875   int shift0, shift1, shift2, shift3;
8876
8877   shift0= mode & 0xff;
8878   shift1 = (mode >> 8) & 0xff;
8879   shift2 = (mode >> 16) & 0xff;
8880   shift3 = (mode >> 24) & 0xff;
8881
8882   skip_whitespace (str);
8883
8884   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8885       || skip_past_comma (&str) == FAIL
8886       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8887       || skip_past_comma (&str) == FAIL
8888       || mav_reg_required_here (&str, shift2, reg2) == FAIL
8889       || skip_past_comma (&str) == FAIL
8890       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
8891     {
8892       if (!inst.error)
8893         inst.error = BAD_ARGS;
8894     }
8895   else
8896     end_of_line (str);
8897 }
8898
8899 static void
8900 do_mav_quad_6a (char * str)
8901 {
8902   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8903                REG_TYPE_MVFX);
8904 }
8905
8906 static void
8907 do_mav_quad_6b (char * str)
8908 {
8909   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8910                REG_TYPE_MVFX);
8911 }
8912
8913 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
8914 static void
8915 do_mav_dspsc_1 (char * str)
8916 {
8917   skip_whitespace (str);
8918
8919   /* cfmvsc32.  */
8920   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8921       || skip_past_comma (&str) == FAIL
8922       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
8923     {
8924       if (!inst.error)
8925         inst.error = BAD_ARGS;
8926
8927       return;
8928     }
8929
8930   end_of_line (str);
8931 }
8932
8933 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
8934 static void
8935 do_mav_dspsc_2 (char * str)
8936 {
8937   skip_whitespace (str);
8938
8939   /* cfmv32sc.  */
8940   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
8941       || skip_past_comma (&str) == FAIL
8942       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8943     {
8944       if (!inst.error)
8945         inst.error = BAD_ARGS;
8946
8947       return;
8948     }
8949
8950   end_of_line (str);
8951 }
8952
8953 /* Maverick shift immediate instructions.
8954    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8955    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
8956
8957 static void
8958 do_mav_shift (char * str,
8959               enum arm_reg_type reg0,
8960               enum arm_reg_type reg1)
8961 {
8962   int error;
8963   int imm, neg = 0;
8964
8965   skip_whitespace (str);
8966
8967   error = 0;
8968
8969   if (mav_reg_required_here (&str, 12, reg0) == FAIL
8970       || skip_past_comma (&str) == FAIL
8971       || mav_reg_required_here (&str, 16, reg1) == FAIL
8972       || skip_past_comma  (&str) == FAIL)
8973     {
8974       if (!inst.error)
8975         inst.error = BAD_ARGS;
8976       return;
8977     }
8978
8979   /* Calculate the immediate operand.
8980      The operand is a 7bit signed number.  */
8981   skip_whitespace (str);
8982
8983   if (*str == '#')
8984     ++str;
8985
8986   if (!ISDIGIT (*str) && *str != '-')
8987     {
8988       inst.error = _("expecting immediate, 7bit operand");
8989       return;
8990     }
8991
8992   if (*str == '-')
8993     {
8994       neg = 1;
8995       ++str;
8996     }
8997
8998   for (imm = 0; *str && ISDIGIT (*str); ++str)
8999     imm = imm * 10 + *str - '0';
9000
9001   if (imm > 64)
9002     {
9003       inst.error = _("immediate out of range");
9004       return;
9005     }
9006
9007   /* Make negative imm's into 7bit signed numbers.  */
9008   if (neg)
9009     {
9010       imm = -imm;
9011       imm &= 0x0000007f;
9012     }
9013
9014   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9015      Bits 5-7 of the insn should have bits 4-6 of the immediate.
9016      Bit 4 should be 0.  */
9017   imm = (imm & 0xf) | ((imm & 0x70) << 1);
9018
9019   inst.instruction |= imm;
9020   end_of_line (str);
9021 }
9022
9023 static void
9024 do_mav_shift_1 (char * str)
9025 {
9026   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9027 }
9028
9029 static void
9030 do_mav_shift_2 (char * str)
9031 {
9032   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9033 }
9034
9035 static int
9036 mav_parse_offset (char ** str, int * negative)
9037 {
9038   char * p = *str;
9039   int offset;
9040
9041   *negative = 0;
9042
9043   skip_whitespace (p);
9044
9045   if (*p == '#')
9046     ++p;
9047
9048   if (*p == '-')
9049     {
9050       *negative = 1;
9051       ++p;
9052     }
9053
9054   if (!ISDIGIT (*p))
9055     {
9056       inst.error = _("offset expected");
9057       return 0;
9058     }
9059
9060   for (offset = 0; *p && ISDIGIT (*p); ++p)
9061     offset = offset * 10 + *p - '0';
9062
9063   if (offset > 0x3fc)
9064     {
9065       inst.error = _("offset out of range");
9066       return 0;
9067     }
9068   if (offset & 0x3)
9069     {
9070       inst.error = _("offset not a multiple of 4");
9071       return 0;
9072     }
9073
9074   *str = p;
9075
9076   return *negative ? -offset : offset;
9077 }
9078
9079 /* Maverick load/store instructions.
9080   <insn><cond> CRd,[Rn,<offset>]{!}.
9081   <insn><cond> CRd,[Rn],<offset>.  */
9082
9083 static void
9084 do_mav_ldst (char * str, enum arm_reg_type reg0)
9085 {
9086   int offset, negative;
9087
9088   skip_whitespace (str);
9089
9090   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9091       || skip_past_comma (&str) == FAIL
9092       || *str++ != '['
9093       || reg_required_here (&str, 16) == FAIL)
9094     goto fail_ldst;
9095
9096   if (skip_past_comma (&str) == SUCCESS)
9097     {
9098       /* You are here: "<offset>]{!}".  */
9099       inst.instruction |= PRE_INDEX;
9100
9101       offset = mav_parse_offset (&str, &negative);
9102
9103       if (inst.error)
9104         return;
9105
9106       if (*str++ != ']')
9107         {
9108           inst.error = _("missing ]");
9109           return;
9110         }
9111
9112       if (*str == '!')
9113         {
9114           inst.instruction |= WRITE_BACK;
9115           ++str;
9116         }
9117     }
9118   else
9119     {
9120       /* You are here: "], <offset>".  */
9121       if (*str++ != ']')
9122         {
9123           inst.error = _("missing ]");
9124           return;
9125         }
9126
9127       if (skip_past_comma (&str) == FAIL
9128           || (offset = mav_parse_offset (&str, &negative), inst.error))
9129         goto fail_ldst;
9130
9131       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
9132     }
9133
9134   if (negative)
9135     offset = -offset;
9136   else
9137     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
9138
9139   inst.instruction |= offset >> 2;
9140   end_of_line (str);
9141   return;
9142
9143 fail_ldst:
9144   if (!inst.error)
9145      inst.error = BAD_ARGS;
9146 }
9147
9148 static void
9149 do_mav_ldst_1 (char * str)
9150 {
9151   do_mav_ldst (str, REG_TYPE_MVF);
9152 }
9153
9154 static void
9155 do_mav_ldst_2 (char * str)
9156 {
9157   do_mav_ldst (str, REG_TYPE_MVD);
9158 }
9159
9160 static void
9161 do_mav_ldst_3 (char * str)
9162 {
9163   do_mav_ldst (str, REG_TYPE_MVFX);
9164 }
9165
9166 static void
9167 do_mav_ldst_4 (char * str)
9168 {
9169   do_mav_ldst (str, REG_TYPE_MVDX);
9170 }
9171
9172 static void
9173 do_t_nop (char * str)
9174 {
9175   /* Do nothing.  */
9176   end_of_line (str);
9177 }
9178
9179 /* Handle the Format 4 instructions that do not have equivalents in other
9180    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9181    BIC and MVN.  */
9182
9183 static void
9184 do_t_arit (char * str)
9185 {
9186   int Rd, Rs, Rn;
9187
9188   skip_whitespace (str);
9189
9190   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9191       || skip_past_comma (&str) == FAIL
9192       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9193     {
9194       inst.error = BAD_ARGS;
9195       return;
9196     }
9197
9198   if (skip_past_comma (&str) != FAIL)
9199     {
9200       /* Three operand format not allowed for TST, CMN, NEG and MVN.
9201          (It isn't allowed for CMP either, but that isn't handled by this
9202          function.)  */
9203       if (inst.instruction == T_OPCODE_TST
9204           || inst.instruction == T_OPCODE_CMN
9205           || inst.instruction == T_OPCODE_NEG
9206           || inst.instruction == T_OPCODE_MVN)
9207         {
9208           inst.error = BAD_ARGS;
9209           return;
9210         }
9211
9212       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9213         return;
9214
9215       if (Rs != Rd)
9216         {
9217           inst.error = _("dest and source1 must be the same register");
9218           return;
9219         }
9220       Rs = Rn;
9221     }
9222
9223   if (inst.instruction == T_OPCODE_MUL
9224       && Rs == Rd)
9225     as_tsktsk (_("Rs and Rd must be different in MUL"));
9226
9227   inst.instruction |= Rd | (Rs << 3);
9228   end_of_line (str);
9229 }
9230
9231 static void
9232 do_t_add (char * str)
9233 {
9234   thumb_add_sub (str, 0);
9235 }
9236
9237 static void
9238 do_t_asr (char * str)
9239 {
9240   thumb_shift (str, THUMB_ASR);
9241 }
9242
9243 static void
9244 do_t_branch9 (char * str)
9245 {
9246   if (my_get_expression (&inst.reloc.exp, &str))
9247     return;
9248   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9249   inst.reloc.pc_rel = 1;
9250   end_of_line (str);
9251 }
9252
9253 static void
9254 do_t_branch12 (char * str)
9255 {
9256   if (my_get_expression (&inst.reloc.exp, &str))
9257     return;
9258   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9259   inst.reloc.pc_rel = 1;
9260   end_of_line (str);
9261 }
9262
9263 /* Find the real, Thumb encoded start of a Thumb function.  */
9264
9265 static symbolS *
9266 find_real_start (symbolS * symbolP)
9267 {
9268   char *       real_start;
9269   const char * name = S_GET_NAME (symbolP);
9270   symbolS *    new_target;
9271
9272   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
9273 #define STUB_NAME ".real_start_of"
9274
9275   if (name == NULL)
9276     abort ();
9277
9278   /* Names that start with '.' are local labels, not function entry points.
9279      The compiler may generate BL instructions to these labels because it
9280      needs to perform a branch to a far away location.  */
9281   if (name[0] == '.')
9282     return symbolP;
9283
9284   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9285   sprintf (real_start, "%s%s", STUB_NAME, name);
9286
9287   new_target = symbol_find (real_start);
9288
9289   if (new_target == NULL)
9290     {
9291       as_warn ("Failed to find real start of function: %s\n", name);
9292       new_target = symbolP;
9293     }
9294
9295   free (real_start);
9296
9297   return new_target;
9298 }
9299
9300 static void
9301 do_t_branch23 (char * str)
9302 {
9303   if (my_get_expression (& inst.reloc.exp, & str))
9304     return;
9305
9306   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
9307   inst.reloc.pc_rel = 1;
9308   end_of_line (str);
9309
9310   /* If the destination of the branch is a defined symbol which does not have
9311      the THUMB_FUNC attribute, then we must be calling a function which has
9312      the (interfacearm) attribute.  We look for the Thumb entry point to that
9313      function and change the branch to refer to that function instead.  */
9314   if (   inst.reloc.exp.X_op == O_symbol
9315       && inst.reloc.exp.X_add_symbol != NULL
9316       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9317       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9318     inst.reloc.exp.X_add_symbol =
9319       find_real_start (inst.reloc.exp.X_add_symbol);
9320 }
9321
9322 static void
9323 do_t_bx (char * str)
9324 {
9325   int reg;
9326
9327   skip_whitespace (str);
9328
9329   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9330     return;
9331
9332   /* This sets THUMB_H2 from the top bit of reg.  */
9333   inst.instruction |= reg << 3;
9334
9335   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
9336      should cause the alignment to be checked once it is known.  This is
9337      because BX PC only works if the instruction is word aligned.  */
9338
9339   end_of_line (str);
9340 }
9341
9342 static void
9343 do_t_compare (char * str)
9344 {
9345   thumb_mov_compare (str, THUMB_COMPARE);
9346 }
9347
9348 static void
9349 do_t_ldmstm (char * str)
9350 {
9351   int Rb;
9352   long range;
9353
9354   skip_whitespace (str);
9355
9356   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9357     return;
9358
9359   if (*str != '!')
9360     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9361   else
9362     str++;
9363
9364   if (skip_past_comma (&str) == FAIL
9365       || (range = reg_list (&str)) == FAIL)
9366     {
9367       if (! inst.error)
9368         inst.error = BAD_ARGS;
9369       return;
9370     }
9371
9372   if (inst.reloc.type != BFD_RELOC_NONE)
9373     {
9374       /* This really doesn't seem worth it.  */
9375       inst.reloc.type = BFD_RELOC_NONE;
9376       inst.error = _("expression too complex");
9377       return;
9378     }
9379
9380   if (range & ~0xff)
9381     {
9382       inst.error = _("only lo-regs valid in load/store multiple");
9383       return;
9384     }
9385
9386   inst.instruction |= (Rb << 8) | range;
9387   end_of_line (str);
9388 }
9389
9390 static void
9391 do_t_ldr (char * str)
9392 {
9393   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9394 }
9395
9396 static void
9397 do_t_ldrb (char * str)
9398 {
9399   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9400 }
9401
9402 static void
9403 do_t_ldrh (char * str)
9404 {
9405   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9406 }
9407
9408 static void
9409 do_t_lds (char * str)
9410 {
9411   int Rd, Rb, Ro;
9412
9413   skip_whitespace (str);
9414
9415   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9416       || skip_past_comma (&str) == FAIL
9417       || *str++ != '['
9418       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9419       || skip_past_comma (&str) == FAIL
9420       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9421       || *str++ != ']')
9422     {
9423       if (! inst.error)
9424         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9425       return;
9426     }
9427
9428   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9429   end_of_line (str);
9430 }
9431
9432 static void
9433 do_t_lsl (char * str)
9434 {
9435   thumb_shift (str, THUMB_LSL);
9436 }
9437
9438 static void
9439 do_t_lsr (char * str)
9440 {
9441   thumb_shift (str, THUMB_LSR);
9442 }
9443
9444 static void
9445 do_t_mov (char * str)
9446 {
9447   thumb_mov_compare (str, THUMB_MOVE);
9448 }
9449
9450 static void
9451 do_t_push_pop (char * str)
9452 {
9453   long range;
9454
9455   skip_whitespace (str);
9456
9457   if ((range = reg_list (&str)) == FAIL)
9458     {
9459       if (! inst.error)
9460         inst.error = BAD_ARGS;
9461       return;
9462     }
9463
9464   if (inst.reloc.type != BFD_RELOC_NONE)
9465     {
9466       /* This really doesn't seem worth it.  */
9467       inst.reloc.type = BFD_RELOC_NONE;
9468       inst.error = _("expression too complex");
9469       return;
9470     }
9471
9472   if (range & ~0xff)
9473     {
9474       if ((inst.instruction == T_OPCODE_PUSH
9475            && (range & ~0xff) == 1 << REG_LR)
9476           || (inst.instruction == T_OPCODE_POP
9477               && (range & ~0xff) == 1 << REG_PC))
9478         {
9479           inst.instruction |= THUMB_PP_PC_LR;
9480           range &= 0xff;
9481         }
9482       else
9483         {
9484           inst.error = _("invalid register list to push/pop instruction");
9485           return;
9486         }
9487     }
9488
9489   inst.instruction |= range;
9490   end_of_line (str);
9491 }
9492
9493 static void
9494 do_t_str (char * str)
9495 {
9496   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9497 }
9498
9499 static void
9500 do_t_strb (char * str)
9501 {
9502   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9503 }
9504
9505 static void
9506 do_t_strh (char * str)
9507 {
9508   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9509 }
9510
9511 static void
9512 do_t_sub (char * str)
9513 {
9514   thumb_add_sub (str, 1);
9515 }
9516
9517 static void
9518 do_t_swi (char * str)
9519 {
9520   skip_whitespace (str);
9521
9522   if (my_get_expression (&inst.reloc.exp, &str))
9523     return;
9524
9525   inst.reloc.type = BFD_RELOC_ARM_SWI;
9526   end_of_line (str);
9527 }
9528
9529 static void
9530 do_t_adr (char * str)
9531 {
9532   int reg;
9533
9534   /* This is a pseudo-op of the form "adr rd, label" to be converted
9535      into a relative address of the form "add rd, pc, #label-.-4".  */
9536   skip_whitespace (str);
9537
9538   /* Store Rd in temporary location inside instruction.  */
9539   if ((reg = reg_required_here (&str, 4)) == FAIL
9540       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
9541       || skip_past_comma (&str) == FAIL
9542       || my_get_expression (&inst.reloc.exp, &str))
9543     {
9544       if (!inst.error)
9545         inst.error = BAD_ARGS;
9546       return;
9547     }
9548
9549   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9550   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
9551   inst.reloc.pc_rel = 1;
9552   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
9553
9554   end_of_line (str);
9555 }
9556
9557 static void
9558 insert_reg (const struct reg_entry * r,
9559             struct hash_control * htab)
9560 {
9561   int    len  = strlen (r->name) + 2;
9562   char * buf  = xmalloc (len);
9563   char * buf2 = xmalloc (len);
9564   int    i    = 0;
9565
9566 #ifdef REGISTER_PREFIX
9567   buf[i++] = REGISTER_PREFIX;
9568 #endif
9569
9570   strcpy (buf + i, r->name);
9571
9572   for (i = 0; buf[i]; i++)
9573     buf2[i] = TOUPPER (buf[i]);
9574
9575   buf2[i] = '\0';
9576
9577   hash_insert (htab, buf,  (PTR) r);
9578   hash_insert (htab, buf2, (PTR) r);
9579 }
9580
9581 static void
9582 build_reg_hsh (struct reg_map * map)
9583 {
9584   const struct reg_entry *r;
9585
9586   if ((map->htab = hash_new ()) == NULL)
9587     as_fatal (_("virtual memory exhausted"));
9588
9589   for (r = map->names; r->name != NULL; r++)
9590     insert_reg (r, map->htab);
9591 }
9592
9593 static void
9594 insert_reg_alias (char * str,
9595                   int regnum,
9596                   struct hash_control *htab)
9597 {
9598   const char * error;
9599   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
9600   const char * name = xmalloc (strlen (str) + 1);
9601
9602   strcpy ((char *) name, str);
9603
9604   new->name = name;
9605   new->number = regnum;
9606   new->builtin = FALSE;
9607
9608   error = hash_insert (htab, name, (PTR) new);
9609   if (error)
9610     {
9611       as_bad (_("failed to create an alias for %s, reason: %s"),
9612             str, error);
9613       free ((char *) name);
9614       free (new);
9615     }
9616 }
9617
9618 /* Look for the .req directive.  This is of the form:
9619
9620         new_register_name .req existing_register_name
9621
9622    If we find one, or if it looks sufficiently like one that we want to
9623    handle any error here, return non-zero.  Otherwise return zero.  */
9624
9625 static int
9626 create_register_alias (char * newname, char * p)
9627 {
9628   char * q;
9629   char c;
9630
9631   q = p;
9632   skip_whitespace (q);
9633
9634   c = *p;
9635   *p = '\0';
9636
9637   if (*q && !strncmp (q, ".req ", 5))
9638     {
9639       char *copy_of_str;
9640       char *r;
9641
9642 #ifndef IGNORE_OPCODE_CASE
9643       newname = original_case_string;
9644 #endif
9645       copy_of_str = newname;
9646
9647       q += 4;
9648       skip_whitespace (q);
9649
9650       for (r = q; *r != '\0'; r++)
9651         if (*r == ' ')
9652           break;
9653
9654       if (r != q)
9655         {
9656           enum arm_reg_type new_type, old_type;
9657           int old_regno;
9658           char d = *r;
9659
9660           *r = '\0';
9661           old_type = arm_reg_parse_any (q);
9662           *r = d;
9663
9664           new_type = arm_reg_parse_any (newname);
9665
9666           if (new_type == REG_TYPE_MAX)
9667             {
9668               if (old_type != REG_TYPE_MAX)
9669                 {
9670                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9671                   insert_reg_alias (newname, old_regno,
9672                                     all_reg_maps[old_type].htab);
9673                 }
9674               else
9675                 as_warn (_("register '%s' does not exist\n"), q);
9676             }
9677           else if (old_type == REG_TYPE_MAX)
9678             {
9679               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9680                        copy_of_str, q);
9681             }
9682           else
9683             {
9684               /* Do not warn about redefinitions to the same alias.  */
9685               if (new_type != old_type
9686                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9687                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9688                 as_warn (_("ignoring redefinition of register alias '%s'"),
9689                          copy_of_str);
9690
9691             }
9692         }
9693       else
9694         as_warn (_("ignoring incomplete .req pseuso op"));
9695
9696       *p = c;
9697       return 1;
9698     }
9699
9700   *p = c;
9701   return 0;
9702 }
9703
9704 static void
9705 set_constant_flonums (void)
9706 {
9707   int i;
9708
9709   for (i = 0; i < NUM_FLOAT_VALS; i++)
9710     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9711       abort ();
9712 }
9713
9714 \f
9715 static const struct asm_opcode insns[] =
9716 {
9717   /* Core ARM Instructions.  */
9718   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
9719   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
9720   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
9721   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
9722   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
9723   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
9724   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
9725   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
9726   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
9727   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
9728   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
9729   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
9730   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
9731   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
9732   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
9733   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
9734   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
9735   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
9736   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
9737   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
9738
9739   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9740   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9741   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
9742   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9743   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9744   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
9745   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9746   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9747   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
9748   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9749   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9750   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
9751
9752   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
9753   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
9754   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
9755   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
9756
9757   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
9758   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
9759   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
9760   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
9761   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
9762   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
9763   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
9764   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
9765
9766   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9767   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9768   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9769   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9770   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9771   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9772   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9773   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9774
9775   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9776   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9777   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9778   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9779   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9780   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9781   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9782   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9783
9784   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
9785 #ifdef TE_WINCE
9786   /* XXX This is the wrong place to do this.  Think multi-arch.  */
9787   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
9788   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
9789 #else
9790   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
9791   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
9792 #endif
9793
9794   /* Pseudo ops.  */
9795   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
9796   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
9797   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_nop},
9798
9799   /* ARM 2 multiplies.  */
9800   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
9801   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
9802   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
9803   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
9804
9805   /* Generic coprocessor instructions.  */
9806   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
9807   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
9808   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
9809   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
9810   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
9811   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
9812   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
9813
9814   /* ARM 3 - swp instructions.  */
9815   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
9816   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
9817
9818   /* ARM 6 Status register instructions.  */
9819   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
9820   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
9821   /* ScottB: our code uses     0xe128f000 for msr.
9822      NickC:  but this is wrong because the bits 16 through 19 are
9823              handled by the PSR_xxx defines above.  */
9824
9825   /* ARM 7M long multiplies.  */
9826   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
9827   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
9828   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
9829   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
9830   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
9831   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
9832   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
9833   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
9834
9835   /* ARM Architecture 4.  */
9836   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9837   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
9838   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
9839   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9840
9841   /* ARM Architecture 4T.  */
9842   /* Note: bx (and blx) are required on V5, even if the processor does
9843      not support Thumb.  */
9844   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
9845
9846   /*  ARM Architecture 5T.  */
9847   /* Note: blx has 2 variants, so the .value is set dynamically.
9848      Only one of the variants has conditional execution.  */
9849   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
9850   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
9851   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
9852   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
9853   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
9854   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
9855   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
9856   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
9857   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
9858   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
9859
9860   /*  ARM Architecture 5TExP.  */
9861   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
9862   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
9863   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9864   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
9865
9866   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
9867   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9868
9869   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
9870   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
9871   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
9872   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
9873
9874   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
9875   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9876   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
9877   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9878
9879   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9880   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9881
9882   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
9883   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
9884   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
9885   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
9886
9887   /*  ARM Architecture 5TE.  */
9888   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
9889   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
9890   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
9891
9892   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9893   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9894
9895   /*  ARM Architecture 5TEJ.  */
9896   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
9897
9898   /*  ARM V6.  */
9899   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
9900   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
9901   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
9902   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
9903   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
9904   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
9905   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
9906   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
9907   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
9908   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
9909   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
9910   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
9911   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
9912   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
9913   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
9914   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
9915   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
9916   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
9917   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
9918   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
9919   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
9920   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
9921   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
9922   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
9923   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
9924   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
9925   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
9926   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
9927   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
9928   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
9929   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
9930   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
9931   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
9932   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
9933   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
9934   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
9935   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
9936   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
9937   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
9938   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
9939   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
9940   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
9941   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
9942   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
9943   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
9944   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
9945   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
9946   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9947   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9948   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9949   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9950   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9951   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9952   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9953   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9954   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
9955   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
9956   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
9957   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
9958   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
9959   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
9960   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
9961   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
9962   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
9963   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
9964   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
9965   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
9966   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
9967   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
9968   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
9969   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
9970   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
9971   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
9972   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
9973   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
9974   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
9975   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
9976   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
9977   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
9978   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
9979   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
9980   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
9981   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
9982   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
9983   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
9984   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
9985   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
9986   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
9987   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
9988   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
9989   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
9990   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
9991   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
9992   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
9993   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
9994   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
9995   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
9996   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
9997   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
9998
9999   /*  ARM V6K.  */
10000   { "clrex",     0xf57ff01f, 0,  ARM_EXT_V6K,      do_empty},
10001   { "ldrexb",    0xe1d00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10002   { "ldrexd",    0xe1b00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10003   { "ldrexh",    0xe1f00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10004   { "sev",       0xe320f004, 3,  ARM_EXT_V6K,      do_empty},
10005   { "strexb",    0xe1c00f90, 6,  ARM_EXT_V6K,      do_strex},
10006   { "strexd",    0xe1a00f90, 6,  ARM_EXT_V6K,      do_strex},
10007   { "strexh",    0xe1e00f90, 6,  ARM_EXT_V6K,      do_strex},
10008   { "wfe",       0xe320f002, 3,  ARM_EXT_V6K,      do_empty},
10009   { "wfi",       0xe320f003, 3,  ARM_EXT_V6K,      do_empty},
10010   { "yield",     0xe320f001, 5,  ARM_EXT_V6K,      do_empty},
10011
10012   /*  ARM V6Z.  */
10013   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
10014
10015   /* Core FPA instruction set (V1).  */
10016   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10017   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10018   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10019   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10020
10021   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10022   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10023   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10024   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10025
10026   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10027   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10028   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10029   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10030
10031   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10032   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10033   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10034   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10035   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10036   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10037   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10038   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10039   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10040   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10041   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10042   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10043
10044   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10045   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10046   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10047   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10048   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10049   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10050   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10051   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10052   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10053   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10054   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10055   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10056
10057   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10058   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10059   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10060   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10061   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10062   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10063   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10064   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10065   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10066   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10067   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10068   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10069
10070   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10071   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10072   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10073   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10074   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10075   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10076   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10077   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10078   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10079   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10080   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10081   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10082
10083   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10084   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10085   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10086   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10087   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10088   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10089   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10090   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10091   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10092   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10093   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10094   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10095
10096   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10097   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10098   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10099   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10100   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10101   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10102   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10103   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10104   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10105   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10106   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10107   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10108
10109   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10110   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10111   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10112   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10113   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10114   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10115   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10116   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10117   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10118   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10119   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10120   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10121
10122   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10123   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10124   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10125   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10126   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10127   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10128   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10129   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10130   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10131   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10132   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10133   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10134
10135   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10136   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10137   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10138   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10139   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10140   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10141   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10142   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10143   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10144   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10145   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10146   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10147
10148   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10149   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10150   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10151   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10152   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10153   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10154   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10155   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10156   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10157   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10158   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10159   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10160
10161   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10162   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10163   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10164   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10165   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10166   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10167   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10168   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10169   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10170   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10171   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10172   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10173
10174   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10175   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10176   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10177   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10178   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10179   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10180   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10181   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10182   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10183   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10184   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10185   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10186
10187   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10188   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10189   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10190   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10191   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10192   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10193   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10194   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10195   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10196   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10197   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10198   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10199
10200   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10201   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10202   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10203   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10204   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10205   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10206   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10207   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10208   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10209   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10210   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10211   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10212
10213   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10214   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10215   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10216   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10217   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10218   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10219   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10220   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10221   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10222   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10223   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10224   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10225
10226   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10227   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10228   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10229   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10230   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10231   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10232   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10233   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10234   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10235   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10236   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10237   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10238
10239   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10240   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10241   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10242   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10243   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10244   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10245   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10246   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10247   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10248   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10249   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10250   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10251
10252   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10253   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10254   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10255   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10256   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10257   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10258   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10259   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10260   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10261   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10262   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10263   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10264
10265   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10266   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10267   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10268   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10269   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10270   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10271   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10272   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10273   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10274   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10275   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10276   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10277
10278   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10279   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10280   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10281   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10282   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10283   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10284   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10285   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10286   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10287   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10288   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10289   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10290
10291   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10292   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10293   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10294   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10295   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10296   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10297   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10298   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10299   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10300   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10301   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10302   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10303
10304   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10305   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10306   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10307   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10308   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10309   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10310   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10311   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10312   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10313   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10314   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10315   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10316
10317   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10318   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10319   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10320   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10321   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10322   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10323   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10324   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10325   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10326   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10327   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10328   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10329
10330   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10331   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10332   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10333   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10334   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10335   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10336   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10337   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10338   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10339   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10340   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10341   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10342
10343   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10344   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10345   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10346   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10347   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10348   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10349   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10350   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10351   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10352   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10353   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10354   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10355
10356   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10357   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10358   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10359   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10360   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10361   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10362   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10363   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10364   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10365   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10366   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10367   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10368
10369   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10370   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10371   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10372   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10373   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10374   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10375   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10376   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10377   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10378   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10379   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10380   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10381
10382   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10383   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10384   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10385   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10386   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10387   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10388   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10389   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10390   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10391   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10392   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10393   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10394
10395   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10396   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10397   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10398   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10399   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10400   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10401   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10402   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10403   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10404   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10405   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10406   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10407
10408   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10409   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10410   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10411   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10412   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
10413      not be an optional suffix, but part of the instruction.  To be
10414      compatible, we accept either.  */
10415   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10416   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10417
10418   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10419   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10420   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10421   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10422   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10423   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10424   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10425   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10426   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10427   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10428   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10429   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10430
10431   /* The implementation of the FIX instruction is broken on some
10432      assemblers, in that it accepts a precision specifier as well as a
10433      rounding specifier, despite the fact that this is meaningless.
10434      To be more compatible, we accept it as well, though of course it
10435      does not set any bits.  */
10436   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10437   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10438   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10439   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10440   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10441   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10442   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10443   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10444   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10445   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10446   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10447   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10448   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10449
10450   /* Instructions that were new with the real FPA, call them V2.  */
10451   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10452   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10453   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10454   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10455   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10456   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10457
10458   /* VFP V1xD (single precision).  */
10459   /* Moves and type conversions.  */
10460   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10461   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
10462   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
10463   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
10464   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10465   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10466   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10467   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10468   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10469   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10470   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
10471   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
10472
10473   /* Memory operations.  */
10474   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10475   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10476   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10477   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10478   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10479   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10480   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10481   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10482   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10483   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10484   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10485   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10486   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10487   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10488   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10489   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10490   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10491   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10492
10493   /* Monadic operations.  */
10494   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10495   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10496   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10497
10498   /* Dyadic operations.  */
10499   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10500   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10501   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10502   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10503   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10504   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10505   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10506   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10507   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10508
10509   /* Comparisons.  */
10510   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10511   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10512   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10513   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10514
10515   /* VFP V1 (Double precision).  */
10516   /* Moves and type conversions.  */
10517   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10518   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10519   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10520   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10521   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10522   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10523   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10524   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10525   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10526   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10527   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10528   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10529   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10530
10531   /* Memory operations.  */
10532   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10533   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10534   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10535   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10536   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10537   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10538   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10539   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10540   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10541   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10542
10543   /* Monadic operations.  */
10544   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10545   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10546   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10547
10548   /* Dyadic operations.  */
10549   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10550   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10551   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10552   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10553   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10554   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10555   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10556   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10557   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10558
10559   /* Comparisons.  */
10560   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10561   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10562   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10563   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10564
10565   /* VFP V2.  */
10566   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
10567   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
10568   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
10569   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
10570
10571   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
10572   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
10573   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10574   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10575   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10576   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10577   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10578   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
10579   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
10580
10581   /* Intel Wireless MMX technology instructions.  */
10582   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10583   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10584   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10585   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10586   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10587   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10588   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10589   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10590   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10591   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10592   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10593   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10594   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10595   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10596   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10597   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10598   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10599   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10600   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
10601   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
10602   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10603   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10604   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10605   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10606   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10607   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10608   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10609   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10610   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10611   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
10612   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
10613   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10614   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10615   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10616   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10617   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10618   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10619   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10620   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10621   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10622   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10623   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10624   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10625   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10626   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10627   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10628   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
10629   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10630   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10631   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10632   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10633   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10634   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10635   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10636   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10637   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10638   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10639   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10640   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10641   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10642   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10643   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10644   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10645   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10646   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10647   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10648   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10649   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10650   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10651   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10652   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10653   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10654   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10655   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10656   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10657   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10658   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10659   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10660   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10661   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10662   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10663   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10664   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10665   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10666   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10667   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10668   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10669   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10670   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
10671   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10672   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10673   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10674   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10675   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10676   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10677   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10678   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10679   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10680   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10681   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10682   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10683   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10684   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10685   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10686   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10687   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10688   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10689   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10690   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10691   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10692   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
10693   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10694   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10695   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10696   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10697   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10698   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10699   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10700   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10701   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10702   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10703   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10704   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10705   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10706   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10707   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10708   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10709   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10710   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10711   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10712   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10713   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10714   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10715   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10716   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10717   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10718   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10719   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10720   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10721   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10722   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10723   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10724   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10725   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10726   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10727   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10728   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10729   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10730   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10731   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10732   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10733   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10734   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10735   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10736   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10737   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10738   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10739   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10740   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10741   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10742   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10743   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
10744
10745   /* Cirrus Maverick instructions.  */
10746   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10747   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10748   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10749   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10750   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10751   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10752   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10753   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10754   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
10755   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
10756   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10757   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10758   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10759   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10760   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10761   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10762   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10763   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10764   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10765   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10766   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10767   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10768   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10769   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10770   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10771   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10772   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
10773   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
10774   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
10775   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
10776   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10777   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10778   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
10779   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
10780   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
10781   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
10782   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
10783   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
10784   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
10785   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
10786   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
10787   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
10788   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
10789   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
10790   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
10791   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
10792   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
10793   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
10794   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
10795   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
10796   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10797   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10798   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10799   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10800   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10801   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10802   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10803   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10804   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10805   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10806   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10807   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10808   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10809   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10810   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10811   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10812   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10813   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10814   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10815   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10816   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10817   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10818   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10819   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10820   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10821   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10822 };
10823
10824 /* Iterate over the base tables to create the instruction patterns.  */
10825
10826 static void
10827 build_arm_ops_hsh (void)
10828 {
10829   unsigned int i;
10830   unsigned int j;
10831   static struct obstack insn_obstack;
10832
10833   obstack_begin (&insn_obstack, 4000);
10834
10835   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10836     {
10837       const struct asm_opcode *insn = insns + i;
10838
10839       if (insn->cond_offset != 0)
10840         {
10841           /* Insn supports conditional execution.  Build the varaints
10842              and insert them in the hash table.  */
10843           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10844             {
10845               unsigned len = strlen (insn->template);
10846               struct asm_opcode *new;
10847               char *template;
10848
10849               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10850               /* All condition codes are two characters.  */
10851               template = obstack_alloc (&insn_obstack, len + 3);
10852
10853               strncpy (template, insn->template, insn->cond_offset);
10854               strcpy (template + insn->cond_offset, conds[j].template);
10855               if (len > insn->cond_offset)
10856                 strcpy (template + insn->cond_offset + 2,
10857                         insn->template + insn->cond_offset);
10858               new->template = template;
10859               new->cond_offset = 0;
10860               new->variant = insn->variant;
10861               new->parms = insn->parms;
10862               new->value = (insn->value & ~COND_MASK) | conds[j].value;
10863
10864               hash_insert (arm_ops_hsh, new->template, (PTR) new);
10865             }
10866         }
10867       /* Finally, insert the unconditional insn in the table directly;
10868          no need to build a copy.  */
10869       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10870     }
10871 }
10872
10873 \f
10874 static const struct thumb_opcode tinsns[] =
10875 {
10876   /* Thumb v1 (ARMv4T).  */
10877   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
10878   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
10879   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
10880   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
10881   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
10882   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
10883   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
10884   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10885   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10886   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10887   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10888   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10889   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
10890   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
10891   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
10892   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
10893   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
10894   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
10895   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
10896   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
10897   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
10898   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
10899   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
10900   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
10901   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
10902   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
10903   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
10904   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
10905   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
10906   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
10907   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
10908   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
10909   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
10910   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10911   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10912   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10913   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10914   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
10915   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
10916   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
10917   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
10918   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
10919   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
10920   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
10921   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
10922   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
10923   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
10924   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
10925   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
10926   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
10927   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
10928   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
10929   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
10930   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
10931   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
10932   /* Pseudo ops:  */
10933   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
10934   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
10935   /* Thumb v2 (ARMv5T).  */
10936   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
10937   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
10938
10939   /* ARM V6.  */
10940   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
10941   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
10942   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
10943   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
10944   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
10945   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
10946   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
10947   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
10948   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
10949   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
10950   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
10951 };
10952
10953 void
10954 md_begin (void)
10955 {
10956   unsigned mach;
10957   unsigned int i;
10958
10959   if (   (arm_ops_hsh = hash_new ()) == NULL
10960       || (arm_tops_hsh = hash_new ()) == NULL
10961       || (arm_cond_hsh = hash_new ()) == NULL
10962       || (arm_shift_hsh = hash_new ()) == NULL
10963       || (arm_psr_hsh = hash_new ()) == NULL)
10964     as_fatal (_("virtual memory exhausted"));
10965
10966   build_arm_ops_hsh ();
10967   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
10968     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
10969   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
10970     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
10971   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
10972     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
10973   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
10974     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
10975
10976   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10977     build_reg_hsh (all_reg_maps + i);
10978
10979   set_constant_flonums ();
10980
10981   /* Set the cpu variant based on the command-line options.  We prefer
10982      -mcpu= over -march= if both are set (as for GCC); and we prefer
10983      -mfpu= over any other way of setting the floating point unit.
10984      Use of legacy options with new options are faulted.  */
10985   if (legacy_cpu != -1)
10986     {
10987       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
10988         as_bad (_("use of old and new-style options to set CPU type"));
10989
10990       mcpu_cpu_opt = legacy_cpu;
10991     }
10992   else if (mcpu_cpu_opt == -1)
10993     mcpu_cpu_opt = march_cpu_opt;
10994
10995   if (legacy_fpu != -1)
10996     {
10997       if (mfpu_opt != -1)
10998         as_bad (_("use of old and new-style options to set FPU type"));
10999
11000       mfpu_opt = legacy_fpu;
11001     }
11002   else if (mfpu_opt == -1)
11003     {
11004 #if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) 
11005       /* Some environments specify a default FPU.  If they don't, infer it
11006          from the processor.  */
11007       if (mcpu_fpu_opt != -1)
11008         mfpu_opt = mcpu_fpu_opt;
11009       else
11010         mfpu_opt = march_fpu_opt;
11011 #else
11012       mfpu_opt = FPU_DEFAULT;
11013 #endif
11014     }
11015
11016   if (mfpu_opt == -1)
11017     {
11018       if (mcpu_cpu_opt == -1)
11019         mfpu_opt = FPU_DEFAULT;
11020       else if (mcpu_cpu_opt & ARM_EXT_V5)
11021         mfpu_opt = FPU_ARCH_VFP_V2;
11022       else
11023         mfpu_opt = FPU_ARCH_FPA;
11024     }
11025
11026   if (mcpu_cpu_opt == -1)
11027     mcpu_cpu_opt = CPU_DEFAULT;
11028
11029   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11030
11031   {
11032     unsigned int flags = 0;
11033
11034 #if defined OBJ_ELF
11035     flags = meabi_flags;
11036
11037     switch (meabi_flags)
11038       {
11039       case EF_ARM_EABI_UNKNOWN:
11040 #endif
11041 #if defined OBJ_COFF || defined OBJ_ELF
11042         /* Set the flags in the private structure.  */
11043         if (uses_apcs_26)      flags |= F_APCS26;
11044         if (support_interwork) flags |= F_INTERWORK;
11045         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11046         if (pic_code)          flags |= F_PIC;
11047         if ((cpu_variant & FPU_ANY) == FPU_NONE
11048              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11049           flags |= F_SOFT_FLOAT;
11050
11051         switch (mfloat_abi_opt)
11052           {
11053           case ARM_FLOAT_ABI_SOFT:
11054           case ARM_FLOAT_ABI_SOFTFP:
11055             flags |= F_SOFT_FLOAT;
11056             break;
11057
11058           case ARM_FLOAT_ABI_HARD:
11059             if (flags & F_SOFT_FLOAT)
11060               as_bad (_("hard-float conflicts with specified fpu"));
11061             break;
11062           }
11063
11064         /* Using VFP conventions (even if soft-float).  */
11065         if (cpu_variant & FPU_VFP_EXT_NONE)
11066           flags |= F_VFP_FLOAT;
11067 #endif
11068 #if defined OBJ_ELF
11069         if (cpu_variant & FPU_ARCH_MAVERICK)
11070             flags |= EF_ARM_MAVERICK_FLOAT;
11071         break;
11072
11073       case EF_ARM_EABI_VER4:
11074         /* No additional flags to set.  */
11075         break;
11076
11077       default:
11078         abort ();
11079       }
11080 #endif
11081 #if defined OBJ_COFF || defined OBJ_ELF
11082     bfd_set_private_flags (stdoutput, flags);
11083
11084     /* We have run out flags in the COFF header to encode the
11085        status of ATPCS support, so instead we create a dummy,
11086        empty, debug section called .arm.atpcs.  */
11087     if (atpcs)
11088       {
11089         asection * sec;
11090
11091         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11092
11093         if (sec != NULL)
11094           {
11095             bfd_set_section_flags
11096               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11097             bfd_set_section_size (stdoutput, sec, 0);
11098             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11099           }
11100       }
11101 #endif
11102   }
11103
11104   /* Record the CPU type as well.  */
11105   switch (cpu_variant & ARM_CPU_MASK)
11106     {
11107     case ARM_2:
11108       mach = bfd_mach_arm_2;
11109       break;
11110
11111     case ARM_3:                 /* Also ARM_250.  */
11112       mach = bfd_mach_arm_2a;
11113       break;
11114
11115     case ARM_6:                 /* Also ARM_7.  */
11116       mach = bfd_mach_arm_3;
11117       break;
11118
11119     default:
11120       mach = bfd_mach_arm_unknown;
11121       break;
11122     }
11123
11124   /* Catch special cases.  */
11125   if (cpu_variant & ARM_CEXT_IWMMXT)
11126     mach = bfd_mach_arm_iWMMXt;
11127   else if (cpu_variant & ARM_CEXT_XSCALE)
11128     mach = bfd_mach_arm_XScale;
11129   else if (cpu_variant & ARM_CEXT_MAVERICK)
11130     mach = bfd_mach_arm_ep9312;
11131   else if (cpu_variant & ARM_EXT_V5E)
11132     mach = bfd_mach_arm_5TE;
11133   else if (cpu_variant & ARM_EXT_V5)
11134     {
11135       if (cpu_variant & ARM_EXT_V4T)
11136         mach = bfd_mach_arm_5T;
11137       else
11138         mach = bfd_mach_arm_5;
11139     }
11140   else if (cpu_variant & ARM_EXT_V4)
11141     {
11142       if (cpu_variant & ARM_EXT_V4T)
11143         mach = bfd_mach_arm_4T;
11144       else
11145         mach = bfd_mach_arm_4;
11146     }
11147   else if (cpu_variant & ARM_EXT_V3M)
11148     mach = bfd_mach_arm_3M;
11149
11150   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11151 }
11152
11153 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11154    for use in the a.out file, and stores them in the array pointed to by buf.
11155    This knows about the endian-ness of the target machine and does
11156    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11157    2 (short) and 4 (long)  Floating numbers are put out as a series of
11158    LITTLENUMS (shorts, here at least).  */
11159
11160 void
11161 md_number_to_chars (char * buf, valueT val, int n)
11162 {
11163   if (target_big_endian)
11164     number_to_chars_bigendian (buf, val, n);
11165   else
11166     number_to_chars_littleendian (buf, val, n);
11167 }
11168
11169 static valueT
11170 md_chars_to_number (char * buf, int n)
11171 {
11172   valueT result = 0;
11173   unsigned char * where = (unsigned char *) buf;
11174
11175   if (target_big_endian)
11176     {
11177       while (n--)
11178         {
11179           result <<= 8;
11180           result |= (*where++ & 255);
11181         }
11182     }
11183   else
11184     {
11185       while (n--)
11186         {
11187           result <<= 8;
11188           result |= (where[n] & 255);
11189         }
11190     }
11191
11192   return result;
11193 }
11194
11195 /* Turn a string in input_line_pointer into a floating point constant
11196    of type TYPE, and store the appropriate bytes in *LITP.  The number
11197    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11198    returned, or NULL on OK.
11199
11200    Note that fp constants aren't represent in the normal way on the ARM.
11201    In big endian mode, things are as expected.  However, in little endian
11202    mode fp constants are big-endian word-wise, and little-endian byte-wise
11203    within the words.  For example, (double) 1.1 in big endian mode is
11204    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11205    the byte sequence 99 99 f1 3f 9a 99 99 99.
11206
11207    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11208
11209 char *
11210 md_atof (int type, char * litP, int * sizeP)
11211 {
11212   int prec;
11213   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11214   char *t;
11215   int i;
11216
11217   switch (type)
11218     {
11219     case 'f':
11220     case 'F':
11221     case 's':
11222     case 'S':
11223       prec = 2;
11224       break;
11225
11226     case 'd':
11227     case 'D':
11228     case 'r':
11229     case 'R':
11230       prec = 4;
11231       break;
11232
11233     case 'x':
11234     case 'X':
11235       prec = 6;
11236       break;
11237
11238     case 'p':
11239     case 'P':
11240       prec = 6;
11241       break;
11242
11243     default:
11244       *sizeP = 0;
11245       return _("bad call to MD_ATOF()");
11246     }
11247
11248   t = atof_ieee (input_line_pointer, type, words);
11249   if (t)
11250     input_line_pointer = t;
11251   *sizeP = prec * 2;
11252
11253   if (target_big_endian)
11254     {
11255       for (i = 0; i < prec; i++)
11256         {
11257           md_number_to_chars (litP, (valueT) words[i], 2);
11258           litP += 2;
11259         }
11260     }
11261   else
11262     {
11263       if (cpu_variant & FPU_ARCH_VFP)
11264         for (i = prec - 1; i >= 0; i--)
11265           {
11266             md_number_to_chars (litP, (valueT) words[i], 2);
11267             litP += 2;
11268           }
11269       else
11270         /* For a 4 byte float the order of elements in `words' is 1 0.
11271            For an 8 byte float the order is 1 0 3 2.  */
11272         for (i = 0; i < prec; i += 2)
11273           {
11274             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11275             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11276             litP += 4;
11277           }
11278     }
11279
11280   return 0;
11281 }
11282
11283 /* The knowledge of the PC's pipeline offset is built into the insns
11284    themselves.  */
11285
11286 long
11287 md_pcrel_from (fixS * fixP)
11288 {
11289   if (fixP->fx_addsy
11290       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11291       && fixP->fx_subsy == NULL)
11292     return 0;
11293
11294   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11295     {
11296       /* PC relative addressing on the Thumb is slightly odd
11297          as the bottom two bits of the PC are forced to zero
11298          for the calculation.  */
11299       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11300     }
11301
11302 #ifdef TE_WINCE
11303   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11304      so we un-adjust here to compensate for the accommodation.  */
11305   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11306 #else
11307   return fixP->fx_where + fixP->fx_frag->fr_address;
11308 #endif
11309 }
11310
11311 /* Round up a section size to the appropriate boundary.  */
11312
11313 valueT
11314 md_section_align (segT   segment ATTRIBUTE_UNUSED,
11315                   valueT size)
11316 {
11317 #ifdef OBJ_ELF
11318   return size;
11319 #else
11320   /* Round all sects to multiple of 4.  */
11321   return (size + 3) & ~3;
11322 #endif
11323 }
11324
11325 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
11326    Otherwise we have no need to default values of symbols.  */
11327
11328 symbolS *
11329 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
11330 {
11331 #ifdef OBJ_ELF
11332   if (name[0] == '_' && name[1] == 'G'
11333       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
11334     {
11335       if (!GOT_symbol)
11336         {
11337           if (symbol_find (name))
11338             as_bad ("GOT already in the symbol table");
11339
11340           GOT_symbol = symbol_new (name, undefined_section,
11341                                    (valueT) 0, & zero_address_frag);
11342         }
11343
11344       return GOT_symbol;
11345     }
11346 #endif
11347
11348   return 0;
11349 }
11350
11351 void
11352 md_apply_fix3 (fixS *   fixP,
11353                valueT * valP,
11354                segT     seg)
11355 {
11356   offsetT        value = * valP;
11357   offsetT        newval;
11358   unsigned int   newimm;
11359   unsigned long  temp;
11360   int            sign;
11361   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
11362   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
11363
11364   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
11365
11366   /* Note whether this will delete the relocation.  */
11367   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11368     fixP->fx_done = 1;
11369
11370   /* If this symbol is in a different section then we need to leave it for
11371      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
11372      so we have to undo it's effects here.  */
11373   if (fixP->fx_pcrel)
11374     {
11375       if (fixP->fx_addsy != NULL
11376           && S_IS_DEFINED (fixP->fx_addsy)
11377           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11378         value += md_pcrel_from (fixP);
11379     }
11380
11381   /* Remember value for emit_reloc.  */
11382   fixP->fx_addnumber = value;
11383
11384   switch (fixP->fx_r_type)
11385     {
11386     case BFD_RELOC_ARM_IMMEDIATE:
11387       /* We claim that this fixup has been processed here,
11388          even if in fact we generate an error because we do
11389          not have a reloc for it, so tc_gen_reloc will reject it.  */
11390       fixP->fx_done = 1;
11391
11392       if (fixP->fx_addsy
11393           && ! S_IS_DEFINED (fixP->fx_addsy))
11394         {
11395           as_bad_where (fixP->fx_file, fixP->fx_line,
11396                         _("undefined symbol %s used as an immediate value"),
11397                         S_GET_NAME (fixP->fx_addsy));
11398           break;
11399         }
11400
11401       newimm = validate_immediate (value);
11402       temp = md_chars_to_number (buf, INSN_SIZE);
11403
11404       /* If the instruction will fail, see if we can fix things up by
11405          changing the opcode.  */
11406       if (newimm == (unsigned int) FAIL
11407           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11408         {
11409           as_bad_where (fixP->fx_file, fixP->fx_line,
11410                         _("invalid constant (%lx) after fixup"),
11411                         (unsigned long) value);
11412           break;
11413         }
11414
11415       newimm |= (temp & 0xfffff000);
11416       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11417       break;
11418
11419     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11420       {
11421         unsigned int highpart = 0;
11422         unsigned int newinsn  = 0xe1a00000; /* nop.  */
11423
11424         newimm = validate_immediate (value);
11425         temp = md_chars_to_number (buf, INSN_SIZE);
11426
11427         /* If the instruction will fail, see if we can fix things up by
11428            changing the opcode.  */
11429         if (newimm == (unsigned int) FAIL
11430             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11431           {
11432             /* No ?  OK - try using two ADD instructions to generate
11433                the value.  */
11434             newimm = validate_immediate_twopart (value, & highpart);
11435
11436             /* Yes - then make sure that the second instruction is
11437                also an add.  */
11438             if (newimm != (unsigned int) FAIL)
11439               newinsn = temp;
11440             /* Still No ?  Try using a negated value.  */
11441             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11442               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11443             /* Otherwise - give up.  */
11444             else
11445               {
11446                 as_bad_where (fixP->fx_file, fixP->fx_line,
11447                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11448                               (long) value);
11449                 break;
11450               }
11451
11452             /* Replace the first operand in the 2nd instruction (which
11453                is the PC) with the destination register.  We have
11454                already added in the PC in the first instruction and we
11455                do not want to do it again.  */
11456             newinsn &= ~ 0xf0000;
11457             newinsn |= ((newinsn & 0x0f000) << 4);
11458           }
11459
11460         newimm |= (temp & 0xfffff000);
11461         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11462
11463         highpart |= (newinsn & 0xfffff000);
11464         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11465       }
11466       break;
11467
11468     case BFD_RELOC_ARM_OFFSET_IMM:
11469       sign = value >= 0;
11470
11471       if (value < 0)
11472         value = - value;
11473
11474       if (validate_offset_imm (value, 0) == FAIL)
11475         {
11476           as_bad_where (fixP->fx_file, fixP->fx_line,
11477                         _("bad immediate value for offset (%ld)"),
11478                         (long) value);
11479           break;
11480         }
11481
11482       newval = md_chars_to_number (buf, INSN_SIZE);
11483       newval &= 0xff7ff000;
11484       newval |= value | (sign ? INDEX_UP : 0);
11485       md_number_to_chars (buf, newval, INSN_SIZE);
11486       break;
11487
11488     case BFD_RELOC_ARM_OFFSET_IMM8:
11489     case BFD_RELOC_ARM_HWLITERAL:
11490       sign = value >= 0;
11491
11492       if (value < 0)
11493         value = - value;
11494
11495       if (validate_offset_imm (value, 1) == FAIL)
11496         {
11497           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11498             as_bad_where (fixP->fx_file, fixP->fx_line,
11499                           _("invalid literal constant: pool needs to be closer"));
11500           else
11501             as_bad (_("bad immediate value for half-word offset (%ld)"),
11502                     (long) value);
11503           break;
11504         }
11505
11506       newval = md_chars_to_number (buf, INSN_SIZE);
11507       newval &= 0xff7ff0f0;
11508       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11509       md_number_to_chars (buf, newval, INSN_SIZE);
11510       break;
11511
11512     case BFD_RELOC_ARM_LITERAL:
11513       sign = value >= 0;
11514
11515       if (value < 0)
11516         value = - value;
11517
11518       if (validate_offset_imm (value, 0) == FAIL)
11519         {
11520           as_bad_where (fixP->fx_file, fixP->fx_line,
11521                         _("invalid literal constant: pool needs to be closer"));
11522           break;
11523         }
11524
11525       newval = md_chars_to_number (buf, INSN_SIZE);
11526       newval &= 0xff7ff000;
11527       newval |= value | (sign ? INDEX_UP : 0);
11528       md_number_to_chars (buf, newval, INSN_SIZE);
11529       break;
11530
11531     case BFD_RELOC_ARM_SHIFT_IMM:
11532       newval = md_chars_to_number (buf, INSN_SIZE);
11533       if (((unsigned long) value) > 32
11534           || (value == 32
11535               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11536         {
11537           as_bad_where (fixP->fx_file, fixP->fx_line,
11538                         _("shift expression is too large"));
11539           break;
11540         }
11541
11542       if (value == 0)
11543         /* Shifts of zero must be done as lsl.  */
11544         newval &= ~0x60;
11545       else if (value == 32)
11546         value = 0;
11547       newval &= 0xfffff07f;
11548       newval |= (value & 0x1f) << 7;
11549       md_number_to_chars (buf, newval, INSN_SIZE);
11550       break;
11551
11552     case BFD_RELOC_ARM_SMI:
11553       if (((unsigned long) value) > 0xffff)
11554         as_bad_where (fixP->fx_file, fixP->fx_line,
11555                       _("invalid smi expression"));
11556       newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0;
11557       newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11558       md_number_to_chars (buf, newval, INSN_SIZE);
11559       break;
11560
11561     case BFD_RELOC_ARM_SWI:
11562       if (arm_data->thumb_mode)
11563         {
11564           if (((unsigned long) value) > 0xff)
11565             as_bad_where (fixP->fx_file, fixP->fx_line,
11566                           _("invalid swi expression"));
11567           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11568           newval |= value;
11569           md_number_to_chars (buf, newval, THUMB_SIZE);
11570         }
11571       else
11572         {
11573           if (((unsigned long) value) > 0x00ffffff)
11574             as_bad_where (fixP->fx_file, fixP->fx_line,
11575                           _("invalid swi expression"));
11576           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11577           newval |= value;
11578           md_number_to_chars (buf, newval, INSN_SIZE);
11579         }
11580       break;
11581
11582     case BFD_RELOC_ARM_MULTI:
11583       if (((unsigned long) value) > 0xffff)
11584         as_bad_where (fixP->fx_file, fixP->fx_line,
11585                       _("invalid expression in load/store multiple"));
11586       newval = value | md_chars_to_number (buf, INSN_SIZE);
11587       md_number_to_chars (buf, newval, INSN_SIZE);
11588       break;
11589
11590     case BFD_RELOC_ARM_PCREL_BRANCH:
11591       newval = md_chars_to_number (buf, INSN_SIZE);
11592
11593       /* Sign-extend a 24-bit number.  */
11594 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11595
11596 #ifdef OBJ_ELF
11597       value = fixP->fx_offset;
11598 #endif
11599
11600       /* We are going to store value (shifted right by two) in the
11601          instruction, in a 24 bit, signed field.  Thus we need to check
11602          that none of the top 8 bits of the shifted value (top 7 bits of
11603          the unshifted, unsigned value) are set, or that they are all set.  */
11604       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
11605           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
11606         {
11607 #ifdef OBJ_ELF
11608           /* Normally we would be stuck at this point, since we cannot store
11609              the absolute address that is the destination of the branch in the
11610              24 bits of the branch instruction.  If however, we happen to know
11611              that the destination of the branch is in the same section as the
11612              branch instruction itself, then we can compute the relocation for
11613              ourselves and not have to bother the linker with it.
11614
11615              FIXME: The test for OBJ_ELF is only here because I have not
11616              worked out how to do this for OBJ_COFF.  */
11617           if (fixP->fx_addsy != NULL
11618               && S_IS_DEFINED (fixP->fx_addsy)
11619               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
11620             {
11621               /* Get pc relative value to go into the branch.  */
11622               value = * valP;
11623
11624               /* Permit a backward branch provided that enough bits
11625                  are set.  Allow a forwards branch, provided that
11626                  enough bits are clear.  */
11627               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
11628                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
11629                 fixP->fx_done = 1;
11630             }
11631
11632           if (! fixP->fx_done)
11633 #endif
11634             as_bad_where (fixP->fx_file, fixP->fx_line,
11635                           _("GAS can't handle same-section branch dest >= 0x04000000"));
11636         }
11637
11638       value >>= 2;
11639       value += SEXT24 (newval);
11640
11641       if (    (value & ~ ((offsetT) 0xffffff)) != 0
11642           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
11643         as_bad_where (fixP->fx_file, fixP->fx_line,
11644                       _("out of range branch"));
11645
11646       if (seg->use_rela_p && !fixP->fx_done)
11647         {
11648           /* Must unshift the value before storing it in the addend.  */
11649           value <<= 2;
11650 #ifdef OBJ_ELF
11651           fixP->fx_offset = value;
11652 #endif
11653           fixP->fx_addnumber = value;
11654           newval = newval & 0xff000000;
11655         }
11656       else
11657           newval = (value & 0x00ffffff) | (newval & 0xff000000);
11658       md_number_to_chars (buf, newval, INSN_SIZE);
11659       break;
11660
11661     case BFD_RELOC_ARM_PCREL_BLX:
11662       {
11663         offsetT hbit;
11664         newval = md_chars_to_number (buf, INSN_SIZE);
11665
11666 #ifdef OBJ_ELF
11667         value = fixP->fx_offset;
11668 #endif
11669         hbit   = (value >> 1) & 1;
11670         value  = (value >> 2) & 0x00ffffff;
11671         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
11672
11673         if (seg->use_rela_p && !fixP->fx_done)
11674           {
11675             /* Must sign-extend and unshift the value before storing
11676                it in the addend.  */
11677             value = SEXT24 (value);
11678             value = (value << 2) | hbit;
11679 #ifdef OBJ_ELF
11680             fixP->fx_offset = value;
11681 #endif
11682             fixP->fx_addnumber = value;
11683             newval = newval & 0xfe000000;
11684           }
11685         else
11686           newval = value | (newval & 0xfe000000) | (hbit << 24);
11687         md_number_to_chars (buf, newval, INSN_SIZE);
11688       }
11689       break;
11690
11691     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
11692       newval = md_chars_to_number (buf, THUMB_SIZE);
11693       {
11694         addressT diff = (newval & 0xff) << 1;
11695         if (diff & 0x100)
11696           diff |= ~0xff;
11697
11698         value += diff;
11699         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
11700           as_bad_where (fixP->fx_file, fixP->fx_line,
11701                         _("branch out of range"));
11702         if (seg->use_rela_p && !fixP->fx_done)
11703           {
11704 #ifdef OBJ_ELF
11705             fixP->fx_offset = value;
11706 #endif
11707             fixP->fx_addnumber = value;
11708             newval = newval & 0xff00;
11709           }
11710         else
11711           newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
11712       }
11713       md_number_to_chars (buf, newval, THUMB_SIZE);
11714       break;
11715
11716     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
11717       newval = md_chars_to_number (buf, THUMB_SIZE);
11718       {
11719         addressT diff = (newval & 0x7ff) << 1;
11720         if (diff & 0x800)
11721           diff |= ~0x7ff;
11722
11723         value += diff;
11724         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
11725           as_bad_where (fixP->fx_file, fixP->fx_line,
11726                         _("branch out of range"));
11727         if (seg->use_rela_p && !fixP->fx_done)
11728           {
11729 #ifdef OBJ_ELF
11730             fixP->fx_offset = value;
11731 #endif
11732             fixP->fx_addnumber = value;
11733             newval = newval & 0xf800;
11734           }
11735         else
11736           newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
11737       }
11738       md_number_to_chars (buf, newval, THUMB_SIZE);
11739       break;
11740
11741     case BFD_RELOC_THUMB_PCREL_BLX:
11742     case BFD_RELOC_THUMB_PCREL_BRANCH23:
11743       {
11744         offsetT newval2;
11745         addressT diff;
11746
11747         newval  = md_chars_to_number (buf, THUMB_SIZE);
11748         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11749         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
11750         if (diff & 0x400000)
11751           diff |= ~0x3fffff;
11752 #ifdef OBJ_ELF
11753         value = fixP->fx_offset;
11754 #endif
11755         value += diff;
11756
11757         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
11758           as_bad_where (fixP->fx_file, fixP->fx_line,
11759                         _("branch with link out of range"));
11760
11761         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
11762           /* For a BLX instruction, make sure that the relocation is rounded up
11763              to a word boundary.  This follows the semantics of the instruction
11764              which specifies that bit 1 of the target address will come from bit
11765              1 of the base address.  */
11766           value = (value + 1) & ~ 1;
11767
11768         if (seg->use_rela_p && !fixP->fx_done)
11769           {
11770 #ifdef OBJ_ELF
11771             fixP->fx_offset = value;
11772 #endif
11773             fixP->fx_addnumber = value;
11774             newval = newval & 0xf800;
11775             newval2 = newval2 & 0xf800;
11776           }
11777         else
11778           {
11779             newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
11780             newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
11781           }
11782         md_number_to_chars (buf, newval, THUMB_SIZE);
11783         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11784       }
11785       break;
11786
11787     case BFD_RELOC_8:
11788       if (seg->use_rela_p && !fixP->fx_done)
11789         break;
11790       if (fixP->fx_done || fixP->fx_pcrel)
11791         md_number_to_chars (buf, value, 1);
11792 #ifdef OBJ_ELF
11793       else
11794         {
11795           value = fixP->fx_offset;
11796           md_number_to_chars (buf, value, 1);
11797         }
11798 #endif
11799       break;
11800
11801     case BFD_RELOC_16:
11802       if (seg->use_rela_p && !fixP->fx_done)
11803         break;
11804       if (fixP->fx_done || fixP->fx_pcrel)
11805         md_number_to_chars (buf, value, 2);
11806 #ifdef OBJ_ELF
11807       else
11808         {
11809           value = fixP->fx_offset;
11810           md_number_to_chars (buf, value, 2);
11811         }
11812 #endif
11813       break;
11814
11815 #ifdef OBJ_ELF
11816     case BFD_RELOC_ARM_GOT32:
11817     case BFD_RELOC_ARM_GOTOFF:
11818     case BFD_RELOC_ARM_TARGET2:
11819       if (seg->use_rela_p && !fixP->fx_done)
11820         break;
11821       md_number_to_chars (buf, 0, 4);
11822       break;
11823 #endif
11824
11825     case BFD_RELOC_RVA:
11826     case BFD_RELOC_32:
11827     case BFD_RELOC_ARM_TARGET1:
11828     case BFD_RELOC_ARM_ROSEGREL32:
11829     case BFD_RELOC_ARM_SBREL32:
11830     case BFD_RELOC_32_PCREL:
11831       if (seg->use_rela_p && !fixP->fx_done)
11832         break;
11833       if (fixP->fx_done || fixP->fx_pcrel)
11834         md_number_to_chars (buf, value, 4);
11835 #ifdef OBJ_ELF
11836       else
11837         {
11838           value = fixP->fx_offset;
11839           md_number_to_chars (buf, value, 4);
11840         }
11841 #endif
11842       break;
11843
11844 #ifdef OBJ_ELF
11845     case BFD_RELOC_ARM_PREL31:
11846       if (fixP->fx_done || fixP->fx_pcrel)
11847         {
11848           newval = md_chars_to_number (buf, 4) & 0x80000000;
11849           if ((value ^ (value >> 1)) & 0x40000000)
11850             {
11851               as_bad_where (fixP->fx_file, fixP->fx_line,
11852                             _("rel31 relocation overflow"));
11853             }
11854           newval |= value & 0x7fffffff;
11855           md_number_to_chars (buf, newval, 4);
11856         }
11857       break;
11858
11859     case BFD_RELOC_ARM_PLT32:
11860       /* It appears the instruction is fully prepared at this point.  */
11861       break;
11862 #endif
11863
11864     case BFD_RELOC_ARM_CP_OFF_IMM:
11865       sign = value >= 0;
11866       if (value < -1023 || value > 1023 || (value & 3))
11867         as_bad_where (fixP->fx_file, fixP->fx_line,
11868                       _("illegal value for co-processor offset"));
11869       if (value < 0)
11870         value = -value;
11871       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11872       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11873       md_number_to_chars (buf, newval, INSN_SIZE);
11874       break;
11875
11876     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11877       sign = value >= 0;
11878       if (value < -255 || value > 255)
11879         as_bad_where (fixP->fx_file, fixP->fx_line,
11880                       _("Illegal value for co-processor offset"));
11881       if (value < 0)
11882         value = -value;
11883       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11884       newval |= value | (sign ?  INDEX_UP : 0);
11885       md_number_to_chars (buf, newval , INSN_SIZE);
11886       break;
11887
11888     case BFD_RELOC_ARM_THUMB_OFFSET:
11889       newval = md_chars_to_number (buf, THUMB_SIZE);
11890       /* Exactly what ranges, and where the offset is inserted depends
11891          on the type of instruction, we can establish this from the
11892          top 4 bits.  */
11893       switch (newval >> 12)
11894         {
11895         case 4: /* PC load.  */
11896           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11897              forced to zero for these loads, so we will need to round
11898              up the offset if the instruction address is not word
11899              aligned (since the final address produced must be, and
11900              we can only describe word-aligned immediate offsets).  */
11901
11902           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11903             as_bad_where (fixP->fx_file, fixP->fx_line,
11904                           _("invalid offset, target not word aligned (0x%08X)"),
11905                           (unsigned int) (fixP->fx_frag->fr_address
11906                                           + fixP->fx_where + value));
11907
11908           if ((value + 2) & ~0x3fe)
11909             as_bad_where (fixP->fx_file, fixP->fx_line,
11910                           _("invalid offset, value too big (0x%08lX)"),
11911                           (long) value);
11912
11913           /* Round up, since pc will be rounded down.  */
11914           newval |= (value + 2) >> 2;
11915           break;
11916
11917         case 9: /* SP load/store.  */
11918           if (value & ~0x3fc)
11919             as_bad_where (fixP->fx_file, fixP->fx_line,
11920                           _("invalid offset, value too big (0x%08lX)"),
11921                           (long) value);
11922           newval |= value >> 2;
11923           break;
11924
11925         case 6: /* Word load/store.  */
11926           if (value & ~0x7c)
11927             as_bad_where (fixP->fx_file, fixP->fx_line,
11928                           _("invalid offset, value too big (0x%08lX)"),
11929                           (long) value);
11930           newval |= value << 4; /* 6 - 2.  */
11931           break;
11932
11933         case 7: /* Byte load/store.  */
11934           if (value & ~0x1f)
11935             as_bad_where (fixP->fx_file, fixP->fx_line,
11936                           _("invalid offset, value too big (0x%08lX)"),
11937                           (long) value);
11938           newval |= value << 6;
11939           break;
11940
11941         case 8: /* Halfword load/store.  */
11942           if (value & ~0x3e)
11943             as_bad_where (fixP->fx_file, fixP->fx_line,
11944                           _("invalid offset, value too big (0x%08lX)"),
11945                           (long) value);
11946           newval |= value << 5; /* 6 - 1.  */
11947           break;
11948
11949         default:
11950           as_bad_where (fixP->fx_file, fixP->fx_line,
11951                         "Unable to process relocation for thumb opcode: %lx",
11952                         (unsigned long) newval);
11953           break;
11954         }
11955       md_number_to_chars (buf, newval, THUMB_SIZE);
11956       break;
11957
11958     case BFD_RELOC_ARM_THUMB_ADD:
11959       /* This is a complicated relocation, since we use it for all of
11960          the following immediate relocations:
11961
11962             3bit ADD/SUB
11963             8bit ADD/SUB
11964             9bit ADD/SUB SP word-aligned
11965            10bit ADD PC/SP word-aligned
11966
11967          The type of instruction being processed is encoded in the
11968          instruction field:
11969
11970            0x8000  SUB
11971            0x00F0  Rd
11972            0x000F  Rs
11973       */
11974       newval = md_chars_to_number (buf, THUMB_SIZE);
11975       {
11976         int rd = (newval >> 4) & 0xf;
11977         int rs = newval & 0xf;
11978         int subtract = newval & 0x8000;
11979
11980         if (rd == REG_SP)
11981           {
11982             if (value & ~0x1fc)
11983               as_bad_where (fixP->fx_file, fixP->fx_line,
11984                             _("invalid immediate for stack address calculation"));
11985             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11986             newval |= value >> 2;
11987           }
11988         else if (rs == REG_PC || rs == REG_SP)
11989           {
11990             if (subtract ||
11991                 value & ~0x3fc)
11992               as_bad_where (fixP->fx_file, fixP->fx_line,
11993                             _("invalid immediate for address calculation (value = 0x%08lX)"),
11994                             (unsigned long) value);
11995             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
11996             newval |= rd << 8;
11997             newval |= value >> 2;
11998           }
11999         else if (rs == rd)
12000           {
12001             if (value & ~0xff)
12002               as_bad_where (fixP->fx_file, fixP->fx_line,
12003                             _("invalid 8bit immediate"));
12004             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12005             newval |= (rd << 8) | value;
12006           }
12007         else
12008           {
12009             if (value & ~0x7)
12010               as_bad_where (fixP->fx_file, fixP->fx_line,
12011                             _("invalid 3bit immediate"));
12012             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12013             newval |= rd | (rs << 3) | (value << 6);
12014           }
12015       }
12016       md_number_to_chars (buf, newval, THUMB_SIZE);
12017       break;
12018
12019     case BFD_RELOC_ARM_THUMB_IMM:
12020       newval = md_chars_to_number (buf, THUMB_SIZE);
12021       switch (newval >> 11)
12022         {
12023         case 0x04: /* 8bit immediate MOV.  */
12024         case 0x05: /* 8bit immediate CMP.  */
12025           if (value < 0 || value > 255)
12026             as_bad_where (fixP->fx_file, fixP->fx_line,
12027                           _("invalid immediate: %ld is too large"),
12028                           (long) value);
12029           newval |= value;
12030           break;
12031
12032         default:
12033           abort ();
12034         }
12035       md_number_to_chars (buf, newval, THUMB_SIZE);
12036       break;
12037
12038     case BFD_RELOC_ARM_THUMB_SHIFT:
12039       /* 5bit shift value (0..31).  */
12040       if (value < 0 || value > 31)
12041         as_bad_where (fixP->fx_file, fixP->fx_line,
12042                       _("illegal Thumb shift value: %ld"), (long) value);
12043       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12044       newval |= value << 6;
12045       md_number_to_chars (buf, newval, THUMB_SIZE);
12046       break;
12047
12048     case BFD_RELOC_VTABLE_INHERIT:
12049     case BFD_RELOC_VTABLE_ENTRY:
12050       fixP->fx_done = 0;
12051       return;
12052
12053     case BFD_RELOC_NONE:
12054     default:
12055       as_bad_where (fixP->fx_file, fixP->fx_line,
12056                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12057     }
12058 }
12059
12060 /* Translate internal representation of relocation info to BFD target
12061    format.  */
12062
12063 arelent *
12064 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
12065               fixS *     fixp)
12066 {
12067   arelent * reloc;
12068   bfd_reloc_code_real_type code;
12069
12070   reloc = xmalloc (sizeof (arelent));
12071
12072   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
12073   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12074   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12075
12076   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12077 #ifndef OBJ_ELF
12078   if (fixp->fx_pcrel == 0)
12079     reloc->addend = fixp->fx_offset;
12080   else
12081     reloc->addend = fixp->fx_offset = reloc->address;
12082 #else  /* OBJ_ELF */
12083   reloc->addend = fixp->fx_offset;
12084 #endif
12085
12086   switch (fixp->fx_r_type)
12087     {
12088     case BFD_RELOC_8:
12089       if (fixp->fx_pcrel)
12090         {
12091           code = BFD_RELOC_8_PCREL;
12092           break;
12093         }
12094
12095     case BFD_RELOC_16:
12096       if (fixp->fx_pcrel)
12097         {
12098           code = BFD_RELOC_16_PCREL;
12099           break;
12100         }
12101
12102     case BFD_RELOC_32:
12103       if (fixp->fx_pcrel)
12104         {
12105           code = BFD_RELOC_32_PCREL;
12106           break;
12107         }
12108
12109     case BFD_RELOC_ARM_PCREL_BRANCH:
12110     case BFD_RELOC_ARM_PCREL_BLX:
12111     case BFD_RELOC_RVA:
12112     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12113     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12114     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12115     case BFD_RELOC_THUMB_PCREL_BLX:
12116     case BFD_RELOC_VTABLE_ENTRY:
12117     case BFD_RELOC_VTABLE_INHERIT:
12118       code = fixp->fx_r_type;
12119       break;
12120
12121     case BFD_RELOC_ARM_LITERAL:
12122     case BFD_RELOC_ARM_HWLITERAL:
12123       /* If this is called then the a literal has
12124          been referenced across a section boundary.  */
12125       as_bad_where (fixp->fx_file, fixp->fx_line,
12126                     _("literal referenced across section boundary"));
12127       return NULL;
12128
12129 #ifdef OBJ_ELF
12130     case BFD_RELOC_ARM_GOT32:
12131     case BFD_RELOC_ARM_GOTOFF:
12132     case BFD_RELOC_ARM_PLT32:
12133     case BFD_RELOC_ARM_TARGET1:
12134     case BFD_RELOC_ARM_ROSEGREL32:
12135     case BFD_RELOC_ARM_SBREL32:
12136     case BFD_RELOC_ARM_PREL31:
12137     case BFD_RELOC_ARM_TARGET2:
12138       code = fixp->fx_r_type;
12139       break;
12140 #endif
12141
12142     case BFD_RELOC_ARM_IMMEDIATE:
12143       as_bad_where (fixp->fx_file, fixp->fx_line,
12144                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12145       return NULL;
12146
12147     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12148       as_bad_where (fixp->fx_file, fixp->fx_line,
12149                     _("ADRL used for a symbol not defined in the same file"));
12150       return NULL;
12151
12152     case BFD_RELOC_ARM_OFFSET_IMM:
12153       if (fixp->fx_addsy != NULL
12154           && !S_IS_DEFINED (fixp->fx_addsy)
12155           && S_IS_LOCAL (fixp->fx_addsy))
12156         {
12157           as_bad_where (fixp->fx_file, fixp->fx_line,
12158                         _("undefined local label `%s'"),
12159                         S_GET_NAME (fixp->fx_addsy));
12160           return NULL;
12161         }
12162
12163       as_bad_where (fixp->fx_file, fixp->fx_line,
12164                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12165       return NULL;
12166
12167     default:
12168       {
12169         char * type;
12170
12171         switch (fixp->fx_r_type)
12172           {
12173           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12174           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12175           case BFD_RELOC_ARM_SMI:          type = "SMI";          break;
12176           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12177           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12178           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12179           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12180           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12181           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12182           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12183           default:                         type = _("<unknown>"); break;
12184           }
12185         as_bad_where (fixp->fx_file, fixp->fx_line,
12186                       _("cannot represent %s relocation in this object file format"),
12187                       type);
12188         return NULL;
12189       }
12190     }
12191
12192 #ifdef OBJ_ELF
12193   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12194       && GOT_symbol
12195       && fixp->fx_addsy == GOT_symbol)
12196     {
12197       code = BFD_RELOC_ARM_GOTPC;
12198       reloc->addend = fixp->fx_offset = reloc->address;
12199     }
12200 #endif
12201
12202   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12203
12204   if (reloc->howto == NULL)
12205     {
12206       as_bad_where (fixp->fx_file, fixp->fx_line,
12207                     _("cannot represent %s relocation in this object file format"),
12208                     bfd_get_reloc_code_name (code));
12209       return NULL;
12210     }
12211
12212   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12213      vtable entry to be used in the relocation's section offset.  */
12214   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12215     reloc->address = fixp->fx_offset;
12216
12217   return reloc;
12218 }
12219
12220 int
12221 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
12222                                segT    segtype ATTRIBUTE_UNUSED)
12223 {
12224   as_fatal (_("md_estimate_size_before_relax\n"));
12225   return 1;
12226 }
12227
12228 /* We need to be able to fix up arbitrary expressions in some statements.
12229    This is so that we can handle symbols that are an arbitrary distance from
12230    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12231    which returns part of an address in a form which will be valid for
12232    a data instruction.  We do this by pushing the expression into a symbol
12233    in the expr_section, and creating a fix for that.  */
12234
12235 static void
12236 fix_new_arm (fragS *       frag,
12237              int           where,
12238              short int     size,
12239              expressionS * exp,
12240              int           pc_rel,
12241              int           reloc)
12242 {
12243   fixS *           new_fix;
12244   arm_fix_data *   arm_data;
12245
12246   switch (exp->X_op)
12247     {
12248     case O_constant:
12249     case O_symbol:
12250     case O_add:
12251     case O_subtract:
12252       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12253       break;
12254
12255     default:
12256       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12257                          pc_rel, reloc);
12258       break;
12259     }
12260
12261   /* Mark whether the fix is to a THUMB instruction, or an ARM
12262      instruction.  */
12263   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
12264   new_fix->tc_fix_data = (PTR) arm_data;
12265   arm_data->thumb_mode = thumb_mode;
12266 }
12267
12268 static void
12269 output_inst (const char * str)
12270 {
12271   char * to = NULL;
12272
12273   if (inst.error)
12274     {
12275       as_bad ("%s -- `%s'", inst.error, str);
12276       return;
12277     }
12278
12279   to = frag_more (inst.size);
12280
12281   if (thumb_mode && (inst.size > THUMB_SIZE))
12282     {
12283       assert (inst.size == (2 * THUMB_SIZE));
12284       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12285       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12286     }
12287   else if (inst.size > INSN_SIZE)
12288     {
12289       assert (inst.size == (2 * INSN_SIZE));
12290       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12291       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12292     }
12293   else
12294     md_number_to_chars (to, inst.instruction, inst.size);
12295
12296   if (inst.reloc.type != BFD_RELOC_NONE)
12297     fix_new_arm (frag_now, to - frag_now->fr_literal,
12298                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12299                  inst.reloc.type);
12300
12301 #ifdef OBJ_ELF
12302   dwarf2_emit_insn (inst.size);
12303 #endif
12304 }
12305
12306 void
12307 md_assemble (char * str)
12308 {
12309   char  c;
12310   char *p;
12311   char *start;
12312
12313   /* Align the previous label if needed.  */
12314   if (last_label_seen != NULL)
12315     {
12316       symbol_set_frag (last_label_seen, frag_now);
12317       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12318       S_SET_SEGMENT (last_label_seen, now_seg);
12319     }
12320
12321   memset (&inst, '\0', sizeof (inst));
12322   inst.reloc.type = BFD_RELOC_NONE;
12323
12324   skip_whitespace (str);
12325
12326   /* Scan up to the end of the op-code, which must end in white space or
12327      end of string.  */
12328   for (start = p = str; *p != '\0'; p++)
12329     if (*p == ' ')
12330       break;
12331
12332   if (p == str)
12333     {
12334       as_bad (_("no operator -- statement `%s'\n"), str);
12335       return;
12336     }
12337
12338   if (thumb_mode)
12339     {
12340       const struct thumb_opcode * opcode;
12341
12342       c = *p;
12343       *p = '\0';
12344       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12345       *p = c;
12346
12347       if (opcode)
12348         {
12349           /* Check that this instruction is supported for this CPU.  */
12350           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12351             {
12352               as_bad (_("selected processor does not support `%s'"), str);
12353               return;
12354             }
12355
12356           mapping_state (MAP_THUMB);
12357           inst.instruction = opcode->value;
12358           inst.size = opcode->size;
12359           opcode->parms (p);
12360           output_inst (str);
12361           return;
12362         }
12363     }
12364   else
12365     {
12366       const struct asm_opcode * opcode;
12367
12368       c = *p;
12369       *p = '\0';
12370       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12371       *p = c;
12372
12373       if (opcode)
12374         {
12375           /* Check that this instruction is supported for this CPU.  */
12376           if ((opcode->variant & cpu_variant) == 0)
12377             {
12378               as_bad (_("selected processor does not support `%s'"), str);
12379               return;
12380             }
12381
12382           mapping_state (MAP_ARM);
12383           inst.instruction = opcode->value;
12384           inst.size = INSN_SIZE;
12385           opcode->parms (p);
12386           output_inst (str);
12387           return;
12388         }
12389     }
12390
12391   /* It wasn't an instruction, but it might be a register alias of the form
12392      alias .req reg.  */
12393   if (create_register_alias (str, p))
12394     return;
12395
12396   as_bad (_("bad instruction `%s'"), start);
12397 }
12398
12399 /* md_parse_option
12400       Invocation line includes a switch not recognized by the base assembler.
12401       See if it's a processor-specific option.
12402
12403       This routine is somewhat complicated by the need for backwards
12404       compatibility (since older releases of gcc can't be changed).
12405       The new options try to make the interface as compatible as
12406       possible with GCC.
12407
12408       New options (supported) are:
12409
12410               -mcpu=<cpu name>           Assemble for selected processor
12411               -march=<architecture name> Assemble for selected architecture
12412               -mfpu=<fpu architecture>   Assemble for selected FPU.
12413               -EB/-mbig-endian           Big-endian
12414               -EL/-mlittle-endian        Little-endian
12415               -k                         Generate PIC code
12416               -mthumb                    Start in Thumb mode
12417               -mthumb-interwork          Code supports ARM/Thumb interworking
12418
12419       For now we will also provide support for:
12420
12421               -mapcs-32                  32-bit Program counter
12422               -mapcs-26                  26-bit Program counter
12423               -macps-float               Floats passed in FP registers
12424               -mapcs-reentrant           Reentrant code
12425               -matpcs
12426       (sometime these will probably be replaced with -mapcs=<list of options>
12427       and -matpcs=<list of options>)
12428
12429       The remaining options are only supported for back-wards compatibility.
12430       Cpu variants, the arm part is optional:
12431               -m[arm]1                Currently not supported.
12432               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
12433               -m[arm]3                Arm 3 processor
12434               -m[arm]6[xx],           Arm 6 processors
12435               -m[arm]7[xx][t][[d]m]   Arm 7 processors
12436               -m[arm]8[10]            Arm 8 processors
12437               -m[arm]9[20][tdmi]      Arm 9 processors
12438               -mstrongarm[110[0]]     StrongARM processors
12439               -mxscale                XScale processors
12440               -m[arm]v[2345[t[e]]]    Arm architectures
12441               -mall                   All (except the ARM1)
12442       FP variants:
12443               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
12444               -mfpe-old               (No float load/store multiples)
12445               -mvfpxd                 VFP Single precision
12446               -mvfp                   All VFP
12447               -mno-fpu                Disable all floating point instructions
12448
12449       The following CPU names are recognized:
12450               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12451               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12452               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12453               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12454               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12455               arm10t arm10e, arm1020t, arm1020e, arm10200e,
12456               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
12457
12458       */
12459
12460 const char * md_shortopts = "m:k";
12461
12462 #ifdef ARM_BI_ENDIAN
12463 #define OPTION_EB (OPTION_MD_BASE + 0)
12464 #define OPTION_EL (OPTION_MD_BASE + 1)
12465 #else
12466 #if TARGET_BYTES_BIG_ENDIAN
12467 #define OPTION_EB (OPTION_MD_BASE + 0)
12468 #else
12469 #define OPTION_EL (OPTION_MD_BASE + 1)
12470 #endif
12471 #endif
12472
12473 struct option md_longopts[] =
12474 {
12475 #ifdef OPTION_EB
12476   {"EB", no_argument, NULL, OPTION_EB},
12477 #endif
12478 #ifdef OPTION_EL
12479   {"EL", no_argument, NULL, OPTION_EL},
12480 #endif
12481   {NULL, no_argument, NULL, 0}
12482 };
12483
12484 size_t md_longopts_size = sizeof (md_longopts);
12485
12486 struct arm_option_table
12487 {
12488   char *option;         /* Option name to match.  */
12489   char *help;           /* Help information.  */
12490   int  *var;            /* Variable to change.  */
12491   int   value;          /* What to change it to.  */
12492   char *deprecated;     /* If non-null, print this message.  */
12493 };
12494
12495 struct arm_option_table arm_opts[] =
12496 {
12497   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
12498   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
12499   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12500    &support_interwork, 1, NULL},
12501   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12502   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12503   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12504    1, NULL},
12505   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12506   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12507   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12508   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
12509    NULL},
12510
12511   /* These are recognized by the assembler, but have no affect on code.  */
12512   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12513   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12514
12515   /* DON'T add any new processors to this list -- we want the whole list
12516      to go away...  Add them to the processors table instead.  */
12517   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12518   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12519   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12520   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12521   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12522   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12523   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12524   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12525   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12526   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12527   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12528   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12529   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12530   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12531   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12532   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12533   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12534   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12535   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12536   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12537   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12538   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12539   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12540   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12541   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12542   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12543   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12544   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12545   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12546   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12547   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12548   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12549   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12550   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12551   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12552   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12553   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12554   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12555   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12556   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12557   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12558   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12559   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12560   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12561   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12562   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12563   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12564   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12565   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12566   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12567   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12568   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12569   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12570   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12571   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12572   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12573   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12574   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12575   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12576   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12577   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12578   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12579   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12580   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12581   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12582   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12583   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12584   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12585   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
12586   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12587    N_("use -mcpu=strongarm110")},
12588   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12589    N_("use -mcpu=strongarm1100")},
12590   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12591    N_("use -mcpu=strongarm1110")},
12592   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12593   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12594   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
12595
12596   /* Architecture variants -- don't add any more to this list either.  */
12597   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12598   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12599   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12600   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12601   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12602   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12603   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12604   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12605   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12606   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12607   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12608   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12609   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12610   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12611   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12612   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12613   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12614   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12615
12616   /* Floating point variants -- don't add any more to this list either.  */
12617   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12618   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12619   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12620   {"mno-fpu",  NULL, &legacy_fpu, 0,
12621    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
12622
12623   {NULL, NULL, NULL, 0, NULL}
12624 };
12625
12626 struct arm_cpu_option_table
12627 {
12628   char *name;
12629   int   value;
12630   /* For some CPUs we assume an FPU unless the user explicitly sets
12631      -mfpu=...  */
12632   int   default_fpu;
12633 };
12634
12635 /* This list should, at a minimum, contain all the cpu names
12636    recognized by GCC.  */
12637 static struct arm_cpu_option_table arm_cpus[] =
12638 {
12639   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12640   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
12641   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
12642   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12643   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
12644   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12645   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12646   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12647   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12648   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12649   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12650   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
12651   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12652   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12653   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12654   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
12655   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12656   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12657   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12658   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12659   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12660   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12661   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12662   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12663   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12664   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12665   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12666   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
12667   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
12668   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12669   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
12670   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
12671   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
12672   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
12673   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
12674   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
12675   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12676   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12677   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
12678   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12679   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12680   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12681   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12682   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12683   /* For V5 or later processors we default to using VFP; but the user
12684      should really set the FPU type explicitly.  */
12685   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12686   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12687   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12688   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12689   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12690   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12691   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12692   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12693   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12694   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12695   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12696   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12697   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12698   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12699   {"arm1026ejs",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12700   {"arm1026ej-s",       ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12701   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
12702   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
12703   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12704   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12705   {"mpcore",            ARM_ARCH_V6K,    FPU_ARCH_VFP_V2},
12706   {"mpcorenovfp",       ARM_ARCH_V6K,    FPU_NONE},
12707   {"arm1176jz-s",       ARM_ARCH_V6ZK,   FPU_NONE},
12708   {"arm1176jzf-s",      ARM_ARCH_V6ZK,   FPU_ARCH_VFP_V2},
12709   /* ??? XSCALE is really an architecture.  */
12710   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12711   /* ??? iwmmxt is not a processor.  */
12712   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
12713   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12714   /* Maverick */
12715   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
12716   {NULL, 0, 0}
12717 };
12718
12719 struct arm_arch_option_table
12720 {
12721   char *name;
12722   int   value;
12723   int   default_fpu;
12724 };
12725
12726 /* This list should, at a minimum, contain all the architecture names
12727    recognized by GCC.  */
12728 static struct arm_arch_option_table arm_archs[] =
12729 {
12730   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12731   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
12732   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
12733   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12734   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12735   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12736   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12737   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
12738   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
12739   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12740   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
12741   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
12742   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
12743   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
12744   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
12745   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
12746   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
12747   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
12748   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
12749   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
12750   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
12751   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
12752   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
12753   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
12754   {NULL, 0, 0}
12755 };
12756
12757 /* ISA extensions in the co-processor space.  */
12758 struct arm_arch_extension_table
12759 {
12760   char *name;
12761   int value;
12762 };
12763
12764 static struct arm_arch_extension_table arm_extensions[] =
12765 {
12766   {"maverick",          ARM_CEXT_MAVERICK},
12767   {"xscale",            ARM_CEXT_XSCALE},
12768   {"iwmmxt",            ARM_CEXT_IWMMXT},
12769   {NULL,                0}
12770 };
12771
12772 struct arm_fpu_option_table
12773 {
12774   char *name;
12775   int   value;
12776 };
12777
12778 /* This list should, at a minimum, contain all the fpu names
12779    recognized by GCC.  */
12780 static struct arm_fpu_option_table arm_fpus[] =
12781 {
12782   {"softfpa",           FPU_NONE},
12783   {"fpe",               FPU_ARCH_FPE},
12784   {"fpe2",              FPU_ARCH_FPE},
12785   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
12786   {"fpa",               FPU_ARCH_FPA},
12787   {"fpa10",             FPU_ARCH_FPA},
12788   {"fpa11",             FPU_ARCH_FPA},
12789   {"arm7500fe",         FPU_ARCH_FPA},
12790   {"softvfp",           FPU_ARCH_VFP},
12791   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
12792   {"vfp",               FPU_ARCH_VFP_V2},
12793   {"vfp9",              FPU_ARCH_VFP_V2},
12794   {"vfp10",             FPU_ARCH_VFP_V2},
12795   {"vfp10-r0",          FPU_ARCH_VFP_V1},
12796   {"vfpxd",             FPU_ARCH_VFP_V1xD},
12797   {"arm1020t",          FPU_ARCH_VFP_V1},
12798   {"arm1020e",          FPU_ARCH_VFP_V2},
12799   {"arm1136jfs",        FPU_ARCH_VFP_V2},
12800   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
12801   {"maverick",          FPU_ARCH_MAVERICK},
12802   {NULL, 0}
12803 };
12804
12805 struct arm_float_abi_option_table
12806 {
12807   char *name;
12808   int value;
12809 };
12810
12811 static struct arm_float_abi_option_table arm_float_abis[] =
12812 {
12813   {"hard",      ARM_FLOAT_ABI_HARD},
12814   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
12815   {"soft",      ARM_FLOAT_ABI_SOFT},
12816   {NULL, 0}
12817 };
12818
12819 struct arm_eabi_option_table
12820 {
12821   char *name;
12822   unsigned int value;
12823 };
12824
12825 #ifdef OBJ_ELF
12826 /* We only know how to output GNU and ver 4 (AAELF) formats.  */
12827 static struct arm_eabi_option_table arm_eabis[] =
12828 {
12829   {"gnu",       EF_ARM_EABI_UNKNOWN},
12830   {"4",         EF_ARM_EABI_VER4},
12831   {NULL, 0}
12832 };
12833 #endif
12834
12835 struct arm_long_option_table
12836 {
12837   char * option;                /* Substring to match.  */
12838   char * help;                  /* Help information.  */
12839   int (* func) (char * subopt); /* Function to decode sub-option.  */
12840   char * deprecated;            /* If non-null, print this message.  */
12841 };
12842
12843 static int
12844 arm_parse_extension (char * str, int * opt_p)
12845 {
12846   while (str != NULL && *str != 0)
12847     {
12848       struct arm_arch_extension_table * opt;
12849       char * ext;
12850       int optlen;
12851
12852       if (*str != '+')
12853         {
12854           as_bad (_("invalid architectural extension"));
12855           return 0;
12856         }
12857
12858       str++;
12859       ext = strchr (str, '+');
12860
12861       if (ext != NULL)
12862         optlen = ext - str;
12863       else
12864         optlen = strlen (str);
12865
12866       if (optlen == 0)
12867         {
12868           as_bad (_("missing architectural extension"));
12869           return 0;
12870         }
12871
12872       for (opt = arm_extensions; opt->name != NULL; opt++)
12873         if (strncmp (opt->name, str, optlen) == 0)
12874           {
12875             *opt_p |= opt->value;
12876             break;
12877           }
12878
12879       if (opt->name == NULL)
12880         {
12881           as_bad (_("unknown architectural extnsion `%s'"), str);
12882           return 0;
12883         }
12884
12885       str = ext;
12886     };
12887
12888   return 1;
12889 }
12890
12891 static int
12892 arm_parse_cpu (char * str)
12893 {
12894   struct arm_cpu_option_table * opt;
12895   char * ext = strchr (str, '+');
12896   int optlen;
12897
12898   if (ext != NULL)
12899     optlen = ext - str;
12900   else
12901     optlen = strlen (str);
12902
12903   if (optlen == 0)
12904     {
12905       as_bad (_("missing cpu name `%s'"), str);
12906       return 0;
12907     }
12908
12909   for (opt = arm_cpus; opt->name != NULL; opt++)
12910     if (strncmp (opt->name, str, optlen) == 0)
12911       {
12912         mcpu_cpu_opt = opt->value;
12913         mcpu_fpu_opt = opt->default_fpu;
12914
12915         if (ext != NULL)
12916           return arm_parse_extension (ext, &mcpu_cpu_opt);
12917
12918         return 1;
12919       }
12920
12921   as_bad (_("unknown cpu `%s'"), str);
12922   return 0;
12923 }
12924
12925 static int
12926 arm_parse_arch (char * str)
12927 {
12928   struct arm_arch_option_table *opt;
12929   char *ext = strchr (str, '+');
12930   int optlen;
12931
12932   if (ext != NULL)
12933     optlen = ext - str;
12934   else
12935     optlen = strlen (str);
12936
12937   if (optlen == 0)
12938     {
12939       as_bad (_("missing architecture name `%s'"), str);
12940       return 0;
12941     }
12942
12943
12944   for (opt = arm_archs; opt->name != NULL; opt++)
12945     if (streq (opt->name, str))
12946       {
12947         march_cpu_opt = opt->value;
12948         march_fpu_opt = opt->default_fpu;
12949
12950         if (ext != NULL)
12951           return arm_parse_extension (ext, &march_cpu_opt);
12952
12953         return 1;
12954       }
12955
12956   as_bad (_("unknown architecture `%s'\n"), str);
12957   return 0;
12958 }
12959
12960 static int
12961 arm_parse_fpu (char * str)
12962 {
12963   struct arm_fpu_option_table * opt;
12964
12965   for (opt = arm_fpus; opt->name != NULL; opt++)
12966     if (streq (opt->name, str))
12967       {
12968         mfpu_opt = opt->value;
12969         return 1;
12970       }
12971
12972   as_bad (_("unknown floating point format `%s'\n"), str);
12973   return 0;
12974 }
12975
12976 static int
12977 arm_parse_float_abi (char * str)
12978 {
12979   struct arm_float_abi_option_table * opt;
12980
12981   for (opt = arm_float_abis; opt->name != NULL; opt++)
12982     if (streq (opt->name, str))
12983       {
12984         mfloat_abi_opt = opt->value;
12985         return 1;
12986       }
12987
12988   as_bad (_("unknown floating point abi `%s'\n"), str);
12989   return 0;
12990 }
12991
12992 #ifdef OBJ_ELF
12993 static int
12994 arm_parse_eabi (char * str)
12995 {
12996   struct arm_eabi_option_table *opt;
12997
12998   for (opt = arm_eabis; opt->name != NULL; opt++)
12999     if (streq (opt->name, str))
13000       {
13001         meabi_flags = opt->value;
13002         return 1;
13003       }
13004   as_bad (_("unknown EABI `%s'\n"), str);
13005   return 0;
13006 }
13007 #endif
13008
13009 struct arm_long_option_table arm_long_opts[] =
13010 {
13011   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13012    arm_parse_cpu, NULL},
13013   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13014    arm_parse_arch, NULL},
13015   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13016    arm_parse_fpu, NULL},
13017   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13018    arm_parse_float_abi, NULL},
13019 #ifdef OBJ_ELF
13020   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13021    arm_parse_eabi, NULL},
13022 #endif
13023   {NULL, NULL, 0, NULL}
13024 };
13025
13026 int
13027 md_parse_option (int c, char * arg)
13028 {
13029   struct arm_option_table *opt;
13030   struct arm_long_option_table *lopt;
13031
13032   switch (c)
13033     {
13034 #ifdef OPTION_EB
13035     case OPTION_EB:
13036       target_big_endian = 1;
13037       break;
13038 #endif
13039
13040 #ifdef OPTION_EL
13041     case OPTION_EL:
13042       target_big_endian = 0;
13043       break;
13044 #endif
13045
13046     case 'a':
13047       /* Listing option.  Just ignore these, we don't support additional
13048          ones.  */
13049       return 0;
13050
13051     default:
13052       for (opt = arm_opts; opt->option != NULL; opt++)
13053         {
13054           if (c == opt->option[0]
13055               && ((arg == NULL && opt->option[1] == 0)
13056                   || streq (arg, opt->option + 1)))
13057             {
13058 #if WARN_DEPRECATED
13059               /* If the option is deprecated, tell the user.  */
13060               if (opt->deprecated != NULL)
13061                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13062                            arg ? arg : "", _(opt->deprecated));
13063 #endif
13064
13065               if (opt->var != NULL)
13066                 *opt->var = opt->value;
13067
13068               return 1;
13069             }
13070         }
13071
13072       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13073         {
13074           /* These options are expected to have an argument.  */
13075           if (c == lopt->option[0]
13076               && arg != NULL
13077               && strncmp (arg, lopt->option + 1,
13078                           strlen (lopt->option + 1)) == 0)
13079             {
13080 #if WARN_DEPRECATED
13081               /* If the option is deprecated, tell the user.  */
13082               if (lopt->deprecated != NULL)
13083                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13084                            _(lopt->deprecated));
13085 #endif
13086
13087               /* Call the sup-option parser.  */
13088               return lopt->func (arg + strlen (lopt->option) - 1);
13089             }
13090         }
13091
13092       return 0;
13093     }
13094
13095   return 1;
13096 }
13097
13098 void
13099 md_show_usage (FILE * fp)
13100 {
13101   struct arm_option_table *opt;
13102   struct arm_long_option_table *lopt;
13103
13104   fprintf (fp, _(" ARM-specific assembler options:\n"));
13105
13106   for (opt = arm_opts; opt->option != NULL; opt++)
13107     if (opt->help != NULL)
13108       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13109
13110   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13111     if (lopt->help != NULL)
13112       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13113
13114 #ifdef OPTION_EB
13115   fprintf (fp, _("\
13116   -EB                     assemble code for a big-endian cpu\n"));
13117 #endif
13118
13119 #ifdef OPTION_EL
13120   fprintf (fp, _("\
13121   -EL                     assemble code for a little-endian cpu\n"));
13122 #endif
13123 }
13124
13125 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13126
13127 void
13128 cons_fix_new_arm (fragS *       frag,
13129                   int           where,
13130                   int           size,
13131                   expressionS * exp)
13132 {
13133   bfd_reloc_code_real_type type;
13134   int pcrel = 0;
13135
13136   /* Pick a reloc.
13137      FIXME: @@ Should look at CPU word size.  */
13138   switch (size)
13139     {
13140     case 1:
13141       type = BFD_RELOC_8;
13142       break;
13143     case 2:
13144       type = BFD_RELOC_16;
13145       break;
13146     case 4:
13147     default:
13148       type = BFD_RELOC_32;
13149       break;
13150     case 8:
13151       type = BFD_RELOC_64;
13152       break;
13153     }
13154
13155   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13156 }
13157
13158 /* A good place to do this, although this was probably not intended
13159    for this kind of use.  We need to dump the literal pool before
13160    references are made to a null symbol pointer.  */
13161
13162 void
13163 arm_cleanup (void)
13164 {
13165   literal_pool * pool;
13166
13167   for (pool = list_of_pools; pool; pool = pool->next)
13168     {
13169       /* Put it at the end of the relevent section.  */
13170       subseg_set (pool->section, pool->sub_section);
13171 #ifdef OBJ_ELF
13172       arm_elf_change_section ();
13173 #endif
13174       s_ltorg (0);
13175     }
13176 }
13177
13178 void
13179 arm_start_line_hook (void)
13180 {
13181   last_label_seen = NULL;
13182 }
13183
13184 void
13185 arm_frob_label (symbolS * sym)
13186 {
13187   last_label_seen = sym;
13188
13189   ARM_SET_THUMB (sym, thumb_mode);
13190
13191 #if defined OBJ_COFF || defined OBJ_ELF
13192   ARM_SET_INTERWORK (sym, support_interwork);
13193 #endif
13194
13195   /* Note - do not allow local symbols (.Lxxx) to be labeled
13196      as Thumb functions.  This is because these labels, whilst
13197      they exist inside Thumb code, are not the entry points for
13198      possible ARM->Thumb calls.  Also, these labels can be used
13199      as part of a computed goto or switch statement.  eg gcc
13200      can generate code that looks like this:
13201
13202                 ldr  r2, [pc, .Laaa]
13203                 lsl  r3, r3, #2
13204                 ldr  r2, [r3, r2]
13205                 mov  pc, r2
13206
13207        .Lbbb:  .word .Lxxx
13208        .Lccc:  .word .Lyyy
13209        ..etc...
13210        .Laaa:   .word Lbbb
13211
13212      The first instruction loads the address of the jump table.
13213      The second instruction converts a table index into a byte offset.
13214      The third instruction gets the jump address out of the table.
13215      The fourth instruction performs the jump.
13216
13217      If the address stored at .Laaa is that of a symbol which has the
13218      Thumb_Func bit set, then the linker will arrange for this address
13219      to have the bottom bit set, which in turn would mean that the
13220      address computation performed by the third instruction would end
13221      up with the bottom bit set.  Since the ARM is capable of unaligned
13222      word loads, the instruction would then load the incorrect address
13223      out of the jump table, and chaos would ensue.  */
13224   if (label_is_thumb_function_name
13225       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13226       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13227     {
13228       /* When the address of a Thumb function is taken the bottom
13229          bit of that address should be set.  This will allow
13230          interworking between Arm and Thumb functions to work
13231          correctly.  */
13232
13233       THUMB_SET_FUNC (sym, 1);
13234
13235       label_is_thumb_function_name = FALSE;
13236     }
13237 }
13238
13239 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13240    ARM ones.  */
13241
13242 void
13243 arm_adjust_symtab (void)
13244 {
13245 #ifdef OBJ_COFF
13246   symbolS * sym;
13247
13248   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13249     {
13250       if (ARM_IS_THUMB (sym))
13251         {
13252           if (THUMB_IS_FUNC (sym))
13253             {
13254               /* Mark the symbol as a Thumb function.  */
13255               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13256                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13257                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13258
13259               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13260                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13261               else
13262                 as_bad (_("%s: unexpected function type: %d"),
13263                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13264             }
13265           else switch (S_GET_STORAGE_CLASS (sym))
13266             {
13267             case C_EXT:
13268               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13269               break;
13270             case C_STAT:
13271               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13272               break;
13273             case C_LABEL:
13274               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13275               break;
13276             default:
13277               /* Do nothing.  */
13278               break;
13279             }
13280         }
13281
13282       if (ARM_IS_INTERWORK (sym))
13283         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13284     }
13285 #endif
13286 #ifdef OBJ_ELF
13287   symbolS * sym;
13288   char      bind;
13289
13290   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13291     {
13292       if (ARM_IS_THUMB (sym))
13293         {
13294           elf_symbol_type * elf_sym;
13295
13296           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13297           bind = ELF_ST_BIND (elf_sym);
13298
13299           /* If it's a .thumb_func, declare it as so,
13300              otherwise tag label as .code 16.  */
13301           if (THUMB_IS_FUNC (sym))
13302             elf_sym->internal_elf_sym.st_info =
13303               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13304           else
13305             elf_sym->internal_elf_sym.st_info =
13306               ELF_ST_INFO (bind, STT_ARM_16BIT);
13307         }
13308     }
13309 #endif
13310 }
13311
13312 int
13313 arm_data_in_code (void)
13314 {
13315   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13316     {
13317       *input_line_pointer = '/';
13318       input_line_pointer += 5;
13319       *input_line_pointer = 0;
13320       return 1;
13321     }
13322
13323   return 0;
13324 }
13325
13326 char *
13327 arm_canonicalize_symbol_name (char * name)
13328 {
13329   int len;
13330
13331   if (thumb_mode && (len = strlen (name)) > 5
13332       && streq (name + len - 5, "/data"))
13333     *(name + len - 5) = 0;
13334
13335   return name;
13336 }
13337
13338 #if defined OBJ_COFF || defined OBJ_ELF
13339 void
13340 arm_validate_fix (fixS * fixP)
13341 {
13342   /* If the destination of the branch is a defined symbol which does not have
13343      the THUMB_FUNC attribute, then we must be calling a function which has
13344      the (interfacearm) attribute.  We look for the Thumb entry point to that
13345      function and change the branch to refer to that function instead.  */
13346   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13347       && fixP->fx_addsy != NULL
13348       && S_IS_DEFINED (fixP->fx_addsy)
13349       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13350     {
13351       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13352     }
13353 }
13354 #endif
13355
13356 int
13357 arm_force_relocation (struct fix * fixp)
13358 {
13359 #if defined (OBJ_COFF) && defined (TE_PE)
13360   if (fixp->fx_r_type == BFD_RELOC_RVA)
13361     return 1;
13362 #endif
13363 #ifdef OBJ_ELF
13364   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13365       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13366       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13367       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13368     return 1;
13369 #endif
13370
13371   /* Resolve these relocations even if the symbol is extern or weak.  */
13372   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13373       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13374       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13375     return 0;
13376
13377   return generic_force_reloc (fixp);
13378 }
13379
13380 #ifdef OBJ_COFF
13381 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13382    local labels from being added to the output symbol table when they
13383    are used with the ADRL pseudo op.  The ADRL relocation should always
13384    be resolved before the binbary is emitted, so it is safe to say that
13385    it is adjustable.  */
13386
13387 bfd_boolean
13388 arm_fix_adjustable (fixS * fixP)
13389 {
13390   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13391     return 1;
13392   return 0;
13393 }
13394 #endif
13395
13396 #ifdef OBJ_ELF
13397 /* Relocations against Thumb function names must be left unadjusted,
13398    so that the linker can use this information to correctly set the
13399    bottom bit of their addresses.  The MIPS version of this function
13400    also prevents relocations that are mips-16 specific, but I do not
13401    know why it does this.
13402
13403    FIXME:
13404    There is one other problem that ought to be addressed here, but
13405    which currently is not:  Taking the address of a label (rather
13406    than a function) and then later jumping to that address.  Such
13407    addresses also ought to have their bottom bit set (assuming that
13408    they reside in Thumb code), but at the moment they will not.  */
13409
13410 bfd_boolean
13411 arm_fix_adjustable (fixS * fixP)
13412 {
13413   if (fixP->fx_addsy == NULL)
13414     return 1;
13415
13416   if (THUMB_IS_FUNC (fixP->fx_addsy)
13417       && fixP->fx_subsy == NULL)
13418     return 0;
13419
13420   /* We need the symbol name for the VTABLE entries.  */
13421   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
13422       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
13423     return 0;
13424
13425   /* Don't allow symbols to be discarded on GOT related relocs.  */
13426   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
13427       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
13428       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
13429       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
13430     return 0;
13431
13432   return 1;
13433 }
13434
13435 const char *
13436 elf32_arm_target_format (void)
13437 {
13438 #ifdef TE_SYMBIAN
13439   return (target_big_endian
13440           ? "elf32-bigarm-symbian"
13441           : "elf32-littlearm-symbian");
13442 #elif defined (TE_VXWORKS)
13443   return (target_big_endian
13444           ? "elf32-bigarm-vxworks"
13445           : "elf32-littlearm-vxworks");
13446 #else
13447   if (target_big_endian)
13448     return "elf32-bigarm";
13449   else
13450     return "elf32-littlearm";
13451 #endif
13452 }
13453
13454 void
13455 armelf_frob_symbol (symbolS * symp,
13456                     int *     puntp)
13457 {
13458   elf_frob_symbol (symp, puntp);
13459 }
13460
13461 static void
13462 s_arm_elf_cons (int nbytes)
13463 {
13464   expressionS exp;
13465
13466 #ifdef md_flush_pending_output
13467   md_flush_pending_output ();
13468 #endif
13469
13470   if (is_it_end_of_statement ())
13471     {
13472       demand_empty_rest_of_line ();
13473       return;
13474     }
13475
13476 #ifdef md_cons_align
13477   md_cons_align (nbytes);
13478 #endif
13479
13480   mapping_state (MAP_DATA);
13481   do
13482     {
13483       bfd_reloc_code_real_type reloc;
13484
13485       expression (& exp);
13486
13487       if (exp.X_op == O_symbol
13488           && * input_line_pointer == '('
13489           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
13490         {
13491           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13492           int size = bfd_get_reloc_size (howto);
13493
13494           if (size > nbytes)
13495             as_bad ("%s relocations do not fit in %d bytes",
13496                     howto->name, nbytes);
13497           else
13498             {
13499               char *p = frag_more ((int) nbytes);
13500               int offset = nbytes - size;
13501
13502               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13503                            &exp, 0, reloc);
13504             }
13505         }
13506       else
13507         emit_expr (&exp, (unsigned int) nbytes);
13508     }
13509   while (*input_line_pointer++ == ',');
13510
13511   /* Put terminator back into stream.  */
13512   input_line_pointer --;
13513   demand_empty_rest_of_line ();
13514 }
13515
13516
13517 /* Parse a .rel31 directive.  */
13518
13519 static void
13520 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
13521 {
13522   expressionS exp;
13523   char *p;
13524   valueT highbit;
13525
13526   SKIP_WHITESPACE ();
13527
13528   highbit = 0;
13529   if (*input_line_pointer == '1')
13530     highbit = 0x80000000;
13531   else if (*input_line_pointer != '0')
13532     as_bad (_("expected 0 or 1"));
13533
13534   input_line_pointer++;
13535   SKIP_WHITESPACE ();
13536   if (*input_line_pointer != ',')
13537     as_bad (_("missing comma"));
13538   input_line_pointer++;
13539
13540 #ifdef md_flush_pending_output
13541   md_flush_pending_output ();
13542 #endif
13543
13544 #ifdef md_cons_align
13545   md_cons_align (4);
13546 #endif
13547
13548   mapping_state (MAP_DATA);
13549
13550   expression (&exp);
13551
13552   p = frag_more (4);
13553   md_number_to_chars (p, highbit, 4);
13554   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
13555                BFD_RELOC_ARM_PREL31);
13556
13557   demand_empty_rest_of_line ();
13558 }
13559 \f
13560 /* Code to deal with unwinding tables.  */
13561
13562 static void add_unwind_adjustsp (offsetT);
13563
13564 /* Switch to section NAME and create section if necessary.  It's
13565    rather ugly that we have to manipulate input_line_pointer but I
13566    don't see any other way to accomplish the same thing without
13567    changing obj-elf.c (which may be the Right Thing, in the end).
13568    Copied from tc-ia64.c.  */
13569
13570 static void
13571 set_section (char *name)
13572 {
13573   char *saved_input_line_pointer;
13574
13575   saved_input_line_pointer = input_line_pointer;
13576   input_line_pointer = name;
13577   obj_elf_section (0);
13578   input_line_pointer = saved_input_line_pointer;
13579 }
13580
13581 /* Cenerate and deferred unwind frame offset.  */
13582
13583 static void
13584 flush_pending_unwind (void)
13585 {
13586   offsetT offset;
13587
13588   offset = unwind.pending_offset;
13589   unwind.pending_offset = 0;
13590   if (offset != 0)
13591     add_unwind_adjustsp (offset);
13592 }
13593
13594 /* Add an opcode to this list for this function.  Two-byte opcodes should
13595    be passed as op[0] << 8 | op[1].  The list of opcodes is built in reverse
13596    order.  */
13597
13598 static void
13599 add_unwind_opcode (valueT op, int length)
13600 {
13601   /* Add any deferred stack adjustment.  */
13602   if (unwind.pending_offset)
13603     flush_pending_unwind ();
13604
13605   unwind.sp_restored = 0;
13606
13607   if (unwind.opcode_count + length > unwind.opcode_alloc)
13608     {
13609       unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
13610       if (unwind.opcodes)
13611         unwind.opcodes = xrealloc (unwind.opcodes,
13612                                    unwind.opcode_alloc);
13613       else
13614         unwind.opcodes = xmalloc (unwind.opcode_alloc);
13615     }
13616   while (length > 0)
13617     {
13618       length--;
13619       unwind.opcodes[unwind.opcode_count] = op & 0xff;
13620       op >>= 8;
13621       unwind.opcode_count++;
13622     }
13623 }
13624
13625 /* Add unwind opcodes to adjust the stack pointer.  */
13626
13627 static void
13628 add_unwind_adjustsp (offsetT offset)
13629 {
13630   valueT op;
13631
13632   if (offset > 0x200)
13633     {
13634       /* We need at most 5 bytes to hold a 32-bit value in a uleb128.  */
13635       char bytes[5];
13636       int n;
13637       valueT o;
13638
13639       /* Long form: 0xb2, uleb128.  */
13640       /* This might not fit in a word so add the individual bytes,
13641          remembering the list is built in reverse order.  */
13642       o = (valueT) ((offset - 0x204) >> 2);
13643       if (o == 0)
13644         add_unwind_opcode (0, 1);
13645
13646       /* Calculate the uleb128 encoding of the offset.  */
13647       n = 0;
13648       while (o)
13649         {
13650           bytes[n] = o & 0x7f;
13651           o >>= 7;
13652           if (o)
13653             bytes[n] |= 0x80;
13654           n++;
13655         }
13656       /* Add the insn.  */
13657       for (; n; n--)
13658         add_unwind_opcode (bytes[n - 1], 1);
13659       add_unwind_opcode (0xb2, 1);
13660     }
13661   else if (offset > 0x100)
13662     {
13663       /* Two short opcodes.  */
13664       add_unwind_opcode (0x3f, 1);
13665       op = (offset - 0x104) >> 2;
13666       add_unwind_opcode (op, 1);
13667     }
13668   else if (offset > 0)
13669     {
13670       /* Short opcode.  */
13671       op = (offset - 4) >> 2;
13672       add_unwind_opcode (op, 1);
13673     }
13674   else if (offset < 0)
13675     {
13676       offset = -offset;
13677       while (offset > 0x100)
13678         {
13679           add_unwind_opcode (0x7f, 1);
13680           offset -= 0x100;
13681         }
13682       op = ((offset - 4) >> 2) | 0x40;
13683       add_unwind_opcode (op, 1);
13684     }
13685 }
13686
13687 /* Finish the list of unwind opcodes for this function.  */
13688 static void
13689 finish_unwind_opcodes (void)
13690 {
13691   valueT op;
13692
13693   if (unwind.fp_used)
13694     {
13695       /* Adjust sp as neccessary.  */
13696       unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
13697       flush_pending_unwind ();
13698
13699       /* After restoring sp from the frame pointer.  */
13700       op = 0x90 | unwind.fp_reg;
13701       add_unwind_opcode (op, 1);
13702     }
13703   else
13704     flush_pending_unwind ();
13705 }
13706
13707
13708 /* Start an exception table entry.  If idx is nonzero this is an index table
13709    entry.  */
13710
13711 static void
13712 start_unwind_section (const segT text_seg, int idx)
13713 {
13714   const char * text_name;
13715   const char * prefix;
13716   const char * prefix_once;
13717   size_t prefix_len;
13718   size_t text_len;
13719   char * sec_name;
13720   size_t sec_name_len;
13721
13722   if (idx)
13723     {
13724       prefix = ELF_STRING_ARM_unwind;
13725       prefix_once = ELF_STRING_ARM_unwind_once;
13726     }
13727   else
13728     {
13729       prefix = ELF_STRING_ARM_unwind_info;
13730       prefix_once = ELF_STRING_ARM_unwind_info_once;
13731     }
13732
13733   text_name = segment_name (text_seg);
13734   if (streq (text_name, ".text"))
13735     text_name = "";
13736
13737   if (strncmp (text_name, ".gnu.linkonce.t.",
13738                strlen (".gnu.linkonce.t.")) == 0)
13739     {
13740       prefix = prefix_once;
13741       text_name += strlen (".gnu.linkonce.t.");
13742     }
13743
13744   prefix_len = strlen (prefix);
13745   text_len = strlen (text_name);
13746   sec_name_len = prefix_len + text_len;
13747   sec_name = alloca (sec_name_len + 1);
13748   memcpy (sec_name, prefix, prefix_len);
13749   memcpy (sec_name + prefix_len, text_name, text_len);
13750   sec_name[prefix_len + text_len] = '\0';
13751
13752   /* Handle COMDAT group.  */
13753   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
13754     {
13755       char *section;
13756       size_t len, group_name_len;
13757       const char *group_name = elf_group_name (text_seg);
13758
13759       if (group_name == NULL)
13760         {
13761           as_bad ("Group section `%s' has no group signature",
13762                   segment_name (text_seg));
13763           ignore_rest_of_line ();
13764           return;
13765         }
13766       /* We have to construct a fake section directive.  */
13767       group_name_len = strlen (group_name);
13768       if (idx)
13769         prefix_len = 13;
13770       else
13771         prefix_len = 16;
13772
13773       len = (sec_name_len
13774              + prefix_len             /* ,"aG",%sectiontype,  */
13775              + group_name_len         /* ,group_name  */
13776              + 7);                    /* ,comdat  */
13777
13778       section = alloca (len + 1);
13779       memcpy (section, sec_name, sec_name_len);
13780       if (idx)
13781           memcpy (section + sec_name_len, ",\"aG\",%exidx,", 13);
13782       else
13783           memcpy (section + sec_name_len, ",\"aG\",%progbits,", 16);
13784       memcpy (section + sec_name_len + prefix_len, group_name, group_name_len);
13785       memcpy (section + len - 7, ",comdat", 7);
13786       section [len] = '\0';
13787       set_section (section);
13788     }
13789   else
13790     {
13791       set_section (sec_name);
13792       bfd_set_section_flags (stdoutput, now_seg,
13793                              SEC_LOAD | SEC_ALLOC | SEC_READONLY);
13794     }
13795
13796   /* Set the setion link for index tables.  */
13797   if (idx)
13798     elf_linked_to_section (now_seg) = text_seg;
13799 }
13800
13801
13802 /* Start an unwind table entry.  HAVE_DATA is nonzero if we have additional
13803    personality routine data.  Returns zero, or the index table value for
13804    and inline entry.  */
13805
13806 static valueT
13807 create_unwind_entry (int have_data)
13808 {
13809   int size;
13810   addressT where;
13811   unsigned char *ptr;
13812   /* The current word of data.  */
13813   valueT data;
13814   /* The number of bytes left in this word.  */
13815   int n;
13816
13817   finish_unwind_opcodes ();
13818
13819   /* Remember the current text section.  */
13820   unwind.saved_seg = now_seg;
13821   unwind.saved_subseg = now_subseg;
13822
13823   start_unwind_section (now_seg, 0);
13824
13825   if (unwind.personality_routine == NULL)
13826     {
13827       if (unwind.personality_index == -2)
13828         {
13829           if (have_data)
13830             as_bad (_("handerdata in cantunwind frame"));
13831           return 1; /* EXIDX_CANTUNWIND.  */
13832         }
13833
13834       /* Use a default personality routine if none is specified.  */
13835       if (unwind.personality_index == -1)
13836         {
13837           if (unwind.opcode_count > 3)
13838             unwind.personality_index = 1;
13839           else
13840             unwind.personality_index = 0;
13841         }
13842
13843       /* Space for the personality routine entry.  */
13844       if (unwind.personality_index == 0)
13845         {
13846           if (unwind.opcode_count > 3)
13847             as_bad (_("too many unwind opcodes for personality routine 0"));
13848
13849           if (!have_data)
13850             {
13851               /* All the data is inline in the index table.  */
13852               data = 0x80;
13853               n = 3;
13854               while (unwind.opcode_count > 0)
13855                 {
13856                   unwind.opcode_count--;
13857                   data = (data << 8) | unwind.opcodes[unwind.opcode_count];
13858                   n--;
13859                 }
13860
13861               /* Pad with "finish" opcodes.  */
13862               while (n--)
13863                 data = (data << 8) | 0xb0;
13864
13865               return data;
13866             }
13867           size = 0;
13868         }
13869       else
13870         /* We get two opcodes "free" in the first word.  */
13871         size = unwind.opcode_count - 2;
13872     }
13873   else
13874     /* An extra byte is required for the opcode count.  */
13875     size = unwind.opcode_count + 1;
13876
13877   size = (size + 3) >> 2;
13878   if (size > 0xff)
13879     as_bad (_("too many unwind opcodes"));
13880
13881   frag_align (2, 0, 0);
13882   record_alignment (now_seg, 2);
13883   unwind.table_entry = expr_build_dot ();
13884
13885   /* Allocate the table entry.  */
13886   ptr = frag_more ((size << 2) + 4);
13887   where = frag_now_fix () - ((size << 2) + 4);
13888
13889   switch (unwind.personality_index)
13890     {
13891     case -1:
13892       /* ??? Should this be a PLT generating relocation?  */
13893       /* Custom personality routine.  */
13894       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
13895                BFD_RELOC_ARM_PREL31);
13896       where += 4;
13897       ptr += 4;
13898
13899       /* Set the first byte to the number of additional words.  */
13900       data = size - 1;
13901       n = 3;
13902       break;
13903
13904     /* ABI defined personality routines.  */
13905     /* TODO: Emit R_ARM_NONE to the personality routine.  */
13906     case 0:
13907       /* Three opcodes bytes are packed into the first word.  */
13908       data = 0x80;
13909       n = 3;
13910       break;
13911
13912     case 1:
13913     case 2:
13914       /* The size and first two opcode bytes go in the first word.  */
13915       data = ((0x80 + unwind.personality_index) << 8) | size;
13916       n = 2;
13917       break;
13918
13919     default:
13920       /* Should never happen.  */
13921       abort ();
13922     }
13923
13924   /* Pack the opcodes into words (MSB first), reversing the list at the same
13925      time.  */
13926   while (unwind.opcode_count > 0)
13927     {
13928       if (n == 0)
13929         {
13930           md_number_to_chars (ptr, data, 4);
13931           ptr += 4;
13932           n = 4;
13933           data = 0;
13934         }
13935       unwind.opcode_count--;
13936       n--;
13937       data = (data << 8) | unwind.opcodes[unwind.opcode_count];
13938     }
13939
13940   /* Finish off the last word.  */
13941   if (n < 4)
13942     {
13943       /* Pad with "finish" opcodes.  */
13944       while (n--)
13945         data = (data << 8) | 0xb0;
13946
13947       md_number_to_chars (ptr, data, 4);
13948     }
13949
13950   if (!have_data)
13951     {
13952       /* Add an empty descriptor if there is no user-specified data.   */
13953       ptr = frag_more (4);
13954       md_number_to_chars (ptr, 0, 4);
13955     }
13956
13957   return 0;
13958 }
13959
13960
13961 /* Parse an unwind_fnstart directive.  Simply records the current location.  */
13962
13963 static void
13964 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
13965 {
13966   demand_empty_rest_of_line ();
13967   /* Mark the start of the function.  */
13968   unwind.proc_start = expr_build_dot ();
13969
13970   /* Reset the rest of the unwind info.  */
13971   unwind.opcode_count = 0;
13972   unwind.table_entry = NULL;
13973   unwind.personality_routine = NULL;
13974   unwind.personality_index = -1;
13975   unwind.frame_size = 0;
13976   unwind.fp_offset = 0;
13977   unwind.fp_reg = 13;
13978   unwind.fp_used = 0;
13979   unwind.sp_restored = 0;
13980 }
13981
13982
13983 /* Parse a handlerdata directive.  Creates the exception handling table entry
13984    for the function.  */
13985
13986 static void
13987 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
13988 {
13989   demand_empty_rest_of_line ();
13990   if (unwind.table_entry)
13991     as_bad (_("dupicate .handlerdata directive"));
13992
13993   create_unwind_entry (1);
13994 }
13995
13996 /* Parse an unwind_fnend directive.  Generates the index table entry.  */
13997
13998 static void
13999 s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
14000 {
14001   long where;
14002   unsigned char *ptr;
14003   valueT val;
14004
14005   demand_empty_rest_of_line ();
14006
14007   /* Add eh table entry.  */
14008   if (unwind.table_entry == NULL)
14009     val = create_unwind_entry (0);
14010   else
14011     val = 0;
14012
14013   /* Add index table entry.  This is two words.  */
14014   start_unwind_section (unwind.saved_seg, 1);
14015   frag_align (2, 0, 0);
14016   record_alignment (now_seg, 2);
14017
14018   ptr = frag_more (8);
14019   where = frag_now_fix () - 8;
14020
14021   /* Self relative offset of the function start.  */
14022   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
14023            BFD_RELOC_ARM_PREL31);
14024
14025   if (val)
14026     /* Inline exception table entry.  */
14027     md_number_to_chars (ptr + 4, val, 4);
14028   else
14029     /* Self relative offset of the table entry.  */
14030     fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
14031              BFD_RELOC_ARM_PREL31);
14032
14033   /* Restore the original section.  */
14034   subseg_set (unwind.saved_seg, unwind.saved_subseg);
14035 }
14036
14037
14038 /* Parse an unwind_cantunwind directive.  */
14039
14040 static void
14041 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
14042 {
14043   demand_empty_rest_of_line ();
14044   if (unwind.personality_routine || unwind.personality_index != -1)
14045     as_bad (_("personality routine specified for cantunwind frame"));
14046
14047   unwind.personality_index = -2;
14048 }
14049
14050
14051 /* Parse a personalityindex directive.  */
14052
14053 static void
14054 s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
14055 {
14056   expressionS exp;
14057
14058   if (unwind.personality_routine || unwind.personality_index != -1)
14059     as_bad (_("duplicate .personalityindex directive"));
14060
14061   SKIP_WHITESPACE ();
14062
14063   expression (&exp);
14064
14065   if (exp.X_op != O_constant
14066       || exp.X_add_number < 0 || exp.X_add_number > 15)
14067     {
14068       as_bad (_("bad personality routine number"));
14069       ignore_rest_of_line ();
14070       return;
14071     }
14072
14073   unwind.personality_index = exp.X_add_number;
14074
14075   demand_empty_rest_of_line ();
14076 }
14077
14078
14079 /* Parse a personality directive.  */
14080
14081 static void
14082 s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
14083 {
14084   char *name, *p, c;
14085
14086   if (unwind.personality_routine || unwind.personality_index != -1)
14087     as_bad (_("duplicate .personality directive"));
14088
14089   SKIP_WHITESPACE ();
14090   name = input_line_pointer;
14091   c = get_symbol_end ();
14092   p = input_line_pointer;
14093   unwind.personality_routine = symbol_find_or_make (name);
14094   *p = c;
14095   SKIP_WHITESPACE ();
14096   demand_empty_rest_of_line ();
14097 }
14098
14099
14100 /* Parse a directive saving core registers.  */
14101
14102 static void
14103 s_arm_unwind_save_core (void)
14104 {
14105   valueT op;
14106   long range;
14107   int n;
14108
14109   SKIP_WHITESPACE ();
14110   range = reg_list (&input_line_pointer);
14111   if (range == FAIL)
14112     {
14113       as_bad (_("expected register list"));
14114       ignore_rest_of_line ();
14115       return;
14116     }
14117
14118   demand_empty_rest_of_line ();
14119
14120   /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
14121      into .unwind_save {..., sp...}.  We aren't bothered about the value of
14122      ip because it is clobbered by calls.  */
14123   if (unwind.sp_restored && unwind.fp_reg == 12
14124       && (range & 0x3000) == 0x1000)
14125     {
14126       unwind.opcode_count--;
14127       unwind.sp_restored = 0;
14128       range = (range | 0x2000) & ~0x1000;
14129       unwind.pending_offset = 0;
14130     }
14131
14132   /* See if we can use the short opcodes.  These pop a block of upto 8
14133      registers starting with r4, plus maybe r14.  */
14134   for (n = 0; n < 8; n++)
14135     {
14136       /* Break at the first non-saved register.  */
14137       if ((range & (1 << (n + 4))) == 0)
14138         break;
14139     }
14140   /* See if there are any other bits set.  */
14141   if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
14142     {
14143       /* Use the long form.  */
14144       op = 0x8000 | ((range >> 4) & 0xfff);
14145       add_unwind_opcode (op, 2);
14146     }
14147   else
14148     {
14149       /* Use the short form.  */
14150       if (range & 0x4000)
14151         op = 0xa8; /* Pop r14.  */
14152       else
14153         op = 0xa0; /* Do not pop r14.  */
14154       op |= (n - 1);
14155       add_unwind_opcode (op, 1);
14156     }
14157
14158   /* Pop r0-r3.  */
14159   if (range & 0xf)
14160     {
14161       op = 0xb100 | (range & 0xf);
14162       add_unwind_opcode (op, 2);
14163     }
14164
14165   /* Record the number of bytes pushed.  */
14166   for (n = 0; n < 16; n++)
14167     {
14168       if (range & (1 << n))
14169         unwind.frame_size += 4;
14170     }
14171 }
14172
14173
14174 /* Parse a directive saving FPA registers.  */
14175
14176 static void
14177 s_arm_unwind_save_fpa (int reg)
14178 {
14179   expressionS exp;
14180   int num_regs;
14181   valueT op;
14182
14183   /* Get Number of registers to transfer.  */
14184   if (skip_past_comma (&input_line_pointer) != FAIL)
14185     expression (&exp);
14186   else
14187     exp.X_op = O_illegal;
14188
14189   if (exp.X_op != O_constant)
14190     {
14191       as_bad (_("expected , <constant>"));
14192       ignore_rest_of_line ();
14193       return;
14194     }
14195
14196   num_regs = exp.X_add_number;
14197
14198   if (num_regs < 1 || num_regs > 4)
14199     {
14200       as_bad (_("number of registers must be in the range [1:4]"));
14201       ignore_rest_of_line ();
14202       return;
14203     }
14204
14205   demand_empty_rest_of_line ();
14206
14207   if (reg == 4)
14208     {
14209       /* Short form.  */
14210       op = 0xb4 | (num_regs - 1);
14211       add_unwind_opcode (op, 1);
14212     }
14213   else
14214     {
14215       /* Long form.  */
14216       op = 0xc800 | (reg << 4) | (num_regs - 1);
14217       add_unwind_opcode (op, 2);
14218     }
14219   unwind.frame_size += num_regs * 12;
14220 }
14221
14222
14223 /* Parse a directive saving VFP registers.  */
14224
14225 static void
14226 s_arm_unwind_save_vfp (void)
14227 {
14228   int count;
14229   int reg;
14230   valueT op;
14231
14232   count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
14233   if (count == FAIL)
14234     {
14235       as_bad (_("expected register list"));
14236       ignore_rest_of_line ();
14237       return;
14238     }
14239
14240   demand_empty_rest_of_line ();
14241
14242   if (reg == 8)
14243     {
14244       /* Short form.  */
14245       op = 0xb8 | (count - 1);
14246       add_unwind_opcode (op, 1);
14247     }
14248   else
14249     {
14250       /* Long form.  */
14251       op = 0xb300 | (reg << 4) | (count - 1);
14252       add_unwind_opcode (op, 2);
14253     }
14254   unwind.frame_size += count * 8 + 4;
14255 }
14256
14257
14258 /* Parse a directive saving iWMMXt registers.  */
14259
14260 static void
14261 s_arm_unwind_save_wmmx (void)
14262 {
14263   int reg;
14264   int hi_reg;
14265   int i;
14266   unsigned wcg_mask;
14267   unsigned wr_mask;
14268   valueT op;
14269
14270   if (*input_line_pointer == '{')
14271     input_line_pointer++;
14272
14273   wcg_mask = 0;
14274   wr_mask = 0;
14275   do
14276     {
14277       reg = arm_reg_parse (&input_line_pointer,
14278                            all_reg_maps[REG_TYPE_IWMMXT].htab);
14279
14280       if (wr_register (reg))
14281         {
14282           i = reg & ~WR_PREFIX;
14283           if (wr_mask >> i)
14284             as_tsktsk (_("register list not in ascending order"));
14285           wr_mask |= 1 << i;
14286         }
14287       else if (wcg_register (reg))
14288         {
14289           i = (reg & ~WC_PREFIX) - 8;
14290           if (wcg_mask >> i)
14291             as_tsktsk (_("register list not in ascending order"));
14292           wcg_mask |= 1 << i;
14293         }
14294       else
14295         {
14296           as_bad (_("expected wr or wcgr"));
14297           goto error;
14298         }
14299
14300       SKIP_WHITESPACE ();
14301       if (*input_line_pointer == '-')
14302         {
14303           hi_reg = arm_reg_parse (&input_line_pointer,
14304                                   all_reg_maps[REG_TYPE_IWMMXT].htab);
14305           if (wr_register (reg) && wr_register (hi_reg))
14306             {
14307               for (; reg < hi_reg; reg++)
14308                 wr_mask |= 1 << (reg & ~WR_PREFIX);
14309             }
14310           else if (wcg_register (reg) && wcg_register (hi_reg))
14311             {
14312               for (; reg < hi_reg; reg++)
14313                 wcg_mask |= 1 << ((reg & ~WC_PREFIX) - 8);
14314             }
14315           else
14316             {
14317               as_bad (_("bad register range"));
14318               goto error;
14319             }
14320         }
14321     }
14322   while (skip_past_comma (&input_line_pointer) != FAIL);
14323
14324   SKIP_WHITESPACE ();
14325   if (*input_line_pointer == '}')
14326     input_line_pointer++;
14327
14328   demand_empty_rest_of_line ();
14329
14330   if (wr_mask && wcg_mask)
14331     {
14332       as_bad (_("inconsistent register types"));
14333       goto error;
14334     }
14335
14336   /* Generate any deferred opcodes becuuse we're going to be looking at
14337      the list.  */
14338   flush_pending_unwind ();
14339
14340   if (wcg_mask)
14341     {
14342       for (i = 0; i < 16; i++)
14343         {
14344           if (wcg_mask & (1 << i))
14345             unwind.frame_size += 4;
14346         }
14347       op = 0xc700 | wcg_mask;
14348       add_unwind_opcode (op, 2);
14349     }
14350   else
14351     {
14352       for (i = 0; i < 16; i++)
14353         {
14354           if (wr_mask & (1 << i))
14355             unwind.frame_size += 8;
14356         }
14357       /* Attempt to combine with a previous opcode.  We do this because gcc
14358          likes to output separate unwind directives for a single block of
14359          registers.  */
14360       if (unwind.opcode_count > 0)
14361         {
14362           i = unwind.opcodes[unwind.opcode_count - 1];
14363           if ((i & 0xf8) == 0xc0)
14364             {
14365               i &= 7;
14366               /* Only merge if the blocks are contiguous.  */
14367               if (i < 6)
14368                 {
14369                   if ((wr_mask & 0xfe00) == (1 << 9))
14370                     {
14371                       wr_mask |= ((1 << (i + 11)) - 1) & 0xfc00;
14372                       unwind.opcode_count--;
14373                     }
14374                 }
14375               else if (i == 6 && unwind.opcode_count >= 2)
14376                 {
14377                   i = unwind.opcodes[unwind.opcode_count - 2];
14378                   reg = i >> 4;
14379                   i &= 0xf;
14380
14381                   op = 0xffff << (reg - 1);
14382                   if (reg > 0
14383                       || ((wr_mask & op) == (1u << (reg - 1))))
14384                     {
14385                       op = (1 << (reg + i + 1)) - 1;
14386                       op &= ~((1 << reg) - 1);
14387                       wr_mask |= op;
14388                       unwind.opcode_count -= 2;
14389                     }
14390                 }
14391             }
14392         }
14393
14394       hi_reg = 15;
14395       /* We want to generate opcodes in the order the registers have been
14396          saved, ie. descending order.  */
14397       for (reg = 15; reg >= -1; reg--)
14398         {
14399           /* Save registers in blocks.  */
14400           if (reg < 0
14401               || !(wr_mask & (1 << reg)))
14402             {
14403               /* We found an unsaved reg.  Generate opcodes to save the
14404                  preceeding block.  */
14405               if (reg != hi_reg)
14406                 {
14407                   if (reg == 9)
14408                     {
14409                       /* Short form.  */
14410                       op = 0xc0 | (hi_reg - 10);
14411                       add_unwind_opcode (op, 1);
14412                     }
14413                   else
14414                     {
14415                       /* Long form.  */
14416                       op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
14417                       add_unwind_opcode (op, 2);
14418                     }
14419                 }
14420               hi_reg = reg - 1;
14421             }
14422         }
14423     }
14424   return;
14425 error:
14426   ignore_rest_of_line ();
14427 }
14428
14429
14430 /* Parse an unwind_save directive.  */
14431
14432 static void
14433 s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
14434 {
14435   char *saved_ptr;
14436   int reg;
14437
14438   /* Figure out what sort of save we have.  */
14439   SKIP_WHITESPACE ();
14440   saved_ptr = input_line_pointer;
14441
14442   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_FN].htab);
14443   if (reg != FAIL)
14444     {
14445       s_arm_unwind_save_fpa (reg);
14446       return;
14447     }
14448
14449   if (*input_line_pointer == '{')
14450     input_line_pointer++;
14451
14452   SKIP_WHITESPACE ();
14453
14454   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_RN].htab);
14455   if (reg != FAIL)
14456     {
14457       input_line_pointer = saved_ptr;
14458       s_arm_unwind_save_core ();
14459       return;
14460     }
14461
14462   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_DN].htab);
14463   if (reg != FAIL)
14464     {
14465       input_line_pointer = saved_ptr;
14466       s_arm_unwind_save_vfp ();
14467       return;
14468     }
14469
14470   reg = arm_reg_parse (&input_line_pointer,
14471                        all_reg_maps[REG_TYPE_IWMMXT].htab);
14472   if (reg != FAIL)
14473     {
14474       input_line_pointer = saved_ptr;
14475       s_arm_unwind_save_wmmx ();
14476       return;
14477     }
14478
14479   /* TODO: Maverick registers.  */
14480   as_bad (_("unrecognised register"));
14481 }
14482
14483
14484 /* Parse an unwind_movsp directive.  */
14485
14486 static void
14487 s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
14488 {
14489   int reg;
14490   valueT op;
14491
14492   SKIP_WHITESPACE ();
14493   reg = reg_required_here (&input_line_pointer, -1);
14494   if (reg == FAIL)
14495     {
14496       as_bad (_("ARM register expected"));
14497       ignore_rest_of_line ();
14498       return;
14499     }
14500
14501   if (reg == 13 || reg == 15)
14502     {
14503       as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
14504       ignore_rest_of_line ();
14505       return;
14506     }
14507
14508   if (unwind.fp_reg != 13)
14509     as_bad (_("unexpected .unwind_movsp directive"));
14510
14511   /* Generate opcode to restore the value.  */
14512   op = 0x90 | reg;
14513   add_unwind_opcode (op, 1);
14514
14515   /* Record the information for later.  */
14516   unwind.fp_reg = reg;
14517   unwind.fp_offset = unwind.frame_size;
14518   unwind.sp_restored = 1;
14519   demand_empty_rest_of_line ();
14520 }
14521
14522
14523 /* Parse #<number>.  */
14524
14525 static int
14526 require_hashconst (int * val)
14527 {
14528   expressionS exp;
14529
14530   SKIP_WHITESPACE ();
14531   if (*input_line_pointer == '#')
14532     {
14533       input_line_pointer++;
14534       expression (&exp);
14535     }
14536   else
14537     exp.X_op = O_illegal;
14538
14539   if (exp.X_op != O_constant)
14540     {
14541       as_bad (_("expected #constant"));
14542       ignore_rest_of_line ();
14543       return FAIL;
14544     }
14545   *val = exp.X_add_number;
14546   return SUCCESS;
14547 }
14548
14549 /* Parse an unwind_pad directive.  */
14550
14551 static void
14552 s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
14553 {
14554   int offset;
14555
14556   if (require_hashconst (&offset) == FAIL)
14557     return;
14558
14559   if (offset & 3)
14560     {
14561       as_bad (_("stack increment must be multiple of 4"));
14562       ignore_rest_of_line ();
14563       return;
14564     }
14565
14566   /* Don't generate any opcodes, just record the details for later.  */
14567   unwind.frame_size += offset;
14568   unwind.pending_offset += offset;
14569
14570   demand_empty_rest_of_line ();
14571 }
14572
14573 /* Parse an unwind_setfp directive.  */
14574
14575 static void
14576 s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
14577 {
14578   int sp_reg;
14579   int fp_reg;
14580   int offset;
14581
14582   fp_reg = reg_required_here (&input_line_pointer, -1);
14583   if (skip_past_comma (&input_line_pointer) == FAIL)
14584     sp_reg = FAIL;
14585   else
14586     sp_reg = reg_required_here (&input_line_pointer, -1);
14587
14588   if (fp_reg == FAIL || sp_reg == FAIL)
14589     {
14590       as_bad (_("expected <reg>, <reg>"));
14591       ignore_rest_of_line ();
14592       return;
14593     }
14594
14595   /* Optonal constant.  */
14596   if (skip_past_comma (&input_line_pointer) != FAIL)
14597     {
14598       if (require_hashconst (&offset) == FAIL)
14599         return;
14600     }
14601   else
14602     offset = 0;
14603
14604   demand_empty_rest_of_line ();
14605
14606   if (sp_reg != 13 && sp_reg != unwind.fp_reg)
14607     {
14608       as_bad (_("register must be either sp or set by a previous"
14609                 "unwind_movsp directive"));
14610       return;
14611     }
14612
14613   /* Don't generate any opcodes, just record the information for later.  */
14614   unwind.fp_reg = fp_reg;
14615   unwind.fp_used = 1;
14616   if (sp_reg == 13)
14617     unwind.fp_offset = unwind.frame_size - offset;
14618   else
14619     unwind.fp_offset -= offset;
14620 }
14621
14622 /* Parse an unwind_raw directive.  */
14623
14624 static void
14625 s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
14626 {
14627   expressionS exp;
14628   /* This is an arbitary limit.  */
14629   unsigned char op[16];
14630   int count;
14631
14632   SKIP_WHITESPACE ();
14633   expression (&exp);
14634   if (exp.X_op == O_constant
14635       && skip_past_comma (&input_line_pointer) != FAIL)
14636     {
14637       unwind.frame_size += exp.X_add_number;
14638       expression (&exp);
14639     }
14640   else
14641     exp.X_op = O_illegal;
14642
14643   if (exp.X_op != O_constant)
14644     {
14645       as_bad (_("expected <offset>, <opcode>"));
14646       ignore_rest_of_line ();
14647       return;
14648     }
14649
14650   count = 0;
14651
14652   /* Parse the opcode.  */
14653   for (;;)
14654     {
14655       if (count >= 16)
14656         {
14657           as_bad (_("unwind opcode too long"));
14658           ignore_rest_of_line ();
14659         }
14660       if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
14661         {
14662           as_bad (_("invalid unwind opcode"));
14663           ignore_rest_of_line ();
14664           return;
14665         }
14666       op[count++] = exp.X_add_number;
14667
14668       /* Parse the next byte.  */
14669       if (skip_past_comma (&input_line_pointer) == FAIL)
14670         break;
14671
14672       expression (&exp);
14673     }
14674
14675   /* Add the opcode bytes in reverse order.  */
14676   while (count--)
14677     add_unwind_opcode (op[count], 1);
14678
14679   demand_empty_rest_of_line ();
14680 }
14681
14682 #endif /* OBJ_ELF */
14683
14684 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14685    of an rs_align_code fragment.  */
14686
14687 void
14688 arm_handle_align (fragS * fragP)
14689 {
14690   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14691   static char const thumb_noop[2] = { 0xc0, 0x46 };
14692   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14693   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14694
14695   int bytes, fix, noop_size;
14696   char * p;
14697   const char * noop;
14698
14699   if (fragP->fr_type != rs_align_code)
14700     return;
14701
14702   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14703   p = fragP->fr_literal + fragP->fr_fix;
14704   fix = 0;
14705
14706   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14707     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14708
14709   if (fragP->tc_frag_data)
14710     {
14711       if (target_big_endian)
14712         noop = thumb_bigend_noop;
14713       else
14714         noop = thumb_noop;
14715       noop_size = sizeof (thumb_noop);
14716     }
14717   else
14718     {
14719       if (target_big_endian)
14720         noop = arm_bigend_noop;
14721       else
14722         noop = arm_noop;
14723       noop_size = sizeof (arm_noop);
14724     }
14725
14726   if (bytes & (noop_size - 1))
14727     {
14728       fix = bytes & (noop_size - 1);
14729       memset (p, 0, fix);
14730       p += fix;
14731       bytes -= fix;
14732     }
14733
14734   while (bytes >= noop_size)
14735     {
14736       memcpy (p, noop, noop_size);
14737       p += noop_size;
14738       bytes -= noop_size;
14739       fix += noop_size;
14740     }
14741
14742   fragP->fr_fix += fix;
14743   fragP->fr_var = noop_size;
14744 }
14745
14746 /* Called from md_do_align.  Used to create an alignment
14747    frag in a code section.  */
14748
14749 void
14750 arm_frag_align_code (int n, int max)
14751 {
14752   char * p;
14753
14754   /* We assume that there will never be a requirement
14755      to support alignments greater than 32 bytes.  */
14756   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14757     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14758
14759   p = frag_var (rs_align_code,
14760                 MAX_MEM_FOR_RS_ALIGN_CODE,
14761                 1,
14762                 (relax_substateT) max,
14763                 (symbolS *) NULL,
14764                 (offsetT) n,
14765                 (char *) NULL);
14766   *p = 0;
14767 }
14768
14769 /* Perform target specific initialisation of a frag.  */
14770
14771 void
14772 arm_init_frag (fragS * fragP)
14773 {
14774   /* Record whether this frag is in an ARM or a THUMB area.  */
14775   fragP->tc_frag_data = thumb_mode;
14776 }
14777
14778 #ifdef OBJ_ELF
14779
14780 /* Convert REGNAME to a DWARF-2 register number.  */
14781
14782 int
14783 tc_arm_regname_to_dw2regnum (const char *regname)
14784 {
14785   unsigned int i;
14786
14787   for (i = 0; rn_table[i].name; i++)
14788     if (streq (regname, rn_table[i].name))
14789       return rn_table[i].number;
14790
14791   return -1;
14792 }
14793
14794 /* Initialize the DWARF-2 unwind information for this procedure.  */
14795
14796 void
14797 tc_arm_frame_initial_instructions (void)
14798 {
14799   cfi_add_CFA_def_cfa (REG_SP, 0);
14800 }
14801 #endif
14802
14803 /* This table describes all the machine specific pseudo-ops the assembler
14804    has to support.  The fields are:
14805      pseudo-op name without dot
14806      function to call to execute this pseudo-op
14807      Integer arg to pass to the function.  */
14808
14809 const pseudo_typeS md_pseudo_table[] =
14810 {
14811   /* Never called because '.req' does not start a line.  */
14812   { "req",         s_req,         0 },
14813   { "unreq",       s_unreq,       0 },
14814   { "bss",         s_bss,         0 },
14815   { "align",       s_align,       0 },
14816   { "arm",         s_arm,         0 },
14817   { "thumb",       s_thumb,       0 },
14818   { "code",        s_code,        0 },
14819   { "force_thumb", s_force_thumb, 0 },
14820   { "thumb_func",  s_thumb_func,  0 },
14821   { "thumb_set",   s_thumb_set,   0 },
14822   { "even",        s_even,        0 },
14823   { "ltorg",       s_ltorg,       0 },
14824   { "pool",        s_ltorg,       0 },
14825 #ifdef OBJ_ELF
14826   { "word",        s_arm_elf_cons, 4 },
14827   { "long",        s_arm_elf_cons, 4 },
14828   { "rel31",       s_arm_rel31,   0 },
14829   { "fnstart",          s_arm_unwind_fnstart,   0 },
14830   { "fnend",            s_arm_unwind_fnend,     0 },
14831   { "cantunwind",       s_arm_unwind_cantunwind, 0 },
14832   { "personality",      s_arm_unwind_personality, 0 },
14833   { "personalityindex", s_arm_unwind_personalityindex, 0 },
14834   { "handlerdata",      s_arm_unwind_handlerdata, 0 },
14835   { "save",             s_arm_unwind_save,      0 },
14836   { "movsp",            s_arm_unwind_movsp,     0 },
14837   { "pad",              s_arm_unwind_pad,       0 },
14838   { "setfp",            s_arm_unwind_setfp,     0 },
14839   { "unwind_raw",       s_arm_unwind_raw,       0 },
14840 #else
14841   { "word",        cons, 4},
14842 #endif
14843   { "extend",      float_cons, 'x' },
14844   { "ldouble",     float_cons, 'x' },
14845   { "packed",      float_cons, 'p' },
14846   { 0, 0, 0 }
14847 };
This page took 0.820793 seconds and 4 git commands to generate.