]> Git Repo - binutils.git/blob - gas/config/tc-arm.c
* config/tc-m88k.c (get_reg): Make reg_prefix param unsigned.
[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
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw ([email protected])
5         Modified by David Taylor ([email protected])
6         Cirrus coprocessor mods by Aldy Hernandez ([email protected])
7
8    This file is part of GAS, the GNU Assembler.
9
10    GAS is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2, or (at your option)
13    any later version.
14
15    GAS is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with GAS; see the file COPYING.  If not, write to the Free
22    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.  */
24
25 #include <string.h>
26 #define  NO_RELOC 0
27 #include "as.h"
28 #include "safe-ctype.h"
29
30 /* Need TARGET_CPU.  */
31 #include "config.h"
32 #include "subsegs.h"
33 #include "obstack.h"
34 #include "symbols.h"
35 #include "listing.h"
36
37 #ifdef OBJ_ELF
38 #include "elf/arm.h"
39 #include "dwarf2dbg.h"
40 #endif
41
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
44
45 /* The following bitmasks control CPU extensions:  */
46 #define ARM_EXT_V1       0x00000001     /* All processors (core set).  */
47 #define ARM_EXT_V2       0x00000002     /* Multiply instructions.  */
48 #define ARM_EXT_V2S      0x00000004     /* SWP instructions.       */
49 #define ARM_EXT_V3       0x00000008     /* MSR MRS.                */
50 #define ARM_EXT_V3M      0x00000010     /* Allow long multiplies.  */
51 #define ARM_EXT_V4       0x00000020     /* Allow half word loads.  */
52 #define ARM_EXT_V4T      0x00000040     /* Thumb v1.               */
53 #define ARM_EXT_V5       0x00000080     /* Allow CLZ, etc.         */
54 #define ARM_EXT_V5T      0x00000100     /* Thumb v2.               */
55 #define ARM_EXT_V5ExP    0x00000200     /* DSP core set.           */
56 #define ARM_EXT_V5E      0x00000400     /* DSP Double transfers.   */
57 #define ARM_EXT_V5J      0x00000800     /* Jazelle extension.      */
58
59 /* Co-processor space extensions.  */
60 #define ARM_CEXT_XSCALE   0x00800000    /* Allow MIA etc.          */
61 #define ARM_CEXT_MAVERICK 0x00400000    /* Use Cirrus/DSP coprocessor.  */
62
63 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
64    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
65    ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
66    three more to cover cores prior to ARM6.  Finally, there are cores which
67    implement further extensions in the co-processor space.  */
68 #define ARM_ARCH_V1                       ARM_EXT_V1
69 #define ARM_ARCH_V2     (ARM_ARCH_V1    | ARM_EXT_V2)
70 #define ARM_ARCH_V2S    (ARM_ARCH_V2    | ARM_EXT_V2S)
71 #define ARM_ARCH_V3     (ARM_ARCH_V2S   | ARM_EXT_V3)
72 #define ARM_ARCH_V3M    (ARM_ARCH_V3    | ARM_EXT_V3M)
73 #define ARM_ARCH_V4xM   (ARM_ARCH_V3    | ARM_EXT_V4)
74 #define ARM_ARCH_V4     (ARM_ARCH_V3M   | ARM_EXT_V4)
75 #define ARM_ARCH_V4TxM  (ARM_ARCH_V4xM  | ARM_EXT_V4T)
76 #define ARM_ARCH_V4T    (ARM_ARCH_V4    | ARM_EXT_V4T)
77 #define ARM_ARCH_V5xM   (ARM_ARCH_V4xM  | ARM_EXT_V5)
78 #define ARM_ARCH_V5     (ARM_ARCH_V4    | ARM_EXT_V5)
79 #define ARM_ARCH_V5TxM  (ARM_ARCH_V5xM  | ARM_EXT_V4T | ARM_EXT_V5T)
80 #define ARM_ARCH_V5T    (ARM_ARCH_V5    | ARM_EXT_V4T | ARM_EXT_V5T)
81 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T   | ARM_EXT_V5ExP)
82 #define ARM_ARCH_V5TE   (ARM_ARCH_V5TExP | ARM_EXT_V5E)
83 #define ARM_ARCH_V5TEJ  (ARM_ARCH_V5TE  | ARM_EXT_V5J)
84
85 /* Processors with specific extensions in the co-processor space.  */
86 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE  | ARM_CEXT_XSCALE)
87
88 /* Some useful combinations:  */
89 #define ARM_ANY         0x0000ffff      /* Any basic core.  */
90 #define ARM_ALL         0x00ffffff      /* Any core + co-processor */
91 #define CPROC_ANY       0x00ff0000      /* Any co-processor */
92 #define FPU_ANY         0xff000000      /* Note this is ~ARM_ALL.  */
93
94
95 #define FPU_FPA_EXT_V1   0x80000000     /* Base FPA instruction set.  */
96 #define FPU_FPA_EXT_V2   0x40000000     /* LFM/SFM.                   */
97 #define FPU_VFP_EXT_NONE 0x20000000     /* Use VFP word-ordering.     */
98 #define FPU_VFP_EXT_V1xD 0x10000000     /* Base VFP instruction set.  */
99 #define FPU_VFP_EXT_V1   0x08000000     /* Double-precision insns.    */
100 #define FPU_VFP_EXT_V2   0x04000000     /* ARM10E VFPr1.              */
101 #define FPU_NONE         0
102
103 #define FPU_ARCH_FPE     FPU_FPA_EXT_V1
104 #define FPU_ARCH_FPA    (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
105
106 #define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
107 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
108 #define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
109 #define FPU_ARCH_VFP_V2   (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
110
111 /* Types of processor to assemble for.  */
112 #define ARM_1           ARM_ARCH_V1
113 #define ARM_2           ARM_ARCH_V2
114 #define ARM_3           ARM_ARCH_V2S
115 #define ARM_250         ARM_ARCH_V2S
116 #define ARM_6           ARM_ARCH_V3
117 #define ARM_7           ARM_ARCH_V3
118 #define ARM_8           ARM_ARCH_V4
119 #define ARM_9           ARM_ARCH_V4T
120 #define ARM_STRONG      ARM_ARCH_V4
121 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
122
123 #ifndef CPU_DEFAULT
124 #if defined __XSCALE__
125 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
126 #else
127 #if defined __thumb__
128 #define CPU_DEFAULT     (ARM_ARCH_V5T)
129 #else
130 #define CPU_DEFAULT     ARM_ANY
131 #endif
132 #endif
133 #endif
134
135 /* For backwards compatibility we default to the FPA.  */
136 #ifndef FPU_DEFAULT
137 #define FPU_DEFAULT FPU_ARCH_FPA
138 #endif
139
140 #define streq(a, b)           (strcmp (a, b) == 0)
141 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
142
143 static unsigned long cpu_variant;
144 static int target_oabi = 0;
145
146 /* Flags stored in private area of BFD structure.  */
147 static int uses_apcs_26      = FALSE;
148 static int atpcs             = FALSE;
149 static int support_interwork = FALSE;
150 static int uses_apcs_float   = FALSE;
151 static int pic_code          = FALSE;
152
153 /* Variables that we set while parsing command-line options.  Once all
154    options have been read we re-process these values to set the real
155    assembly flags.  */
156 static int legacy_cpu = -1;
157 static int legacy_fpu = -1;
158
159 static int mcpu_cpu_opt = -1;
160 static int mcpu_fpu_opt = -1;
161 static int march_cpu_opt = -1;
162 static int march_fpu_opt = -1;
163 static int mfpu_opt = -1;
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 #define NO_SHIFT_RESTRICT 1
277 #define SHIFT_RESTRICT    0
278
279 #define NUM_FLOAT_VALS 8
280
281 const char * fp_const[] =
282 {
283   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
284 };
285
286 /* Number of littlenums required to hold an extended precision number.  */
287 #define MAX_LITTLENUMS 6
288
289 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
290
291 #define FAIL    (-1)
292 #define SUCCESS (0)
293
294 /* Whether a Co-processor load/store operation accepts write-back forms.  */
295 #define CP_WB_OK 1
296 #define CP_NO_WB 0
297
298 #define SUFF_S 1
299 #define SUFF_D 2
300 #define SUFF_E 3
301 #define SUFF_P 4
302
303 #define CP_T_X   0x00008000
304 #define CP_T_Y   0x00400000
305 #define CP_T_Pre 0x01000000
306 #define CP_T_UD  0x00800000
307 #define CP_T_WB  0x00200000
308
309 #define CONDS_BIT        0x00100000
310 #define LOAD_BIT         0x00100000
311
312 #define DOUBLE_LOAD_FLAG 0x00000001
313
314 struct asm_cond
315 {
316   const char *  template;
317   unsigned long value;
318 };
319
320 #define COND_ALWAYS 0xe0000000
321 #define COND_MASK   0xf0000000
322
323 static const struct asm_cond conds[] =
324 {
325   {"eq", 0x00000000},
326   {"ne", 0x10000000},
327   {"cs", 0x20000000}, {"hs", 0x20000000},
328   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
329   {"mi", 0x40000000},
330   {"pl", 0x50000000},
331   {"vs", 0x60000000},
332   {"vc", 0x70000000},
333   {"hi", 0x80000000},
334   {"ls", 0x90000000},
335   {"ge", 0xa0000000},
336   {"lt", 0xb0000000},
337   {"gt", 0xc0000000},
338   {"le", 0xd0000000},
339   {"al", 0xe0000000},
340   {"nv", 0xf0000000}
341 };
342
343 struct asm_psr
344 {
345   const char *template;
346   bfd_boolean cpsr;
347   unsigned long field;
348 };
349
350 /* The bit that distnguishes CPSR and SPSR.  */
351 #define SPSR_BIT   (1 << 22)
352
353 /* How many bits to shift the PSR_xxx bits up by.  */
354 #define PSR_SHIFT  16
355
356 #define PSR_c   (1 << 0)
357 #define PSR_x   (1 << 1)
358 #define PSR_s   (1 << 2)
359 #define PSR_f   (1 << 3)
360
361 static const struct asm_psr psrs[] =
362 {
363   {"CPSR",      TRUE,  PSR_c | PSR_f},
364   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
365   {"SPSR",      FALSE, PSR_c | PSR_f},
366   {"SPSR_all",  FALSE, PSR_c | PSR_f},
367   {"CPSR_flg",  TRUE,  PSR_f},
368   {"CPSR_f",    TRUE,  PSR_f},
369   {"SPSR_flg",  FALSE, PSR_f},
370   {"SPSR_f",    FALSE, PSR_f},
371   {"CPSR_c",    TRUE,  PSR_c},
372   {"CPSR_ctl",  TRUE,  PSR_c},
373   {"SPSR_c",    FALSE, PSR_c},
374   {"SPSR_ctl",  FALSE, PSR_c},
375   {"CPSR_x",    TRUE,  PSR_x},
376   {"CPSR_s",    TRUE,  PSR_s},
377   {"SPSR_x",    FALSE, PSR_x},
378   {"SPSR_s",    FALSE, PSR_s},
379   /* Combinations of flags.  */
380   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
381   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
382   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
383   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
384   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
385   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
386   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
387   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
388   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
389   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
390   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
391   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
392   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
393   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
394   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
395   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
396   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
397   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
398   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
399   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
400   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
401   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
402   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
403   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
404   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
405   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
406   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
407   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
408   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
409   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
410   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
411   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
412   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
413   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
414   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
415   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
416   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
417   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
418   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
419   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
420   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
421   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
422   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
423   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
424   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
425   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
426   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
427   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
428   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
429   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
430   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
431   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
432   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
433   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
434   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
435   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
436   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
437   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
438   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
439   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
440   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
441   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
442   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
443   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
444   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
445   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
446   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
447   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
448   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
449   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
450   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
451   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
452   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
453   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
454   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
455   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
456   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
457   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
458   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
459   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
460   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
461   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
462   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
463   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
464   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
465   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
466   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
467   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
468   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
469   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
470   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
471   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
472   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
473   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
474   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
475   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
476   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
477   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
478   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
479   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
480   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
481   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
482   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
483   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
484   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
485   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
486   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
487   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
488   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
489   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
490   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
491   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
492   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
493   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
494   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
495   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
496   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
497   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
498   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
499   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
500 };
501
502 enum vfp_dp_reg_pos
503 {
504   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
505 };
506
507 enum vfp_sp_reg_pos
508 {
509   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
510 };
511
512 enum vfp_ldstm_type
513 {
514   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
515 };
516
517 /* VFP system registers.  */
518 struct vfp_reg
519 {
520   const char *name;
521   unsigned long regno;
522 };
523
524 static const struct vfp_reg vfp_regs[] =
525 {
526   {"fpsid", 0x00000000},
527   {"FPSID", 0x00000000},
528   {"fpscr", 0x00010000},
529   {"FPSCR", 0x00010000},
530   {"fpexc", 0x00080000},
531   {"FPEXC", 0x00080000}
532 };
533
534 /* Structure for a hash table entry for a register.  */
535 struct reg_entry
536 {
537   const char * name;
538   int          number;
539 };
540
541 /* Some well known registers that we refer to directly elsewhere.  */
542 #define REG_SP  13
543 #define REG_LR  14
544 #define REG_PC  15
545
546 /* These are the standard names.  Users can add aliases with .req.  */
547 /* Integer Register Numbers.  */
548 static const struct reg_entry rn_table[] =
549 {
550   {"r0",  0},  {"r1",  1},      {"r2",  2},      {"r3",  3},
551   {"r4",  4},  {"r5",  5},      {"r6",  6},      {"r7",  7},
552   {"r8",  8},  {"r9",  9},      {"r10", 10},     {"r11", 11},
553   {"r12", 12}, {"r13", REG_SP}, {"r14", REG_LR}, {"r15", REG_PC},
554   /* ATPCS Synonyms.  */
555   {"a1",  0},  {"a2",  1},      {"a3",  2},      {"a4",  3},
556   {"v1",  4},  {"v2",  5},      {"v3",  6},      {"v4",  7},
557   {"v5",  8},  {"v6",  9},      {"v7",  10},     {"v8",  11},
558   /* Well-known aliases.  */
559                                                  {"wr",  7},
560                {"sb",  9},      {"sl",  10},     {"fp",  11},
561   {"ip",  12}, {"sp",  REG_SP}, {"lr",  REG_LR}, {"pc",  REG_PC},
562   {NULL, 0}
563 };
564
565 /* Co-processor Numbers.  */
566 static const struct reg_entry cp_table[] =
567 {
568   {"p0",  0},  {"p1",  1},  {"p2",  2},  {"p3", 3},
569   {"p4",  4},  {"p5",  5},  {"p6",  6},  {"p7", 7},
570   {"p8",  8},  {"p9",  9},  {"p10", 10}, {"p11", 11},
571   {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
572   {NULL, 0}
573 };
574
575 /* Co-processor Register Numbers.  */
576 static const struct reg_entry cn_table[] =
577 {
578   {"c0",   0},  {"c1",   1},  {"c2",   2},  {"c3",   3},
579   {"c4",   4},  {"c5",   5},  {"c6",   6},  {"c7",   7},
580   {"c8",   8},  {"c9",   9},  {"c10",  10}, {"c11",  11},
581   {"c12",  12}, {"c13",  13}, {"c14",  14}, {"c15",  15},
582   /* Not really valid, but kept for back-wards compatibility.  */
583   {"cr0",  0},  {"cr1",  1},  {"cr2",  2},  {"cr3",  3},
584   {"cr4",  4},  {"cr5",  5},  {"cr6",  6},  {"cr7",  7},
585   {"cr8",  8},  {"cr9",  9},  {"cr10", 10}, {"cr11", 11},
586   {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
587   {NULL, 0}
588 };
589
590 /* FPA Registers.  */
591 static const struct reg_entry fn_table[] =
592 {
593   {"f0", 0},   {"f1", 1},   {"f2", 2},   {"f3", 3},
594   {"f4", 4},   {"f5", 5},   {"f6", 6},   {"f7", 7},
595   {NULL, 0}
596 };
597
598 /* VFP SP Registers.  */
599 static const struct reg_entry sn_table[] =
600 {
601   {"s0",  0},  {"s1",  1},  {"s2",  2},  {"s3", 3},
602   {"s4",  4},  {"s5",  5},  {"s6",  6},  {"s7", 7},
603   {"s8",  8},  {"s9",  9},  {"s10", 10}, {"s11", 11},
604   {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
605   {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
606   {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
607   {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
608   {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
609   {NULL, 0}
610 };
611
612 /* VFP DP Registers.  */
613 static const struct reg_entry dn_table[] =
614 {
615   {"d0",  0},  {"d1",  1},  {"d2",  2},  {"d3", 3},
616   {"d4",  4},  {"d5",  5},  {"d6",  6},  {"d7", 7},
617   {"d8",  8},  {"d9",  9},  {"d10", 10}, {"d11", 11},
618   {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
619   {NULL, 0}
620 };
621
622 /* Maverick DSP coprocessor registers.  */
623 static const struct reg_entry mav_mvf_table[] =
624 {
625   {"mvf0",  0},  {"mvf1",  1},  {"mvf2",  2},  {"mvf3",  3},
626   {"mvf4",  4},  {"mvf5",  5},  {"mvf6",  6},  {"mvf7",  7},
627   {"mvf8",  8},  {"mvf9",  9},  {"mvf10", 10}, {"mvf11", 11},
628   {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
629   {NULL, 0}
630 };
631
632 static const struct reg_entry mav_mvd_table[] =
633 {
634   {"mvd0",  0},  {"mvd1",  1},  {"mvd2",  2},  {"mvd3",  3},
635   {"mvd4",  4},  {"mvd5",  5},  {"mvd6",  6},  {"mvd7",  7},
636   {"mvd8",  8},  {"mvd9",  9},  {"mvd10", 10}, {"mvd11", 11},
637   {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
638   {NULL, 0}
639 };
640
641 static const struct reg_entry mav_mvfx_table[] =
642 {
643   {"mvfx0",  0},  {"mvfx1",  1},  {"mvfx2",  2},  {"mvfx3",  3},
644   {"mvfx4",  4},  {"mvfx5",  5},  {"mvfx6",  6},  {"mvfx7",  7},
645   {"mvfx8",  8},  {"mvfx9",  9},  {"mvfx10", 10}, {"mvfx11", 11},
646   {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
647   {NULL, 0}
648 };
649
650 static const struct reg_entry mav_mvdx_table[] =
651 {
652   {"mvdx0",  0},  {"mvdx1",  1},  {"mvdx2",  2},  {"mvdx3",  3},
653   {"mvdx4",  4},  {"mvdx5",  5},  {"mvdx6",  6},  {"mvdx7",  7},
654   {"mvdx8",  8},  {"mvdx9",  9},  {"mvdx10", 10}, {"mvdx11", 11},
655   {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
656   {NULL, 0}
657 };
658
659 static const struct reg_entry mav_mvax_table[] =
660 {
661   {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
662   {NULL, 0}
663 };
664
665 static const struct reg_entry mav_dspsc_table[] =
666 {
667   {"dspsc", 0},
668   {NULL, 0}
669 };
670
671 struct reg_map
672 {
673   const struct reg_entry *names;
674   int max_regno;
675   struct hash_control *htab;
676   const char *expected;
677 };
678
679 struct reg_map all_reg_maps[] =
680 {
681   {rn_table,        15, NULL, N_("ARM register expected")},
682   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
683   {cn_table,        15, NULL, N_("co-processor register expected")},
684   {fn_table,         7, NULL, N_("FPA register expected")},
685   {sn_table,        31, NULL, N_("VFP single precision register expected")},
686   {dn_table,        15, NULL, N_("VFP double precision register expected")},
687   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
688   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
689   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
690   {mav_mvdx_table,  15, NULL, N_("Maverick MVFX register expected")},
691   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
692   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
693 };
694
695 /* Enumeration matching entries in table above.  */
696 enum arm_reg_type
697 {
698   REG_TYPE_RN = 0,
699 #define REG_TYPE_FIRST REG_TYPE_RN
700   REG_TYPE_CP = 1,
701   REG_TYPE_CN = 2,
702   REG_TYPE_FN = 3,
703   REG_TYPE_SN = 4,
704   REG_TYPE_DN = 5,
705   REG_TYPE_MVF = 6,
706   REG_TYPE_MVD = 7,
707   REG_TYPE_MVFX = 8,
708   REG_TYPE_MVDX = 9,
709   REG_TYPE_MVAX = 10,
710   REG_TYPE_DSPSC = 11,
711
712   REG_TYPE_MAX = 12
713 };
714
715 /* Functions called by parser.  */
716 /* ARM instructions.  */
717 static void do_arit             PARAMS ((char *));
718 static void do_cmp              PARAMS ((char *));
719 static void do_mov              PARAMS ((char *));
720 static void do_ldst             PARAMS ((char *));
721 static void do_ldstt            PARAMS ((char *));
722 static void do_ldmstm           PARAMS ((char *));
723 static void do_branch           PARAMS ((char *));
724 static void do_swi              PARAMS ((char *));
725
726 /* Pseudo Op codes.  */
727 static void do_adr              PARAMS ((char *));
728 static void do_adrl             PARAMS ((char *));
729 static void do_empty            PARAMS ((char *));
730
731 /* ARM v2.  */
732 static void do_mul              PARAMS ((char *));
733 static void do_mla              PARAMS ((char *));
734
735 /* ARM v2S.  */
736 static void do_swap             PARAMS ((char *));
737
738 /* ARM v3.  */
739 static void do_msr              PARAMS ((char *));
740 static void do_mrs              PARAMS ((char *));
741
742 /* ARM v3M.  */
743 static void do_mull             PARAMS ((char *));
744
745 /* ARM v4.  */
746 static void do_ldstv4           PARAMS ((char *));
747
748 /* ARM v4T.  */
749 static void do_bx               PARAMS ((char *));
750
751 /* ARM v5T.  */
752 static void do_blx              PARAMS ((char *));
753 static void do_bkpt             PARAMS ((char *));
754 static void do_clz              PARAMS ((char *));
755 static void do_lstc2            PARAMS ((char *));
756 static void do_cdp2             PARAMS ((char *));
757 static void do_co_reg2          PARAMS ((char *));
758
759 /* ARM v5TExP.  */
760 static void do_smla             PARAMS ((char *));
761 static void do_smlal            PARAMS ((char *));
762 static void do_smul             PARAMS ((char *));
763 static void do_qadd             PARAMS ((char *));
764
765 /* ARM v5TE.  */
766 static void do_pld              PARAMS ((char *));
767 static void do_ldrd             PARAMS ((char *));
768 static void do_co_reg2c         PARAMS ((char *));
769
770 /* ARM v5TEJ.  */
771 static void do_bxj              PARAMS ((char *));
772
773 /* Coprocessor Instructions.  */
774 static void do_cdp              PARAMS ((char *));
775 static void do_lstc             PARAMS ((char *));
776 static void do_co_reg           PARAMS ((char *));
777
778 /* FPA instructions.  */
779 static void do_fpa_ctrl         PARAMS ((char *));
780 static void do_fpa_ldst         PARAMS ((char *));
781 static void do_fpa_ldmstm       PARAMS ((char *));
782 static void do_fpa_dyadic       PARAMS ((char *));
783 static void do_fpa_monadic      PARAMS ((char *));
784 static void do_fpa_cmp          PARAMS ((char *));
785 static void do_fpa_from_reg     PARAMS ((char *));
786 static void do_fpa_to_reg       PARAMS ((char *));
787
788 /* VFP instructions.  */
789 static void do_vfp_sp_monadic   PARAMS ((char *));
790 static void do_vfp_dp_monadic   PARAMS ((char *));
791 static void do_vfp_sp_dyadic    PARAMS ((char *));
792 static void do_vfp_dp_dyadic    PARAMS ((char *));
793 static void do_vfp_reg_from_sp  PARAMS ((char *));
794 static void do_vfp_sp_from_reg  PARAMS ((char *));
795 static void do_vfp_sp_reg2      PARAMS ((char *));
796 static void do_vfp_reg_from_dp  PARAMS ((char *));
797 static void do_vfp_reg2_from_dp PARAMS ((char *));
798 static void do_vfp_dp_from_reg  PARAMS ((char *));
799 static void do_vfp_dp_from_reg2 PARAMS ((char *));
800 static void do_vfp_reg_from_ctrl PARAMS ((char *));
801 static void do_vfp_ctrl_from_reg PARAMS ((char *));
802 static void do_vfp_sp_ldst      PARAMS ((char *));
803 static void do_vfp_dp_ldst      PARAMS ((char *));
804 static void do_vfp_sp_ldstmia   PARAMS ((char *));
805 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
806 static void do_vfp_dp_ldstmia   PARAMS ((char *));
807 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
808 static void do_vfp_xp_ldstmia   PARAMS ((char *));
809 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
810 static void do_vfp_sp_compare_z PARAMS ((char *));
811 static void do_vfp_dp_compare_z PARAMS ((char *));
812 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
813 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
814
815 /* XScale.  */
816 static void do_xsc_mia          PARAMS ((char *));
817 static void do_xsc_mar          PARAMS ((char *));
818 static void do_xsc_mra          PARAMS ((char *));
819
820 /* Maverick.  */
821 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
822                                          enum arm_reg_type));
823 static void do_mav_binops_1a    PARAMS ((char *));
824 static void do_mav_binops_1b    PARAMS ((char *));
825 static void do_mav_binops_1c    PARAMS ((char *));
826 static void do_mav_binops_1d    PARAMS ((char *));
827 static void do_mav_binops_1e    PARAMS ((char *));
828 static void do_mav_binops_1f    PARAMS ((char *));
829 static void do_mav_binops_1g    PARAMS ((char *));
830 static void do_mav_binops_1h    PARAMS ((char *));
831 static void do_mav_binops_1i    PARAMS ((char *));
832 static void do_mav_binops_1j    PARAMS ((char *));
833 static void do_mav_binops_1k    PARAMS ((char *));
834 static void do_mav_binops_1l    PARAMS ((char *));
835 static void do_mav_binops_1m    PARAMS ((char *));
836 static void do_mav_binops_1n    PARAMS ((char *));
837 static void do_mav_binops_1o    PARAMS ((char *));
838 static void do_mav_binops_2a    PARAMS ((char *));
839 static void do_mav_binops_2b    PARAMS ((char *));
840 static void do_mav_binops_2c    PARAMS ((char *));
841 static void do_mav_binops_3a    PARAMS ((char *));
842 static void do_mav_binops_3b    PARAMS ((char *));
843 static void do_mav_binops_3c    PARAMS ((char *));
844 static void do_mav_binops_3d    PARAMS ((char *));
845 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
846                                          enum arm_reg_type,
847                                          enum arm_reg_type));
848 static void do_mav_triple_4a    PARAMS ((char *));
849 static void do_mav_triple_4b    PARAMS ((char *));
850 static void do_mav_triple_5a    PARAMS ((char *));
851 static void do_mav_triple_5b    PARAMS ((char *));
852 static void do_mav_triple_5c    PARAMS ((char *));
853 static void do_mav_triple_5d    PARAMS ((char *));
854 static void do_mav_triple_5e    PARAMS ((char *));
855 static void do_mav_triple_5f    PARAMS ((char *));
856 static void do_mav_triple_5g    PARAMS ((char *));
857 static void do_mav_triple_5h    PARAMS ((char *));
858 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
859                                          enum arm_reg_type,
860                                          enum arm_reg_type,
861                                          enum arm_reg_type));
862 static void do_mav_quad_6a      PARAMS ((char *));
863 static void do_mav_quad_6b      PARAMS ((char *));
864 static void do_mav_dspsc_1      PARAMS ((char *));
865 static void do_mav_dspsc_2      PARAMS ((char *));
866 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
867                                          enum arm_reg_type));
868 static void do_mav_shift_1      PARAMS ((char *));
869 static void do_mav_shift_2      PARAMS ((char *));
870 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
871 static void do_mav_ldst_1       PARAMS ((char *));
872 static void do_mav_ldst_2       PARAMS ((char *));
873 static void do_mav_ldst_3       PARAMS ((char *));
874 static void do_mav_ldst_4       PARAMS ((char *));
875
876 static int mav_reg_required_here        PARAMS ((char **, int,
877                                                  enum arm_reg_type));
878 static int mav_parse_offset     PARAMS ((char **, int *));
879
880 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
881                                          int, int));
882 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
883 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
884 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
885 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
886                                          fragS *));
887 static int add_to_lit_pool      PARAMS ((void));
888 static unsigned validate_immediate PARAMS ((unsigned));
889 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
890                                                     unsigned int *));
891 static int validate_offset_imm  PARAMS ((unsigned int, int));
892 static void opcode_select       PARAMS ((int));
893 static void end_of_line         PARAMS ((char *));
894 static int reg_required_here    PARAMS ((char **, int));
895 static int psr_required_here    PARAMS ((char **));
896 static int co_proc_number       PARAMS ((char **));
897 static int cp_opc_expr          PARAMS ((char **, int, int));
898 static int cp_reg_required_here PARAMS ((char **, int));
899 static int fp_reg_required_here PARAMS ((char **, int));
900 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
901 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
902 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
903 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
904 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
905 static long vfp_dp_reg_list     PARAMS ((char **));
906 static int vfp_psr_required_here PARAMS ((char **str));
907 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
908 static int cp_address_offset    PARAMS ((char **));
909 static int cp_address_required_here     PARAMS ((char **, int));
910 static int my_get_float_expression      PARAMS ((char **));
911 static int skip_past_comma      PARAMS ((char **));
912 static int walk_no_bignums      PARAMS ((symbolS *));
913 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
914 static int data_op2             PARAMS ((char **));
915 static int fp_op2               PARAMS ((char **));
916 static long reg_list            PARAMS ((char **));
917 static void thumb_load_store    PARAMS ((char *, int, int));
918 static int decode_shift         PARAMS ((char **, int));
919 static int ldst_extend          PARAMS ((char **));
920 static int ldst_extend_v4               PARAMS ((char **));
921 static void thumb_add_sub       PARAMS ((char *, int));
922 static void insert_reg          PARAMS ((const struct reg_entry *,
923                                          struct hash_control *));
924 static void thumb_shift         PARAMS ((char *, int));
925 static void thumb_mov_compare   PARAMS ((char *, int));
926 static void build_arm_ops_hsh   PARAMS ((void));
927 static void set_constant_flonums        PARAMS ((void));
928 static valueT md_chars_to_number        PARAMS ((char *, int));
929 static void build_reg_hsh       PARAMS ((struct reg_map *));
930 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
931 static int create_register_alias        PARAMS ((char *, char *));
932 static void output_inst         PARAMS ((const char *));
933 static int accum0_required_here PARAMS ((char **));
934 static int ld_mode_required_here PARAMS ((char **));
935 static void do_branch25         PARAMS ((char *));
936 static symbolS * find_real_start PARAMS ((symbolS *));
937 #ifdef OBJ_ELF
938 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
939 #endif
940
941 /* ARM instructions take 4bytes in the object file, Thumb instructions
942    take 2:  */
943 #define INSN_SIZE       4
944
945 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
946 #define MAV_MODE1       0x100c
947
948 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
949 #define MAV_MODE2       0x0c10
950
951 /* "INSN<cond> X,Y" where X:0, Y:bit16.  */
952 #define MAV_MODE3       0x1000
953
954 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
955 #define MAV_MODE4       0x0c0010
956
957 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
958 #define MAV_MODE5       0x00100c
959
960 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
961 #define MAV_MODE6       0x00100c05
962
963 struct asm_opcode
964 {
965   /* Basic string to match.  */
966   const char * template;
967
968   /* Basic instruction code.  */
969   unsigned long value;
970
971   /* Offset into the template where the condition code (if any) will be.
972      If zero, then the instruction is never conditional.  */
973   unsigned cond_offset;
974
975   /* Which architecture variant provides this instruction.  */
976   unsigned long variant;
977
978   /* Function to call to parse args.  */
979   void (* parms) PARAMS ((char *));
980 };
981
982 static const struct asm_opcode insns[] =
983 {
984   /* Core ARM Instructions.  */
985   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
986   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
987   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
988   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
989   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
990   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
991   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
992   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
993   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
994   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
995   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
996   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
997   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
998   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
999   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1000   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1001   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1002   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1003   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1004   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1005
1006   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1007   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1008   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1009   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1010   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1011   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1012   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1013   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1014   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1015   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1016   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1017   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1018
1019   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1020   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1021   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1022   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1023
1024   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1025   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1026   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1027   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1028   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1029   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1030   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1031   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1032
1033   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1034   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1035   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1036   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1037   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1038   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1039   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1040   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1041
1042   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1043   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1044   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1045   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1046   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1047   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1048   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1049   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1050
1051   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1052 #ifdef TE_WINCE
1053   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1054   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1055   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1056 #else
1057   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1058   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1059 #endif
1060
1061   /* Pseudo ops.  */
1062   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1063   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1064   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1065
1066   /* ARM 2 multiplies.  */
1067   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1068   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1069   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1070   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1071
1072   /* Generic copressor instructions.  */
1073   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1074   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1075   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1076   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1077   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1078   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1079   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1080
1081   /* ARM 3 - swp instructions.  */
1082   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1083   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1084
1085   /* ARM 6 Status register instructions.  */
1086   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1087   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1088   /* ScottB: our code uses     0xe128f000 for msr.
1089      NickC:  but this is wrong because the bits 16 through 19 are
1090              handled by the PSR_xxx defines above.  */
1091
1092   /* ARM 7M long multiplies.  */
1093   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1094   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1095   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1096   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1097   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1098   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1099   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1100   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1101
1102   /* ARM Architecture 4.  */
1103   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1104   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1105   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1106   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1107
1108   /* ARM Architecture 4T.  */
1109   /* Note: bx (and blx) are required on V5, even if the processor does
1110      not support Thumb.  */
1111   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1112
1113   /*  ARM Architecture 5T.  */
1114   /* Note: blx has 2 variants, so the .value is set dynamically.
1115      Only one of the variants has conditional execution.  */
1116   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1117   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1118   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1119   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1120   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1121   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1122   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1123   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1124   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1125   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1126
1127   /*  ARM Architecture 5TExP.  */
1128   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1129   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1130   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1131   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1132
1133   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1134   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1135
1136   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1137   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1138   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1139   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1140
1141   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1142   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1143   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1144   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1145
1146   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1147   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1148
1149   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1150   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1151   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1152   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1153
1154   /*  ARM Architecture 5TE.  */
1155   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1156   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1157   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1158
1159   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1160   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1161
1162   /*  ARM Architecture 5TEJ.  */
1163   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1164
1165   /* Core FPA instruction set (V1).  */
1166   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1167   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1168   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1169   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1170
1171   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1172   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1173   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1174   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1175
1176   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1177   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1178   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1179   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1180
1181   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1182   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1183   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1184   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1185   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1186   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1187   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1188   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1189   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1190   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1191   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1192   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1193
1194   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1195   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1196   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1197   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1198   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1199   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1200   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1201   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1202   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1203   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1204   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1205   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1206
1207   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1208   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1209   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1210   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1211   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1212   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1213   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1214   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1215   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1216   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1217   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1218   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1219
1220   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1221   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1222   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1223   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1224   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1225   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1226   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1227   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1228   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1229   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1230   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1231   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1232
1233   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1234   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1235   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1236   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1237   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1238   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1239   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1240   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1241   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1242   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1243   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1244   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1245
1246   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1247   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1248   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1249   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1250   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1251   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1252   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1253   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1254   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1255   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1256   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1257   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1258
1259   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1260   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1261   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1262   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1263   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1264   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1265   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1266   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1267   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1268   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1269   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1270   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1271
1272   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1273   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1274   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1275   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1276   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1277   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1278   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1279   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1280   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1281   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1282   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1283   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1284
1285   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1286   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1287   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1288   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1289   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1290   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1291   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1292   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1293   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1294   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1295   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1296   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1297
1298   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1299   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1300   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1301   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1302   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1303   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1304   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1305   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1306   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1307   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1308   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1309   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1310
1311   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1312   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1313   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1314   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1315   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1316   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1317   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1318   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1319   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1320   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1321   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1322   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1323
1324   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1325   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1326   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1327   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1328   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1329   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1330   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1331   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1332   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1333   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1334   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1335   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1336
1337   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1338   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1339   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1340   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1341   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1342   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1343   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1344   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1345   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1346   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1347   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1348   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1349
1350   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1351   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1352   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1353   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1354   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1355   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1356   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1357   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1358   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1359   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1360   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1361   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1362
1363   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1364   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1365   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1366   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1367   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1368   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1369   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1370   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1371   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1372   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1373   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1374   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1375
1376   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1377   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1378   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1379   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1380   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1381   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1382   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1383   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1384   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1385   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1386   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1387   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1388
1389   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1390   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1391   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1392   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1393   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1394   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1395   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1396   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1397   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1398   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1399   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1400   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1401
1402   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1403   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1404   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1405   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1406   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1407   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1408   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1409   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1410   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1411   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1412   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1413   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1414
1415   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1416   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1417   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1418   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1419   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1420   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1421   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1422   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1423   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1424   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1425   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1426   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1427
1428   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1429   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1430   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1431   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1432   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1433   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1434   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1435   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1436   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1437   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1438   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1439   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1440
1441   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1442   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1443   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1444   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1445   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1446   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1447   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1448   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1449   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1450   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1451   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1452   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1453
1454   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1455   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1456   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1457   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1458   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1459   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1460   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1461   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1462   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1463   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1464   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1465   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1466
1467   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1468   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1469   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1470   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1471   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1472   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1473   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1474   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1475   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1476   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1477   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1478   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1479
1480   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1481   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1482   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1483   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1484   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1485   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1486   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1487   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1488   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1489   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1490   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1491   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1492
1493   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1494   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1495   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1496   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1497   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1498   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1499   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1500   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1501   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1502   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1503   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1504   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1505
1506   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1507   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1508   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1509   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1510   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1511   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1512   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1513   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1514   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1515   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1516   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1517   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1518
1519   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1520   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1521   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1522   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1523   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1524   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1525   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1526   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1527   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1528   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1529   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1530   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1531
1532   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1533   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1534   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1535   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1536   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1537   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1538   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1539   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1540   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1541   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1542   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1543   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1544
1545   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1546   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1547   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1548   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1549   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1550   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1551   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1552   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1553   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1554   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1555   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1556   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1557
1558   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1559   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1560   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1561   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1562   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1563      not be an optional suffix, but part of the instruction.  To be
1564      compatible, we accept either.  */
1565   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1566   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1567
1568   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1569   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1570   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1571   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1572   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1573   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1574   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1575   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1576   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1577   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1578   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1579   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1580
1581   /* The implementation of the FIX instruction is broken on some
1582      assemblers, in that it accepts a precision specifier as well as a
1583      rounding specifier, despite the fact that this is meaningless.
1584      To be more compatible, we accept it as well, though of course it
1585      does not set any bits.  */
1586   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1587   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1588   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1589   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1590   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1591   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1592   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1593   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1594   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1595   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1596   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1597   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1598   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1599
1600   /* Instructions that were new with the real FPA, call them V2.  */
1601   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1602   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1603   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1604   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1605   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1606   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1607
1608   /* VFP V1xD (single precision).  */
1609   /* Moves and type conversions.  */
1610   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1611   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1612   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1613   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1614   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1615   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1616   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1617   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1618   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1619   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1620   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1621   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1622
1623   /* Memory operations.  */
1624   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1625   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1626   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1627   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1628   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1629   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1630   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1631   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1632   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1633   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1634   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1635   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1636   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1637   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1638   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1639   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1640   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1641   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1642
1643   /* Monadic operations.  */
1644   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1645   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1646   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1647
1648   /* Dyadic operations.  */
1649   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1650   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1651   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1652   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1653   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1654   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1655   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1656   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1657   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1658
1659   /* Comparisons.  */
1660   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1661   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1662   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1663   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1664
1665   /* VFP V1 (Double precision).  */
1666   /* Moves and type conversions.  */
1667   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1668   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1669   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1670   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1671   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1672   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1673   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1674   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1675   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1676   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1677   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1678   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1679   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1680
1681   /* Memory operations.  */
1682   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1683   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1684   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1685   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1686   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1687   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1688   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1689   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1690   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1691   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1692
1693   /* Monadic operations.  */
1694   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1695   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1696   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1697
1698   /* Dyadic operations.  */
1699   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1700   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1701   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1702   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1703   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1704   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1705   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1706   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1707   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1708
1709   /* Comparisons.  */
1710   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1711   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1712   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1713   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1714
1715   /* VFP V2.  */
1716   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp_reg2},
1717   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp_reg2},
1718   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1719   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1720
1721   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1722   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1723   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1724   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1725   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1726   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1727   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1728   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1729   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1730
1731   /* Cirrus Maverick instructions.  */
1732   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
1733   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
1734   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
1735   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
1736   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
1737   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
1738   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
1739   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
1740   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
1741   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
1742   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
1743   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
1744   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
1745   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
1746   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
1747   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
1748   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
1749   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
1750   {"cfmval32",   0xee100610, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
1751   {"cfmv32al",   0xee000610, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
1752   {"cfmvam32",   0xee100630, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
1753   {"cfmv32am",   0xee000630, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
1754   {"cfmvah32",   0xee100650, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
1755   {"cfmv32ah",   0xee000650, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
1756   {"cfmva32",    0xee100670, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
1757   {"cfmv32a",    0xee000670, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
1758   {"cfmva64",    0xee100690, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
1759   {"cfmv64a",    0xee000690, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
1760   {"cfmvsc32",   0xee1006b0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
1761   {"cfmv32sc",   0xee0006b0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
1762   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
1763   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
1764   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
1765   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
1766   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
1767   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
1768   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
1769   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
1770   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
1771   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
1772   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
1773   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
1774   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
1775   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
1776   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
1777   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
1778   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
1779   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
1780   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
1781   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
1782   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
1783   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
1784   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
1785   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
1786   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
1787   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
1788   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
1789   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
1790   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
1791   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
1792   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
1793   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
1794   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
1795   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
1796   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
1797   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
1798   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
1799   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
1800   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
1801   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
1802   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
1803   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
1804   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
1805   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
1806   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
1807   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
1808 };
1809
1810 /* Defines for various bits that we will want to toggle.  */
1811 #define INST_IMMEDIATE  0x02000000
1812 #define OFFSET_REG      0x02000000
1813 #define HWOFFSET_IMM    0x00400000
1814 #define SHIFT_BY_REG    0x00000010
1815 #define PRE_INDEX       0x01000000
1816 #define INDEX_UP        0x00800000
1817 #define WRITE_BACK      0x00200000
1818 #define LDM_TYPE_2_OR_3 0x00400000
1819
1820 #define LITERAL_MASK    0xf000f000
1821 #define OPCODE_MASK     0xfe1fffff
1822 #define V4_STR_BIT      0x00000020
1823
1824 #define DATA_OP_SHIFT   21
1825
1826 /* Codes to distinguish the arithmetic instructions.  */
1827 #define OPCODE_AND      0
1828 #define OPCODE_EOR      1
1829 #define OPCODE_SUB      2
1830 #define OPCODE_RSB      3
1831 #define OPCODE_ADD      4
1832 #define OPCODE_ADC      5
1833 #define OPCODE_SBC      6
1834 #define OPCODE_RSC      7
1835 #define OPCODE_TST      8
1836 #define OPCODE_TEQ      9
1837 #define OPCODE_CMP      10
1838 #define OPCODE_CMN      11
1839 #define OPCODE_ORR      12
1840 #define OPCODE_MOV      13
1841 #define OPCODE_BIC      14
1842 #define OPCODE_MVN      15
1843
1844 /* Thumb v1 (ARMv4T).  */
1845 static void do_t_nop            PARAMS ((char *));
1846 static void do_t_arit           PARAMS ((char *));
1847 static void do_t_add            PARAMS ((char *));
1848 static void do_t_asr            PARAMS ((char *));
1849 static void do_t_branch9        PARAMS ((char *));
1850 static void do_t_branch12       PARAMS ((char *));
1851 static void do_t_branch23       PARAMS ((char *));
1852 static void do_t_bx             PARAMS ((char *));
1853 static void do_t_compare        PARAMS ((char *));
1854 static void do_t_ldmstm         PARAMS ((char *));
1855 static void do_t_ldr            PARAMS ((char *));
1856 static void do_t_ldrb           PARAMS ((char *));
1857 static void do_t_ldrh           PARAMS ((char *));
1858 static void do_t_lds            PARAMS ((char *));
1859 static void do_t_lsl            PARAMS ((char *));
1860 static void do_t_lsr            PARAMS ((char *));
1861 static void do_t_mov            PARAMS ((char *));
1862 static void do_t_push_pop       PARAMS ((char *));
1863 static void do_t_str            PARAMS ((char *));
1864 static void do_t_strb           PARAMS ((char *));
1865 static void do_t_strh           PARAMS ((char *));
1866 static void do_t_sub            PARAMS ((char *));
1867 static void do_t_swi            PARAMS ((char *));
1868 static void do_t_adr            PARAMS ((char *));
1869
1870 /* Thumb v2 (ARMv5T).  */
1871 static void do_t_blx            PARAMS ((char *));
1872 static void do_t_bkpt           PARAMS ((char *));
1873
1874 #define T_OPCODE_MUL 0x4340
1875 #define T_OPCODE_TST 0x4200
1876 #define T_OPCODE_CMN 0x42c0
1877 #define T_OPCODE_NEG 0x4240
1878 #define T_OPCODE_MVN 0x43c0
1879
1880 #define T_OPCODE_ADD_R3 0x1800
1881 #define T_OPCODE_SUB_R3 0x1a00
1882 #define T_OPCODE_ADD_HI 0x4400
1883 #define T_OPCODE_ADD_ST 0xb000
1884 #define T_OPCODE_SUB_ST 0xb080
1885 #define T_OPCODE_ADD_SP 0xa800
1886 #define T_OPCODE_ADD_PC 0xa000
1887 #define T_OPCODE_ADD_I8 0x3000
1888 #define T_OPCODE_SUB_I8 0x3800
1889 #define T_OPCODE_ADD_I3 0x1c00
1890 #define T_OPCODE_SUB_I3 0x1e00
1891
1892 #define T_OPCODE_ASR_R  0x4100
1893 #define T_OPCODE_LSL_R  0x4080
1894 #define T_OPCODE_LSR_R  0x40c0
1895 #define T_OPCODE_ASR_I  0x1000
1896 #define T_OPCODE_LSL_I  0x0000
1897 #define T_OPCODE_LSR_I  0x0800
1898
1899 #define T_OPCODE_MOV_I8 0x2000
1900 #define T_OPCODE_CMP_I8 0x2800
1901 #define T_OPCODE_CMP_LR 0x4280
1902 #define T_OPCODE_MOV_HR 0x4600
1903 #define T_OPCODE_CMP_HR 0x4500
1904
1905 #define T_OPCODE_LDR_PC 0x4800
1906 #define T_OPCODE_LDR_SP 0x9800
1907 #define T_OPCODE_STR_SP 0x9000
1908 #define T_OPCODE_LDR_IW 0x6800
1909 #define T_OPCODE_STR_IW 0x6000
1910 #define T_OPCODE_LDR_IH 0x8800
1911 #define T_OPCODE_STR_IH 0x8000
1912 #define T_OPCODE_LDR_IB 0x7800
1913 #define T_OPCODE_STR_IB 0x7000
1914 #define T_OPCODE_LDR_RW 0x5800
1915 #define T_OPCODE_STR_RW 0x5000
1916 #define T_OPCODE_LDR_RH 0x5a00
1917 #define T_OPCODE_STR_RH 0x5200
1918 #define T_OPCODE_LDR_RB 0x5c00
1919 #define T_OPCODE_STR_RB 0x5400
1920
1921 #define T_OPCODE_PUSH   0xb400
1922 #define T_OPCODE_POP    0xbc00
1923
1924 #define T_OPCODE_BRANCH 0xe7fe
1925
1926 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
1927
1928 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
1929 #define THUMB_REG_LO    0x1
1930 #define THUMB_REG_HI    0x2
1931 #define THUMB_REG_ANY   0x3
1932
1933 #define THUMB_H1        0x0080
1934 #define THUMB_H2        0x0040
1935
1936 #define THUMB_ASR 0
1937 #define THUMB_LSL 1
1938 #define THUMB_LSR 2
1939
1940 #define THUMB_MOVE 0
1941 #define THUMB_COMPARE 1
1942
1943 #define THUMB_LOAD 0
1944 #define THUMB_STORE 1
1945
1946 #define THUMB_PP_PC_LR 0x0100
1947
1948 /* These three are used for immediate shifts, do not alter.  */
1949 #define THUMB_WORD 2
1950 #define THUMB_HALFWORD 1
1951 #define THUMB_BYTE 0
1952
1953 struct thumb_opcode
1954 {
1955   /* Basic string to match.  */
1956   const char * template;
1957
1958   /* Basic instruction code.  */
1959   unsigned long value;
1960
1961   int size;
1962
1963   /* Which CPU variants this exists for.  */
1964   unsigned long variant;
1965
1966   /* Function to call to parse args.  */
1967   void (* parms) PARAMS ((char *));
1968 };
1969
1970 static const struct thumb_opcode tinsns[] =
1971 {
1972   /* Thumb v1 (ARMv4T).  */
1973   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
1974   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
1975   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
1976   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
1977   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
1978   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
1979   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
1980   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
1981   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
1982   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
1983   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
1984   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
1985   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
1986   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
1987   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
1988   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
1989   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
1990   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
1991   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
1992   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
1993   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
1994   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
1995   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
1996   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
1997   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
1998   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
1999   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2000   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2001   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2002   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2003   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2004   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2005   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2006   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2007   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2008   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2009   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2010   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2011   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2012   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2013   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2014   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2015   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2016   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2017   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2018   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2019   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2020   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2021   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2022   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2023   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2024   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2025   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2026   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2027   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2028   /* Pseudo ops:  */
2029   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2030   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2031   /* Thumb v2 (ARMv5T).  */
2032   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2033   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2034 };
2035
2036 #define BAD_ARGS        _("bad arguments to instruction")
2037 #define BAD_PC          _("r15 not allowed here")
2038 #define BAD_COND        _("instruction is not conditional")
2039 #define ERR_NO_ACCUM    _("acc0 expected")
2040
2041 static struct hash_control * arm_ops_hsh   = NULL;
2042 static struct hash_control * arm_tops_hsh  = NULL;
2043 static struct hash_control * arm_cond_hsh  = NULL;
2044 static struct hash_control * arm_shift_hsh = NULL;
2045 static struct hash_control * arm_psr_hsh   = NULL;
2046
2047 /* This table describes all the machine specific pseudo-ops the assembler
2048    has to support.  The fields are:
2049      pseudo-op name without dot
2050      function to call to execute this pseudo-op
2051      Integer arg to pass to the function.  */
2052
2053 static void s_req PARAMS ((int));
2054 static void s_align PARAMS ((int));
2055 static void s_bss PARAMS ((int));
2056 static void s_even PARAMS ((int));
2057 static void s_ltorg PARAMS ((int));
2058 static void s_arm PARAMS ((int));
2059 static void s_thumb PARAMS ((int));
2060 static void s_code PARAMS ((int));
2061 static void s_force_thumb PARAMS ((int));
2062 static void s_thumb_func PARAMS ((int));
2063 static void s_thumb_set PARAMS ((int));
2064 #ifdef OBJ_ELF
2065 static void s_arm_elf_cons PARAMS ((int));
2066 #endif
2067
2068 static int my_get_expression PARAMS ((expressionS *, char **));
2069
2070 const pseudo_typeS md_pseudo_table[] =
2071 {
2072   /* Never called becasue '.req' does not start line.  */
2073   { "req",         s_req,         0 },
2074   { "bss",         s_bss,         0 },
2075   { "align",       s_align,       0 },
2076   { "arm",         s_arm,         0 },
2077   { "thumb",       s_thumb,       0 },
2078   { "code",        s_code,        0 },
2079   { "force_thumb", s_force_thumb, 0 },
2080   { "thumb_func",  s_thumb_func,  0 },
2081   { "thumb_set",   s_thumb_set,   0 },
2082   { "even",        s_even,        0 },
2083   { "ltorg",       s_ltorg,       0 },
2084   { "pool",        s_ltorg,       0 },
2085 #ifdef OBJ_ELF
2086   { "word",        s_arm_elf_cons, 4 },
2087   { "long",        s_arm_elf_cons, 4 },
2088   { "file",        (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
2089   { "loc",         dwarf2_directive_loc,  0 },
2090 #else
2091   { "word",        cons, 4},
2092 #endif
2093   { "extend",      float_cons, 'x' },
2094   { "ldouble",     float_cons, 'x' },
2095   { "packed",      float_cons, 'p' },
2096   { 0, 0, 0 }
2097 };
2098
2099 /* Other internal functions.  */
2100 static int arm_parse_extension PARAMS ((char *, int *));
2101 static int arm_parse_cpu PARAMS ((char *));
2102 static int arm_parse_arch PARAMS ((char *));
2103 static int arm_parse_fpu PARAMS ((char *));
2104
2105 /* Stuff needed to resolve the label ambiguity
2106    As:
2107      ...
2108      label:   <insn>
2109    may differ from:
2110      ...
2111      label:
2112               <insn>
2113 */
2114
2115 symbolS *  last_label_seen;
2116 static int label_is_thumb_function_name = FALSE;
2117
2118 /* Literal Pool stuff.  */
2119
2120 #define MAX_LITERAL_POOL_SIZE 1024
2121
2122 /* Literal pool structure.  Held on a per-section
2123    and per-sub-section basis.  */
2124 typedef struct literal_pool
2125 {
2126   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2127   unsigned int   next_free_entry;
2128   unsigned int   id;
2129   symbolS *      symbol;
2130   segT           section;
2131   subsegT        sub_section;
2132   struct literal_pool * next;
2133 } literal_pool;
2134
2135 /* Pointer to a linked list of literal pools.  */
2136 literal_pool * list_of_pools = NULL;
2137
2138 static literal_pool * find_literal_pool PARAMS ((void));
2139 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2140
2141 static literal_pool *
2142 find_literal_pool ()
2143 {
2144   literal_pool * pool;
2145
2146   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2147     {
2148       if (pool->section == now_seg
2149           && pool->sub_section == now_subseg)
2150         break;
2151     }
2152
2153   return pool;
2154 }
2155
2156 static literal_pool *
2157 find_or_make_literal_pool ()
2158 {
2159   /* Next literal pool ID number.  */
2160   static unsigned int latest_pool_num = 1;
2161   literal_pool *      pool;
2162
2163   pool = find_literal_pool ();
2164
2165   if (pool == NULL)
2166     {
2167       /* Create a new pool.  */
2168       pool = (literal_pool *) xmalloc (sizeof (* pool));
2169       if (! pool)
2170         return NULL;
2171
2172       pool->next_free_entry = 0;
2173       pool->section         = now_seg;
2174       pool->sub_section     = now_subseg;
2175       pool->next            = list_of_pools;
2176       pool->symbol          = NULL;
2177
2178       /* Add it to the list.  */
2179       list_of_pools = pool;
2180     }
2181
2182   /* New pools, and emptied pools, will have a NULL symbol.  */
2183   if (pool->symbol == NULL)
2184     {
2185       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2186                                     (valueT) 0, &zero_address_frag);
2187       pool->id = latest_pool_num ++;
2188     }
2189
2190   /* Done.  */
2191   return pool;
2192 }
2193
2194 /* Add the literal in the global 'inst'
2195    structure to the relevent literal pool.  */
2196 static int
2197 add_to_lit_pool ()
2198 {
2199   literal_pool * pool;
2200   unsigned int entry;
2201
2202   pool = find_or_make_literal_pool ();
2203
2204   /* Check if this literal value is already in the pool.  */
2205   for (entry = 0; entry < pool->next_free_entry; entry ++)
2206     {
2207       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2208           && (inst.reloc.exp.X_op == O_constant)
2209           && (pool->literals[entry].X_add_number
2210               == inst.reloc.exp.X_add_number)
2211           && (pool->literals[entry].X_unsigned
2212               == inst.reloc.exp.X_unsigned))
2213         break;
2214
2215       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2216           && (inst.reloc.exp.X_op == O_symbol)
2217           && (pool->literals[entry].X_add_number
2218               == inst.reloc.exp.X_add_number)
2219           && (pool->literals[entry].X_add_symbol
2220               == inst.reloc.exp.X_add_symbol)
2221           && (pool->literals[entry].X_op_symbol
2222               == inst.reloc.exp.X_op_symbol))
2223         break;
2224     }
2225
2226   /* Do we need to create a new entry?  */
2227   if (entry == pool->next_free_entry)
2228     {
2229       if (entry >= MAX_LITERAL_POOL_SIZE)
2230         {
2231           inst.error = _("literal pool overflow");
2232           return FAIL;
2233         }
2234
2235       pool->literals[entry] = inst.reloc.exp;
2236       pool->next_free_entry += 1;
2237     }
2238
2239   inst.reloc.exp.X_op         = O_symbol;
2240   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2241   inst.reloc.exp.X_add_symbol = pool->symbol;
2242
2243   return SUCCESS;
2244 }
2245
2246 /* Can't use symbol_new here, so have to create a symbol and then at
2247    a later date assign it a value. Thats what these functions do.  */
2248
2249 static void
2250 symbol_locate (symbolP, name, segment, valu, frag)
2251      symbolS *    symbolP;
2252      const char * name;         /* It is copied, the caller can modify.  */
2253      segT         segment;      /* Segment identifier (SEG_<something>).  */
2254      valueT       valu;         /* Symbol value.  */
2255      fragS *      frag;         /* Associated fragment.  */
2256 {
2257   unsigned int name_length;
2258   char * preserved_copy_of_name;
2259
2260   name_length = strlen (name) + 1;   /* +1 for \0.  */
2261   obstack_grow (&notes, name, name_length);
2262   preserved_copy_of_name = obstack_finish (&notes);
2263 #ifdef STRIP_UNDERSCORE
2264   if (preserved_copy_of_name[0] == '_')
2265     preserved_copy_of_name++;
2266 #endif
2267
2268 #ifdef tc_canonicalize_symbol_name
2269   preserved_copy_of_name =
2270     tc_canonicalize_symbol_name (preserved_copy_of_name);
2271 #endif
2272
2273   S_SET_NAME (symbolP, preserved_copy_of_name);
2274
2275   S_SET_SEGMENT (symbolP, segment);
2276   S_SET_VALUE (symbolP, valu);
2277   symbol_clear_list_pointers (symbolP);
2278
2279   symbol_set_frag (symbolP, frag);
2280
2281   /* Link to end of symbol chain.  */
2282   {
2283     extern int symbol_table_frozen;
2284     if (symbol_table_frozen)
2285       abort ();
2286   }
2287
2288   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2289
2290   obj_symbol_new_hook (symbolP);
2291
2292 #ifdef tc_symbol_new_hook
2293   tc_symbol_new_hook (symbolP);
2294 #endif
2295
2296 #ifdef DEBUG_SYMS
2297   verify_symbol_chain (symbol_rootP, symbol_lastP);
2298 #endif /* DEBUG_SYMS  */
2299 }
2300
2301 /* Check that an immediate is valid.
2302    If so, convert it to the right format.  */
2303
2304 static unsigned int
2305 validate_immediate (val)
2306      unsigned int val;
2307 {
2308   unsigned int a;
2309   unsigned int i;
2310
2311 #define rotate_left(v, n) (v << n | v >> (32 - n))
2312
2313   for (i = 0; i < 32; i += 2)
2314     if ((a = rotate_left (val, i)) <= 0xff)
2315       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2316
2317   return FAIL;
2318 }
2319
2320 /* Check to see if an immediate can be computed as two seperate immediate
2321    values, added together.  We already know that this value cannot be
2322    computed by just one ARM instruction.  */
2323
2324 static unsigned int
2325 validate_immediate_twopart (val, highpart)
2326      unsigned int   val;
2327      unsigned int * highpart;
2328 {
2329   unsigned int a;
2330   unsigned int i;
2331
2332   for (i = 0; i < 32; i += 2)
2333     if (((a = rotate_left (val, i)) & 0xff) != 0)
2334       {
2335         if (a & 0xff00)
2336           {
2337             if (a & ~ 0xffff)
2338               continue;
2339             * highpart = (a  >> 8) | ((i + 24) << 7);
2340           }
2341         else if (a & 0xff0000)
2342           {
2343             if (a & 0xff000000)
2344               continue;
2345             * highpart = (a >> 16) | ((i + 16) << 7);
2346           }
2347         else
2348           {
2349             assert (a & 0xff000000);
2350             * highpart = (a >> 24) | ((i + 8) << 7);
2351           }
2352
2353         return (a & 0xff) | (i << 7);
2354       }
2355
2356   return FAIL;
2357 }
2358
2359 static int
2360 validate_offset_imm (val, hwse)
2361      unsigned int val;
2362      int hwse;
2363 {
2364   if ((hwse && val > 255) || val > 4095)
2365     return FAIL;
2366   return val;
2367 }
2368
2369 static void
2370 s_req (a)
2371      int a ATTRIBUTE_UNUSED;
2372 {
2373   as_bad (_("invalid syntax for .req directive"));
2374 }
2375
2376 static void
2377 s_bss (ignore)
2378      int ignore ATTRIBUTE_UNUSED;
2379 {
2380   /* We don't support putting frags in the BSS segment, we fake it by
2381      marking in_bss, then looking at s_skip for clues.  */
2382   subseg_set (bss_section, 0);
2383   demand_empty_rest_of_line ();
2384 }
2385
2386 static void
2387 s_even (ignore)
2388      int ignore ATTRIBUTE_UNUSED;
2389 {
2390   /* Never make frag if expect extra pass.  */
2391   if (!need_pass_2)
2392     frag_align (1, 0, 0);
2393
2394   record_alignment (now_seg, 1);
2395
2396   demand_empty_rest_of_line ();
2397 }
2398
2399 static void
2400 s_ltorg (ignored)
2401      int ignored ATTRIBUTE_UNUSED;
2402 {
2403   unsigned int entry;
2404   literal_pool * pool;
2405   char sym_name[20];
2406
2407   pool = find_literal_pool ();
2408   if (pool == NULL
2409       || pool->symbol == NULL
2410       || pool->next_free_entry == 0)
2411     return;
2412
2413   /* Align pool as you have word accesses.
2414      Only make a frag if we have to.  */
2415   if (!need_pass_2)
2416     frag_align (2, 0, 0);
2417
2418   record_alignment (now_seg, 2);
2419
2420   sprintf (sym_name, "$$lit_\002%x", pool->id);
2421
2422   symbol_locate (pool->symbol, sym_name, now_seg,
2423                  (valueT) frag_now_fix (), frag_now);
2424   symbol_table_insert (pool->symbol);
2425
2426   ARM_SET_THUMB (pool->symbol, thumb_mode);
2427
2428 #if defined OBJ_COFF || defined OBJ_ELF
2429   ARM_SET_INTERWORK (pool->symbol, support_interwork);
2430 #endif
2431
2432   for (entry = 0; entry < pool->next_free_entry; entry ++)
2433     /* First output the expression in the instruction to the pool.  */
2434     emit_expr (&(pool->literals[entry]), 4); /* .word  */
2435
2436   /* Mark the pool as empty.  */
2437   pool->next_free_entry = 0;
2438   pool->symbol = NULL;
2439 }
2440
2441 /* Same as s_align_ptwo but align 0 => align 2.  */
2442
2443 static void
2444 s_align (unused)
2445      int unused ATTRIBUTE_UNUSED;
2446 {
2447   register int temp;
2448   register long temp_fill;
2449   long max_alignment = 15;
2450
2451   temp = get_absolute_expression ();
2452   if (temp > max_alignment)
2453     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2454   else if (temp < 0)
2455     {
2456       as_bad (_("alignment negative. 0 assumed."));
2457       temp = 0;
2458     }
2459
2460   if (*input_line_pointer == ',')
2461     {
2462       input_line_pointer++;
2463       temp_fill = get_absolute_expression ();
2464     }
2465   else
2466     temp_fill = 0;
2467
2468   if (!temp)
2469     temp = 2;
2470
2471   /* Only make a frag if we HAVE to.  */
2472   if (temp && !need_pass_2)
2473     frag_align (temp, (int) temp_fill, 0);
2474   demand_empty_rest_of_line ();
2475
2476   record_alignment (now_seg, temp);
2477 }
2478
2479 static void
2480 s_force_thumb (ignore)
2481      int ignore ATTRIBUTE_UNUSED;
2482 {
2483   /* If we are not already in thumb mode go into it, EVEN if
2484      the target processor does not support thumb instructions.
2485      This is used by gcc/config/arm/lib1funcs.asm for example
2486      to compile interworking support functions even if the
2487      target processor should not support interworking.  */
2488   if (! thumb_mode)
2489     {
2490       thumb_mode = 2;
2491
2492       record_alignment (now_seg, 1);
2493     }
2494
2495   demand_empty_rest_of_line ();
2496 }
2497
2498 static void
2499 s_thumb_func (ignore)
2500      int ignore ATTRIBUTE_UNUSED;
2501 {
2502   if (! thumb_mode)
2503     opcode_select (16);
2504
2505   /* The following label is the name/address of the start of a Thumb function.
2506      We need to know this for the interworking support.  */
2507   label_is_thumb_function_name = TRUE;
2508
2509   demand_empty_rest_of_line ();
2510 }
2511
2512 /* Perform a .set directive, but also mark the alias as
2513    being a thumb function.  */
2514
2515 static void
2516 s_thumb_set (equiv)
2517      int equiv;
2518 {
2519   /* XXX the following is a duplicate of the code for s_set() in read.c
2520      We cannot just call that code as we need to get at the symbol that
2521      is created.  */
2522   register char *    name;
2523   register char      delim;
2524   register char *    end_name;
2525   register symbolS * symbolP;
2526
2527   /* Especial apologies for the random logic:
2528      This just grew, and could be parsed much more simply!
2529      Dean - in haste.  */
2530   name      = input_line_pointer;
2531   delim     = get_symbol_end ();
2532   end_name  = input_line_pointer;
2533   *end_name = delim;
2534
2535   SKIP_WHITESPACE ();
2536
2537   if (*input_line_pointer != ',')
2538     {
2539       *end_name = 0;
2540       as_bad (_("expected comma after name \"%s\""), name);
2541       *end_name = delim;
2542       ignore_rest_of_line ();
2543       return;
2544     }
2545
2546   input_line_pointer++;
2547   *end_name = 0;
2548
2549   if (name[0] == '.' && name[1] == '\0')
2550     {
2551       /* XXX - this should not happen to .thumb_set.  */
2552       abort ();
2553     }
2554
2555   if ((symbolP = symbol_find (name)) == NULL
2556       && (symbolP = md_undefined_symbol (name)) == NULL)
2557     {
2558 #ifndef NO_LISTING
2559       /* When doing symbol listings, play games with dummy fragments living
2560          outside the normal fragment chain to record the file and line info
2561          for this symbol.  */
2562       if (listing & LISTING_SYMBOLS)
2563         {
2564           extern struct list_info_struct * listing_tail;
2565           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
2566
2567           memset (dummy_frag, 0, sizeof (fragS));
2568           dummy_frag->fr_type = rs_fill;
2569           dummy_frag->line = listing_tail;
2570           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
2571           dummy_frag->fr_symbol = symbolP;
2572         }
2573       else
2574 #endif
2575         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
2576
2577 #ifdef OBJ_COFF
2578       /* "set" symbols are local unless otherwise specified.  */
2579       SF_SET_LOCAL (symbolP);
2580 #endif /* OBJ_COFF  */
2581     }                           /* Make a new symbol.  */
2582
2583   symbol_table_insert (symbolP);
2584
2585   * end_name = delim;
2586
2587   if (equiv
2588       && S_IS_DEFINED (symbolP)
2589       && S_GET_SEGMENT (symbolP) != reg_section)
2590     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
2591
2592   pseudo_set (symbolP);
2593
2594   demand_empty_rest_of_line ();
2595
2596   /* XXX Now we come to the Thumb specific bit of code.  */
2597
2598   THUMB_SET_FUNC (symbolP, 1);
2599   ARM_SET_THUMB (symbolP, 1);
2600 #if defined OBJ_ELF || defined OBJ_COFF
2601   ARM_SET_INTERWORK (symbolP, support_interwork);
2602 #endif
2603 }
2604
2605 static void
2606 opcode_select (width)
2607      int width;
2608 {
2609   switch (width)
2610     {
2611     case 16:
2612       if (! thumb_mode)
2613         {
2614           if (! (cpu_variant & ARM_EXT_V4T))
2615             as_bad (_("selected processor does not support THUMB opcodes"));
2616
2617           thumb_mode = 1;
2618           /* No need to force the alignment, since we will have been
2619              coming from ARM mode, which is word-aligned.  */
2620           record_alignment (now_seg, 1);
2621         }
2622       break;
2623
2624     case 32:
2625       if (thumb_mode)
2626         {
2627           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
2628             as_bad (_("selected processor does not support ARM opcodes"));
2629
2630           thumb_mode = 0;
2631
2632           if (!need_pass_2)
2633             frag_align (2, 0, 0);
2634
2635           record_alignment (now_seg, 1);
2636         }
2637       break;
2638
2639     default:
2640       as_bad (_("invalid instruction size selected (%d)"), width);
2641     }
2642 }
2643
2644 static void
2645 s_arm (ignore)
2646      int ignore ATTRIBUTE_UNUSED;
2647 {
2648   opcode_select (32);
2649   demand_empty_rest_of_line ();
2650 }
2651
2652 static void
2653 s_thumb (ignore)
2654      int ignore ATTRIBUTE_UNUSED;
2655 {
2656   opcode_select (16);
2657   demand_empty_rest_of_line ();
2658 }
2659
2660 static void
2661 s_code (unused)
2662      int unused ATTRIBUTE_UNUSED;
2663 {
2664   register int temp;
2665
2666   temp = get_absolute_expression ();
2667   switch (temp)
2668     {
2669     case 16:
2670     case 32:
2671       opcode_select (temp);
2672       break;
2673
2674     default:
2675       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2676     }
2677 }
2678
2679 static void
2680 end_of_line (str)
2681      char *str;
2682 {
2683   skip_whitespace (str);
2684
2685   if (*str != '\0' && !inst.error)
2686     inst.error = _("garbage following instruction");
2687 }
2688
2689 static int
2690 skip_past_comma (str)
2691      char ** str;
2692 {
2693   char * p = * str, c;
2694   int comma = 0;
2695
2696   while ((c = *p) == ' ' || c == ',')
2697     {
2698       p++;
2699       if (c == ',' && comma++)
2700         return FAIL;
2701     }
2702
2703   if (c == '\0')
2704     return FAIL;
2705
2706   *str = p;
2707   return comma ? SUCCESS : FAIL;
2708 }
2709
2710 /* A standard register must be given at this point.
2711    SHIFT is the place to put it in inst.instruction.
2712    Restores input start point on error.
2713    Returns the reg#, or FAIL.  */
2714
2715 static int
2716 reg_required_here (str, shift)
2717      char ** str;
2718      int     shift;
2719 {
2720   static char buff [128]; /* XXX  */
2721   int         reg;
2722   char *      start = * str;
2723
2724   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
2725     {
2726       if (shift >= 0)
2727         inst.instruction |= reg << shift;
2728       return reg;
2729     }
2730
2731   /* Restore the start point, we may have got a reg of the wrong class.  */
2732   *str = start;
2733
2734   /* In the few cases where we might be able to accept something else
2735      this error can be overridden.  */
2736   sprintf (buff, _("register expected, not '%.100s'"), start);
2737   inst.error = buff;
2738
2739   return FAIL;
2740 }
2741
2742 static const struct asm_psr *
2743 arm_psr_parse (ccp)
2744      register char ** ccp;
2745 {
2746   char * start = * ccp;
2747   char   c;
2748   char * p;
2749   const struct asm_psr * psr;
2750
2751   p = start;
2752
2753   /* Skip to the end of the next word in the input stream.  */
2754   do
2755     {
2756       c = *p++;
2757     }
2758   while (ISALPHA (c) || c == '_');
2759
2760   /* Terminate the word.  */
2761   *--p = 0;
2762
2763   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
2764      feature for ease of use and backwards compatibility.  */
2765   if (!strncmp (start, "cpsr", 4))
2766     strncpy (start, "CPSR", 4);
2767   else if (!strncmp (start, "spsr", 4))
2768     strncpy (start, "SPSR", 4);
2769
2770   /* Now locate the word in the psr hash table.  */
2771   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2772
2773   /* Restore the input stream.  */
2774   *p = c;
2775
2776   /* If we found a valid match, advance the
2777      stream pointer past the end of the word.  */
2778   *ccp = p;
2779
2780   return psr;
2781 }
2782
2783 /* Parse the input looking for a PSR flag.  */
2784
2785 static int
2786 psr_required_here (str)
2787      char ** str;
2788 {
2789   char * start = * str;
2790   const struct asm_psr * psr;
2791
2792   psr = arm_psr_parse (str);
2793
2794   if (psr)
2795     {
2796       /* If this is the SPSR that is being modified, set the R bit.  */
2797       if (! psr->cpsr)
2798         inst.instruction |= SPSR_BIT;
2799
2800       /* Set the psr flags in the MSR instruction.  */
2801       inst.instruction |= psr->field << PSR_SHIFT;
2802
2803       return SUCCESS;
2804     }
2805
2806   /* In the few cases where we might be able to accept
2807      something else this error can be overridden.  */
2808   inst.error = _("flag for {c}psr instruction expected");
2809
2810   /* Restore the start point.  */
2811   *str = start;
2812   return FAIL;
2813 }
2814
2815 static int
2816 co_proc_number (str)
2817      char **str;
2818 {
2819   int processor, pchar;
2820   char *start;
2821
2822   skip_whitespace (*str);
2823   start = *str;
2824
2825   /* The data sheet seems to imply that just a number on its own is valid
2826      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
2827      accept either.  */
2828   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2829       == FAIL)
2830     {
2831       *str = start;
2832
2833       pchar = *(*str)++;
2834       if (pchar >= '0' && pchar <= '9')
2835         {
2836           processor = pchar - '0';
2837           if (**str >= '0' && **str <= '9')
2838             {
2839               processor = processor * 10 + *(*str)++ - '0';
2840               if (processor > 15)
2841                 {
2842                   inst.error = _("illegal co-processor number");
2843                   return FAIL;
2844                 }
2845             }
2846         }
2847       else
2848         {
2849           inst.error = _("bad or missing co-processor number");
2850           return FAIL;
2851         }
2852     }
2853
2854   inst.instruction |= processor << 8;
2855   return SUCCESS;
2856 }
2857
2858 static int
2859 cp_opc_expr (str, where, length)
2860      char ** str;
2861      int where;
2862      int length;
2863 {
2864   expressionS expr;
2865
2866   skip_whitespace (* str);
2867
2868   memset (&expr, '\0', sizeof (expr));
2869
2870   if (my_get_expression (&expr, str))
2871     return FAIL;
2872   if (expr.X_op != O_constant)
2873     {
2874       inst.error = _("bad or missing expression");
2875       return FAIL;
2876     }
2877
2878   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2879     {
2880       inst.error = _("immediate co-processor expression too large");
2881       return FAIL;
2882     }
2883
2884   inst.instruction |= expr.X_add_number << where;
2885   return SUCCESS;
2886 }
2887
2888 static int
2889 cp_reg_required_here (str, where)
2890      char ** str;
2891      int     where;
2892 {
2893   int    reg;
2894   char * start = *str;
2895
2896   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2897     {
2898       inst.instruction |= reg << where;
2899       return reg;
2900     }
2901
2902   /* In the few cases where we might be able to accept something else
2903      this error can be overridden.  */
2904   inst.error = _("co-processor register expected");
2905
2906   /* Restore the start point.  */
2907   *str = start;
2908   return FAIL;
2909 }
2910
2911 static int
2912 fp_reg_required_here (str, where)
2913      char ** str;
2914      int     where;
2915 {
2916   int    reg;
2917   char * start = * str;
2918
2919   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2920     {
2921       inst.instruction |= reg << where;
2922       return reg;
2923     }
2924
2925   /* In the few cases where we might be able to accept something else
2926      this error can be overridden.  */
2927   inst.error = _("floating point register expected");
2928
2929   /* Restore the start point.  */
2930   *str = start;
2931   return FAIL;
2932 }
2933
2934 static int
2935 cp_address_offset (str)
2936      char ** str;
2937 {
2938   int offset;
2939
2940   skip_whitespace (* str);
2941
2942   if (! is_immediate_prefix (**str))
2943     {
2944       inst.error = _("immediate expression expected");
2945       return FAIL;
2946     }
2947
2948   (*str)++;
2949
2950   if (my_get_expression (& inst.reloc.exp, str))
2951     return FAIL;
2952
2953   if (inst.reloc.exp.X_op == O_constant)
2954     {
2955       offset = inst.reloc.exp.X_add_number;
2956
2957       if (offset & 3)
2958         {
2959           inst.error = _("co-processor address must be word aligned");
2960           return FAIL;
2961         }
2962
2963       if (offset > 1023 || offset < -1023)
2964         {
2965           inst.error = _("offset too large");
2966           return FAIL;
2967         }
2968
2969       if (offset >= 0)
2970         inst.instruction |= INDEX_UP;
2971       else
2972         offset = -offset;
2973
2974       inst.instruction |= offset >> 2;
2975     }
2976   else
2977     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2978
2979   return SUCCESS;
2980 }
2981
2982 static int
2983 cp_address_required_here (str, wb_ok)
2984      char ** str;
2985      int wb_ok;
2986 {
2987   char * p = * str;
2988   int    pre_inc = 0;
2989   int    write_back = 0;
2990
2991   if (*p == '[')
2992     {
2993       int reg;
2994
2995       p++;
2996       skip_whitespace (p);
2997
2998       if ((reg = reg_required_here (& p, 16)) == FAIL)
2999         return FAIL;
3000
3001       skip_whitespace (p);
3002
3003       if (*p == ']')
3004         {
3005           p++;
3006
3007           if (wb_ok && skip_past_comma (& p) == SUCCESS)
3008             {
3009               /* [Rn], #expr  */
3010               write_back = WRITE_BACK;
3011
3012               if (reg == REG_PC)
3013                 {
3014                   inst.error = _("pc may not be used in post-increment");
3015                   return FAIL;
3016                 }
3017
3018               if (cp_address_offset (& p) == FAIL)
3019                 return FAIL;
3020             }
3021           else
3022             pre_inc = PRE_INDEX | INDEX_UP;
3023         }
3024       else
3025         {
3026           /* '['Rn, #expr']'[!]  */
3027
3028           if (skip_past_comma (& p) == FAIL)
3029             {
3030               inst.error = _("pre-indexed expression expected");
3031               return FAIL;
3032             }
3033
3034           pre_inc = PRE_INDEX;
3035
3036           if (cp_address_offset (& p) == FAIL)
3037             return FAIL;
3038
3039           skip_whitespace (p);
3040
3041           if (*p++ != ']')
3042             {
3043               inst.error = _("missing ]");
3044               return FAIL;
3045             }
3046
3047           skip_whitespace (p);
3048
3049           if (wb_ok && *p == '!')
3050             {
3051               if (reg == REG_PC)
3052                 {
3053                   inst.error = _("pc may not be used with write-back");
3054                   return FAIL;
3055                 }
3056
3057               p++;
3058               write_back = WRITE_BACK;
3059             }
3060         }
3061     }
3062   else
3063     {
3064       if (my_get_expression (&inst.reloc.exp, &p))
3065         return FAIL;
3066
3067       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3068       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3069       inst.reloc.pc_rel = 1;
3070       inst.instruction |= (REG_PC << 16);
3071       pre_inc = PRE_INDEX;
3072     }
3073
3074   inst.instruction |= write_back | pre_inc;
3075   *str = p;
3076   return SUCCESS;
3077 }
3078
3079 static void
3080 do_empty (str)
3081      char * str;
3082 {
3083   /* Do nothing really.  */
3084   end_of_line (str);
3085   return;
3086 }
3087
3088 static void
3089 do_mrs (str)
3090      char *str;
3091 {
3092   int skip = 0;
3093
3094   /* Only one syntax.  */
3095   skip_whitespace (str);
3096
3097   if (reg_required_here (&str, 12) == FAIL)
3098     {
3099       inst.error = BAD_ARGS;
3100       return;
3101     }
3102
3103   if (skip_past_comma (&str) == FAIL)
3104     {
3105       inst.error = _("comma expected after register name");
3106       return;
3107     }
3108
3109   skip_whitespace (str);
3110
3111   if (   strcmp (str, "CPSR") == 0
3112       || strcmp (str, "SPSR") == 0
3113          /* Lower case versions for backwards compatability.  */
3114       || strcmp (str, "cpsr") == 0
3115       || strcmp (str, "spsr") == 0)
3116     skip = 4;
3117
3118   /* This is for backwards compatability with older toolchains.  */
3119   else if (   strcmp (str, "cpsr_all") == 0
3120            || strcmp (str, "spsr_all") == 0)
3121     skip = 8;
3122   else
3123     {
3124       inst.error = _("CPSR or SPSR expected");
3125       return;
3126     }
3127
3128   if (* str == 's' || * str == 'S')
3129     inst.instruction |= SPSR_BIT;
3130   str += skip;
3131
3132   end_of_line (str);
3133 }
3134
3135 /* Two possible forms:
3136       "{C|S}PSR_<field>, Rm",
3137       "{C|S}PSR_f, #expression".  */
3138
3139 static void
3140 do_msr (str)
3141      char * str;
3142 {
3143   skip_whitespace (str);
3144
3145   if (psr_required_here (& str) == FAIL)
3146     return;
3147
3148   if (skip_past_comma (& str) == FAIL)
3149     {
3150       inst.error = _("comma missing after psr flags");
3151       return;
3152     }
3153
3154   skip_whitespace (str);
3155
3156   if (reg_required_here (& str, 0) != FAIL)
3157     {
3158       inst.error = NULL;
3159       end_of_line (str);
3160       return;
3161     }
3162
3163   if (! is_immediate_prefix (* str))
3164     {
3165       inst.error =
3166         _("only a register or immediate value can follow a psr flag");
3167       return;
3168     }
3169
3170   str ++;
3171   inst.error = NULL;
3172
3173   if (my_get_expression (& inst.reloc.exp, & str))
3174     {
3175       inst.error =
3176         _("only a register or immediate value can follow a psr flag");
3177       return;
3178     }
3179
3180 #if 0  /* The first edition of the ARM architecture manual stated that
3181           writing anything other than the flags with an immediate operation
3182           had UNPREDICTABLE effects.  This constraint was removed in the
3183           second edition of the specification.  */
3184   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3185       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3186     {
3187       inst.error = _("immediate value cannot be used to set this field");
3188       return;
3189     }
3190 #endif
3191
3192   inst.instruction |= INST_IMMEDIATE;
3193
3194   if (inst.reloc.exp.X_add_symbol)
3195     {
3196       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3197       inst.reloc.pc_rel = 0;
3198     }
3199   else
3200     {
3201       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3202
3203       if (value == (unsigned) FAIL)
3204         {
3205           inst.error = _("invalid constant");
3206           return;
3207         }
3208
3209       inst.instruction |= value;
3210     }
3211
3212   inst.error = NULL;
3213   end_of_line (str);
3214 }
3215
3216 /* Long Multiply Parser
3217    UMULL RdLo, RdHi, Rm, Rs
3218    SMULL RdLo, RdHi, Rm, Rs
3219    UMLAL RdLo, RdHi, Rm, Rs
3220    SMLAL RdLo, RdHi, Rm, Rs.  */
3221
3222 static void
3223 do_mull (str)
3224      char * str;
3225 {
3226   int rdlo, rdhi, rm, rs;
3227
3228   /* Only one format "rdlo, rdhi, rm, rs".  */
3229   skip_whitespace (str);
3230
3231   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
3232     {
3233       inst.error = BAD_ARGS;
3234       return;
3235     }
3236
3237   if (skip_past_comma (&str) == FAIL
3238       || (rdhi = reg_required_here (&str, 16)) == FAIL)
3239     {
3240       inst.error = BAD_ARGS;
3241       return;
3242     }
3243
3244   if (skip_past_comma (&str) == FAIL
3245       || (rm = reg_required_here (&str, 0)) == FAIL)
3246     {
3247       inst.error = BAD_ARGS;
3248       return;
3249     }
3250
3251   /* rdhi, rdlo and rm must all be different.  */
3252   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
3253     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3254
3255   if (skip_past_comma (&str) == FAIL
3256       || (rs = reg_required_here (&str, 8)) == FAIL)
3257     {
3258       inst.error = BAD_ARGS;
3259       return;
3260     }
3261
3262   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
3263     {
3264       inst.error = BAD_PC;
3265       return;
3266     }
3267
3268   end_of_line (str);
3269   return;
3270 }
3271
3272 static void
3273 do_mul (str)
3274      char * str;
3275 {
3276   int rd, rm;
3277
3278   /* Only one format "rd, rm, rs".  */
3279   skip_whitespace (str);
3280
3281   if ((rd = reg_required_here (&str, 16)) == FAIL)
3282     {
3283       inst.error = BAD_ARGS;
3284       return;
3285     }
3286
3287   if (rd == REG_PC)
3288     {
3289       inst.error = BAD_PC;
3290       return;
3291     }
3292
3293   if (skip_past_comma (&str) == FAIL
3294       || (rm = reg_required_here (&str, 0)) == FAIL)
3295     {
3296       inst.error = BAD_ARGS;
3297       return;
3298     }
3299
3300   if (rm == REG_PC)
3301     {
3302       inst.error = BAD_PC;
3303       return;
3304     }
3305
3306   if (rm == rd)
3307     as_tsktsk (_("rd and rm should be different in mul"));
3308
3309   if (skip_past_comma (&str) == FAIL
3310       || (rm = reg_required_here (&str, 8)) == FAIL)
3311     {
3312       inst.error = BAD_ARGS;
3313       return;
3314     }
3315
3316   if (rm == REG_PC)
3317     {
3318       inst.error = BAD_PC;
3319       return;
3320     }
3321
3322   end_of_line (str);
3323   return;
3324 }
3325
3326 static void
3327 do_mla (str)
3328      char * str;
3329 {
3330   int rd, rm;
3331
3332   /* Only one format "rd, rm, rs, rn".  */
3333   skip_whitespace (str);
3334
3335   if ((rd = reg_required_here (&str, 16)) == FAIL)
3336     {
3337       inst.error = BAD_ARGS;
3338       return;
3339     }
3340
3341   if (rd == REG_PC)
3342     {
3343       inst.error = BAD_PC;
3344       return;
3345     }
3346
3347   if (skip_past_comma (&str) == FAIL
3348       || (rm = reg_required_here (&str, 0)) == FAIL)
3349     {
3350       inst.error = BAD_ARGS;
3351       return;
3352     }
3353
3354   if (rm == REG_PC)
3355     {
3356       inst.error = BAD_PC;
3357       return;
3358     }
3359
3360   if (rm == rd)
3361     as_tsktsk (_("rd and rm should be different in mla"));
3362
3363   if (skip_past_comma (&str) == FAIL
3364       || (rd = reg_required_here (&str, 8)) == FAIL
3365       || skip_past_comma (&str) == FAIL
3366       || (rm = reg_required_here (&str, 12)) == FAIL)
3367     {
3368       inst.error = BAD_ARGS;
3369       return;
3370     }
3371
3372   if (rd == REG_PC || rm == REG_PC)
3373     {
3374       inst.error = BAD_PC;
3375       return;
3376     }
3377
3378   end_of_line (str);
3379   return;
3380 }
3381
3382 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3383    Advances *str to the next non-alphanumeric.
3384    Returns 0, or else FAIL (in which case sets inst.error).
3385
3386   (In a future XScale, there may be accumulators other than zero.
3387   At that time this routine and its callers can be upgraded to suit.)  */
3388
3389 static int
3390 accum0_required_here (str)
3391      char ** str;
3392 {
3393   static char buff [128];       /* Note the address is taken.  Hence, static.  */
3394   char * p = * str;
3395   char   c;
3396   int result = 0;               /* The accum number.  */
3397
3398   skip_whitespace (p);
3399
3400   *str = p;                     /* Advance caller's string pointer too.  */
3401   c = *p++;
3402   while (ISALNUM (c))
3403     c = *p++;
3404
3405   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
3406
3407   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
3408     {
3409       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
3410       inst.error = buff;
3411       result = FAIL;
3412     }
3413
3414   *p = c;                       /* Unzap.  */
3415   *str = p;                     /* Caller's string pointer to after match.  */
3416   return result;
3417 }
3418
3419 /* Expects **str -> after a comma. May be leading blanks.
3420    Advances *str, recognizing a load  mode, and setting inst.instruction.
3421    Returns rn, or else FAIL (in which case may set inst.error
3422    and not advance str)
3423
3424    Note: doesn't know Rd, so no err checks that require such knowledge.  */
3425
3426 static int
3427 ld_mode_required_here (string)
3428      char ** string;
3429 {
3430   char * str = * string;
3431   int    rn;
3432   int    pre_inc = 0;
3433
3434   skip_whitespace (str);
3435
3436   if (* str == '[')
3437     {
3438       str++;
3439
3440       skip_whitespace (str);
3441
3442       if ((rn = reg_required_here (& str, 16)) == FAIL)
3443         return FAIL;
3444
3445       skip_whitespace (str);
3446
3447       if (* str == ']')
3448         {
3449           str ++;
3450
3451           if (skip_past_comma (& str) == SUCCESS)
3452             {
3453               /* [Rn],... (post inc) */
3454               if (ldst_extend_v4 (&str) == FAIL)
3455                 return FAIL;
3456             }
3457           else        /* [Rn] */
3458             {
3459               skip_whitespace (str);
3460
3461               if (* str == '!')
3462                 {
3463                   str ++;
3464                   inst.instruction |= WRITE_BACK;
3465                 }
3466
3467               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3468               pre_inc = 1;
3469             }
3470         }
3471       else        /* [Rn,...] */
3472         {
3473           if (skip_past_comma (& str) == FAIL)
3474             {
3475               inst.error = _("pre-indexed expression expected");
3476               return FAIL;
3477             }
3478
3479           pre_inc = 1;
3480
3481           if (ldst_extend_v4 (&str) == FAIL)
3482             return FAIL;
3483
3484           skip_whitespace (str);
3485
3486           if (* str ++ != ']')
3487             {
3488               inst.error = _("missing ]");
3489               return FAIL;
3490             }
3491
3492           skip_whitespace (str);
3493
3494           if (* str == '!')
3495             {
3496               str ++;
3497               inst.instruction |= WRITE_BACK;
3498             }
3499         }
3500     }
3501   else if (* str == '=')        /* ldr's "r,=label" syntax */
3502     /* We should never reach here, because <text> = <expression> is
3503        caught gas/read.c read_a_source_file() as a .set operation.  */
3504     return FAIL;
3505   else                          /* PC +- 8 bit immediate offset.  */
3506     {
3507       if (my_get_expression (& inst.reloc.exp, & str))
3508         return FAIL;
3509
3510       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3511       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3512       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3513       inst.reloc.pc_rel            = 1;
3514       inst.instruction            |= (REG_PC << 16);
3515
3516       rn = REG_PC;
3517       pre_inc = 1;
3518     }
3519
3520   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3521   * string = str;
3522
3523   return rn;
3524 }
3525
3526 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3527    SMLAxy{cond} Rd,Rm,Rs,Rn
3528    SMLAWy{cond} Rd,Rm,Rs,Rn
3529    Error if any register is R15.  */
3530
3531 static void
3532 do_smla (str)
3533      char *        str;
3534 {
3535   int rd, rm, rs, rn;
3536
3537   skip_whitespace (str);
3538
3539   if ((rd = reg_required_here (& str, 16)) == FAIL
3540       || skip_past_comma (& str) == FAIL
3541       || (rm = reg_required_here (& str, 0)) == FAIL
3542       || skip_past_comma (& str) == FAIL
3543       || (rs = reg_required_here (& str, 8)) == FAIL
3544       || skip_past_comma (& str) == FAIL
3545       || (rn = reg_required_here (& str, 12)) == FAIL)
3546     inst.error = BAD_ARGS;
3547
3548   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3549     inst.error = BAD_PC;
3550
3551   else
3552     end_of_line (str);
3553 }
3554
3555 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3556    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3557    Error if any register is R15.
3558    Warning if Rdlo == Rdhi.  */
3559
3560 static void
3561 do_smlal (str)
3562      char *        str;
3563 {
3564   int rdlo, rdhi, rm, rs;
3565
3566   skip_whitespace (str);
3567
3568   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3569       || skip_past_comma (& str) == FAIL
3570       || (rdhi = reg_required_here (& str, 16)) == FAIL
3571       || skip_past_comma (& str) == FAIL
3572       || (rm = reg_required_here (& str, 0)) == FAIL
3573       || skip_past_comma (& str) == FAIL
3574       || (rs = reg_required_here (& str, 8)) == FAIL)
3575     {
3576       inst.error = BAD_ARGS;
3577       return;
3578     }
3579
3580   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3581     {
3582       inst.error = BAD_PC;
3583       return;
3584     }
3585
3586   if (rdlo == rdhi)
3587     as_tsktsk (_("rdhi and rdlo must be different"));
3588
3589   end_of_line (str);
3590 }
3591
3592 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3593    SMULxy{cond} Rd,Rm,Rs
3594    Error if any register is R15.  */
3595
3596 static void
3597 do_smul (str)
3598      char *        str;
3599 {
3600   int rd, rm, rs;
3601
3602   skip_whitespace (str);
3603
3604   if ((rd = reg_required_here (& str, 16)) == FAIL
3605       || skip_past_comma (& str) == FAIL
3606       || (rm = reg_required_here (& str, 0)) == FAIL
3607       || skip_past_comma (& str) == FAIL
3608       || (rs = reg_required_here (& str, 8)) == FAIL)
3609     inst.error = BAD_ARGS;
3610
3611   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3612     inst.error = BAD_PC;
3613
3614   else
3615     end_of_line (str);
3616 }
3617
3618 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3619    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3620    Error if any register is R15.  */
3621
3622 static void
3623 do_qadd (str)
3624      char *        str;
3625 {
3626   int rd, rm, rn;
3627
3628   skip_whitespace (str);
3629
3630   if ((rd = reg_required_here (& str, 12)) == FAIL
3631       || skip_past_comma (& str) == FAIL
3632       || (rm = reg_required_here (& str, 0)) == FAIL
3633       || skip_past_comma (& str) == FAIL
3634       || (rn = reg_required_here (& str, 16)) == FAIL)
3635     inst.error = BAD_ARGS;
3636
3637   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3638     inst.error = BAD_PC;
3639
3640   else
3641     end_of_line (str);
3642 }
3643
3644 /* ARM V5E (el Segundo)
3645    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3646    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3647
3648    These are equivalent to the XScale instructions MAR and MRA,
3649    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3650
3651    Result unpredicatable if Rd or Rn is R15.  */
3652
3653 static void
3654 do_co_reg2c (str)
3655      char *        str;
3656 {
3657   int rd, rn;
3658
3659   skip_whitespace (str);
3660
3661   if (co_proc_number (& str) == FAIL)
3662     {
3663       if (!inst.error)
3664         inst.error = BAD_ARGS;
3665       return;
3666     }
3667
3668   if (skip_past_comma (& str) == FAIL
3669       || cp_opc_expr (& str, 4, 4) == FAIL)
3670     {
3671       if (!inst.error)
3672         inst.error = BAD_ARGS;
3673       return;
3674     }
3675
3676   if (skip_past_comma (& str) == FAIL
3677       || (rd = reg_required_here (& str, 12)) == FAIL)
3678     {
3679       if (!inst.error)
3680         inst.error = BAD_ARGS;
3681       return;
3682     }
3683
3684   if (skip_past_comma (& str) == FAIL
3685       || (rn = reg_required_here (& str, 16)) == FAIL)
3686     {
3687       if (!inst.error)
3688         inst.error = BAD_ARGS;
3689       return;
3690     }
3691
3692   /* Unpredictable result if rd or rn is R15.  */
3693   if (rd == REG_PC || rn == REG_PC)
3694     as_tsktsk
3695       (_("Warning: instruction unpredictable when using r15"));
3696
3697   if (skip_past_comma (& str) == FAIL
3698       || cp_reg_required_here (& str, 0) == FAIL)
3699     {
3700       if (!inst.error)
3701         inst.error = BAD_ARGS;
3702       return;
3703     }
3704
3705   end_of_line (str);
3706 }
3707
3708 /* ARM V5 count-leading-zeroes instruction (argument parse)
3709      CLZ{<cond>} <Rd>, <Rm>
3710      Condition defaults to COND_ALWAYS.
3711      Error if Rd or Rm are R15.  */
3712
3713 static void
3714 do_clz (str)
3715      char *        str;
3716 {
3717   int rd, rm;
3718
3719   skip_whitespace (str);
3720
3721   if (((rd = reg_required_here (& str, 12)) == FAIL)
3722       || (skip_past_comma (& str) == FAIL)
3723       || ((rm = reg_required_here (& str, 0)) == FAIL))
3724     inst.error = BAD_ARGS;
3725
3726   else if (rd == REG_PC || rm == REG_PC )
3727     inst.error = BAD_PC;
3728
3729   else
3730     end_of_line (str);
3731 }
3732
3733 /* ARM V5 (argument parse)
3734      LDC2{L} <coproc>, <CRd>, <addressing mode>
3735      STC2{L} <coproc>, <CRd>, <addressing mode>
3736      Instruction is not conditional, and has 0xf in the codition field.
3737      Otherwise, it's the same as LDC/STC.  */
3738
3739 static void
3740 do_lstc2 (str)
3741      char *        str;
3742 {
3743   skip_whitespace (str);
3744
3745   if (co_proc_number (& str) == FAIL)
3746     {
3747       if (!inst.error)
3748         inst.error = BAD_ARGS;
3749     }
3750   else if (skip_past_comma (& str) == FAIL
3751            || cp_reg_required_here (& str, 12) == FAIL)
3752     {
3753       if (!inst.error)
3754         inst.error = BAD_ARGS;
3755     }
3756   else if (skip_past_comma (& str) == FAIL
3757            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3758     {
3759       if (! inst.error)
3760         inst.error = BAD_ARGS;
3761     }
3762   else
3763     end_of_line (str);
3764 }
3765
3766 /* ARM V5 (argument parse)
3767      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3768      Instruction is not conditional, and has 0xf in the condition field.
3769      Otherwise, it's the same as CDP.  */
3770
3771 static void
3772 do_cdp2 (str)
3773      char *        str;
3774 {
3775   skip_whitespace (str);
3776
3777   if (co_proc_number (& str) == FAIL)
3778     {
3779       if (!inst.error)
3780         inst.error = BAD_ARGS;
3781       return;
3782     }
3783
3784   if (skip_past_comma (& str) == FAIL
3785       || cp_opc_expr (& str, 20,4) == FAIL)
3786     {
3787       if (!inst.error)
3788         inst.error = BAD_ARGS;
3789       return;
3790     }
3791
3792   if (skip_past_comma (& str) == FAIL
3793       || cp_reg_required_here (& str, 12) == FAIL)
3794     {
3795       if (!inst.error)
3796         inst.error = BAD_ARGS;
3797       return;
3798     }
3799
3800   if (skip_past_comma (& str) == FAIL
3801       || cp_reg_required_here (& str, 16) == FAIL)
3802     {
3803       if (!inst.error)
3804         inst.error = BAD_ARGS;
3805       return;
3806     }
3807
3808   if (skip_past_comma (& str) == FAIL
3809       || cp_reg_required_here (& str, 0) == FAIL)
3810     {
3811       if (!inst.error)
3812         inst.error = BAD_ARGS;
3813       return;
3814     }
3815
3816   if (skip_past_comma (& str) == SUCCESS)
3817     {
3818       if (cp_opc_expr (& str, 5, 3) == FAIL)
3819         {
3820           if (!inst.error)
3821             inst.error = BAD_ARGS;
3822           return;
3823         }
3824     }
3825
3826   end_of_line (str);
3827 }
3828
3829 /* ARM V5 (argument parse)
3830      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3831      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3832      Instruction is not conditional, and has 0xf in the condition field.
3833      Otherwise, it's the same as MCR/MRC.  */
3834
3835 static void
3836 do_co_reg2 (str)
3837      char *        str;
3838 {
3839   skip_whitespace (str);
3840
3841   if (co_proc_number (& str) == FAIL)
3842     {
3843       if (!inst.error)
3844         inst.error = BAD_ARGS;
3845       return;
3846     }
3847
3848   if (skip_past_comma (& str) == FAIL
3849       || cp_opc_expr (& str, 21, 3) == FAIL)
3850     {
3851       if (!inst.error)
3852         inst.error = BAD_ARGS;
3853       return;
3854     }
3855
3856   if (skip_past_comma (& str) == FAIL
3857       || reg_required_here (& str, 12) == FAIL)
3858     {
3859       if (!inst.error)
3860         inst.error = BAD_ARGS;
3861       return;
3862     }
3863
3864   if (skip_past_comma (& str) == FAIL
3865       || cp_reg_required_here (& str, 16) == FAIL)
3866     {
3867       if (!inst.error)
3868         inst.error = BAD_ARGS;
3869       return;
3870     }
3871
3872   if (skip_past_comma (& str) == FAIL
3873       || cp_reg_required_here (& str, 0) == FAIL)
3874     {
3875       if (!inst.error)
3876         inst.error = BAD_ARGS;
3877       return;
3878     }
3879
3880   if (skip_past_comma (& str) == SUCCESS)
3881     {
3882       if (cp_opc_expr (& str, 5, 3) == FAIL)
3883         {
3884           if (!inst.error)
3885             inst.error = BAD_ARGS;
3886           return;
3887         }
3888     }
3889
3890   end_of_line (str);
3891 }
3892
3893 /* ARM v5TEJ.  Jump to Jazelle code.  */
3894 static void
3895 do_bxj (str)
3896      char * str;
3897 {
3898   int reg;
3899
3900   skip_whitespace (str);
3901
3902   if ((reg = reg_required_here (&str, 0)) == FAIL)
3903     {
3904       inst.error = BAD_ARGS;
3905       return;
3906     }
3907
3908   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3909   if (reg == REG_PC)
3910     as_tsktsk (_("use of r15 in bxj is not really useful"));
3911
3912   end_of_line (str);
3913 }
3914
3915 /* THUMB V5 breakpoint instruction (argument parse)
3916         BKPT <immed_8>.  */
3917
3918 static void
3919 do_t_bkpt (str)
3920      char * str;
3921 {
3922   expressionS expr;
3923   unsigned long number;
3924
3925   skip_whitespace (str);
3926
3927   /* Allow optional leading '#'.  */
3928   if (is_immediate_prefix (*str))
3929     str ++;
3930
3931   memset (& expr, '\0', sizeof (expr));
3932   if (my_get_expression (& expr, & str)
3933       || (expr.X_op != O_constant
3934           /* As a convenience we allow 'bkpt' without an operand.  */
3935           && expr.X_op != O_absent))
3936     {
3937       inst.error = _("bad expression");
3938       return;
3939     }
3940
3941   number = expr.X_add_number;
3942
3943   /* Check it fits an 8 bit unsigned.  */
3944   if (number != (number & 0xff))
3945     {
3946       inst.error = _("immediate value out of range");
3947       return;
3948     }
3949
3950   inst.instruction |= number;
3951
3952   end_of_line (str);
3953 }
3954
3955 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3956    Expects inst.instruction is set for BLX(1).
3957    Note: this is cloned from do_branch, and the reloc changed to be a
3958         new one that can cope with setting one extra bit (the H bit).  */
3959
3960 static void
3961 do_branch25 (str)
3962      char *        str;
3963 {
3964   if (my_get_expression (& inst.reloc.exp, & str))
3965     return;
3966
3967 #ifdef OBJ_ELF
3968   {
3969     char * save_in;
3970
3971     /* ScottB: February 5, 1998 */
3972     /* Check to see of PLT32 reloc required for the instruction.  */
3973
3974     /* arm_parse_reloc() works on input_line_pointer.
3975        We actually want to parse the operands to the branch instruction
3976        passed in 'str'.  Save the input pointer and restore it later.  */
3977     save_in = input_line_pointer;
3978     input_line_pointer = str;
3979
3980     if (inst.reloc.exp.X_op == O_symbol
3981         && *str == '('
3982         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3983       {
3984         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
3985         inst.reloc.pc_rel = 0;
3986         /* Modify str to point to after parsed operands, otherwise
3987            end_of_line() will complain about the (PLT) left in str.  */
3988         str = input_line_pointer;
3989       }
3990     else
3991       {
3992         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
3993         inst.reloc.pc_rel = 1;
3994       }
3995
3996     input_line_pointer = save_in;
3997   }
3998 #else
3999   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4000   inst.reloc.pc_rel = 1;
4001 #endif /* OBJ_ELF */
4002
4003   end_of_line (str);
4004 }
4005
4006 /* ARM V5 branch-link-exchange instruction (argument parse)
4007      BLX <target_addr>          ie BLX(1)
4008      BLX{<condition>} <Rm>      ie BLX(2)
4009    Unfortunately, there are two different opcodes for this mnemonic.
4010    So, the insns[].value is not used, and the code here zaps values
4011         into inst.instruction.
4012    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4013
4014 static void
4015 do_blx (str)
4016      char *        str;
4017 {
4018   char * mystr = str;
4019   int rm;
4020
4021   skip_whitespace (mystr);
4022   rm = reg_required_here (& mystr, 0);
4023
4024   /* The above may set inst.error.  Ignore his opinion.  */
4025   inst.error = 0;
4026
4027   if (rm != FAIL)
4028     {
4029       /* Arg is a register.
4030          Use the condition code our caller put in inst.instruction.
4031          Pass ourselves off as a BX with a funny opcode.  */
4032       inst.instruction |= 0x012fff30;
4033       do_bx (str);
4034     }
4035   else
4036     {
4037       /* This must be is BLX <target address>, no condition allowed.  */
4038       if (inst.instruction != COND_ALWAYS)
4039         {
4040           inst.error = BAD_COND;
4041           return;
4042         }
4043
4044       inst.instruction = 0xfafffffe;
4045
4046       /* Process like a B/BL, but with a different reloc.
4047          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4048       do_branch25 (str);
4049     }
4050 }
4051
4052 /* ARM V5 Thumb BLX (argument parse)
4053         BLX <target_addr>       which is BLX(1)
4054         BLX <Rm>                which is BLX(2)
4055    Unfortunately, there are two different opcodes for this mnemonic.
4056    So, the tinsns[].value is not used, and the code here zaps values
4057         into inst.instruction.  */
4058
4059 static void
4060 do_t_blx (str)
4061      char * str;
4062 {
4063   char * mystr = str;
4064   int rm;
4065
4066   skip_whitespace (mystr);
4067   inst.instruction = 0x4780;
4068
4069   /* Note that this call is to the ARM register recognizer.  BLX(2)
4070      uses the ARM register space, not the Thumb one, so a call to
4071      thumb_reg() would be wrong.  */
4072   rm = reg_required_here (& mystr, 3);
4073   inst.error = 0;
4074
4075   if (rm != FAIL)
4076     {
4077       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
4078       inst.size = 2;
4079     }
4080   else
4081     {
4082       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
4083       inst.instruction = 0xf7ffeffe;
4084       inst.size = 4;
4085
4086       if (my_get_expression (& inst.reloc.exp, & mystr))
4087         return;
4088
4089       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
4090       inst.reloc.pc_rel = 1;
4091     }
4092
4093   end_of_line (mystr);
4094 }
4095
4096 /* ARM V5 breakpoint instruction (argument parse)
4097      BKPT <16 bit unsigned immediate>
4098      Instruction is not conditional.
4099         The bit pattern given in insns[] has the COND_ALWAYS condition,
4100         and it is an error if the caller tried to override that.  */
4101
4102 static void
4103 do_bkpt (str)
4104      char *        str;
4105 {
4106   expressionS expr;
4107   unsigned long number;
4108
4109   skip_whitespace (str);
4110
4111   /* Allow optional leading '#'.  */
4112   if (is_immediate_prefix (* str))
4113     str++;
4114
4115   memset (& expr, '\0', sizeof (expr));
4116
4117   if (my_get_expression (& expr, & str)
4118       || (expr.X_op != O_constant
4119           /* As a convenience we allow 'bkpt' without an operand.  */
4120           && expr.X_op != O_absent))
4121     {
4122       inst.error = _("bad expression");
4123       return;
4124     }
4125
4126   number = expr.X_add_number;
4127
4128   /* Check it fits a 16 bit unsigned.  */
4129   if (number != (number & 0xffff))
4130     {
4131       inst.error = _("immediate value out of range");
4132       return;
4133     }
4134
4135   /* Top 12 of 16 bits to bits 19:8.  */
4136   inst.instruction |= (number & 0xfff0) << 4;
4137
4138   /* Bottom 4 of 16 bits to bits 3:0.  */
4139   inst.instruction |= number & 0xf;
4140
4141   end_of_line (str);
4142 }
4143
4144 /* Xscale multiply-accumulate (argument parse)
4145      MIAcc   acc0,Rm,Rs
4146      MIAPHcc acc0,Rm,Rs
4147      MIAxycc acc0,Rm,Rs.  */
4148
4149 static void
4150 do_xsc_mia (str)
4151      char * str;
4152 {
4153   int rs;
4154   int rm;
4155
4156   if (accum0_required_here (& str) == FAIL)
4157     inst.error = ERR_NO_ACCUM;
4158
4159   else if (skip_past_comma (& str) == FAIL
4160            || (rm = reg_required_here (& str, 0)) == FAIL)
4161     inst.error = BAD_ARGS;
4162
4163   else if (skip_past_comma (& str) == FAIL
4164            || (rs = reg_required_here (& str, 12)) == FAIL)
4165     inst.error = BAD_ARGS;
4166
4167   /* inst.instruction has now been zapped with both rm and rs.  */
4168   else if (rm == REG_PC || rs == REG_PC)
4169     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
4170
4171   else
4172     end_of_line (str);
4173 }
4174
4175 /* Xscale move-accumulator-register (argument parse)
4176
4177      MARcc   acc0,RdLo,RdHi.  */
4178
4179 static void
4180 do_xsc_mar (str)
4181      char * str;
4182 {
4183   int rdlo, rdhi;
4184
4185   if (accum0_required_here (& str) == FAIL)
4186     inst.error = ERR_NO_ACCUM;
4187
4188   else if (skip_past_comma (& str) == FAIL
4189            || (rdlo = reg_required_here (& str, 12)) == FAIL)
4190     inst.error = BAD_ARGS;
4191
4192   else if (skip_past_comma (& str) == FAIL
4193            || (rdhi = reg_required_here (& str, 16)) == FAIL)
4194     inst.error = BAD_ARGS;
4195
4196   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
4197   else if (rdlo == REG_PC || rdhi == REG_PC)
4198     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
4199
4200   else
4201     end_of_line (str);
4202 }
4203
4204 /* Xscale move-register-accumulator (argument parse)
4205
4206      MRAcc   RdLo,RdHi,acc0.  */
4207
4208 static void
4209 do_xsc_mra (str)
4210      char * str;
4211 {
4212   int rdlo;
4213   int rdhi;
4214
4215   skip_whitespace (str);
4216
4217   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
4218     inst.error = BAD_ARGS;
4219
4220   else if (skip_past_comma (& str) == FAIL
4221            || (rdhi = reg_required_here (& str, 16)) == FAIL)
4222     inst.error = BAD_ARGS;
4223
4224   else if  (skip_past_comma (& str) == FAIL
4225             || accum0_required_here (& str) == FAIL)
4226     inst.error = ERR_NO_ACCUM;
4227
4228   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
4229   else if (rdlo == rdhi)
4230     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
4231
4232   else if (rdlo == REG_PC || rdhi == REG_PC)
4233     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
4234   else
4235     end_of_line (str);
4236 }
4237
4238 /* ARMv5TE: Preload-Cache
4239
4240     PLD <addr_mode>
4241
4242   Syntactically, like LDR with B=1, W=0, L=1.  */
4243
4244 static void
4245 do_pld (str)
4246      char * str;
4247 {
4248   int rd;
4249
4250   skip_whitespace (str);
4251
4252   if (* str != '[')
4253     {
4254       inst.error = _("'[' expected after PLD mnemonic");
4255       return;
4256     }
4257
4258   ++str;
4259   skip_whitespace (str);
4260
4261   if ((rd = reg_required_here (& str, 16)) == FAIL)
4262     return;
4263
4264   skip_whitespace (str);
4265
4266   if (*str == ']')
4267     {
4268       /* [Rn], ... ?  */
4269       ++str;
4270       skip_whitespace (str);
4271
4272       /* Post-indexed addressing is not allowed with PLD.  */
4273       if (skip_past_comma (&str) == SUCCESS)
4274         {
4275           inst.error
4276             = _("post-indexed expression used in preload instruction");
4277           return;
4278         }
4279       else if (*str == '!') /* [Rn]! */
4280         {
4281           inst.error = _("writeback used in preload instruction");
4282           ++str;
4283         }
4284       else /* [Rn] */
4285         inst.instruction |= INDEX_UP | PRE_INDEX;
4286     }
4287   else /* [Rn, ...] */
4288     {
4289       if (skip_past_comma (& str) == FAIL)
4290         {
4291           inst.error = _("pre-indexed expression expected");
4292           return;
4293         }
4294
4295       if (ldst_extend (&str) == FAIL)
4296         return;
4297
4298       skip_whitespace (str);
4299
4300       if (* str != ']')
4301         {
4302           inst.error = _("missing ]");
4303           return;
4304         }
4305
4306       ++ str;
4307       skip_whitespace (str);
4308
4309       if (* str == '!') /* [Rn]! */
4310         {
4311           inst.error = _("writeback used in preload instruction");
4312           ++ str;
4313         }
4314
4315       inst.instruction |= PRE_INDEX;
4316     }
4317
4318   end_of_line (str);
4319 }
4320
4321 /* ARMv5TE load-consecutive (argument parse)
4322    Mode is like LDRH.
4323
4324      LDRccD R, mode
4325      STRccD R, mode.  */
4326
4327 static void
4328 do_ldrd (str)
4329      char * str;
4330 {
4331   int rd;
4332   int rn;
4333
4334   skip_whitespace (str);
4335
4336   if ((rd = reg_required_here (& str, 12)) == FAIL)
4337     {
4338       inst.error = BAD_ARGS;
4339       return;
4340     }
4341
4342   if (skip_past_comma (& str) == FAIL
4343       || (rn = ld_mode_required_here (& str)) == FAIL)
4344     {
4345       if (!inst.error)
4346         inst.error = BAD_ARGS;
4347       return;
4348     }
4349
4350   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
4351   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
4352     {
4353       inst.error = _("destination register must be even");
4354       return;
4355     }
4356
4357   if (rd == REG_LR)
4358     {
4359       inst.error = _("r14 not allowed here");
4360       return;
4361     }
4362
4363   if (((rd == rn) || (rd + 1 == rn))
4364       && ((inst.instruction & WRITE_BACK)
4365           || (!(inst.instruction & PRE_INDEX))))
4366     as_warn (_("pre/post-indexing used when modified address register is destination"));
4367
4368   /* For an index-register load, the index register must not overlap the
4369      destination (even if not write-back).  */
4370   if ((inst.instruction & V4_STR_BIT) == 0
4371       && (inst.instruction & HWOFFSET_IMM) == 0)
4372     {
4373       int rm = inst.instruction & 0x0000000f;
4374
4375       if (rm == rd || (rm == rd + 1))
4376         as_warn (_("ldrd destination registers must not overlap index register"));
4377     }
4378
4379   end_of_line (str);
4380 }
4381
4382 /* Returns the index into fp_values of a floating point number,
4383    or -1 if not in the table.  */
4384
4385 static int
4386 my_get_float_expression (str)
4387      char ** str;
4388 {
4389   LITTLENUM_TYPE words[MAX_LITTLENUMS];
4390   char *         save_in;
4391   expressionS    exp;
4392   int            i;
4393   int            j;
4394
4395   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
4396
4397   /* Look for a raw floating point number.  */
4398   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
4399       && is_end_of_line[(unsigned char) *save_in])
4400     {
4401       for (i = 0; i < NUM_FLOAT_VALS; i++)
4402         {
4403           for (j = 0; j < MAX_LITTLENUMS; j++)
4404             {
4405               if (words[j] != fp_values[i][j])
4406                 break;
4407             }
4408
4409           if (j == MAX_LITTLENUMS)
4410             {
4411               *str = save_in;
4412               return i;
4413             }
4414         }
4415     }
4416
4417   /* Try and parse a more complex expression, this will probably fail
4418      unless the code uses a floating point prefix (eg "0f").  */
4419   save_in = input_line_pointer;
4420   input_line_pointer = *str;
4421   if (expression (&exp) == absolute_section
4422       && exp.X_op == O_big
4423       && exp.X_add_number < 0)
4424     {
4425       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4426          Ditto for 15.  */
4427       if (gen_to_words (words, 5, (long) 15) == 0)
4428         {
4429           for (i = 0; i < NUM_FLOAT_VALS; i++)
4430             {
4431               for (j = 0; j < MAX_LITTLENUMS; j++)
4432                 {
4433                   if (words[j] != fp_values[i][j])
4434                     break;
4435                 }
4436
4437               if (j == MAX_LITTLENUMS)
4438                 {
4439                   *str = input_line_pointer;
4440                   input_line_pointer = save_in;
4441                   return i;
4442                 }
4443             }
4444         }
4445     }
4446
4447   *str = input_line_pointer;
4448   input_line_pointer = save_in;
4449   return -1;
4450 }
4451
4452 /* Return TRUE if anything in the expression is a bignum.  */
4453
4454 static int
4455 walk_no_bignums (sp)
4456      symbolS * sp;
4457 {
4458   if (symbol_get_value_expression (sp)->X_op == O_big)
4459     return 1;
4460
4461   if (symbol_get_value_expression (sp)->X_add_symbol)
4462     {
4463       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
4464               || (symbol_get_value_expression (sp)->X_op_symbol
4465                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
4466     }
4467
4468   return 0;
4469 }
4470
4471 static int in_my_get_expression = 0;
4472
4473 static int
4474 my_get_expression (ep, str)
4475      expressionS * ep;
4476      char ** str;
4477 {
4478   char * save_in;
4479   segT   seg;
4480
4481   save_in = input_line_pointer;
4482   input_line_pointer = *str;
4483   in_my_get_expression = 1;
4484   seg = expression (ep);
4485   in_my_get_expression = 0;
4486
4487   if (ep->X_op == O_illegal)
4488     {
4489       /* We found a bad expression in md_operand().  */
4490       *str = input_line_pointer;
4491       input_line_pointer = save_in;
4492       return 1;
4493     }
4494
4495 #ifdef OBJ_AOUT
4496   if (seg != absolute_section
4497       && seg != text_section
4498       && seg != data_section
4499       && seg != bss_section
4500       && seg != undefined_section)
4501     {
4502       inst.error = _("bad_segment");
4503       *str = input_line_pointer;
4504       input_line_pointer = save_in;
4505       return 1;
4506     }
4507 #endif
4508
4509   /* Get rid of any bignums now, so that we don't generate an error for which
4510      we can't establish a line number later on.  Big numbers are never valid
4511      in instructions, which is where this routine is always called.  */
4512   if (ep->X_op == O_big
4513       || (ep->X_add_symbol
4514           && (walk_no_bignums (ep->X_add_symbol)
4515               || (ep->X_op_symbol
4516                   && walk_no_bignums (ep->X_op_symbol)))))
4517     {
4518       inst.error = _("invalid constant");
4519       *str = input_line_pointer;
4520       input_line_pointer = save_in;
4521       return 1;
4522     }
4523
4524   *str = input_line_pointer;
4525   input_line_pointer = save_in;
4526   return 0;
4527 }
4528
4529 /* We handle all bad expressions here, so that we can report the faulty
4530    instruction in the error message.  */
4531 void
4532 md_operand (expr)
4533      expressionS *expr;
4534 {
4535   if (in_my_get_expression)
4536     {
4537       expr->X_op = O_illegal;
4538       if (inst.error == NULL)
4539         inst.error = _("bad expression");
4540     }
4541 }
4542
4543 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4544    instruction.  */
4545
4546 static int
4547 decode_shift (str, unrestrict)
4548      char ** str;
4549      int     unrestrict;
4550 {
4551   const struct asm_shift_name * shift;
4552   char * p;
4553   char   c;
4554
4555   skip_whitespace (* str);
4556
4557   for (p = * str; ISALPHA (* p); p ++)
4558     ;
4559
4560   if (p == * str)
4561     {
4562       inst.error = _("shift expression expected");
4563       return FAIL;
4564     }
4565
4566   c = * p;
4567   * p = '\0';
4568   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
4569   * p = c;
4570
4571   if (shift == NULL)
4572     {
4573       inst.error = _("shift expression expected");
4574       return FAIL;
4575     }
4576
4577   assert (shift->properties->index == shift_properties[shift->properties->index].index);
4578
4579   if (shift->properties->index == SHIFT_RRX)
4580     {
4581       * str = p;
4582       inst.instruction |= shift->properties->bit_field;
4583       return SUCCESS;
4584     }
4585
4586   skip_whitespace (p);
4587
4588   if (unrestrict && reg_required_here (& p, 8) != FAIL)
4589     {
4590       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
4591       * str = p;
4592       return SUCCESS;
4593     }
4594   else if (! is_immediate_prefix (* p))
4595     {
4596       inst.error = (unrestrict
4597                     ? _("shift requires register or #expression")
4598                     : _("shift requires #expression"));
4599       * str = p;
4600       return FAIL;
4601     }
4602
4603   inst.error = NULL;
4604   p ++;
4605
4606   if (my_get_expression (& inst.reloc.exp, & p))
4607     return FAIL;
4608
4609   /* Validate some simple #expressions.  */
4610   if (inst.reloc.exp.X_op == O_constant)
4611     {
4612       unsigned num = inst.reloc.exp.X_add_number;
4613
4614       /* Reject operations greater than 32.  */
4615       if (num > 32
4616           /* Reject a shift of 0 unless the mode allows it.  */
4617           || (num == 0 && shift->properties->allows_0 == 0)
4618           /* Reject a shift of 32 unless the mode allows it.  */
4619           || (num == 32 && shift->properties->allows_32 == 0)
4620           )
4621         {
4622           /* As a special case we allow a shift of zero for
4623              modes that do not support it to be recoded as an
4624              logical shift left of zero (ie nothing).  We warn
4625              about this though.  */
4626           if (num == 0)
4627             {
4628               as_warn (_("shift of 0 ignored."));
4629               shift = & shift_names[0];
4630               assert (shift->properties->index == SHIFT_LSL);
4631             }
4632           else
4633             {
4634               inst.error = _("invalid immediate shift");
4635               return FAIL;
4636             }
4637         }
4638
4639       /* Shifts of 32 are encoded as 0, for those shifts that
4640          support it.  */
4641       if (num == 32)
4642         num = 0;
4643
4644       inst.instruction |= (num << 7) | shift->properties->bit_field;
4645     }
4646   else
4647     {
4648       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
4649       inst.reloc.pc_rel = 0;
4650       inst.instruction |= shift->properties->bit_field;
4651     }
4652
4653   * str = p;
4654   return SUCCESS;
4655 }
4656
4657 /* Do those data_ops which can take a negative immediate constant
4658    by altering the instuction.  A bit of a hack really.
4659         MOV <-> MVN
4660         AND <-> BIC
4661         ADC <-> SBC
4662         by inverting the second operand, and
4663         ADD <-> SUB
4664         CMP <-> CMN
4665         by negating the second operand.  */
4666
4667 static int
4668 negate_data_op (instruction, value)
4669      unsigned long * instruction;
4670      unsigned long   value;
4671 {
4672   int op, new_inst;
4673   unsigned long negated, inverted;
4674
4675   negated = validate_immediate (-value);
4676   inverted = validate_immediate (~value);
4677
4678   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
4679   switch (op)
4680     {
4681       /* First negates.  */
4682     case OPCODE_SUB:             /* ADD <-> SUB  */
4683       new_inst = OPCODE_ADD;
4684       value = negated;
4685       break;
4686
4687     case OPCODE_ADD:
4688       new_inst = OPCODE_SUB;
4689       value = negated;
4690       break;
4691
4692     case OPCODE_CMP:             /* CMP <-> CMN  */
4693       new_inst = OPCODE_CMN;
4694       value = negated;
4695       break;
4696
4697     case OPCODE_CMN:
4698       new_inst = OPCODE_CMP;
4699       value = negated;
4700       break;
4701
4702       /* Now Inverted ops.  */
4703     case OPCODE_MOV:             /* MOV <-> MVN  */
4704       new_inst = OPCODE_MVN;
4705       value = inverted;
4706       break;
4707
4708     case OPCODE_MVN:
4709       new_inst = OPCODE_MOV;
4710       value = inverted;
4711       break;
4712
4713     case OPCODE_AND:             /* AND <-> BIC  */
4714       new_inst = OPCODE_BIC;
4715       value = inverted;
4716       break;
4717
4718     case OPCODE_BIC:
4719       new_inst = OPCODE_AND;
4720       value = inverted;
4721       break;
4722
4723     case OPCODE_ADC:              /* ADC <-> SBC  */
4724       new_inst = OPCODE_SBC;
4725       value = inverted;
4726       break;
4727
4728     case OPCODE_SBC:
4729       new_inst = OPCODE_ADC;
4730       value = inverted;
4731       break;
4732
4733       /* We cannot do anything.  */
4734     default:
4735       return FAIL;
4736     }
4737
4738   if (value == (unsigned) FAIL)
4739     return FAIL;
4740
4741   *instruction &= OPCODE_MASK;
4742   *instruction |= new_inst << DATA_OP_SHIFT;
4743   return value;
4744 }
4745
4746 static int
4747 data_op2 (str)
4748      char ** str;
4749 {
4750   int value;
4751   expressionS expr;
4752
4753   skip_whitespace (* str);
4754
4755   if (reg_required_here (str, 0) != FAIL)
4756     {
4757       if (skip_past_comma (str) == SUCCESS)
4758         /* Shift operation on register.  */
4759         return decode_shift (str, NO_SHIFT_RESTRICT);
4760
4761       return SUCCESS;
4762     }
4763   else
4764     {
4765       /* Immediate expression.  */
4766       if (is_immediate_prefix (**str))
4767         {
4768           (*str)++;
4769           inst.error = NULL;
4770
4771           if (my_get_expression (&inst.reloc.exp, str))
4772             return FAIL;
4773
4774           if (inst.reloc.exp.X_add_symbol)
4775             {
4776               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4777               inst.reloc.pc_rel = 0;
4778             }
4779           else
4780             {
4781               if (skip_past_comma (str) == SUCCESS)
4782                 {
4783                   /* #x, y -- ie explicit rotation by Y.  */
4784                   if (my_get_expression (&expr, str))
4785                     return FAIL;
4786
4787                   if (expr.X_op != O_constant)
4788                     {
4789                       inst.error = _("constant expression expected");
4790                       return FAIL;
4791                     }
4792
4793                   /* Rotate must be a multiple of 2.  */
4794                   if (((unsigned) expr.X_add_number) > 30
4795                       || (expr.X_add_number & 1) != 0
4796                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
4797                     {
4798                       inst.error = _("invalid constant");
4799                       return FAIL;
4800                     }
4801                   inst.instruction |= INST_IMMEDIATE;
4802                   inst.instruction |= inst.reloc.exp.X_add_number;
4803                   inst.instruction |= expr.X_add_number << 7;
4804                   return SUCCESS;
4805                 }
4806
4807               /* Implicit rotation, select a suitable one.  */
4808               value = validate_immediate (inst.reloc.exp.X_add_number);
4809
4810               if (value == FAIL)
4811                 {
4812                   /* Can't be done.  Perhaps the code reads something like
4813                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
4814                   if ((value = negate_data_op (&inst.instruction,
4815                                                inst.reloc.exp.X_add_number))
4816                       == FAIL)
4817                     {
4818                       inst.error = _("invalid constant");
4819                       return FAIL;
4820                     }
4821                 }
4822
4823               inst.instruction |= value;
4824             }
4825
4826           inst.instruction |= INST_IMMEDIATE;
4827           return SUCCESS;
4828         }
4829
4830       (*str)++;
4831       inst.error = _("register or shift expression expected");
4832       return FAIL;
4833     }
4834 }
4835
4836 static int
4837 fp_op2 (str)
4838      char ** str;
4839 {
4840   skip_whitespace (* str);
4841
4842   if (fp_reg_required_here (str, 0) != FAIL)
4843     return SUCCESS;
4844   else
4845     {
4846       /* Immediate expression.  */
4847       if (*((*str)++) == '#')
4848         {
4849           int i;
4850
4851           inst.error = NULL;
4852
4853           skip_whitespace (* str);
4854
4855           /* First try and match exact strings, this is to guarantee
4856              that some formats will work even for cross assembly.  */
4857
4858           for (i = 0; fp_const[i]; i++)
4859             {
4860               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4861                 {
4862                   char *start = *str;
4863
4864                   *str += strlen (fp_const[i]);
4865                   if (is_end_of_line[(unsigned char) **str])
4866                     {
4867                       inst.instruction |= i + 8;
4868                       return SUCCESS;
4869                     }
4870                   *str = start;
4871                 }
4872             }
4873
4874           /* Just because we didn't get a match doesn't mean that the
4875              constant isn't valid, just that it is in a format that we
4876              don't automatically recognize.  Try parsing it with
4877              the standard expression routines.  */
4878           if ((i = my_get_float_expression (str)) >= 0)
4879             {
4880               inst.instruction |= i + 8;
4881               return SUCCESS;
4882             }
4883
4884           inst.error = _("invalid floating point immediate expression");
4885           return FAIL;
4886         }
4887       inst.error =
4888         _("floating point register or immediate expression expected");
4889       return FAIL;
4890     }
4891 }
4892
4893 static void
4894 do_arit (str)
4895      char * str;
4896 {
4897   skip_whitespace (str);
4898
4899   if (reg_required_here (&str, 12) == FAIL
4900       || skip_past_comma (&str) == FAIL
4901       || reg_required_here (&str, 16) == FAIL
4902       || skip_past_comma (&str) == FAIL
4903       || data_op2 (&str) == FAIL)
4904     {
4905       if (!inst.error)
4906         inst.error = BAD_ARGS;
4907       return;
4908     }
4909
4910   end_of_line (str);
4911   return;
4912 }
4913
4914 static void
4915 do_adr (str)
4916      char * str;
4917 {
4918   /* This is a pseudo-op of the form "adr rd, label" to be converted
4919      into a relative address of the form "add rd, pc, #label-.-8".  */
4920   skip_whitespace (str);
4921
4922   if (reg_required_here (&str, 12) == FAIL
4923       || skip_past_comma (&str) == FAIL
4924       || my_get_expression (&inst.reloc.exp, &str))
4925     {
4926       if (!inst.error)
4927         inst.error = BAD_ARGS;
4928       return;
4929     }
4930
4931   /* Frag hacking will turn this into a sub instruction if the offset turns
4932      out to be negative.  */
4933   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4934   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
4935   inst.reloc.pc_rel = 1;
4936
4937   end_of_line (str);
4938 }
4939
4940 static void
4941 do_adrl (str)
4942      char * str;
4943 {
4944   /* This is a pseudo-op of the form "adrl rd, label" to be converted
4945      into a relative address of the form:
4946      add rd, pc, #low(label-.-8)"
4947      add rd, rd, #high(label-.-8)"  */
4948
4949   skip_whitespace (str);
4950
4951   if (reg_required_here (&str, 12) == FAIL
4952       || skip_past_comma (&str) == FAIL
4953       || my_get_expression (&inst.reloc.exp, &str))
4954     {
4955       if (!inst.error)
4956         inst.error = BAD_ARGS;
4957
4958       return;
4959     }
4960
4961   end_of_line (str);
4962   /* Frag hacking will turn this into a sub instruction if the offset turns
4963      out to be negative.  */
4964   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4965   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
4966   inst.reloc.pc_rel            = 1;
4967   inst.size                    = INSN_SIZE * 2;
4968
4969   return;
4970 }
4971
4972 static void
4973 do_cmp (str)
4974      char * str;
4975 {
4976   skip_whitespace (str);
4977
4978   if (reg_required_here (&str, 16) == FAIL)
4979     {
4980       if (!inst.error)
4981         inst.error = BAD_ARGS;
4982       return;
4983     }
4984
4985   if (skip_past_comma (&str) == FAIL
4986       || data_op2 (&str) == FAIL)
4987     {
4988       if (!inst.error)
4989         inst.error = BAD_ARGS;
4990       return;
4991     }
4992
4993   end_of_line (str);
4994   return;
4995 }
4996
4997 static void
4998 do_mov (str)
4999      char * str;
5000 {
5001   skip_whitespace (str);
5002
5003   if (reg_required_here (&str, 12) == FAIL)
5004     {
5005       if (!inst.error)
5006         inst.error = BAD_ARGS;
5007       return;
5008     }
5009
5010   if (skip_past_comma (&str) == FAIL
5011       || data_op2 (&str) == FAIL)
5012     {
5013       if (!inst.error)
5014         inst.error = BAD_ARGS;
5015       return;
5016     }
5017
5018   end_of_line (str);
5019   return;
5020 }
5021
5022 static int
5023 ldst_extend (str)
5024      char ** str;
5025 {
5026   int add = INDEX_UP;
5027
5028   switch (**str)
5029     {
5030     case '#':
5031     case '$':
5032       (*str)++;
5033       if (my_get_expression (& inst.reloc.exp, str))
5034         return FAIL;
5035
5036       if (inst.reloc.exp.X_op == O_constant)
5037         {
5038           int value = inst.reloc.exp.X_add_number;
5039
5040           if (value < -4095 || value > 4095)
5041             {
5042               inst.error = _("address offset too large");
5043               return FAIL;
5044             }
5045
5046           if (value < 0)
5047             {
5048               value = -value;
5049               add = 0;
5050             }
5051
5052           inst.instruction |= add | value;
5053         }
5054       else
5055         {
5056           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5057           inst.reloc.pc_rel = 0;
5058         }
5059       return SUCCESS;
5060
5061     case '-':
5062       add = 0;
5063       /* Fall through.  */
5064
5065     case '+':
5066       (*str)++;
5067       /* Fall through.  */
5068
5069     default:
5070       if (reg_required_here (str, 0) == FAIL)
5071         return FAIL;
5072
5073       inst.instruction |= add | OFFSET_REG;
5074       if (skip_past_comma (str) == SUCCESS)
5075         return decode_shift (str, SHIFT_RESTRICT);
5076
5077       return SUCCESS;
5078     }
5079 }
5080
5081 static void
5082 do_ldst (str)
5083      char *        str;
5084 {
5085   int pre_inc = 0;
5086   int conflict_reg;
5087   int value;
5088
5089   skip_whitespace (str);
5090
5091   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
5092     {
5093       if (!inst.error)
5094         inst.error = BAD_ARGS;
5095       return;
5096     }
5097
5098   if (skip_past_comma (&str) == FAIL)
5099     {
5100       inst.error = _("address expected");
5101       return;
5102     }
5103
5104   if (*str == '[')
5105     {
5106       int reg;
5107
5108       str++;
5109
5110       skip_whitespace (str);
5111
5112       if ((reg = reg_required_here (&str, 16)) == FAIL)
5113         return;
5114
5115       /* Conflicts can occur on stores as well as loads.  */
5116       conflict_reg = (conflict_reg == reg);
5117
5118       skip_whitespace (str);
5119
5120       if (*str == ']')
5121         {
5122           str ++;
5123
5124           if (skip_past_comma (&str) == SUCCESS)
5125             {
5126               /* [Rn],... (post inc)  */
5127               if (ldst_extend (&str) == FAIL)
5128                 return;
5129               if (conflict_reg)
5130                 as_warn (_("%s register same as write-back base"),
5131                          ((inst.instruction & LOAD_BIT)
5132                           ? _("destination") : _("source")));
5133             }
5134           else
5135             {
5136               /* [Rn]  */
5137               skip_whitespace (str);
5138
5139               if (*str == '!')
5140                 {
5141                   if (conflict_reg)
5142                     as_warn (_("%s register same as write-back base"),
5143                              ((inst.instruction & LOAD_BIT)
5144                               ? _("destination") : _("source")));
5145                   str++;
5146                   inst.instruction |= WRITE_BACK;
5147                 }
5148
5149               inst.instruction |= INDEX_UP;
5150               pre_inc = 1;
5151             }
5152         }
5153       else
5154         {
5155           /* [Rn,...]  */
5156           if (skip_past_comma (&str) == FAIL)
5157             {
5158               inst.error = _("pre-indexed expression expected");
5159               return;
5160             }
5161
5162           pre_inc = 1;
5163           if (ldst_extend (&str) == FAIL)
5164             return;
5165
5166           skip_whitespace (str);
5167
5168           if (*str++ != ']')
5169             {
5170               inst.error = _("missing ]");
5171               return;
5172             }
5173
5174           skip_whitespace (str);
5175
5176           if (*str == '!')
5177             {
5178               if (conflict_reg)
5179                 as_warn (_("%s register same as write-back base"),
5180                          ((inst.instruction & LOAD_BIT)
5181                           ? _("destination") : _("source")));
5182               str++;
5183               inst.instruction |= WRITE_BACK;
5184             }
5185         }
5186     }
5187   else if (*str == '=')
5188     {
5189       if ((inst.instruction & LOAD_BIT) == 0)
5190         {
5191           inst.error = _("invalid pseudo operation");
5192           return;
5193         }
5194
5195       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
5196       str++;
5197
5198       skip_whitespace (str);
5199
5200       if (my_get_expression (&inst.reloc.exp, &str))
5201         return;
5202
5203       if (inst.reloc.exp.X_op != O_constant
5204           && inst.reloc.exp.X_op != O_symbol)
5205         {
5206           inst.error = _("constant expression expected");
5207           return;
5208         }
5209
5210       if (inst.reloc.exp.X_op == O_constant)
5211         {
5212           value = validate_immediate (inst.reloc.exp.X_add_number);
5213
5214           if (value != FAIL)
5215             {
5216               /* This can be done with a mov instruction.  */
5217               inst.instruction &= LITERAL_MASK;
5218               inst.instruction |= (INST_IMMEDIATE
5219                                    | (OPCODE_MOV << DATA_OP_SHIFT));
5220               inst.instruction |= value & 0xfff;
5221               end_of_line (str);
5222               return;
5223             }
5224
5225           value = validate_immediate (~inst.reloc.exp.X_add_number);
5226
5227           if (value != FAIL)
5228             {
5229               /* This can be done with a mvn instruction.  */
5230               inst.instruction &= LITERAL_MASK;
5231               inst.instruction |= (INST_IMMEDIATE
5232                                    | (OPCODE_MVN << DATA_OP_SHIFT));
5233               inst.instruction |= value & 0xfff;
5234               end_of_line (str);
5235               return;
5236             }
5237         }
5238
5239       /* Insert into literal pool.  */
5240       if (add_to_lit_pool () == FAIL)
5241         {
5242           if (!inst.error)
5243             inst.error = _("literal pool insertion failed");
5244           return;
5245         }
5246
5247       /* Change the instruction exp to point to the pool.  */
5248       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
5249       inst.reloc.pc_rel = 1;
5250       inst.instruction |= (REG_PC << 16);
5251       pre_inc = 1;
5252     }
5253   else
5254     {
5255       if (my_get_expression (&inst.reloc.exp, &str))
5256         return;
5257
5258       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5259 #ifndef TE_WINCE
5260       /* PC rel adjust.  */
5261       inst.reloc.exp.X_add_number -= 8;
5262 #endif
5263       inst.reloc.pc_rel = 1;
5264       inst.instruction |= (REG_PC << 16);
5265       pre_inc = 1;
5266     }
5267
5268   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5269   end_of_line (str);
5270   return;
5271 }
5272
5273 static void
5274 do_ldstt (str)
5275      char *        str;
5276 {
5277   int conflict_reg;
5278
5279   skip_whitespace (str);
5280
5281   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5282     {
5283       if (!inst.error)
5284         inst.error = BAD_ARGS;
5285       return;
5286     }
5287
5288   if (skip_past_comma (& str) == FAIL)
5289     {
5290       inst.error = _("address expected");
5291       return;
5292     }
5293
5294   if (*str == '[')
5295     {
5296       int reg;
5297
5298       str++;
5299
5300       skip_whitespace (str);
5301
5302       if ((reg = reg_required_here (&str, 16)) == FAIL)
5303         return;
5304
5305       /* ldrt/strt always use post-indexed addressing, so if the base is
5306          the same as Rd, we warn.  */
5307       if (conflict_reg == reg)
5308         as_warn (_("%s register same as write-back base"),
5309                  ((inst.instruction & LOAD_BIT)
5310                   ? _("destination") : _("source")));
5311
5312       skip_whitespace (str);
5313
5314       if (*str == ']')
5315         {
5316           str ++;
5317
5318           if (skip_past_comma (&str) == SUCCESS)
5319             {
5320               /* [Rn],... (post inc)  */
5321               if (ldst_extend (&str) == FAIL)
5322                 return;
5323             }
5324           else
5325             {
5326               /* [Rn]  */
5327               skip_whitespace (str);
5328
5329               /* Skip a write-back '!'.  */
5330               if (*str == '!')
5331                 str++;
5332
5333               inst.instruction |= INDEX_UP;
5334             }
5335         }
5336       else
5337         {
5338           inst.error = _("post-indexed expression expected");
5339           return;
5340         }
5341     }
5342   else
5343     {
5344       inst.error = _("post-indexed expression expected");
5345       return;
5346     }
5347
5348   end_of_line (str);
5349   return;
5350 }
5351
5352 static int
5353 ldst_extend_v4 (str)
5354      char ** str;
5355 {
5356   int add = INDEX_UP;
5357
5358   switch (**str)
5359     {
5360     case '#':
5361     case '$':
5362       (*str)++;
5363       if (my_get_expression (& inst.reloc.exp, str))
5364         return FAIL;
5365
5366       if (inst.reloc.exp.X_op == O_constant)
5367         {
5368           int value = inst.reloc.exp.X_add_number;
5369
5370           if (value < -255 || value > 255)
5371             {
5372               inst.error = _("address offset too large");
5373               return FAIL;
5374             }
5375
5376           if (value < 0)
5377             {
5378               value = -value;
5379               add = 0;
5380             }
5381
5382           /* Halfword and signextension instructions have the
5383              immediate value split across bits 11..8 and bits 3..0.  */
5384           inst.instruction |= (add | HWOFFSET_IMM
5385                                | ((value >> 4) << 8) | (value & 0xF));
5386         }
5387       else
5388         {
5389           inst.instruction |= HWOFFSET_IMM;
5390           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5391           inst.reloc.pc_rel = 0;
5392         }
5393       return SUCCESS;
5394
5395     case '-':
5396       add = 0;
5397       /* Fall through.  */
5398
5399     case '+':
5400       (*str)++;
5401       /* Fall through.  */
5402
5403     default:
5404       if (reg_required_here (str, 0) == FAIL)
5405         return FAIL;
5406
5407       inst.instruction |= add;
5408       return SUCCESS;
5409     }
5410 }
5411
5412 /* Halfword and signed-byte load/store operations.  */
5413 static void
5414 do_ldstv4 (str)
5415      char *        str;
5416 {
5417   int pre_inc = 0;
5418   int conflict_reg;
5419   int value;
5420
5421   skip_whitespace (str);
5422
5423   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5424     {
5425       if (!inst.error)
5426         inst.error = BAD_ARGS;
5427       return;
5428     }
5429
5430   if (skip_past_comma (& str) == FAIL)
5431     {
5432       inst.error = _("address expected");
5433       return;
5434     }
5435
5436   if (*str == '[')
5437     {
5438       int reg;
5439
5440       str++;
5441
5442       skip_whitespace (str);
5443
5444       if ((reg = reg_required_here (&str, 16)) == FAIL)
5445         return;
5446
5447       /* Conflicts can occur on stores as well as loads.  */
5448       conflict_reg = (conflict_reg == reg);
5449
5450       skip_whitespace (str);
5451
5452       if (*str == ']')
5453         {
5454           str ++;
5455
5456           if (skip_past_comma (&str) == SUCCESS)
5457             {
5458               /* [Rn],... (post inc)  */
5459               if (ldst_extend_v4 (&str) == FAIL)
5460                 return;
5461               if (conflict_reg)
5462                 as_warn (_("%s register same as write-back base"),
5463                          ((inst.instruction & LOAD_BIT)
5464                           ? _("destination") : _("source")));
5465             }
5466           else
5467             {
5468               /* [Rn]  */
5469               inst.instruction |= HWOFFSET_IMM;
5470
5471               skip_whitespace (str);
5472
5473               if (*str == '!')
5474                 {
5475                   if (conflict_reg)
5476                     as_warn (_("%s register same as write-back base"),
5477                              ((inst.instruction & LOAD_BIT)
5478                               ? _("destination") : _("source")));
5479                   str++;
5480                   inst.instruction |= WRITE_BACK;
5481                 }
5482
5483               inst.instruction |= INDEX_UP;
5484               pre_inc = 1;
5485             }
5486         }
5487       else
5488         {
5489           /* [Rn,...]  */
5490           if (skip_past_comma (&str) == FAIL)
5491             {
5492               inst.error = _("pre-indexed expression expected");
5493               return;
5494             }
5495
5496           pre_inc = 1;
5497           if (ldst_extend_v4 (&str) == FAIL)
5498             return;
5499
5500           skip_whitespace (str);
5501
5502           if (*str++ != ']')
5503             {
5504               inst.error = _("missing ]");
5505               return;
5506             }
5507
5508           skip_whitespace (str);
5509
5510           if (*str == '!')
5511             {
5512               if (conflict_reg)
5513                 as_warn (_("%s register same as write-back base"),
5514                          ((inst.instruction & LOAD_BIT)
5515                           ? _("destination") : _("source")));
5516               str++;
5517               inst.instruction |= WRITE_BACK;
5518             }
5519         }
5520     }
5521   else if (*str == '=')
5522     {
5523       if ((inst.instruction & LOAD_BIT) == 0)
5524         {
5525           inst.error = _("invalid pseudo operation");
5526           return;
5527         }
5528
5529       /* XXX Does this work correctly for half-word/byte ops?  */
5530       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
5531       str++;
5532
5533       skip_whitespace (str);
5534
5535       if (my_get_expression (&inst.reloc.exp, &str))
5536         return;
5537
5538       if (inst.reloc.exp.X_op != O_constant
5539           && inst.reloc.exp.X_op != O_symbol)
5540         {
5541           inst.error = _("constant expression expected");
5542           return;
5543         }
5544
5545       if (inst.reloc.exp.X_op == O_constant)
5546         {
5547           value = validate_immediate (inst.reloc.exp.X_add_number);
5548
5549           if (value != FAIL)
5550             {
5551               /* This can be done with a mov instruction.  */
5552               inst.instruction &= LITERAL_MASK;
5553               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
5554               inst.instruction |= value & 0xfff;
5555               end_of_line (str);
5556               return;
5557             }
5558
5559           value = validate_immediate (~ inst.reloc.exp.X_add_number);
5560
5561           if (value != FAIL)
5562             {
5563               /* This can be done with a mvn instruction.  */
5564               inst.instruction &= LITERAL_MASK;
5565               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
5566               inst.instruction |= value & 0xfff;
5567               end_of_line (str);
5568               return;
5569             }
5570         }
5571
5572       /* Insert into literal pool.  */
5573       if (add_to_lit_pool () == FAIL)
5574         {
5575           if (!inst.error)
5576             inst.error = _("literal pool insertion failed");
5577           return;
5578         }
5579
5580       /* Change the instruction exp to point to the pool.  */
5581       inst.instruction |= HWOFFSET_IMM;
5582       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
5583       inst.reloc.pc_rel = 1;
5584       inst.instruction |= (REG_PC << 16);
5585       pre_inc = 1;
5586     }
5587   else
5588     {
5589       if (my_get_expression (&inst.reloc.exp, &str))
5590         return;
5591
5592       inst.instruction |= HWOFFSET_IMM;
5593       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5594 #ifndef TE_WINCE
5595       /* PC rel adjust.  */
5596       inst.reloc.exp.X_add_number -= 8;
5597 #endif
5598       inst.reloc.pc_rel = 1;
5599       inst.instruction |= (REG_PC << 16);
5600       pre_inc = 1;
5601     }
5602
5603   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5604   end_of_line (str);
5605   return;
5606 }
5607
5608 static long
5609 reg_list (strp)
5610      char ** strp;
5611 {
5612   char * str = * strp;
5613   long   range = 0;
5614   int    another_range;
5615
5616   /* We come back here if we get ranges concatenated by '+' or '|'.  */
5617   do
5618     {
5619       another_range = 0;
5620
5621       if (*str == '{')
5622         {
5623           int in_range = 0;
5624           int cur_reg = -1;
5625
5626           str++;
5627           do
5628             {
5629               int reg;
5630
5631               skip_whitespace (str);
5632
5633               if ((reg = reg_required_here (& str, -1)) == FAIL)
5634                 return FAIL;
5635
5636               if (in_range)
5637                 {
5638                   int i;
5639
5640                   if (reg <= cur_reg)
5641                     {
5642                       inst.error = _("bad range in register list");
5643                       return FAIL;
5644                     }
5645
5646                   for (i = cur_reg + 1; i < reg; i++)
5647                     {
5648                       if (range & (1 << i))
5649                         as_tsktsk
5650                           (_("Warning: duplicated register (r%d) in register list"),
5651                            i);
5652                       else
5653                         range |= 1 << i;
5654                     }
5655                   in_range = 0;
5656                 }
5657
5658               if (range & (1 << reg))
5659                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
5660                            reg);
5661               else if (reg <= cur_reg)
5662                 as_tsktsk (_("Warning: register range not in ascending order"));
5663
5664               range |= 1 << reg;
5665               cur_reg = reg;
5666             }
5667           while (skip_past_comma (&str) != FAIL
5668                  || (in_range = 1, *str++ == '-'));
5669           str--;
5670           skip_whitespace (str);
5671
5672           if (*str++ != '}')
5673             {
5674               inst.error = _("missing `}'");
5675               return FAIL;
5676             }
5677         }
5678       else
5679         {
5680           expressionS expr;
5681
5682           if (my_get_expression (&expr, &str))
5683             return FAIL;
5684
5685           if (expr.X_op == O_constant)
5686             {
5687               if (expr.X_add_number
5688                   != (expr.X_add_number & 0x0000ffff))
5689                 {
5690                   inst.error = _("invalid register mask");
5691                   return FAIL;
5692                 }
5693
5694               if ((range & expr.X_add_number) != 0)
5695                 {
5696                   int regno = range & expr.X_add_number;
5697
5698                   regno &= -regno;
5699                   regno = (1 << regno) - 1;
5700                   as_tsktsk
5701                     (_("Warning: duplicated register (r%d) in register list"),
5702                      regno);
5703                 }
5704
5705               range |= expr.X_add_number;
5706             }
5707           else
5708             {
5709               if (inst.reloc.type != 0)
5710                 {
5711                   inst.error = _("expression too complex");
5712                   return FAIL;
5713                 }
5714
5715               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
5716               inst.reloc.type = BFD_RELOC_ARM_MULTI;
5717               inst.reloc.pc_rel = 0;
5718             }
5719         }
5720
5721       skip_whitespace (str);
5722
5723       if (*str == '|' || *str == '+')
5724         {
5725           str++;
5726           another_range = 1;
5727         }
5728     }
5729   while (another_range);
5730
5731   *strp = str;
5732   return range;
5733 }
5734
5735 static void
5736 do_ldmstm (str)
5737      char * str;
5738 {
5739   int base_reg;
5740   long range;
5741
5742   skip_whitespace (str);
5743
5744   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
5745     return;
5746
5747   if (base_reg == REG_PC)
5748     {
5749       inst.error = _("r15 not allowed as base register");
5750       return;
5751     }
5752
5753   skip_whitespace (str);
5754
5755   if (*str == '!')
5756     {
5757       inst.instruction |= WRITE_BACK;
5758       str++;
5759     }
5760
5761   if (skip_past_comma (&str) == FAIL
5762       || (range = reg_list (&str)) == FAIL)
5763     {
5764       if (! inst.error)
5765         inst.error = BAD_ARGS;
5766       return;
5767     }
5768
5769   if (*str == '^')
5770     {
5771       str++;
5772       inst.instruction |= LDM_TYPE_2_OR_3;
5773     }
5774
5775   if (inst.instruction & WRITE_BACK)
5776     {
5777       /* Check for unpredictable uses of writeback.  */
5778       if (inst.instruction & LOAD_BIT)
5779         {
5780           /* Not allowed in LDM type 2.  */
5781           if ((inst.instruction & LDM_TYPE_2_OR_3)
5782               && ((range & (1 << REG_PC)) == 0))
5783             as_warn (_("writeback of base register is UNPREDICTABLE"));
5784           /* Only allowed if base reg not in list for other types.  */
5785           else if (range & (1 << base_reg))
5786             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
5787         }
5788       else /* STM.  */
5789         {
5790           /* Not allowed for type 2.  */
5791           if (inst.instruction & LDM_TYPE_2_OR_3)
5792             as_warn (_("writeback of base register is UNPREDICTABLE"));
5793           /* Only allowed if base reg not in list, or first in list.  */
5794           else if ((range & (1 << base_reg))
5795                    && (range & ((1 << base_reg) - 1)))
5796             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
5797         }
5798     }
5799
5800   inst.instruction |= range;
5801   end_of_line (str);
5802   return;
5803 }
5804
5805 static void
5806 do_swi (str)
5807      char * str;
5808 {
5809   skip_whitespace (str);
5810
5811   /* Allow optional leading '#'.  */
5812   if (is_immediate_prefix (*str))
5813     str++;
5814
5815   if (my_get_expression (& inst.reloc.exp, & str))
5816     return;
5817
5818   inst.reloc.type = BFD_RELOC_ARM_SWI;
5819   inst.reloc.pc_rel = 0;
5820   end_of_line (str);
5821
5822   return;
5823 }
5824
5825 static void
5826 do_swap (str)
5827      char * str;
5828 {
5829   int reg;
5830
5831   skip_whitespace (str);
5832
5833   if ((reg = reg_required_here (&str, 12)) == FAIL)
5834     return;
5835
5836   if (reg == REG_PC)
5837     {
5838       inst.error = _("r15 not allowed in swap");
5839       return;
5840     }
5841
5842   if (skip_past_comma (&str) == FAIL
5843       || (reg = reg_required_here (&str, 0)) == FAIL)
5844     {
5845       if (!inst.error)
5846         inst.error = BAD_ARGS;
5847       return;
5848     }
5849
5850   if (reg == REG_PC)
5851     {
5852       inst.error = _("r15 not allowed in swap");
5853       return;
5854     }
5855
5856   if (skip_past_comma (&str) == FAIL
5857       || *str++ != '[')
5858     {
5859       inst.error = BAD_ARGS;
5860       return;
5861     }
5862
5863   skip_whitespace (str);
5864
5865   if ((reg = reg_required_here (&str, 16)) == FAIL)
5866     return;
5867
5868   if (reg == REG_PC)
5869     {
5870       inst.error = BAD_PC;
5871       return;
5872     }
5873
5874   skip_whitespace (str);
5875
5876   if (*str++ != ']')
5877     {
5878       inst.error = _("missing ]");
5879       return;
5880     }
5881
5882   end_of_line (str);
5883   return;
5884 }
5885
5886 static void
5887 do_branch (str)
5888      char * str;
5889 {
5890   if (my_get_expression (&inst.reloc.exp, &str))
5891     return;
5892
5893 #ifdef OBJ_ELF
5894   {
5895     char * save_in;
5896
5897     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5898        required for the instruction.  */
5899
5900     /* arm_parse_reloc () works on input_line_pointer.
5901        We actually want to parse the operands to the branch instruction
5902        passed in 'str'.  Save the input pointer and restore it later.  */
5903     save_in = input_line_pointer;
5904     input_line_pointer = str;
5905     if (inst.reloc.exp.X_op == O_symbol
5906         && *str == '('
5907         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5908       {
5909         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5910         inst.reloc.pc_rel = 0;
5911         /* Modify str to point to after parsed operands, otherwise
5912            end_of_line() will complain about the (PLT) left in str.  */
5913         str = input_line_pointer;
5914       }
5915     else
5916       {
5917         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
5918         inst.reloc.pc_rel = 1;
5919       }
5920     input_line_pointer = save_in;
5921   }
5922 #else
5923   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
5924   inst.reloc.pc_rel = 1;
5925 #endif /* OBJ_ELF  */
5926
5927   end_of_line (str);
5928   return;
5929 }
5930
5931 static void
5932 do_bx (str)
5933      char * str;
5934 {
5935   int reg;
5936
5937   skip_whitespace (str);
5938
5939   if ((reg = reg_required_here (&str, 0)) == FAIL)
5940     {
5941       inst.error = BAD_ARGS;
5942       return;
5943     }
5944
5945   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
5946   if (reg == REG_PC)
5947     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
5948
5949   end_of_line (str);
5950 }
5951
5952 static void
5953 do_cdp (str)
5954      char * str;
5955 {
5956   /* Co-processor data operation.
5957      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
5958   skip_whitespace (str);
5959
5960   if (co_proc_number (&str) == FAIL)
5961     {
5962       if (!inst.error)
5963         inst.error = BAD_ARGS;
5964       return;
5965     }
5966
5967   if (skip_past_comma (&str) == FAIL
5968       || cp_opc_expr (&str, 20,4) == FAIL)
5969     {
5970       if (!inst.error)
5971         inst.error = BAD_ARGS;
5972       return;
5973     }
5974
5975   if (skip_past_comma (&str) == FAIL
5976       || cp_reg_required_here (&str, 12) == FAIL)
5977     {
5978       if (!inst.error)
5979         inst.error = BAD_ARGS;
5980       return;
5981     }
5982
5983   if (skip_past_comma (&str) == FAIL
5984       || cp_reg_required_here (&str, 16) == FAIL)
5985     {
5986       if (!inst.error)
5987         inst.error = BAD_ARGS;
5988       return;
5989     }
5990
5991   if (skip_past_comma (&str) == FAIL
5992       || cp_reg_required_here (&str, 0) == FAIL)
5993     {
5994       if (!inst.error)
5995         inst.error = BAD_ARGS;
5996       return;
5997     }
5998
5999   if (skip_past_comma (&str) == SUCCESS)
6000     {
6001       if (cp_opc_expr (&str, 5, 3) == FAIL)
6002         {
6003           if (!inst.error)
6004             inst.error = BAD_ARGS;
6005           return;
6006         }
6007     }
6008
6009   end_of_line (str);
6010   return;
6011 }
6012
6013 static void
6014 do_lstc (str)
6015      char * str;
6016 {
6017   /* Co-processor register load/store.
6018      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
6019
6020   skip_whitespace (str);
6021
6022   if (co_proc_number (&str) == FAIL)
6023     {
6024       if (!inst.error)
6025         inst.error = BAD_ARGS;
6026       return;
6027     }
6028
6029   if (skip_past_comma (&str) == FAIL
6030       || cp_reg_required_here (&str, 12) == FAIL)
6031     {
6032       if (!inst.error)
6033         inst.error = BAD_ARGS;
6034       return;
6035     }
6036
6037   if (skip_past_comma (&str) == FAIL
6038       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6039     {
6040       if (! inst.error)
6041         inst.error = BAD_ARGS;
6042       return;
6043     }
6044
6045   end_of_line (str);
6046   return;
6047 }
6048
6049 static void
6050 do_co_reg (str)
6051      char * str;
6052 {
6053   /* Co-processor register transfer.
6054      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
6055
6056   skip_whitespace (str);
6057
6058   if (co_proc_number (&str) == FAIL)
6059     {
6060       if (!inst.error)
6061         inst.error = BAD_ARGS;
6062       return;
6063     }
6064
6065   if (skip_past_comma (&str) == FAIL
6066       || cp_opc_expr (&str, 21, 3) == FAIL)
6067     {
6068       if (!inst.error)
6069         inst.error = BAD_ARGS;
6070       return;
6071     }
6072
6073   if (skip_past_comma (&str) == FAIL
6074       || reg_required_here (&str, 12) == FAIL)
6075     {
6076       if (!inst.error)
6077         inst.error = BAD_ARGS;
6078       return;
6079     }
6080
6081   if (skip_past_comma (&str) == FAIL
6082       || cp_reg_required_here (&str, 16) == FAIL)
6083     {
6084       if (!inst.error)
6085         inst.error = BAD_ARGS;
6086       return;
6087     }
6088
6089   if (skip_past_comma (&str) == FAIL
6090       || cp_reg_required_here (&str, 0) == FAIL)
6091     {
6092       if (!inst.error)
6093         inst.error = BAD_ARGS;
6094       return;
6095     }
6096
6097   if (skip_past_comma (&str) == SUCCESS)
6098     {
6099       if (cp_opc_expr (&str, 5, 3) == FAIL)
6100         {
6101           if (!inst.error)
6102             inst.error = BAD_ARGS;
6103           return;
6104         }
6105     }
6106
6107   end_of_line (str);
6108   return;
6109 }
6110
6111 static void
6112 do_fpa_ctrl (str)
6113      char * str;
6114 {
6115   /* FP control registers.
6116      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
6117
6118   skip_whitespace (str);
6119
6120   if (reg_required_here (&str, 12) == FAIL)
6121     {
6122       if (!inst.error)
6123         inst.error = BAD_ARGS;
6124       return;
6125     }
6126
6127   end_of_line (str);
6128   return;
6129 }
6130
6131 static void
6132 do_fpa_ldst (str)
6133      char * str;
6134 {
6135   skip_whitespace (str);
6136
6137   if (fp_reg_required_here (&str, 12) == FAIL)
6138     {
6139       if (!inst.error)
6140         inst.error = BAD_ARGS;
6141       return;
6142     }
6143
6144   if (skip_past_comma (&str) == FAIL
6145       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6146     {
6147       if (!inst.error)
6148         inst.error = BAD_ARGS;
6149       return;
6150     }
6151
6152   end_of_line (str);
6153 }
6154
6155 static void
6156 do_fpa_ldmstm (str)
6157      char * str;
6158 {
6159   int num_regs;
6160
6161   skip_whitespace (str);
6162
6163   if (fp_reg_required_here (&str, 12) == FAIL)
6164     {
6165       if (! inst.error)
6166         inst.error = BAD_ARGS;
6167       return;
6168     }
6169
6170   /* Get Number of registers to transfer.  */
6171   if (skip_past_comma (&str) == FAIL
6172       || my_get_expression (&inst.reloc.exp, &str))
6173     {
6174       if (! inst.error)
6175         inst.error = _("constant expression expected");
6176       return;
6177     }
6178
6179   if (inst.reloc.exp.X_op != O_constant)
6180     {
6181       inst.error = _("constant value required for number of registers");
6182       return;
6183     }
6184
6185   num_regs = inst.reloc.exp.X_add_number;
6186
6187   if (num_regs < 1 || num_regs > 4)
6188     {
6189       inst.error = _("number of registers must be in the range [1:4]");
6190       return;
6191     }
6192
6193   switch (num_regs)
6194     {
6195     case 1:
6196       inst.instruction |= CP_T_X;
6197       break;
6198     case 2:
6199       inst.instruction |= CP_T_Y;
6200       break;
6201     case 3:
6202       inst.instruction |= CP_T_Y | CP_T_X;
6203       break;
6204     case 4:
6205       break;
6206     default:
6207       abort ();
6208     }
6209
6210   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
6211     {
6212       int reg;
6213       int write_back;
6214       int offset;
6215
6216       /* The instruction specified "ea" or "fd", so we can only accept
6217          [Rn]{!}.  The instruction does not really support stacking or
6218          unstacking, so we have to emulate these by setting appropriate
6219          bits and offsets.  */
6220       if (skip_past_comma (&str) == FAIL
6221           || *str != '[')
6222         {
6223           if (! inst.error)
6224             inst.error = BAD_ARGS;
6225           return;
6226         }
6227
6228       str++;
6229       skip_whitespace (str);
6230
6231       if ((reg = reg_required_here (&str, 16)) == FAIL)
6232         return;
6233
6234       skip_whitespace (str);
6235
6236       if (*str != ']')
6237         {
6238           inst.error = BAD_ARGS;
6239           return;
6240         }
6241
6242       str++;
6243       if (*str == '!')
6244         {
6245           write_back = 1;
6246           str++;
6247           if (reg == REG_PC)
6248             {
6249               inst.error =
6250                 _("r15 not allowed as base register with write-back");
6251               return;
6252             }
6253         }
6254       else
6255         write_back = 0;
6256
6257       if (inst.instruction & CP_T_Pre)
6258         {
6259           /* Pre-decrement.  */
6260           offset = 3 * num_regs;
6261           if (write_back)
6262             inst.instruction |= CP_T_WB;
6263         }
6264       else
6265         {
6266           /* Post-increment.  */
6267           if (write_back)
6268             {
6269               inst.instruction |= CP_T_WB;
6270               offset = 3 * num_regs;
6271             }
6272           else
6273             {
6274               /* No write-back, so convert this into a standard pre-increment
6275                  instruction -- aesthetically more pleasing.  */
6276               inst.instruction |= CP_T_Pre | CP_T_UD;
6277               offset = 0;
6278             }
6279         }
6280
6281       inst.instruction |= offset;
6282     }
6283   else if (skip_past_comma (&str) == FAIL
6284            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6285     {
6286       if (! inst.error)
6287         inst.error = BAD_ARGS;
6288       return;
6289     }
6290
6291   end_of_line (str);
6292 }
6293
6294 static void
6295 do_fpa_dyadic (str)
6296      char * str;
6297 {
6298   skip_whitespace (str);
6299
6300   if (fp_reg_required_here (&str, 12) == FAIL)
6301     {
6302       if (! inst.error)
6303         inst.error = BAD_ARGS;
6304       return;
6305     }
6306
6307   if (skip_past_comma (&str) == FAIL
6308       || fp_reg_required_here (&str, 16) == FAIL)
6309     {
6310       if (! inst.error)
6311         inst.error = BAD_ARGS;
6312       return;
6313     }
6314
6315   if (skip_past_comma (&str) == FAIL
6316       || fp_op2 (&str) == FAIL)
6317     {
6318       if (! inst.error)
6319         inst.error = BAD_ARGS;
6320       return;
6321     }
6322
6323   end_of_line (str);
6324   return;
6325 }
6326
6327 static void
6328 do_fpa_monadic (str)
6329      char * str;
6330 {
6331   skip_whitespace (str);
6332
6333   if (fp_reg_required_here (&str, 12) == FAIL)
6334     {
6335       if (! inst.error)
6336         inst.error = BAD_ARGS;
6337       return;
6338     }
6339
6340   if (skip_past_comma (&str) == FAIL
6341       || fp_op2 (&str) == FAIL)
6342     {
6343       if (! inst.error)
6344         inst.error = BAD_ARGS;
6345       return;
6346     }
6347
6348   end_of_line (str);
6349   return;
6350 }
6351
6352 static void
6353 do_fpa_cmp (str)
6354      char * str;
6355 {
6356   skip_whitespace (str);
6357
6358   if (fp_reg_required_here (&str, 16) == FAIL)
6359     {
6360       if (! inst.error)
6361         inst.error = BAD_ARGS;
6362       return;
6363     }
6364
6365   if (skip_past_comma (&str) == FAIL
6366       || fp_op2 (&str) == FAIL)
6367     {
6368       if (! inst.error)
6369         inst.error = BAD_ARGS;
6370       return;
6371     }
6372
6373   end_of_line (str);
6374   return;
6375 }
6376
6377 static void
6378 do_fpa_from_reg (str)
6379      char * str;
6380 {
6381   skip_whitespace (str);
6382
6383   if (fp_reg_required_here (&str, 16) == FAIL)
6384     {
6385       if (! inst.error)
6386         inst.error = BAD_ARGS;
6387       return;
6388     }
6389
6390   if (skip_past_comma (&str) == FAIL
6391       || reg_required_here (&str, 12) == FAIL)
6392     {
6393       if (! inst.error)
6394         inst.error = BAD_ARGS;
6395       return;
6396     }
6397
6398   end_of_line (str);
6399   return;
6400 }
6401
6402 static void
6403 do_fpa_to_reg (str)
6404      char * str;
6405 {
6406   skip_whitespace (str);
6407
6408   if (reg_required_here (&str, 12) == FAIL)
6409     return;
6410
6411   if (skip_past_comma (&str) == FAIL
6412       || fp_reg_required_here (&str, 0) == FAIL)
6413     {
6414       if (! inst.error)
6415         inst.error = BAD_ARGS;
6416       return;
6417     }
6418
6419   end_of_line (str);
6420   return;
6421 }
6422
6423 static int
6424 vfp_sp_reg_required_here (str, pos)
6425      char **str;
6426      enum vfp_sp_reg_pos pos;
6427 {
6428   int    reg;
6429   char *start = *str;
6430
6431   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
6432     {
6433       switch (pos)
6434         {
6435         case VFP_REG_Sd:
6436           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
6437           break;
6438
6439         case VFP_REG_Sn:
6440           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
6441           break;
6442
6443         case VFP_REG_Sm:
6444           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
6445           break;
6446
6447         default:
6448           abort ();
6449         }
6450       return reg;
6451     }
6452
6453   /* In the few cases where we might be able to accept something else
6454      this error can be overridden.  */
6455   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6456
6457   /* Restore the start point.  */
6458   *str = start;
6459   return FAIL;
6460 }
6461
6462 static int
6463 vfp_dp_reg_required_here (str, pos)
6464      char **str;
6465      enum vfp_dp_reg_pos pos;
6466 {
6467   int   reg;
6468   char *start = *str;
6469
6470   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
6471     {
6472       switch (pos)
6473         {
6474         case VFP_REG_Dd:
6475           inst.instruction |= reg << 12;
6476           break;
6477
6478         case VFP_REG_Dn:
6479           inst.instruction |= reg << 16;
6480           break;
6481
6482         case VFP_REG_Dm:
6483           inst.instruction |= reg << 0;
6484           break;
6485
6486         default:
6487           abort ();
6488         }
6489       return reg;
6490     }
6491
6492   /* In the few cases where we might be able to accept something else
6493      this error can be overridden.  */
6494   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
6495
6496   /* Restore the start point.  */
6497   *str = start;
6498   return FAIL;
6499 }
6500
6501 static void
6502 do_vfp_sp_monadic (str)
6503      char *str;
6504 {
6505   skip_whitespace (str);
6506
6507   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6508     return;
6509
6510   if (skip_past_comma (&str) == FAIL
6511       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6512     {
6513       if (! inst.error)
6514         inst.error = BAD_ARGS;
6515       return;
6516     }
6517
6518   end_of_line (str);
6519   return;
6520 }
6521
6522 static void
6523 do_vfp_dp_monadic (str)
6524      char *str;
6525 {
6526   skip_whitespace (str);
6527
6528   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6529     return;
6530
6531   if (skip_past_comma (&str) == FAIL
6532       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6533     {
6534       if (! inst.error)
6535         inst.error = BAD_ARGS;
6536       return;
6537     }
6538
6539   end_of_line (str);
6540   return;
6541 }
6542
6543 static void
6544 do_vfp_sp_dyadic (str)
6545      char *str;
6546 {
6547   skip_whitespace (str);
6548
6549   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6550     return;
6551
6552   if (skip_past_comma (&str) == FAIL
6553       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
6554       || skip_past_comma (&str) == FAIL
6555       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6556     {
6557       if (! inst.error)
6558         inst.error = BAD_ARGS;
6559       return;
6560     }
6561
6562   end_of_line (str);
6563   return;
6564 }
6565
6566 static void
6567 do_vfp_dp_dyadic (str)
6568      char *str;
6569 {
6570   skip_whitespace (str);
6571
6572   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6573     return;
6574
6575   if (skip_past_comma (&str) == FAIL
6576       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
6577       || skip_past_comma (&str) == FAIL
6578       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6579     {
6580       if (! inst.error)
6581         inst.error = BAD_ARGS;
6582       return;
6583     }
6584
6585   end_of_line (str);
6586   return;
6587 }
6588
6589 static void
6590 do_vfp_reg_from_sp (str)
6591      char *str;
6592 {
6593   skip_whitespace (str);
6594
6595   if (reg_required_here (&str, 12) == FAIL)
6596     return;
6597
6598   if (skip_past_comma (&str) == FAIL
6599       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6600     {
6601       if (! inst.error)
6602         inst.error = BAD_ARGS;
6603       return;
6604     }
6605
6606   end_of_line (str);
6607   return;
6608 }
6609
6610 static void
6611 do_vfp_sp_reg2 (str)
6612      char *str;
6613 {
6614   skip_whitespace (str);
6615
6616   if (reg_required_here (&str, 12) == FAIL)
6617     return;
6618
6619   if (skip_past_comma (&str) == FAIL
6620       || reg_required_here (&str, 16) == FAIL
6621       || skip_past_comma (&str) == FAIL)
6622     {
6623       if (! inst.error)
6624         inst.error = BAD_ARGS;
6625       return;
6626     }
6627
6628   /* We require exactly two consecutive SP registers.  */
6629   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
6630     {
6631       if (! inst.error)
6632         inst.error = _("only two consecutive VFP SP registers allowed here");
6633     }
6634
6635   end_of_line (str);
6636   return;
6637 }
6638
6639 static void
6640 do_vfp_sp_from_reg (str)
6641      char *str;
6642 {
6643   skip_whitespace (str);
6644
6645   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6646     return;
6647
6648   if (skip_past_comma (&str) == FAIL
6649       || reg_required_here (&str, 12) == FAIL)
6650     {
6651       if (! inst.error)
6652         inst.error = BAD_ARGS;
6653       return;
6654     }
6655
6656   end_of_line (str);
6657   return;
6658 }
6659
6660 static void
6661 do_vfp_reg_from_dp (str)
6662      char *str;
6663 {
6664   skip_whitespace (str);
6665
6666   if (reg_required_here (&str, 12) == FAIL)
6667     return;
6668
6669   if (skip_past_comma (&str) == FAIL
6670       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6671     {
6672       if (! inst.error)
6673         inst.error = BAD_ARGS;
6674       return;
6675     }
6676
6677   end_of_line (str);
6678   return;
6679 }
6680
6681 static void
6682 do_vfp_reg2_from_dp (str)
6683      char *str;
6684 {
6685   skip_whitespace (str);
6686
6687   if (reg_required_here (&str, 12) == FAIL)
6688     return;
6689
6690   if (skip_past_comma (&str) == FAIL
6691       || reg_required_here (&str, 16) == FAIL
6692       || skip_past_comma (&str) == FAIL
6693       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6694     {
6695       if (! inst.error)
6696         inst.error = BAD_ARGS;
6697       return;
6698     }
6699
6700   end_of_line (str);
6701   return;
6702 }
6703
6704 static void
6705 do_vfp_dp_from_reg (str)
6706      char *str;
6707 {
6708   skip_whitespace (str);
6709
6710   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6711     return;
6712
6713   if (skip_past_comma (&str) == FAIL
6714       || reg_required_here (&str, 12) == FAIL)
6715     {
6716       if (! inst.error)
6717         inst.error = BAD_ARGS;
6718       return;
6719     }
6720
6721   end_of_line (str);
6722   return;
6723 }
6724
6725 static void
6726 do_vfp_dp_from_reg2 (str)
6727      char *str;
6728 {
6729   skip_whitespace (str);
6730
6731   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6732     return;
6733
6734   if (skip_past_comma (&str) == FAIL
6735       || reg_required_here (&str, 12) == FAIL
6736       || skip_past_comma (&str) == FAIL
6737       || reg_required_here (&str, 16))
6738     {
6739       if (! inst.error)
6740         inst.error = BAD_ARGS;
6741       return;
6742     }
6743
6744   end_of_line (str);
6745   return;
6746 }
6747
6748 static const struct vfp_reg *
6749 vfp_psr_parse (str)
6750      char **str;
6751 {
6752   char *start = *str;
6753   char  c;
6754   char *p;
6755   const struct vfp_reg *vreg;
6756
6757   p = start;
6758
6759   /* Find the end of the current token.  */
6760   do
6761     {
6762       c = *p++;
6763     }
6764   while (ISALPHA (c));
6765
6766   /* Mark it.  */
6767   *--p = 0;
6768
6769   for (vreg = vfp_regs + 0;
6770        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
6771        vreg++)
6772     {
6773       if (strcmp (start, vreg->name) == 0)
6774         {
6775           *p = c;
6776           *str = p;
6777           return vreg;
6778         }
6779     }
6780
6781   *p = c;
6782   return NULL;
6783 }
6784
6785 static int
6786 vfp_psr_required_here (str)
6787      char **str;
6788 {
6789   char *start = *str;
6790   const struct vfp_reg *vreg;
6791
6792   vreg = vfp_psr_parse (str);
6793
6794   if (vreg)
6795     {
6796       inst.instruction |= vreg->regno;
6797       return SUCCESS;
6798     }
6799
6800   inst.error = _("VFP system register expected");
6801
6802   *str = start;
6803   return FAIL;
6804 }
6805
6806 static void
6807 do_vfp_reg_from_ctrl (str)
6808      char *str;
6809 {
6810   skip_whitespace (str);
6811
6812   if (reg_required_here (&str, 12) == FAIL)
6813     return;
6814
6815   if (skip_past_comma (&str) == FAIL
6816       || vfp_psr_required_here (&str) == FAIL)
6817     {
6818       if (! inst.error)
6819         inst.error = BAD_ARGS;
6820       return;
6821     }
6822
6823   end_of_line (str);
6824   return;
6825 }
6826
6827 static void
6828 do_vfp_ctrl_from_reg (str)
6829      char *str;
6830 {
6831   skip_whitespace (str);
6832
6833   if (vfp_psr_required_here (&str) == FAIL)
6834     return;
6835
6836   if (skip_past_comma (&str) == FAIL
6837       || reg_required_here (&str, 12) == FAIL)
6838     {
6839       if (! inst.error)
6840         inst.error = BAD_ARGS;
6841       return;
6842     }
6843
6844   end_of_line (str);
6845   return;
6846 }
6847
6848 static void
6849 do_vfp_sp_ldst (str)
6850      char *str;
6851 {
6852   skip_whitespace (str);
6853
6854   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6855     {
6856       if (!inst.error)
6857         inst.error = BAD_ARGS;
6858       return;
6859     }
6860
6861   if (skip_past_comma (&str) == FAIL
6862       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6863     {
6864       if (!inst.error)
6865         inst.error = BAD_ARGS;
6866       return;
6867     }
6868
6869   end_of_line (str);
6870   return;
6871 }
6872
6873 static void
6874 do_vfp_dp_ldst (str)
6875      char *str;
6876 {
6877   skip_whitespace (str);
6878
6879   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6880     {
6881       if (!inst.error)
6882         inst.error = BAD_ARGS;
6883       return;
6884     }
6885
6886   if (skip_past_comma (&str) == FAIL
6887       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6888     {
6889       if (!inst.error)
6890         inst.error = BAD_ARGS;
6891       return;
6892     }
6893
6894   end_of_line (str);
6895   return;
6896 }
6897
6898 /* Parse and encode a VFP SP register list, storing the initial
6899    register in position POS and returning the range as the result.  If
6900    the string is invalid return FAIL (an invalid range).  */
6901 static long
6902 vfp_sp_reg_list (str, pos)
6903      char **str;
6904      enum vfp_sp_reg_pos pos;
6905 {
6906   long range = 0;
6907   int base_reg = 0;
6908   int new_base;
6909   long base_bits = 0;
6910   int count = 0;
6911   long tempinst;
6912   unsigned long mask = 0;
6913   int warned = 0;
6914
6915   if (**str != '{')
6916     return FAIL;
6917
6918   (*str)++;
6919   skip_whitespace (*str);
6920
6921   tempinst = inst.instruction;
6922
6923   do
6924     {
6925       inst.instruction = 0;
6926
6927       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
6928         return FAIL;
6929
6930       if (count == 0 || base_reg > new_base)
6931         {
6932           base_reg = new_base;
6933           base_bits = inst.instruction;
6934         }
6935
6936       if (mask & (1 << new_base))
6937         {
6938           inst.error = _("invalid register list");
6939           return FAIL;
6940         }
6941
6942       if ((mask >> new_base) != 0 && ! warned)
6943         {
6944           as_tsktsk (_("register list not in ascending order"));
6945           warned = 1;
6946         }
6947
6948       mask |= 1 << new_base;
6949       count++;
6950
6951       skip_whitespace (*str);
6952
6953       if (**str == '-') /* We have the start of a range expression */
6954         {
6955           int high_range;
6956
6957           (*str)++;
6958
6959           if ((high_range
6960                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
6961               == FAIL)
6962             {
6963               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6964               return FAIL;
6965             }
6966
6967           if (high_range <= new_base)
6968             {
6969               inst.error = _("register range not in ascending order");
6970               return FAIL;
6971             }
6972
6973           for (new_base++; new_base <= high_range; new_base++)
6974             {
6975               if (mask & (1 << new_base))
6976                 {
6977                   inst.error = _("invalid register list");
6978                   return FAIL;
6979                 }
6980
6981               mask |= 1 << new_base;
6982               count++;
6983             }
6984         }
6985     }
6986   while (skip_past_comma (str) != FAIL);
6987
6988   if (**str != '}')
6989     {
6990       inst.error = _("invalid register list");
6991       return FAIL;
6992     }
6993
6994   (*str)++;
6995
6996   range = count;
6997
6998   /* Sanity check -- should have raised a parse error above.  */
6999   if (count == 0 || count > 32)
7000     abort ();
7001
7002   /* Final test -- the registers must be consecutive.  */
7003   while (count--)
7004     {
7005       if ((mask & (1 << base_reg++)) == 0)
7006         {
7007           inst.error = _("non-contiguous register range");
7008           return FAIL;
7009         }
7010     }
7011
7012   inst.instruction = tempinst | base_bits;
7013   return range;
7014 }
7015
7016 static long
7017 vfp_dp_reg_list (str)
7018      char **str;
7019 {
7020   long range = 0;
7021   int base_reg = 0;
7022   int new_base;
7023   int count = 0;
7024   long tempinst;
7025   unsigned long mask = 0;
7026   int warned = 0;
7027
7028   if (**str != '{')
7029     return FAIL;
7030
7031   (*str)++;
7032   skip_whitespace (*str);
7033
7034   tempinst = inst.instruction;
7035
7036   do
7037     {
7038       inst.instruction = 0;
7039
7040       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
7041         return FAIL;
7042
7043       if (count == 0 || base_reg > new_base)
7044         {
7045           base_reg = new_base;
7046           range = inst.instruction;
7047         }
7048
7049       if (mask & (1 << new_base))
7050         {
7051           inst.error = _("invalid register list");
7052           return FAIL;
7053         }
7054
7055       if ((mask >> new_base) != 0 && ! warned)
7056         {
7057           as_tsktsk (_("register list not in ascending order"));
7058           warned = 1;
7059         }
7060
7061       mask |= 1 << new_base;
7062       count++;
7063
7064       skip_whitespace (*str);
7065
7066       if (**str == '-') /* We have the start of a range expression */
7067         {
7068           int high_range;
7069
7070           (*str)++;
7071
7072           if ((high_range
7073                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
7074               == FAIL)
7075             {
7076               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7077               return FAIL;
7078             }
7079
7080           if (high_range <= new_base)
7081             {
7082               inst.error = _("register range not in ascending order");
7083               return FAIL;
7084             }
7085
7086           for (new_base++; new_base <= high_range; new_base++)
7087             {
7088               if (mask & (1 << new_base))
7089                 {
7090                   inst.error = _("invalid register list");
7091                   return FAIL;
7092                 }
7093
7094               mask |= 1 << new_base;
7095               count++;
7096             }
7097         }
7098     }
7099   while (skip_past_comma (str) != FAIL);
7100
7101   if (**str != '}')
7102     {
7103       inst.error = _("invalid register list");
7104       return FAIL;
7105     }
7106
7107   (*str)++;
7108
7109   range |= 2 * count;
7110
7111   /* Sanity check -- should have raised a parse error above.  */
7112   if (count == 0 || count > 16)
7113     abort ();
7114
7115   /* Final test -- the registers must be consecutive.  */
7116   while (count--)
7117     {
7118       if ((mask & (1 << base_reg++)) == 0)
7119         {
7120           inst.error = _("non-contiguous register range");
7121           return FAIL;
7122         }
7123     }
7124
7125   inst.instruction = tempinst;
7126   return range;
7127 }
7128
7129 static void
7130 vfp_sp_ldstm (str, ldstm_type)
7131      char *str;
7132      enum vfp_ldstm_type ldstm_type;
7133 {
7134   long range;
7135
7136   skip_whitespace (str);
7137
7138   if (reg_required_here (&str, 16) == FAIL)
7139     return;
7140
7141   skip_whitespace (str);
7142
7143   if (*str == '!')
7144     {
7145       inst.instruction |= WRITE_BACK;
7146       str++;
7147     }
7148   else if (ldstm_type != VFP_LDSTMIA)
7149     {
7150       inst.error = _("this addressing mode requires base-register writeback");
7151       return;
7152     }
7153
7154   if (skip_past_comma (&str) == FAIL
7155       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
7156     {
7157       if (!inst.error)
7158         inst.error = BAD_ARGS;
7159       return;
7160     }
7161
7162   inst.instruction |= range;
7163   end_of_line (str);
7164 }
7165
7166 static void
7167 vfp_dp_ldstm (str, ldstm_type)
7168      char *str;
7169      enum vfp_ldstm_type ldstm_type;
7170 {
7171   long range;
7172
7173   skip_whitespace (str);
7174
7175   if (reg_required_here (&str, 16) == FAIL)
7176     return;
7177
7178   skip_whitespace (str);
7179
7180   if (*str == '!')
7181     {
7182       inst.instruction |= WRITE_BACK;
7183       str++;
7184     }
7185   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7186     {
7187       inst.error = _("this addressing mode requires base-register writeback");
7188       return;
7189     }
7190
7191   if (skip_past_comma (&str) == FAIL
7192       || (range = vfp_dp_reg_list (&str)) == FAIL)
7193     {
7194       if (!inst.error)
7195         inst.error = BAD_ARGS;
7196       return;
7197     }
7198
7199   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7200     range += 1;
7201
7202   inst.instruction |= range;
7203   end_of_line (str);
7204 }
7205
7206 static void
7207 do_vfp_sp_ldstmia (str)
7208      char *str;
7209 {
7210   vfp_sp_ldstm (str, VFP_LDSTMIA);
7211 }
7212
7213 static void
7214 do_vfp_sp_ldstmdb (str)
7215      char *str;
7216 {
7217   vfp_sp_ldstm (str, VFP_LDSTMDB);
7218 }
7219
7220 static void
7221 do_vfp_dp_ldstmia (str)
7222      char *str;
7223 {
7224   vfp_dp_ldstm (str, VFP_LDSTMIA);
7225 }
7226
7227 static void
7228 do_vfp_dp_ldstmdb (str)
7229      char *str;
7230 {
7231   vfp_dp_ldstm (str, VFP_LDSTMDB);
7232 }
7233
7234 static void
7235 do_vfp_xp_ldstmia (str)
7236      char *str;
7237 {
7238   vfp_dp_ldstm (str, VFP_LDSTMIAX);
7239 }
7240
7241 static void
7242 do_vfp_xp_ldstmdb (str)
7243      char *str;
7244 {
7245   vfp_dp_ldstm (str, VFP_LDSTMDBX);
7246 }
7247
7248 static void
7249 do_vfp_sp_compare_z (str)
7250      char *str;
7251 {
7252   skip_whitespace (str);
7253
7254   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7255     {
7256       if (!inst.error)
7257         inst.error = BAD_ARGS;
7258       return;
7259     }
7260
7261   end_of_line (str);
7262   return;
7263 }
7264
7265 static void
7266 do_vfp_dp_compare_z (str)
7267      char *str;
7268 {
7269   skip_whitespace (str);
7270
7271   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7272     {
7273       if (!inst.error)
7274         inst.error = BAD_ARGS;
7275       return;
7276     }
7277
7278   end_of_line (str);
7279   return;
7280 }
7281
7282 static void
7283 do_vfp_dp_sp_cvt (str)
7284      char *str;
7285 {
7286   skip_whitespace (str);
7287
7288   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7289     return;
7290
7291   if (skip_past_comma (&str) == FAIL
7292       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7293     {
7294       if (! inst.error)
7295         inst.error = BAD_ARGS;
7296       return;
7297     }
7298
7299   end_of_line (str);
7300   return;
7301 }
7302
7303 static void
7304 do_vfp_sp_dp_cvt (str)
7305      char *str;
7306 {
7307   skip_whitespace (str);
7308
7309   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7310     return;
7311
7312   if (skip_past_comma (&str) == FAIL
7313       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7314     {
7315       if (! inst.error)
7316         inst.error = BAD_ARGS;
7317       return;
7318     }
7319
7320   end_of_line (str);
7321   return;
7322 }
7323
7324 /* Thumb specific routines.  */
7325
7326 /* Parse and validate that a register is of the right form, this saves
7327    repeated checking of this information in many similar cases.
7328    Unlike the 32-bit case we do not insert the register into the opcode
7329    here, since the position is often unknown until the full instruction
7330    has been parsed.  */
7331
7332 static int
7333 thumb_reg (strp, hi_lo)
7334      char ** strp;
7335      int     hi_lo;
7336 {
7337   int reg;
7338
7339   if ((reg = reg_required_here (strp, -1)) == FAIL)
7340     return FAIL;
7341
7342   switch (hi_lo)
7343     {
7344     case THUMB_REG_LO:
7345       if (reg > 7)
7346         {
7347           inst.error = _("lo register required");
7348           return FAIL;
7349         }
7350       break;
7351
7352     case THUMB_REG_HI:
7353       if (reg < 8)
7354         {
7355           inst.error = _("hi register required");
7356           return FAIL;
7357         }
7358       break;
7359
7360     default:
7361       break;
7362     }
7363
7364   return reg;
7365 }
7366
7367 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
7368    was SUB.  */
7369
7370 static void
7371 thumb_add_sub (str, subtract)
7372      char * str;
7373      int    subtract;
7374 {
7375   int Rd, Rs, Rn = FAIL;
7376
7377   skip_whitespace (str);
7378
7379   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7380       || skip_past_comma (&str) == FAIL)
7381     {
7382       if (! inst.error)
7383         inst.error = BAD_ARGS;
7384       return;
7385     }
7386
7387   if (is_immediate_prefix (*str))
7388     {
7389       Rs = Rd;
7390       str++;
7391       if (my_get_expression (&inst.reloc.exp, &str))
7392         return;
7393     }
7394   else
7395     {
7396       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7397         return;
7398
7399       if (skip_past_comma (&str) == FAIL)
7400         {
7401           /* Two operand format, shuffle the registers
7402              and pretend there are 3.  */
7403           Rn = Rs;
7404           Rs = Rd;
7405         }
7406       else if (is_immediate_prefix (*str))
7407         {
7408           str++;
7409           if (my_get_expression (&inst.reloc.exp, &str))
7410             return;
7411         }
7412       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7413         return;
7414     }
7415
7416   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7417      for the latter case, EXPR contains the immediate that was found.  */
7418   if (Rn != FAIL)
7419     {
7420       /* All register format.  */
7421       if (Rd > 7 || Rs > 7 || Rn > 7)
7422         {
7423           if (Rs != Rd)
7424             {
7425               inst.error = _("dest and source1 must be the same register");
7426               return;
7427             }
7428
7429           /* Can't do this for SUB.  */
7430           if (subtract)
7431             {
7432               inst.error = _("subtract valid only on lo regs");
7433               return;
7434             }
7435
7436           inst.instruction = (T_OPCODE_ADD_HI
7437                               | (Rd > 7 ? THUMB_H1 : 0)
7438                               | (Rn > 7 ? THUMB_H2 : 0));
7439           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
7440         }
7441       else
7442         {
7443           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
7444           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
7445         }
7446     }
7447   else
7448     {
7449       /* Immediate expression, now things start to get nasty.  */
7450
7451       /* First deal with HI regs, only very restricted cases allowed:
7452          Adjusting SP, and using PC or SP to get an address.  */
7453       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
7454           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
7455         {
7456           inst.error = _("invalid Hi register with immediate");
7457           return;
7458         }
7459
7460       if (inst.reloc.exp.X_op != O_constant)
7461         {
7462           /* Value isn't known yet, all we can do is store all the fragments
7463              we know about in the instruction and let the reloc hacking
7464              work it all out.  */
7465           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
7466           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
7467         }
7468       else
7469         {
7470           int offset = inst.reloc.exp.X_add_number;
7471
7472           if (subtract)
7473             offset = - offset;
7474
7475           if (offset < 0)
7476             {
7477               offset = - offset;
7478               subtract = 1;
7479
7480               /* Quick check, in case offset is MIN_INT.  */
7481               if (offset < 0)
7482                 {
7483                   inst.error = _("immediate value out of range");
7484                   return;
7485                 }
7486             }
7487           /* Note - you cannot convert a subtract of 0 into an
7488              add of 0 because the carry flag is set differently.  */
7489           else if (offset > 0)
7490             subtract = 0;
7491
7492           if (Rd == REG_SP)
7493             {
7494               if (offset & ~0x1fc)
7495                 {
7496                   inst.error = _("invalid immediate value for stack adjust");
7497                   return;
7498                 }
7499               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
7500               inst.instruction |= offset >> 2;
7501             }
7502           else if (Rs == REG_PC || Rs == REG_SP)
7503             {
7504               if (subtract
7505                   || (offset & ~0x3fc))
7506                 {
7507                   inst.error = _("invalid immediate for address calculation");
7508                   return;
7509                 }
7510               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
7511                                   : T_OPCODE_ADD_SP);
7512               inst.instruction |= (Rd << 8) | (offset >> 2);
7513             }
7514           else if (Rs == Rd)
7515             {
7516               if (offset & ~0xff)
7517                 {
7518                   inst.error = _("immediate value out of range");
7519                   return;
7520                 }
7521               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
7522               inst.instruction |= (Rd << 8) | offset;
7523             }
7524           else
7525             {
7526               if (offset & ~0x7)
7527                 {
7528                   inst.error = _("immediate value out of range");
7529                   return;
7530                 }
7531               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
7532               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
7533             }
7534         }
7535     }
7536
7537   end_of_line (str);
7538 }
7539
7540 static void
7541 thumb_shift (str, shift)
7542      char * str;
7543      int    shift;
7544 {
7545   int Rd, Rs, Rn = FAIL;
7546
7547   skip_whitespace (str);
7548
7549   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7550       || skip_past_comma (&str) == FAIL)
7551     {
7552       if (! inst.error)
7553         inst.error = BAD_ARGS;
7554       return;
7555     }
7556
7557   if (is_immediate_prefix (*str))
7558     {
7559       /* Two operand immediate format, set Rs to Rd.  */
7560       Rs = Rd;
7561       str ++;
7562       if (my_get_expression (&inst.reloc.exp, &str))
7563         return;
7564     }
7565   else
7566     {
7567       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7568         return;
7569
7570       if (skip_past_comma (&str) == FAIL)
7571         {
7572           /* Two operand format, shuffle the registers
7573              and pretend there are 3.  */
7574           Rn = Rs;
7575           Rs = Rd;
7576         }
7577       else if (is_immediate_prefix (*str))
7578         {
7579           str++;
7580           if (my_get_expression (&inst.reloc.exp, &str))
7581             return;
7582         }
7583       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7584         return;
7585     }
7586
7587   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7588      for the latter case, EXPR contains the immediate that was found.  */
7589
7590   if (Rn != FAIL)
7591     {
7592       if (Rs != Rd)
7593         {
7594           inst.error = _("source1 and dest must be same register");
7595           return;
7596         }
7597
7598       switch (shift)
7599         {
7600         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
7601         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
7602         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
7603         }
7604
7605       inst.instruction |= Rd | (Rn << 3);
7606     }
7607   else
7608     {
7609       switch (shift)
7610         {
7611         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
7612         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
7613         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
7614         }
7615
7616       if (inst.reloc.exp.X_op != O_constant)
7617         {
7618           /* Value isn't known yet, create a dummy reloc and let reloc
7619              hacking fix it up.  */
7620           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
7621         }
7622       else
7623         {
7624           unsigned shift_value = inst.reloc.exp.X_add_number;
7625
7626           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
7627             {
7628               inst.error = _("invalid immediate for shift");
7629               return;
7630             }
7631
7632           /* Shifts of zero are handled by converting to LSL.  */
7633           if (shift_value == 0)
7634             inst.instruction = T_OPCODE_LSL_I;
7635
7636           /* Shifts of 32 are encoded as a shift of zero.  */
7637           if (shift_value == 32)
7638             shift_value = 0;
7639
7640           inst.instruction |= shift_value << 6;
7641         }
7642
7643       inst.instruction |= Rd | (Rs << 3);
7644     }
7645
7646   end_of_line (str);
7647 }
7648
7649 static void
7650 thumb_mov_compare (str, move)
7651      char * str;
7652      int    move;
7653 {
7654   int Rd, Rs = FAIL;
7655
7656   skip_whitespace (str);
7657
7658   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7659       || skip_past_comma (&str) == FAIL)
7660     {
7661       if (! inst.error)
7662         inst.error = BAD_ARGS;
7663       return;
7664     }
7665
7666   if (is_immediate_prefix (*str))
7667     {
7668       str++;
7669       if (my_get_expression (&inst.reloc.exp, &str))
7670         return;
7671     }
7672   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7673     return;
7674
7675   if (Rs != FAIL)
7676     {
7677       if (Rs < 8 && Rd < 8)
7678         {
7679           if (move == THUMB_MOVE)
7680             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
7681                since a MOV instruction produces unpredictable results.  */
7682             inst.instruction = T_OPCODE_ADD_I3;
7683           else
7684             inst.instruction = T_OPCODE_CMP_LR;
7685           inst.instruction |= Rd | (Rs << 3);
7686         }
7687       else
7688         {
7689           if (move == THUMB_MOVE)
7690             inst.instruction = T_OPCODE_MOV_HR;
7691           else
7692             inst.instruction = T_OPCODE_CMP_HR;
7693
7694           if (Rd > 7)
7695             inst.instruction |= THUMB_H1;
7696
7697           if (Rs > 7)
7698             inst.instruction |= THUMB_H2;
7699
7700           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
7701         }
7702     }
7703   else
7704     {
7705       if (Rd > 7)
7706         {
7707           inst.error = _("only lo regs allowed with immediate");
7708           return;
7709         }
7710
7711       if (move == THUMB_MOVE)
7712         inst.instruction = T_OPCODE_MOV_I8;
7713       else
7714         inst.instruction = T_OPCODE_CMP_I8;
7715
7716       inst.instruction |= Rd << 8;
7717
7718       if (inst.reloc.exp.X_op != O_constant)
7719         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
7720       else
7721         {
7722           unsigned value = inst.reloc.exp.X_add_number;
7723
7724           if (value > 255)
7725             {
7726               inst.error = _("invalid immediate");
7727               return;
7728             }
7729
7730           inst.instruction |= value;
7731         }
7732     }
7733
7734   end_of_line (str);
7735 }
7736
7737 static void
7738 thumb_load_store (str, load_store, size)
7739      char * str;
7740      int    load_store;
7741      int    size;
7742 {
7743   int Rd, Rb, Ro = FAIL;
7744
7745   skip_whitespace (str);
7746
7747   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7748       || skip_past_comma (&str) == FAIL)
7749     {
7750       if (! inst.error)
7751         inst.error = BAD_ARGS;
7752       return;
7753     }
7754
7755   if (*str == '[')
7756     {
7757       str++;
7758       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7759         return;
7760
7761       if (skip_past_comma (&str) != FAIL)
7762         {
7763           if (is_immediate_prefix (*str))
7764             {
7765               str++;
7766               if (my_get_expression (&inst.reloc.exp, &str))
7767                 return;
7768             }
7769           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7770             return;
7771         }
7772       else
7773         {
7774           inst.reloc.exp.X_op = O_constant;
7775           inst.reloc.exp.X_add_number = 0;
7776         }
7777
7778       if (*str != ']')
7779         {
7780           inst.error = _("expected ']'");
7781           return;
7782         }
7783       str++;
7784     }
7785   else if (*str == '=')
7786     {
7787       if (load_store != THUMB_LOAD)
7788         {
7789           inst.error = _("invalid pseudo operation");
7790           return;
7791         }
7792
7793       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7794       str++;
7795
7796       skip_whitespace (str);
7797
7798       if (my_get_expression (& inst.reloc.exp, & str))
7799         return;
7800
7801       end_of_line (str);
7802
7803       if (   inst.reloc.exp.X_op != O_constant
7804           && inst.reloc.exp.X_op != O_symbol)
7805         {
7806           inst.error = "Constant expression expected";
7807           return;
7808         }
7809
7810       if (inst.reloc.exp.X_op == O_constant
7811           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
7812         {
7813           /* This can be done with a mov instruction.  */
7814
7815           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
7816           inst.instruction |= inst.reloc.exp.X_add_number;
7817           return;
7818         }
7819
7820       /* Insert into literal pool.  */
7821       if (add_to_lit_pool () == FAIL)
7822         {
7823           if (!inst.error)
7824             inst.error = "literal pool insertion failed";
7825           return;
7826         }
7827
7828       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
7829       inst.reloc.pc_rel = 1;
7830       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
7831       /* Adjust ARM pipeline offset to Thumb.  */
7832       inst.reloc.exp.X_add_number += 4;
7833
7834       return;
7835     }
7836   else
7837     {
7838       if (my_get_expression (&inst.reloc.exp, &str))
7839         return;
7840
7841       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
7842       inst.reloc.pc_rel = 1;
7843       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
7844       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7845       end_of_line (str);
7846       return;
7847     }
7848
7849   if (Rb == REG_PC || Rb == REG_SP)
7850     {
7851       if (size != THUMB_WORD)
7852         {
7853           inst.error = _("byte or halfword not valid for base register");
7854           return;
7855         }
7856       else if (Rb == REG_PC && load_store != THUMB_LOAD)
7857         {
7858           inst.error = _("r15 based store not allowed");
7859           return;
7860         }
7861       else if (Ro != FAIL)
7862         {
7863           inst.error = _("invalid base register for register offset");
7864           return;
7865         }
7866
7867       if (Rb == REG_PC)
7868         inst.instruction = T_OPCODE_LDR_PC;
7869       else if (load_store == THUMB_LOAD)
7870         inst.instruction = T_OPCODE_LDR_SP;
7871       else
7872         inst.instruction = T_OPCODE_STR_SP;
7873
7874       inst.instruction |= Rd << 8;
7875       if (inst.reloc.exp.X_op == O_constant)
7876         {
7877           unsigned offset = inst.reloc.exp.X_add_number;
7878
7879           if (offset & ~0x3fc)
7880             {
7881               inst.error = _("invalid offset");
7882               return;
7883             }
7884
7885           inst.instruction |= offset >> 2;
7886         }
7887       else
7888         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7889     }
7890   else if (Rb > 7)
7891     {
7892       inst.error = _("invalid base register in load/store");
7893       return;
7894     }
7895   else if (Ro == FAIL)
7896     {
7897       /* Immediate offset.  */
7898       if (size == THUMB_WORD)
7899         inst.instruction = (load_store == THUMB_LOAD
7900                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
7901       else if (size == THUMB_HALFWORD)
7902         inst.instruction = (load_store == THUMB_LOAD
7903                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
7904       else
7905         inst.instruction = (load_store == THUMB_LOAD
7906                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
7907
7908       inst.instruction |= Rd | (Rb << 3);
7909
7910       if (inst.reloc.exp.X_op == O_constant)
7911         {
7912           unsigned offset = inst.reloc.exp.X_add_number;
7913
7914           if (offset & ~(0x1f << size))
7915             {
7916               inst.error = _("invalid offset");
7917               return;
7918             }
7919           inst.instruction |= (offset >> size) << 6;
7920         }
7921       else
7922         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7923     }
7924   else
7925     {
7926       /* Register offset.  */
7927       if (size == THUMB_WORD)
7928         inst.instruction = (load_store == THUMB_LOAD
7929                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
7930       else if (size == THUMB_HALFWORD)
7931         inst.instruction = (load_store == THUMB_LOAD
7932                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
7933       else
7934         inst.instruction = (load_store == THUMB_LOAD
7935                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
7936
7937       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
7938     }
7939
7940   end_of_line (str);
7941 }
7942
7943 /* A register must be given at this point.
7944
7945    Shift is the place to put it in inst.instruction.
7946
7947    Restores input start point on err.
7948    Returns the reg#, or FAIL.  */
7949
7950 static int
7951 mav_reg_required_here (str, shift, regtype)
7952      char ** str;
7953      int shift;
7954      enum arm_reg_type regtype;
7955 {
7956   int   reg;
7957   char *start = *str;
7958
7959   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
7960     {
7961       if (shift >= 0)
7962         inst.instruction |= reg << shift;
7963
7964       return reg;
7965     }
7966
7967   /* Restore the start point.  */
7968   *str = start;
7969
7970   /* In the few cases where we might be able to accept something else
7971      this error can be overridden.  */
7972   inst.error = _(all_reg_maps[regtype].expected);
7973
7974   return FAIL;
7975 }
7976
7977 /* Cirrus Maverick Instructions.  */
7978
7979 /* Wrapper functions.  */
7980
7981 static void
7982 do_mav_binops_1a (str)
7983      char * str;
7984 {
7985   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
7986 }
7987
7988 static void
7989 do_mav_binops_1b (str)
7990      char * str;
7991 {
7992   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
7993 }
7994
7995 static void
7996 do_mav_binops_1c (str)
7997      char * str;
7998 {
7999   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8000 }
8001
8002 static void
8003 do_mav_binops_1d (str)
8004      char * str;
8005 {
8006   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8007 }
8008
8009 static void
8010 do_mav_binops_1e (str)
8011      char * str;
8012 {
8013   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8014 }
8015
8016 static void
8017 do_mav_binops_1f (str)
8018      char * str;
8019 {
8020   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8021 }
8022
8023 static void
8024 do_mav_binops_1g (str)
8025      char * str;
8026 {
8027   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8028 }
8029
8030 static void
8031 do_mav_binops_1h (str)
8032      char * str;
8033 {
8034   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8035 }
8036
8037 static void
8038 do_mav_binops_1i (str)
8039      char * str;
8040 {
8041   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8042 }
8043
8044 static void
8045 do_mav_binops_1j (str)
8046      char * str;
8047 {
8048   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8049 }
8050
8051 static void
8052 do_mav_binops_1k (str)
8053      char * str;
8054 {
8055   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8056 }
8057
8058 static void
8059 do_mav_binops_1l (str)
8060      char * str;
8061 {
8062   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8063 }
8064
8065 static void
8066 do_mav_binops_1m (str)
8067      char * str;
8068 {
8069   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8070 }
8071
8072 static void
8073 do_mav_binops_1n (str)
8074      char * str;
8075 {
8076   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8077 }
8078
8079 static void
8080 do_mav_binops_1o (str)
8081      char * str;
8082 {
8083   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8084 }
8085
8086 static void
8087 do_mav_binops_2a (str)
8088      char * str;
8089 {
8090   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8091 }
8092
8093 static void
8094 do_mav_binops_2b (str)
8095      char * str;
8096 {
8097   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8098 }
8099
8100 static void
8101 do_mav_binops_2c (str)
8102      char * str;
8103 {
8104   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8105 }
8106
8107 static void
8108 do_mav_binops_3a (str)
8109      char * str;
8110 {
8111   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8112 }
8113
8114 static void
8115 do_mav_binops_3b (str)
8116      char * str;
8117 {
8118   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8119 }
8120
8121 static void
8122 do_mav_binops_3c (str)
8123      char * str;
8124 {
8125   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8126 }
8127
8128 static void
8129 do_mav_binops_3d (str)
8130      char * str;
8131 {
8132   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8133 }
8134
8135 static void
8136 do_mav_triple_4a (str)
8137      char * str;
8138 {
8139   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8140 }
8141
8142 static void
8143 do_mav_triple_4b (str)
8144      char * str;
8145 {
8146   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8147 }
8148
8149 static void
8150 do_mav_triple_5a (str)
8151      char * str;
8152 {
8153   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8154 }
8155
8156 static void
8157 do_mav_triple_5b (str)
8158      char * str;
8159 {
8160   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8161 }
8162
8163 static void
8164 do_mav_triple_5c (str)
8165      char * str;
8166 {
8167   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8168 }
8169
8170 static void
8171 do_mav_triple_5d (str)
8172      char * str;
8173 {
8174   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8175 }
8176
8177 static void
8178 do_mav_triple_5e (str)
8179      char * str;
8180 {
8181   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8182 }
8183
8184 static void
8185 do_mav_triple_5f (str)
8186      char * str;
8187 {
8188   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8189 }
8190
8191 static void
8192 do_mav_triple_5g (str)
8193      char * str;
8194 {
8195   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8196 }
8197
8198 static void
8199 do_mav_triple_5h (str)
8200      char * str;
8201 {
8202   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8203 }
8204
8205 static void
8206 do_mav_quad_6a (str)
8207      char * str;
8208 {
8209   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8210              REG_TYPE_MVFX);
8211 }
8212
8213 static void
8214 do_mav_quad_6b (str)
8215      char * str;
8216 {
8217   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8218              REG_TYPE_MVFX);
8219 }
8220
8221 /* cfmvsc32<cond> DSPSC,MVFX[15:0].  */
8222 static void
8223 do_mav_dspsc_1 (str)
8224      char * str;
8225 {
8226   skip_whitespace (str);
8227
8228   /* cfmvsc32.  */
8229   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8230       || skip_past_comma (&str) == FAIL
8231       || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
8232     {
8233       if (!inst.error)
8234         inst.error = BAD_ARGS;
8235
8236       return;
8237     }
8238
8239   end_of_line (str);
8240 }
8241
8242 /* cfmv32sc<cond> MVFX[15:0],DSPSC.  */
8243 static void
8244 do_mav_dspsc_2 (str)
8245      char * str;
8246 {
8247   skip_whitespace (str);
8248
8249   /* cfmv32sc.  */
8250   if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
8251       || skip_past_comma (&str) == FAIL
8252       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8253     {
8254       if (!inst.error)
8255         inst.error = BAD_ARGS;
8256
8257       return;
8258     }
8259
8260   end_of_line (str);
8261 }
8262
8263 static void
8264 do_mav_shift_1 (str)
8265      char * str;
8266 {
8267   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
8268 }
8269
8270 static void
8271 do_mav_shift_2 (str)
8272      char * str;
8273 {
8274   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
8275 }
8276
8277 static void
8278 do_mav_ldst_1 (str)
8279      char * str;
8280 {
8281   do_mav_ldst (str, REG_TYPE_MVF);
8282 }
8283
8284 static void
8285 do_mav_ldst_2 (str)
8286      char * str;
8287 {
8288   do_mav_ldst (str, REG_TYPE_MVD);
8289 }
8290
8291 static void
8292 do_mav_ldst_3 (str)
8293      char * str;
8294 {
8295   do_mav_ldst (str, REG_TYPE_MVFX);
8296 }
8297
8298 static void
8299 do_mav_ldst_4 (str)
8300      char * str;
8301 {
8302   do_mav_ldst (str, REG_TYPE_MVDX);
8303 }
8304
8305 /* Isnsn like "foo X,Y".  */
8306
8307 static void
8308 do_mav_binops (str, mode, reg0, reg1)
8309      char * str;
8310      int mode;
8311      enum arm_reg_type reg0;
8312      enum arm_reg_type reg1;
8313 {
8314   int shift0, shift1;
8315
8316   shift0 = mode & 0xff;
8317   shift1 = (mode >> 8) & 0xff;
8318
8319   skip_whitespace (str);
8320
8321   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8322       || skip_past_comma (&str) == FAIL
8323       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8324     {
8325       if (!inst.error)
8326         inst.error = BAD_ARGS;
8327     }
8328   else
8329     end_of_line (str);
8330 }
8331
8332 /* Isnsn like "foo X,Y,Z".  */
8333
8334 static void
8335 do_mav_triple (str, mode, reg0, reg1, reg2)
8336      char * str;
8337      int mode;
8338      enum arm_reg_type reg0;
8339      enum arm_reg_type reg1;
8340      enum arm_reg_type reg2;
8341 {
8342   int shift0, shift1, shift2;
8343
8344   shift0 = mode & 0xff;
8345   shift1 = (mode >> 8) & 0xff;
8346   shift2 = (mode >> 16) & 0xff;
8347
8348   skip_whitespace (str);
8349
8350   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8351       || skip_past_comma (&str) == FAIL
8352       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8353       || skip_past_comma (&str) == FAIL
8354       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8355     {
8356       if (!inst.error)
8357         inst.error = BAD_ARGS;
8358     }
8359   else
8360     end_of_line (str);
8361 }
8362
8363 /* Isnsn like "foo W,X,Y,Z".
8364     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
8365
8366 static void
8367 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
8368      char * str;
8369      int mode;
8370      enum arm_reg_type reg0;
8371      enum arm_reg_type reg1;
8372      enum arm_reg_type reg2;
8373      enum arm_reg_type reg3;
8374 {
8375   int shift0, shift1, shift2, shift3;
8376
8377   shift0= mode & 0xff;
8378   shift1 = (mode >> 8) & 0xff;
8379   shift2 = (mode >> 16) & 0xff;
8380   shift3 = (mode >> 24) & 0xff;
8381
8382   skip_whitespace (str);
8383
8384   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8385       || skip_past_comma (&str) == FAIL
8386       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8387       || skip_past_comma (&str) == FAIL
8388       || mav_reg_required_here (&str, shift2, reg2) == FAIL
8389       || skip_past_comma (&str) == FAIL
8390       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
8391     {
8392       if (!inst.error)
8393         inst.error = BAD_ARGS;
8394     }
8395   else
8396     end_of_line (str);
8397 }
8398
8399 /* Maverick shift immediate instructions.
8400    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8401    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
8402
8403 static void
8404 do_mav_shift (str, reg0, reg1)
8405      char * str;
8406      enum arm_reg_type reg0;
8407      enum arm_reg_type reg1;
8408 {
8409   int error;
8410   int imm, neg = 0;
8411
8412   skip_whitespace (str);
8413
8414   error = 0;
8415
8416   if (mav_reg_required_here (&str, 12, reg0) == FAIL
8417       || skip_past_comma (&str) == FAIL
8418       || mav_reg_required_here (&str, 16, reg1) == FAIL
8419       || skip_past_comma  (&str) == FAIL)
8420     {
8421       if (!inst.error)
8422         inst.error = BAD_ARGS;
8423       return;
8424     }
8425
8426   /* Calculate the immediate operand.
8427      The operand is a 7bit signed number.  */
8428   skip_whitespace (str);
8429
8430   if (*str == '#')
8431     ++str;
8432
8433   if (!ISDIGIT (*str) && *str != '-')
8434     {
8435       inst.error = _("expecting immediate, 7bit operand");
8436       return;
8437     }
8438
8439   if (*str == '-')
8440     {
8441       neg = 1;
8442       ++str;
8443     }
8444
8445   for (imm = 0; *str && ISDIGIT (*str); ++str)
8446     imm = imm * 10 + *str - '0';
8447
8448   if (imm > 64)
8449     {
8450       inst.error = _("immediate out of range");
8451       return;
8452     }
8453
8454   /* Make negative imm's into 7bit signed numbers.  */
8455   if (neg)
8456     {
8457       imm = -imm;
8458       imm &= 0x0000007f;
8459     }
8460
8461   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
8462      Bits 5-7 of the insn should have bits 4-6 of the immediate.
8463      Bit 4 should be 0.  */
8464   imm = (imm & 0xf) | ((imm & 0x70) << 1);
8465
8466   inst.instruction |= imm;
8467   end_of_line (str);
8468 }
8469
8470 static int
8471 mav_parse_offset (str, negative)
8472      char ** str;
8473      int *negative;
8474 {
8475   char * p = *str;
8476   int offset;
8477
8478   *negative = 0;
8479
8480   skip_whitespace (p);
8481
8482   if (*p == '#')
8483     ++p;
8484
8485   if (*p == '-')
8486     {
8487       *negative = 1;
8488       ++p;
8489     }
8490
8491   if (!ISDIGIT (*p))
8492     {
8493       inst.error = _("offset expected");
8494       return 0;
8495     }
8496
8497   for (offset = 0; *p && ISDIGIT (*p); ++p)
8498     offset = offset * 10 + *p - '0';
8499
8500   if (offset > 0xff)
8501     {
8502       inst.error = _("offset out of range");
8503       return 0;
8504     }
8505
8506   *str = p;
8507
8508   return *negative ? -offset : offset;
8509 }
8510
8511 /* Maverick load/store instructions.
8512   <insn><cond> CRd,[Rn,<offset>]{!}.
8513   <insn><cond> CRd,[Rn],<offset>.  */
8514
8515 static void
8516 do_mav_ldst (str, reg0)
8517      char * str;
8518      enum arm_reg_type reg0;
8519 {
8520   int offset, negative;
8521
8522   skip_whitespace (str);
8523
8524   if (mav_reg_required_here (&str, 12, reg0) == FAIL
8525       || skip_past_comma (&str) == FAIL
8526       || *str++ != '['
8527       || reg_required_here (&str, 16) == FAIL)
8528     goto fail_ldst;
8529
8530   if (skip_past_comma (&str) == SUCCESS)
8531     {
8532       /* You are here: "<offset>]{!}".  */
8533       inst.instruction |= PRE_INDEX;
8534
8535       offset = mav_parse_offset (&str, &negative);
8536
8537       if (inst.error)
8538         return;
8539
8540       if (*str++ != ']')
8541         {
8542           inst.error = _("missing ]");
8543           return;
8544         }
8545
8546       if (*str == '!')
8547         {
8548           inst.instruction |= WRITE_BACK;
8549           ++str;
8550         }
8551     }
8552   else
8553     {
8554       /* You are here: "], <offset>".  */
8555       if (*str++ != ']')
8556         {
8557           inst.error = _("missing ]");
8558           return;
8559         }
8560
8561       if (skip_past_comma (&str) == FAIL
8562           || (offset = mav_parse_offset (&str, &negative), inst.error))
8563         goto fail_ldst;
8564
8565       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
8566     }
8567
8568   if (negative)
8569     offset = -offset;
8570   else
8571     inst.instruction |= CP_T_UD; /* Postive, so set bit U.  */
8572
8573   inst.instruction |= offset >> 2;
8574   end_of_line (str);
8575   return;
8576
8577 fail_ldst:
8578   if (!inst.error)
8579      inst.error = BAD_ARGS;
8580   return;
8581 }
8582
8583 static void
8584 do_t_nop (str)
8585      char * str;
8586 {
8587   /* Do nothing.  */
8588   end_of_line (str);
8589   return;
8590 }
8591
8592 /* Handle the Format 4 instructions that do not have equivalents in other
8593    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
8594    BIC and MVN.  */
8595
8596 static void
8597 do_t_arit (str)
8598      char * str;
8599 {
8600   int Rd, Rs, Rn;
8601
8602   skip_whitespace (str);
8603
8604   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8605       || skip_past_comma (&str) == FAIL
8606       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8607     {
8608       inst.error = BAD_ARGS;
8609       return;
8610     }
8611
8612   if (skip_past_comma (&str) != FAIL)
8613     {
8614       /* Three operand format not allowed for TST, CMN, NEG and MVN.
8615          (It isn't allowed for CMP either, but that isn't handled by this
8616          function.)  */
8617       if (inst.instruction == T_OPCODE_TST
8618           || inst.instruction == T_OPCODE_CMN
8619           || inst.instruction == T_OPCODE_NEG
8620           || inst.instruction == T_OPCODE_MVN)
8621         {
8622           inst.error = BAD_ARGS;
8623           return;
8624         }
8625
8626       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8627         return;
8628
8629       if (Rs != Rd)
8630         {
8631           inst.error = _("dest and source1 must be the same register");
8632           return;
8633         }
8634       Rs = Rn;
8635     }
8636
8637   if (inst.instruction == T_OPCODE_MUL
8638       && Rs == Rd)
8639     as_tsktsk (_("Rs and Rd must be different in MUL"));
8640
8641   inst.instruction |= Rd | (Rs << 3);
8642   end_of_line (str);
8643 }
8644
8645 static void
8646 do_t_add (str)
8647      char * str;
8648 {
8649   thumb_add_sub (str, 0);
8650 }
8651
8652 static void
8653 do_t_asr (str)
8654      char * str;
8655 {
8656   thumb_shift (str, THUMB_ASR);
8657 }
8658
8659 static void
8660 do_t_branch9 (str)
8661      char * str;
8662 {
8663   if (my_get_expression (&inst.reloc.exp, &str))
8664     return;
8665   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
8666   inst.reloc.pc_rel = 1;
8667   end_of_line (str);
8668 }
8669
8670 static void
8671 do_t_branch12 (str)
8672      char * str;
8673 {
8674   if (my_get_expression (&inst.reloc.exp, &str))
8675     return;
8676   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
8677   inst.reloc.pc_rel = 1;
8678   end_of_line (str);
8679 }
8680
8681 /* Find the real, Thumb encoded start of a Thumb function.  */
8682
8683 static symbolS *
8684 find_real_start (symbolP)
8685      symbolS * symbolP;
8686 {
8687   char *       real_start;
8688   const char * name = S_GET_NAME (symbolP);
8689   symbolS *    new_target;
8690
8691   /* This definiton must agree with the one in gcc/config/arm/thumb.c.  */
8692 #define STUB_NAME ".real_start_of"
8693
8694   if (name == NULL)
8695     abort ();
8696
8697   /* Names that start with '.' are local labels, not function entry points.
8698      The compiler may generate BL instructions to these labels because it
8699      needs to perform a branch to a far away location.  */
8700   if (name[0] == '.')
8701     return symbolP;
8702
8703   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
8704   sprintf (real_start, "%s%s", STUB_NAME, name);
8705
8706   new_target = symbol_find (real_start);
8707
8708   if (new_target == NULL)
8709     {
8710       as_warn ("Failed to find real start of function: %s\n", name);
8711       new_target = symbolP;
8712     }
8713
8714   free (real_start);
8715
8716   return new_target;
8717 }
8718
8719 static void
8720 do_t_branch23 (str)
8721      char * str;
8722 {
8723   if (my_get_expression (& inst.reloc.exp, & str))
8724     return;
8725
8726   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
8727   inst.reloc.pc_rel = 1;
8728   end_of_line (str);
8729
8730   /* If the destination of the branch is a defined symbol which does not have
8731      the THUMB_FUNC attribute, then we must be calling a function which has
8732      the (interfacearm) attribute.  We look for the Thumb entry point to that
8733      function and change the branch to refer to that function instead.  */
8734   if (   inst.reloc.exp.X_op == O_symbol
8735       && inst.reloc.exp.X_add_symbol != NULL
8736       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
8737       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
8738     inst.reloc.exp.X_add_symbol =
8739       find_real_start (inst.reloc.exp.X_add_symbol);
8740 }
8741
8742 static void
8743 do_t_bx (str)
8744      char * str;
8745 {
8746   int reg;
8747
8748   skip_whitespace (str);
8749
8750   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8751     return;
8752
8753   /* This sets THUMB_H2 from the top bit of reg.  */
8754   inst.instruction |= reg << 3;
8755
8756   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
8757      should cause the alignment to be checked once it is known.  This is
8758      because BX PC only works if the instruction is word aligned.  */
8759
8760   end_of_line (str);
8761 }
8762
8763 static void
8764 do_t_compare (str)
8765      char * str;
8766 {
8767   thumb_mov_compare (str, THUMB_COMPARE);
8768 }
8769
8770 static void
8771 do_t_ldmstm (str)
8772      char * str;
8773 {
8774   int Rb;
8775   long range;
8776
8777   skip_whitespace (str);
8778
8779   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8780     return;
8781
8782   if (*str != '!')
8783     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
8784   else
8785     str++;
8786
8787   if (skip_past_comma (&str) == FAIL
8788       || (range = reg_list (&str)) == FAIL)
8789     {
8790       if (! inst.error)
8791         inst.error = BAD_ARGS;
8792       return;
8793     }
8794
8795   if (inst.reloc.type != BFD_RELOC_NONE)
8796     {
8797       /* This really doesn't seem worth it.  */
8798       inst.reloc.type = BFD_RELOC_NONE;
8799       inst.error = _("expression too complex");
8800       return;
8801     }
8802
8803   if (range & ~0xff)
8804     {
8805       inst.error = _("only lo-regs valid in load/store multiple");
8806       return;
8807     }
8808
8809   inst.instruction |= (Rb << 8) | range;
8810   end_of_line (str);
8811 }
8812
8813 static void
8814 do_t_ldr (str)
8815      char * str;
8816 {
8817   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
8818 }
8819
8820 static void
8821 do_t_ldrb (str)
8822      char * str;
8823 {
8824   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
8825 }
8826
8827 static void
8828 do_t_ldrh (str)
8829      char * str;
8830 {
8831   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
8832 }
8833
8834 static void
8835 do_t_lds (str)
8836      char * str;
8837 {
8838   int Rd, Rb, Ro;
8839
8840   skip_whitespace (str);
8841
8842   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8843       || skip_past_comma (&str) == FAIL
8844       || *str++ != '['
8845       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8846       || skip_past_comma (&str) == FAIL
8847       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8848       || *str++ != ']')
8849     {
8850       if (! inst.error)
8851         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
8852       return;
8853     }
8854
8855   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8856   end_of_line (str);
8857 }
8858
8859 static void
8860 do_t_lsl (str)
8861      char * str;
8862 {
8863   thumb_shift (str, THUMB_LSL);
8864 }
8865
8866 static void
8867 do_t_lsr (str)
8868      char * str;
8869 {
8870   thumb_shift (str, THUMB_LSR);
8871 }
8872
8873 static void
8874 do_t_mov (str)
8875      char * str;
8876 {
8877   thumb_mov_compare (str, THUMB_MOVE);
8878 }
8879
8880 static void
8881 do_t_push_pop (str)
8882      char * str;
8883 {
8884   long range;
8885
8886   skip_whitespace (str);
8887
8888   if ((range = reg_list (&str)) == FAIL)
8889     {
8890       if (! inst.error)
8891         inst.error = BAD_ARGS;
8892       return;
8893     }
8894
8895   if (inst.reloc.type != BFD_RELOC_NONE)
8896     {
8897       /* This really doesn't seem worth it.  */
8898       inst.reloc.type = BFD_RELOC_NONE;
8899       inst.error = _("expression too complex");
8900       return;
8901     }
8902
8903   if (range & ~0xff)
8904     {
8905       if ((inst.instruction == T_OPCODE_PUSH
8906            && (range & ~0xff) == 1 << REG_LR)
8907           || (inst.instruction == T_OPCODE_POP
8908               && (range & ~0xff) == 1 << REG_PC))
8909         {
8910           inst.instruction |= THUMB_PP_PC_LR;
8911           range &= 0xff;
8912         }
8913       else
8914         {
8915           inst.error = _("invalid register list to push/pop instruction");
8916           return;
8917         }
8918     }
8919
8920   inst.instruction |= range;
8921   end_of_line (str);
8922 }
8923
8924 static void
8925 do_t_str (str)
8926      char * str;
8927 {
8928   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
8929 }
8930
8931 static void
8932 do_t_strb (str)
8933      char * str;
8934 {
8935   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
8936 }
8937
8938 static void
8939 do_t_strh (str)
8940      char * str;
8941 {
8942   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
8943 }
8944
8945 static void
8946 do_t_sub (str)
8947      char * str;
8948 {
8949   thumb_add_sub (str, 1);
8950 }
8951
8952 static void
8953 do_t_swi (str)
8954      char * str;
8955 {
8956   skip_whitespace (str);
8957
8958   if (my_get_expression (&inst.reloc.exp, &str))
8959     return;
8960
8961   inst.reloc.type = BFD_RELOC_ARM_SWI;
8962   end_of_line (str);
8963   return;
8964 }
8965
8966 static void
8967 do_t_adr (str)
8968      char * str;
8969 {
8970   int reg;
8971
8972   /* This is a pseudo-op of the form "adr rd, label" to be converted
8973      into a relative address of the form "add rd, pc, #label-.-4".  */
8974   skip_whitespace (str);
8975
8976   /* Store Rd in temporary location inside instruction.  */
8977   if ((reg = reg_required_here (&str, 4)) == FAIL
8978       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
8979       || skip_past_comma (&str) == FAIL
8980       || my_get_expression (&inst.reloc.exp, &str))
8981     {
8982       if (!inst.error)
8983         inst.error = BAD_ARGS;
8984       return;
8985     }
8986
8987   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8988   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
8989   inst.reloc.pc_rel = 1;
8990   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
8991
8992   end_of_line (str);
8993 }
8994
8995 static void
8996 insert_reg (r, htab)
8997      const struct reg_entry *r;
8998      struct hash_control *htab;
8999 {
9000   int    len  = strlen (r->name) + 2;
9001   char * buf  = (char *) xmalloc (len);
9002   char * buf2 = (char *) xmalloc (len);
9003   int    i    = 0;
9004
9005 #ifdef REGISTER_PREFIX
9006   buf[i++] = REGISTER_PREFIX;
9007 #endif
9008
9009   strcpy (buf + i, r->name);
9010
9011   for (i = 0; buf[i]; i++)
9012     buf2[i] = TOUPPER (buf[i]);
9013
9014   buf2[i] = '\0';
9015
9016   hash_insert (htab, buf,  (PTR) r);
9017   hash_insert (htab, buf2, (PTR) r);
9018 }
9019
9020 static void
9021 build_reg_hsh (map)
9022      struct reg_map *map;
9023 {
9024   const struct reg_entry *r;
9025
9026   if ((map->htab = hash_new ()) == NULL)
9027     as_fatal (_("virtual memory exhausted"));
9028
9029   for (r = map->names; r->name != NULL; r++)
9030     insert_reg (r, map->htab);
9031 }
9032
9033 static void
9034 insert_reg_alias (str, regnum, htab)
9035      char *str;
9036      int regnum;
9037      struct hash_control *htab;
9038 {
9039   struct reg_entry *new =
9040     (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
9041   char *name = xmalloc (strlen (str) + 1);
9042   strcpy (name, str);
9043
9044   new->name = name;
9045   new->number = regnum;
9046
9047   hash_insert (htab, name, (PTR) new);
9048 }
9049
9050 /* Look for the .req directive.  This is of the form:
9051
9052         newname .req existing_name
9053
9054    If we find one, or if it looks sufficiently like one that we want to
9055    handle any error here, return non-zero.  Otherwise return zero.  */
9056 static int
9057 create_register_alias (newname, p)
9058      char *newname;
9059      char *p;
9060 {
9061   char *q;
9062   char c;
9063
9064   q = p;
9065   skip_whitespace (q);
9066
9067   c = *p;
9068   *p = '\0';
9069
9070   if (*q && !strncmp (q, ".req ", 5))
9071     {
9072       char *copy_of_str;
9073       char *r;
9074
9075 #ifdef IGNORE_OPCODE_CASE
9076       newname = original_case_string;
9077 #endif
9078       copy_of_str = newname;
9079
9080       q += 4;
9081       skip_whitespace (q);
9082
9083       for (r = q; *r != '\0'; r++)
9084         if (*r == ' ')
9085           break;
9086
9087       if (r != q)
9088         {
9089           enum arm_reg_type new_type, old_type;
9090           int old_regno;
9091           char d = *r;
9092
9093           *r = '\0';
9094           old_type = arm_reg_parse_any (q);
9095           *r = d;
9096
9097           new_type = arm_reg_parse_any (newname);
9098
9099           if (new_type == REG_TYPE_MAX)
9100             {
9101               if (old_type != REG_TYPE_MAX)
9102                 {
9103                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9104                   insert_reg_alias (newname, old_regno,
9105                                     all_reg_maps[old_type].htab);
9106                 }
9107               else
9108                 as_warn (_("register '%s' does not exist\n"), q);
9109             }
9110           else if (old_type == REG_TYPE_MAX)
9111             {
9112               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9113                        copy_of_str, q);
9114             }
9115           else
9116             {
9117               /* Do not warn about redefinitions to the same alias.  */
9118               if (new_type != old_type
9119                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9120                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9121                 as_warn (_("ignoring redefinition of register alias '%s'"),
9122                          copy_of_str);
9123
9124             }
9125         }
9126       else
9127         as_warn (_("ignoring incomplete .req pseuso op"));
9128
9129       *p = c;
9130       return 1;
9131     }
9132   *p = c;
9133   return 0;
9134 }
9135
9136 static void
9137 set_constant_flonums ()
9138 {
9139   int i;
9140
9141   for (i = 0; i < NUM_FLOAT_VALS; i++)
9142     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9143       abort ();
9144 }
9145
9146 /* Iterate over the base tables to create the instruction patterns.  */
9147 static void
9148 build_arm_ops_hsh ()
9149 {
9150   unsigned int i;
9151   unsigned int j;
9152   static struct obstack insn_obstack;
9153
9154   obstack_begin (&insn_obstack, 4000);
9155
9156   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
9157     {
9158       const struct asm_opcode *insn = insns + i;
9159
9160       if (insn->cond_offset != 0)
9161         {
9162           /* Insn supports conditional execution.  Build the varaints
9163              and insert them in the hash table.  */
9164           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
9165             {
9166               unsigned len = strlen (insn->template);
9167               struct asm_opcode *new;
9168               char *template;
9169
9170               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
9171               /* All condition codes are two characters.  */
9172               template = obstack_alloc (&insn_obstack, len + 3);
9173
9174               strncpy (template, insn->template, insn->cond_offset);
9175               strcpy (template + insn->cond_offset, conds[j].template);
9176               if (len > insn->cond_offset)
9177                 strcpy (template + insn->cond_offset + 2,
9178                         insn->template + insn->cond_offset);
9179               new->template = template;
9180               new->cond_offset = 0;
9181               new->variant = insn->variant;
9182               new->parms = insn->parms;
9183               new->value = (insn->value & ~COND_MASK) | conds[j].value;
9184
9185               hash_insert (arm_ops_hsh, new->template, (PTR) new);
9186             }
9187         }
9188       /* Finally, insert the unconditional insn in the table directly;
9189          no need to build a copy.  */
9190       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
9191     }
9192 }
9193
9194 void
9195 md_begin ()
9196 {
9197   unsigned mach;
9198   unsigned int i;
9199
9200   if (   (arm_ops_hsh = hash_new ()) == NULL
9201       || (arm_tops_hsh = hash_new ()) == NULL
9202       || (arm_cond_hsh = hash_new ()) == NULL
9203       || (arm_shift_hsh = hash_new ()) == NULL
9204       || (arm_psr_hsh = hash_new ()) == NULL)
9205     as_fatal (_("virtual memory exhausted"));
9206
9207   build_arm_ops_hsh ();
9208   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
9209     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
9210   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
9211     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
9212   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
9213     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
9214   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
9215     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
9216
9217   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9218     build_reg_hsh (all_reg_maps + i);
9219
9220   set_constant_flonums ();
9221
9222   /* Set the cpu variant based on the command-line options.  We prefer
9223      -mcpu= over -march= if both are set (as for GCC); and we prefer
9224      -mfpu= over any other way of setting the floating point unit.
9225      Use of legacy options with new options are faulted.  */
9226   if (legacy_cpu != -1)
9227     {
9228       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
9229         as_bad (_("use of old and new-style options to set CPU type"));
9230
9231       mcpu_cpu_opt = legacy_cpu;
9232     }
9233   else if (mcpu_cpu_opt == -1)
9234     mcpu_cpu_opt = march_cpu_opt;
9235
9236   if (legacy_fpu != -1)
9237     {
9238       if (mfpu_opt != -1)
9239         as_bad (_("use of old and new-style options to set FPU type"));
9240
9241       mfpu_opt = legacy_fpu;
9242     }
9243   else if (mfpu_opt == -1)
9244     {
9245       if (mcpu_fpu_opt != -1)
9246         mfpu_opt = mcpu_fpu_opt;
9247       else
9248         mfpu_opt = march_fpu_opt;
9249     }
9250
9251   if (mfpu_opt == -1)
9252     {
9253       if (mcpu_cpu_opt == -1)
9254         mfpu_opt = FPU_DEFAULT;
9255       else if (mcpu_cpu_opt & ARM_EXT_V5)
9256         mfpu_opt = FPU_ARCH_VFP_V2;
9257       else
9258         mfpu_opt = FPU_ARCH_FPA;
9259     }
9260
9261   if (mcpu_cpu_opt == -1)
9262     mcpu_cpu_opt = CPU_DEFAULT;
9263
9264   cpu_variant = mcpu_cpu_opt | mfpu_opt;
9265
9266 #if defined OBJ_COFF || defined OBJ_ELF
9267   {
9268     unsigned int flags = 0;
9269
9270     /* Set the flags in the private structure.  */
9271     if (uses_apcs_26)      flags |= F_APCS26;
9272     if (support_interwork) flags |= F_INTERWORK;
9273     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
9274     if (pic_code)          flags |= F_PIC;
9275     if ((cpu_variant & FPU_ANY) == FPU_NONE
9276         || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
9277       flags |= F_SOFT_FLOAT;
9278     /* Using VFP conventions (even if soft-float).  */
9279     if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
9280
9281
9282     bfd_set_private_flags (stdoutput, flags);
9283
9284     /* We have run out flags in the COFF header to encode the
9285        status of ATPCS support, so instead we create a dummy,
9286        empty, debug section called .arm.atpcs.  */
9287     if (atpcs)
9288       {
9289         asection * sec;
9290
9291         sec = bfd_make_section (stdoutput, ".arm.atpcs");
9292
9293         if (sec != NULL)
9294           {
9295             bfd_set_section_flags
9296               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
9297             bfd_set_section_size (stdoutput, sec, 0);
9298             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
9299           }
9300       }
9301   }
9302 #endif
9303
9304   /* Record the CPU type as well.  */
9305   switch (cpu_variant & ARM_CPU_MASK)
9306     {
9307     case ARM_2:
9308       mach = bfd_mach_arm_2;
9309       break;
9310
9311     case ARM_3:                 /* Also ARM_250.  */
9312       mach = bfd_mach_arm_2a;
9313       break;
9314
9315     case ARM_6:                 /* Also ARM_7.  */
9316       mach = bfd_mach_arm_3;
9317       break;
9318
9319     default:
9320       mach = bfd_mach_arm_4;
9321       break;
9322     }
9323
9324   /* Catch special cases.  */
9325   if (cpu_variant & ARM_CEXT_XSCALE)
9326     mach = bfd_mach_arm_XScale;
9327   else if (cpu_variant & ARM_EXT_V5E)
9328     mach = bfd_mach_arm_5TE;
9329   else if (cpu_variant & ARM_EXT_V5)
9330     {
9331       if (cpu_variant & ARM_EXT_V4T)
9332         mach = bfd_mach_arm_5T;
9333       else
9334         mach = bfd_mach_arm_5;
9335     }
9336   else if (cpu_variant & ARM_EXT_V4)
9337     {
9338       if (cpu_variant & ARM_EXT_V4T)
9339         mach = bfd_mach_arm_4T;
9340       else
9341         mach = bfd_mach_arm_4;
9342     }
9343   else if (cpu_variant & ARM_EXT_V3M)
9344     mach = bfd_mach_arm_3M;
9345
9346   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
9347 }
9348
9349 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
9350    for use in the a.out file, and stores them in the array pointed to by buf.
9351    This knows about the endian-ness of the target machine and does
9352    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
9353    2 (short) and 4 (long)  Floating numbers are put out as a series of
9354    LITTLENUMS (shorts, here at least).  */
9355
9356 void
9357 md_number_to_chars (buf, val, n)
9358      char * buf;
9359      valueT val;
9360      int    n;
9361 {
9362   if (target_big_endian)
9363     number_to_chars_bigendian (buf, val, n);
9364   else
9365     number_to_chars_littleendian (buf, val, n);
9366 }
9367
9368 static valueT
9369 md_chars_to_number (buf, n)
9370      char * buf;
9371      int    n;
9372 {
9373   valueT result = 0;
9374   unsigned char * where = (unsigned char *) buf;
9375
9376   if (target_big_endian)
9377     {
9378       while (n--)
9379         {
9380           result <<= 8;
9381           result |= (*where++ & 255);
9382         }
9383     }
9384   else
9385     {
9386       while (n--)
9387         {
9388           result <<= 8;
9389           result |= (where[n] & 255);
9390         }
9391     }
9392
9393   return result;
9394 }
9395
9396 /* Turn a string in input_line_pointer into a floating point constant
9397    of type TYPE, and store the appropriate bytes in *LITP.  The number
9398    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
9399    returned, or NULL on OK.
9400
9401    Note that fp constants aren't represent in the normal way on the ARM.
9402    In big endian mode, things are as expected.  However, in little endian
9403    mode fp constants are big-endian word-wise, and little-endian byte-wise
9404    within the words.  For example, (double) 1.1 in big endian mode is
9405    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
9406    the byte sequence 99 99 f1 3f 9a 99 99 99.
9407
9408    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
9409
9410 char *
9411 md_atof (type, litP, sizeP)
9412      char   type;
9413      char * litP;
9414      int *  sizeP;
9415 {
9416   int prec;
9417   LITTLENUM_TYPE words[MAX_LITTLENUMS];
9418   char *t;
9419   int i;
9420
9421   switch (type)
9422     {
9423     case 'f':
9424     case 'F':
9425     case 's':
9426     case 'S':
9427       prec = 2;
9428       break;
9429
9430     case 'd':
9431     case 'D':
9432     case 'r':
9433     case 'R':
9434       prec = 4;
9435       break;
9436
9437     case 'x':
9438     case 'X':
9439       prec = 6;
9440       break;
9441
9442     case 'p':
9443     case 'P':
9444       prec = 6;
9445       break;
9446
9447     default:
9448       *sizeP = 0;
9449       return _("bad call to MD_ATOF()");
9450     }
9451
9452   t = atof_ieee (input_line_pointer, type, words);
9453   if (t)
9454     input_line_pointer = t;
9455   *sizeP = prec * 2;
9456
9457   if (target_big_endian)
9458     {
9459       for (i = 0; i < prec; i++)
9460         {
9461           md_number_to_chars (litP, (valueT) words[i], 2);
9462           litP += 2;
9463         }
9464     }
9465   else
9466     {
9467       if (cpu_variant & FPU_ARCH_VFP)
9468         for (i = prec - 1; i >= 0; i--)
9469           {
9470             md_number_to_chars (litP, (valueT) words[i], 2);
9471             litP += 2;
9472           }
9473       else
9474         /* For a 4 byte float the order of elements in `words' is 1 0.
9475            For an 8 byte float the order is 1 0 3 2.  */
9476         for (i = 0; i < prec; i += 2)
9477           {
9478             md_number_to_chars (litP, (valueT) words[i + 1], 2);
9479             md_number_to_chars (litP + 2, (valueT) words[i], 2);
9480             litP += 4;
9481           }
9482     }
9483
9484   return 0;
9485 }
9486
9487 /* The knowledge of the PC's pipeline offset is built into the insns
9488    themselves.  */
9489
9490 long
9491 md_pcrel_from (fixP)
9492      fixS * fixP;
9493 {
9494   if (fixP->fx_addsy
9495       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
9496       && fixP->fx_subsy == NULL)
9497     return 0;
9498
9499   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
9500     {
9501       /* PC relative addressing on the Thumb is slightly odd
9502          as the bottom two bits of the PC are forced to zero
9503          for the calculation.  */
9504       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
9505     }
9506
9507 #ifdef TE_WINCE
9508   /* The pattern was adjusted to accomodate CE's off-by-one fixups,
9509      so we un-adjust here to compensate for the accomodation.  */
9510   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
9511 #else
9512   return fixP->fx_where + fixP->fx_frag->fr_address;
9513 #endif
9514 }
9515
9516 /* Round up a section size to the appropriate boundary.  */
9517
9518 valueT
9519 md_section_align (segment, size)
9520      segT   segment ATTRIBUTE_UNUSED;
9521      valueT size;
9522 {
9523 #ifdef OBJ_ELF
9524   return size;
9525 #else
9526   /* Round all sects to multiple of 4.  */
9527   return (size + 3) & ~3;
9528 #endif
9529 }
9530
9531 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
9532    Otherwise we have no need to default values of symbols.  */
9533
9534 symbolS *
9535 md_undefined_symbol (name)
9536      char * name ATTRIBUTE_UNUSED;
9537 {
9538 #ifdef OBJ_ELF
9539   if (name[0] == '_' && name[1] == 'G'
9540       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
9541     {
9542       if (!GOT_symbol)
9543         {
9544           if (symbol_find (name))
9545             as_bad ("GOT already in the symbol table");
9546
9547           GOT_symbol = symbol_new (name, undefined_section,
9548                                    (valueT) 0, & zero_address_frag);
9549         }
9550
9551       return GOT_symbol;
9552     }
9553 #endif
9554
9555   return 0;
9556 }
9557
9558 /* arm_reg_parse () := if it looks like a register, return its token and
9559    advance the pointer.  */
9560
9561 static int
9562 arm_reg_parse (ccp, htab)
9563      register char ** ccp;
9564      struct hash_control *htab;
9565 {
9566   char * start = * ccp;
9567   char   c;
9568   char * p;
9569   struct reg_entry * reg;
9570
9571 #ifdef REGISTER_PREFIX
9572   if (*start != REGISTER_PREFIX)
9573     return FAIL;
9574   p = start + 1;
9575 #else
9576   p = start;
9577 #ifdef OPTIONAL_REGISTER_PREFIX
9578   if (*p == OPTIONAL_REGISTER_PREFIX)
9579     p++, start++;
9580 #endif
9581 #endif
9582   if (!ISALPHA (*p) || !is_name_beginner (*p))
9583     return FAIL;
9584
9585   c = *p++;
9586   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
9587     c = *p++;
9588
9589   *--p = 0;
9590   reg = (struct reg_entry *) hash_find (htab, start);
9591   *p = c;
9592
9593   if (reg)
9594     {
9595       *ccp = p;
9596       return reg->number;
9597     }
9598
9599   return FAIL;
9600 }
9601
9602 /* Search for the following register name in each of the possible reg name
9603    tables.  Return the classification if found, or REG_TYPE_MAX if not
9604    present.  */
9605 static enum arm_reg_type
9606 arm_reg_parse_any (cp)
9607      char *cp;
9608 {
9609   int i;
9610
9611   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9612     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
9613       return (enum arm_reg_type) i;
9614
9615   return REG_TYPE_MAX;
9616 }
9617
9618 void
9619 md_apply_fix3 (fixP, valP, seg)
9620      fixS *   fixP;
9621      valueT * valP;
9622      segT     seg;
9623 {
9624   offsetT        value = * valP;
9625   offsetT        newval;
9626   unsigned int   newimm;
9627   unsigned long  temp;
9628   int            sign;
9629   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
9630   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
9631
9632   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
9633
9634   /* Note whether this will delete the relocation.  */
9635 #if 0
9636   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
9637      doesn't work fully.)  */
9638   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
9639       && !fixP->fx_pcrel)
9640 #else
9641   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
9642 #endif
9643     fixP->fx_done = 1;
9644
9645   /* If this symbol is in a different section then we need to leave it for
9646      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
9647      so we have to undo it's effects here.  */
9648   if (fixP->fx_pcrel)
9649     {
9650       if (fixP->fx_addsy != NULL
9651           && S_IS_DEFINED (fixP->fx_addsy)
9652           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
9653         {
9654           if (target_oabi
9655               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
9656                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
9657                   ))
9658             value = 0;
9659           else
9660             value += md_pcrel_from (fixP);
9661         }
9662     }
9663
9664   /* Remember value for emit_reloc.  */
9665   fixP->fx_addnumber = value;
9666
9667   switch (fixP->fx_r_type)
9668     {
9669     case BFD_RELOC_ARM_IMMEDIATE:
9670       newimm = validate_immediate (value);
9671       temp = md_chars_to_number (buf, INSN_SIZE);
9672
9673       /* If the instruction will fail, see if we can fix things up by
9674          changing the opcode.  */
9675       if (newimm == (unsigned int) FAIL
9676           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
9677         {
9678           as_bad_where (fixP->fx_file, fixP->fx_line,
9679                         _("invalid constant (%lx) after fixup"),
9680                         (unsigned long) value);
9681           break;
9682         }
9683
9684       newimm |= (temp & 0xfffff000);
9685       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9686       fixP->fx_done = 1;
9687       break;
9688
9689     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
9690       {
9691         unsigned int highpart = 0;
9692         unsigned int newinsn  = 0xe1a00000; /* nop.  */
9693
9694         newimm = validate_immediate (value);
9695         temp = md_chars_to_number (buf, INSN_SIZE);
9696
9697         /* If the instruction will fail, see if we can fix things up by
9698            changing the opcode.  */
9699         if (newimm == (unsigned int) FAIL
9700             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
9701           {
9702             /* No ?  OK - try using two ADD instructions to generate
9703                the value.  */
9704             newimm = validate_immediate_twopart (value, & highpart);
9705
9706             /* Yes - then make sure that the second instruction is
9707                also an add.  */
9708             if (newimm != (unsigned int) FAIL)
9709               newinsn = temp;
9710             /* Still No ?  Try using a negated value.  */
9711             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
9712               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
9713             /* Otherwise - give up.  */
9714             else
9715               {
9716                 as_bad_where (fixP->fx_file, fixP->fx_line,
9717                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
9718                               (long) value);
9719                 break;
9720               }
9721
9722             /* Replace the first operand in the 2nd instruction (which
9723                is the PC) with the destination register.  We have
9724                already added in the PC in the first instruction and we
9725                do not want to do it again.  */
9726             newinsn &= ~ 0xf0000;
9727             newinsn |= ((newinsn & 0x0f000) << 4);
9728           }
9729
9730         newimm |= (temp & 0xfffff000);
9731         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9732
9733         highpart |= (newinsn & 0xfffff000);
9734         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
9735       }
9736       break;
9737
9738     case BFD_RELOC_ARM_OFFSET_IMM:
9739       sign = value >= 0;
9740
9741       if (value < 0)
9742         value = - value;
9743
9744       if (validate_offset_imm (value, 0) == FAIL)
9745         {
9746           as_bad_where (fixP->fx_file, fixP->fx_line,
9747                         _("bad immediate value for offset (%ld)"),
9748                         (long) value);
9749           break;
9750         }
9751
9752       newval = md_chars_to_number (buf, INSN_SIZE);
9753       newval &= 0xff7ff000;
9754       newval |= value | (sign ? INDEX_UP : 0);
9755       md_number_to_chars (buf, newval, INSN_SIZE);
9756       break;
9757
9758     case BFD_RELOC_ARM_OFFSET_IMM8:
9759     case BFD_RELOC_ARM_HWLITERAL:
9760       sign = value >= 0;
9761
9762       if (value < 0)
9763         value = - value;
9764
9765       if (validate_offset_imm (value, 1) == FAIL)
9766         {
9767           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
9768             as_bad_where (fixP->fx_file, fixP->fx_line,
9769                           _("invalid literal constant: pool needs to be closer"));
9770           else
9771             as_bad (_("bad immediate value for half-word offset (%ld)"),
9772                     (long) value);
9773           break;
9774         }
9775
9776       newval = md_chars_to_number (buf, INSN_SIZE);
9777       newval &= 0xff7ff0f0;
9778       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
9779       md_number_to_chars (buf, newval, INSN_SIZE);
9780       break;
9781
9782     case BFD_RELOC_ARM_LITERAL:
9783       sign = value >= 0;
9784
9785       if (value < 0)
9786         value = - value;
9787
9788       if (validate_offset_imm (value, 0) == FAIL)
9789         {
9790           as_bad_where (fixP->fx_file, fixP->fx_line,
9791                         _("invalid literal constant: pool needs to be closer"));
9792           break;
9793         }
9794
9795       newval = md_chars_to_number (buf, INSN_SIZE);
9796       newval &= 0xff7ff000;
9797       newval |= value | (sign ? INDEX_UP : 0);
9798       md_number_to_chars (buf, newval, INSN_SIZE);
9799       break;
9800
9801     case BFD_RELOC_ARM_SHIFT_IMM:
9802       newval = md_chars_to_number (buf, INSN_SIZE);
9803       if (((unsigned long) value) > 32
9804           || (value == 32
9805               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
9806         {
9807           as_bad_where (fixP->fx_file, fixP->fx_line,
9808                         _("shift expression is too large"));
9809           break;
9810         }
9811
9812       if (value == 0)
9813         /* Shifts of zero must be done as lsl.  */
9814         newval &= ~0x60;
9815       else if (value == 32)
9816         value = 0;
9817       newval &= 0xfffff07f;
9818       newval |= (value & 0x1f) << 7;
9819       md_number_to_chars (buf, newval, INSN_SIZE);
9820       break;
9821
9822     case BFD_RELOC_ARM_SWI:
9823       if (arm_data->thumb_mode)
9824         {
9825           if (((unsigned long) value) > 0xff)
9826             as_bad_where (fixP->fx_file, fixP->fx_line,
9827                           _("invalid swi expression"));
9828           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
9829           newval |= value;
9830           md_number_to_chars (buf, newval, THUMB_SIZE);
9831         }
9832       else
9833         {
9834           if (((unsigned long) value) > 0x00ffffff)
9835             as_bad_where (fixP->fx_file, fixP->fx_line,
9836                           _("invalid swi expression"));
9837           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
9838           newval |= value;
9839           md_number_to_chars (buf, newval, INSN_SIZE);
9840         }
9841       break;
9842
9843     case BFD_RELOC_ARM_MULTI:
9844       if (((unsigned long) value) > 0xffff)
9845         as_bad_where (fixP->fx_file, fixP->fx_line,
9846                       _("invalid expression in load/store multiple"));
9847       newval = value | md_chars_to_number (buf, INSN_SIZE);
9848       md_number_to_chars (buf, newval, INSN_SIZE);
9849       break;
9850
9851     case BFD_RELOC_ARM_PCREL_BRANCH:
9852       newval = md_chars_to_number (buf, INSN_SIZE);
9853
9854       /* Sign-extend a 24-bit number.  */
9855 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
9856
9857 #ifdef OBJ_ELF
9858       if (! target_oabi)
9859         value = fixP->fx_offset;
9860 #endif
9861
9862       /* We are going to store value (shifted right by two) in the
9863          instruction, in a 24 bit, signed field.  Thus we need to check
9864          that none of the top 8 bits of the shifted value (top 7 bits of
9865          the unshifted, unsigned value) are set, or that they are all set.  */
9866       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
9867           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
9868         {
9869 #ifdef OBJ_ELF
9870           /* Normally we would be stuck at this point, since we cannot store
9871              the absolute address that is the destination of the branch in the
9872              24 bits of the branch instruction.  If however, we happen to know
9873              that the destination of the branch is in the same section as the
9874              branch instruciton itself, then we can compute the relocation for
9875              ourselves and not have to bother the linker with it.
9876
9877              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
9878              because I have not worked out how to do this for OBJ_COFF or
9879              target_oabi.  */
9880           if (! target_oabi
9881               && fixP->fx_addsy != NULL
9882               && S_IS_DEFINED (fixP->fx_addsy)
9883               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
9884             {
9885               /* Get pc relative value to go into the branch.  */
9886               value = * valP;
9887
9888               /* Permit a backward branch provided that enough bits
9889                  are set.  Allow a forwards branch, provided that
9890                  enough bits are clear.  */
9891               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
9892                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
9893                 fixP->fx_done = 1;
9894             }
9895
9896           if (! fixP->fx_done)
9897 #endif
9898             as_bad_where (fixP->fx_file, fixP->fx_line,
9899                           _("GAS can't handle same-section branch dest >= 0x04000000"));
9900         }
9901
9902       value >>= 2;
9903       value += SEXT24 (newval);
9904
9905       if (    (value & ~ ((offsetT) 0xffffff)) != 0
9906           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
9907         as_bad_where (fixP->fx_file, fixP->fx_line,
9908                       _("out of range branch"));
9909
9910       newval = (value & 0x00ffffff) | (newval & 0xff000000);
9911       md_number_to_chars (buf, newval, INSN_SIZE);
9912       break;
9913
9914     case BFD_RELOC_ARM_PCREL_BLX:
9915       {
9916         offsetT hbit;
9917         newval = md_chars_to_number (buf, INSN_SIZE);
9918
9919 #ifdef OBJ_ELF
9920         if (! target_oabi)
9921           value = fixP->fx_offset;
9922 #endif
9923         hbit   = (value >> 1) & 1;
9924         value  = (value >> 2) & 0x00ffffff;
9925         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
9926         newval = value | (newval & 0xfe000000) | (hbit << 24);
9927         md_number_to_chars (buf, newval, INSN_SIZE);
9928       }
9929       break;
9930
9931     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
9932       newval = md_chars_to_number (buf, THUMB_SIZE);
9933       {
9934         addressT diff = (newval & 0xff) << 1;
9935         if (diff & 0x100)
9936           diff |= ~0xff;
9937
9938         value += diff;
9939         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
9940           as_bad_where (fixP->fx_file, fixP->fx_line,
9941                         _("branch out of range"));
9942         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
9943       }
9944       md_number_to_chars (buf, newval, THUMB_SIZE);
9945       break;
9946
9947     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
9948       newval = md_chars_to_number (buf, THUMB_SIZE);
9949       {
9950         addressT diff = (newval & 0x7ff) << 1;
9951         if (diff & 0x800)
9952           diff |= ~0x7ff;
9953
9954         value += diff;
9955         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
9956           as_bad_where (fixP->fx_file, fixP->fx_line,
9957                         _("branch out of range"));
9958         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
9959       }
9960       md_number_to_chars (buf, newval, THUMB_SIZE);
9961       break;
9962
9963     case BFD_RELOC_THUMB_PCREL_BLX:
9964     case BFD_RELOC_THUMB_PCREL_BRANCH23:
9965       {
9966         offsetT newval2;
9967         addressT diff;
9968
9969         newval  = md_chars_to_number (buf, THUMB_SIZE);
9970         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
9971         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
9972         if (diff & 0x400000)
9973           diff |= ~0x3fffff;
9974 #ifdef OBJ_ELF
9975         value = fixP->fx_offset;
9976 #endif
9977         value += diff;
9978
9979         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
9980           as_bad_where (fixP->fx_file, fixP->fx_line,
9981                         _("branch with link out of range"));
9982
9983         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
9984         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
9985         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
9986           /* For a BLX instruction, make sure that the relocation is rounded up
9987              to a word boundary.  This follows the semantics of the instruction
9988              which specifies that bit 1 of the target address will come from bit
9989              1 of the base address.  */
9990           newval2 = (newval2 + 1) & ~ 1;
9991         md_number_to_chars (buf, newval, THUMB_SIZE);
9992         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
9993       }
9994       break;
9995
9996     case BFD_RELOC_8:
9997       if (fixP->fx_done || fixP->fx_pcrel)
9998         md_number_to_chars (buf, value, 1);
9999 #ifdef OBJ_ELF
10000       else if (!target_oabi)
10001         {
10002           value = fixP->fx_offset;
10003           md_number_to_chars (buf, value, 1);
10004         }
10005 #endif
10006       break;
10007
10008     case BFD_RELOC_16:
10009       if (fixP->fx_done || fixP->fx_pcrel)
10010         md_number_to_chars (buf, value, 2);
10011 #ifdef OBJ_ELF
10012       else if (!target_oabi)
10013         {
10014           value = fixP->fx_offset;
10015           md_number_to_chars (buf, value, 2);
10016         }
10017 #endif
10018       break;
10019
10020 #ifdef OBJ_ELF
10021     case BFD_RELOC_ARM_GOT32:
10022     case BFD_RELOC_ARM_GOTOFF:
10023       md_number_to_chars (buf, 0, 4);
10024       break;
10025 #endif
10026
10027     case BFD_RELOC_RVA:
10028     case BFD_RELOC_32:
10029       if (fixP->fx_done || fixP->fx_pcrel)
10030         md_number_to_chars (buf, value, 4);
10031 #ifdef OBJ_ELF
10032       else if (!target_oabi)
10033         {
10034           value = fixP->fx_offset;
10035           md_number_to_chars (buf, value, 4);
10036         }
10037 #endif
10038       break;
10039
10040 #ifdef OBJ_ELF
10041     case BFD_RELOC_ARM_PLT32:
10042       /* It appears the instruction is fully prepared at this point.  */
10043       break;
10044 #endif
10045
10046     case BFD_RELOC_ARM_CP_OFF_IMM:
10047       sign = value >= 0;
10048       if (value < -1023 || value > 1023 || (value & 3))
10049         as_bad_where (fixP->fx_file, fixP->fx_line,
10050                       _("illegal value for co-processor offset"));
10051       if (value < 0)
10052         value = -value;
10053       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
10054       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
10055       md_number_to_chars (buf, newval, INSN_SIZE);
10056       break;
10057
10058     case BFD_RELOC_ARM_THUMB_OFFSET:
10059       newval = md_chars_to_number (buf, THUMB_SIZE);
10060       /* Exactly what ranges, and where the offset is inserted depends
10061          on the type of instruction, we can establish this from the
10062          top 4 bits.  */
10063       switch (newval >> 12)
10064         {
10065         case 4: /* PC load.  */
10066           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
10067              forced to zero for these loads, so we will need to round
10068              up the offset if the instruction address is not word
10069              aligned (since the final address produced must be, and
10070              we can only describe word-aligned immediate offsets).  */
10071
10072           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
10073             as_bad_where (fixP->fx_file, fixP->fx_line,
10074                           _("invalid offset, target not word aligned (0x%08X)"),
10075                           (unsigned int) (fixP->fx_frag->fr_address
10076                                           + fixP->fx_where + value));
10077
10078           if ((value + 2) & ~0x3fe)
10079             as_bad_where (fixP->fx_file, fixP->fx_line,
10080                           _("invalid offset, value too big (0x%08lX)"),
10081                           (long) value);
10082
10083           /* Round up, since pc will be rounded down.  */
10084           newval |= (value + 2) >> 2;
10085           break;
10086
10087         case 9: /* SP load/store.  */
10088           if (value & ~0x3fc)
10089             as_bad_where (fixP->fx_file, fixP->fx_line,
10090                           _("invalid offset, value too big (0x%08lX)"),
10091                           (long) value);
10092           newval |= value >> 2;
10093           break;
10094
10095         case 6: /* Word load/store.  */
10096           if (value & ~0x7c)
10097             as_bad_where (fixP->fx_file, fixP->fx_line,
10098                           _("invalid offset, value too big (0x%08lX)"),
10099                           (long) value);
10100           newval |= value << 4; /* 6 - 2.  */
10101           break;
10102
10103         case 7: /* Byte load/store.  */
10104           if (value & ~0x1f)
10105             as_bad_where (fixP->fx_file, fixP->fx_line,
10106                           _("invalid offset, value too big (0x%08lX)"),
10107                           (long) value);
10108           newval |= value << 6;
10109           break;
10110
10111         case 8: /* Halfword load/store.  */
10112           if (value & ~0x3e)
10113             as_bad_where (fixP->fx_file, fixP->fx_line,
10114                           _("invalid offset, value too big (0x%08lX)"),
10115                           (long) value);
10116           newval |= value << 5; /* 6 - 1.  */
10117           break;
10118
10119         default:
10120           as_bad_where (fixP->fx_file, fixP->fx_line,
10121                         "Unable to process relocation for thumb opcode: %lx",
10122                         (unsigned long) newval);
10123           break;
10124         }
10125       md_number_to_chars (buf, newval, THUMB_SIZE);
10126       break;
10127
10128     case BFD_RELOC_ARM_THUMB_ADD:
10129       /* This is a complicated relocation, since we use it for all of
10130          the following immediate relocations:
10131
10132             3bit ADD/SUB
10133             8bit ADD/SUB
10134             9bit ADD/SUB SP word-aligned
10135            10bit ADD PC/SP word-aligned
10136
10137          The type of instruction being processed is encoded in the
10138          instruction field:
10139
10140            0x8000  SUB
10141            0x00F0  Rd
10142            0x000F  Rs
10143       */
10144       newval = md_chars_to_number (buf, THUMB_SIZE);
10145       {
10146         int rd = (newval >> 4) & 0xf;
10147         int rs = newval & 0xf;
10148         int subtract = newval & 0x8000;
10149
10150         if (rd == REG_SP)
10151           {
10152             if (value & ~0x1fc)
10153               as_bad_where (fixP->fx_file, fixP->fx_line,
10154                             _("invalid immediate for stack address calculation"));
10155             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
10156             newval |= value >> 2;
10157           }
10158         else if (rs == REG_PC || rs == REG_SP)
10159           {
10160             if (subtract ||
10161                 value & ~0x3fc)
10162               as_bad_where (fixP->fx_file, fixP->fx_line,
10163                             _("invalid immediate for address calculation (value = 0x%08lX)"),
10164                             (unsigned long) value);
10165             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
10166             newval |= rd << 8;
10167             newval |= value >> 2;
10168           }
10169         else if (rs == rd)
10170           {
10171             if (value & ~0xff)
10172               as_bad_where (fixP->fx_file, fixP->fx_line,
10173                             _("invalid 8bit immediate"));
10174             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
10175             newval |= (rd << 8) | value;
10176           }
10177         else
10178           {
10179             if (value & ~0x7)
10180               as_bad_where (fixP->fx_file, fixP->fx_line,
10181                             _("invalid 3bit immediate"));
10182             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
10183             newval |= rd | (rs << 3) | (value << 6);
10184           }
10185       }
10186       md_number_to_chars (buf, newval, THUMB_SIZE);
10187       break;
10188
10189     case BFD_RELOC_ARM_THUMB_IMM:
10190       newval = md_chars_to_number (buf, THUMB_SIZE);
10191       switch (newval >> 11)
10192         {
10193         case 0x04: /* 8bit immediate MOV.  */
10194         case 0x05: /* 8bit immediate CMP.  */
10195           if (value < 0 || value > 255)
10196             as_bad_where (fixP->fx_file, fixP->fx_line,
10197                           _("invalid immediate: %ld is too large"),
10198                           (long) value);
10199           newval |= value;
10200           break;
10201
10202         default:
10203           abort ();
10204         }
10205       md_number_to_chars (buf, newval, THUMB_SIZE);
10206       break;
10207
10208     case BFD_RELOC_ARM_THUMB_SHIFT:
10209       /* 5bit shift value (0..31).  */
10210       if (value < 0 || value > 31)
10211         as_bad_where (fixP->fx_file, fixP->fx_line,
10212                       _("illegal Thumb shift value: %ld"), (long) value);
10213       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
10214       newval |= value << 6;
10215       md_number_to_chars (buf, newval, THUMB_SIZE);
10216       break;
10217
10218     case BFD_RELOC_VTABLE_INHERIT:
10219     case BFD_RELOC_VTABLE_ENTRY:
10220       fixP->fx_done = 0;
10221       return;
10222
10223     case BFD_RELOC_NONE:
10224     default:
10225       as_bad_where (fixP->fx_file, fixP->fx_line,
10226                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
10227     }
10228 }
10229
10230 /* Translate internal representation of relocation info to BFD target
10231    format.  */
10232
10233 arelent *
10234 tc_gen_reloc (section, fixp)
10235      asection * section ATTRIBUTE_UNUSED;
10236      fixS * fixp;
10237 {
10238   arelent * reloc;
10239   bfd_reloc_code_real_type code;
10240
10241   reloc = (arelent *) xmalloc (sizeof (arelent));
10242
10243   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
10244   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
10245   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
10246
10247   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
10248 #ifndef OBJ_ELF
10249   if (fixp->fx_pcrel == 0)
10250     reloc->addend = fixp->fx_offset;
10251   else
10252     reloc->addend = fixp->fx_offset = reloc->address;
10253 #else  /* OBJ_ELF */
10254   reloc->addend = fixp->fx_offset;
10255 #endif
10256
10257   switch (fixp->fx_r_type)
10258     {
10259     case BFD_RELOC_8:
10260       if (fixp->fx_pcrel)
10261         {
10262           code = BFD_RELOC_8_PCREL;
10263           break;
10264         }
10265
10266     case BFD_RELOC_16:
10267       if (fixp->fx_pcrel)
10268         {
10269           code = BFD_RELOC_16_PCREL;
10270           break;
10271         }
10272
10273     case BFD_RELOC_32:
10274       if (fixp->fx_pcrel)
10275         {
10276           code = BFD_RELOC_32_PCREL;
10277           break;
10278         }
10279
10280     case BFD_RELOC_ARM_PCREL_BRANCH:
10281     case BFD_RELOC_ARM_PCREL_BLX:
10282     case BFD_RELOC_RVA:
10283     case BFD_RELOC_THUMB_PCREL_BRANCH9:
10284     case BFD_RELOC_THUMB_PCREL_BRANCH12:
10285     case BFD_RELOC_THUMB_PCREL_BRANCH23:
10286     case BFD_RELOC_THUMB_PCREL_BLX:
10287     case BFD_RELOC_VTABLE_ENTRY:
10288     case BFD_RELOC_VTABLE_INHERIT:
10289       code = fixp->fx_r_type;
10290       break;
10291
10292     case BFD_RELOC_ARM_LITERAL:
10293     case BFD_RELOC_ARM_HWLITERAL:
10294       /* If this is called then the a literal has
10295          been referenced across a section boundary.  */
10296       as_bad_where (fixp->fx_file, fixp->fx_line,
10297                     _("literal referenced across section boundary"));
10298       return NULL;
10299
10300 #ifdef OBJ_ELF
10301     case BFD_RELOC_ARM_GOT32:
10302     case BFD_RELOC_ARM_GOTOFF:
10303     case BFD_RELOC_ARM_PLT32:
10304       code = fixp->fx_r_type;
10305       break;
10306 #endif
10307
10308     case BFD_RELOC_ARM_IMMEDIATE:
10309       as_bad_where (fixp->fx_file, fixp->fx_line,
10310                     _("internal relocation (type: IMMEDIATE) not fixed up"));
10311       return NULL;
10312
10313     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
10314       as_bad_where (fixp->fx_file, fixp->fx_line,
10315                     _("ADRL used for a symbol not defined in the same file"));
10316       return NULL;
10317
10318     case BFD_RELOC_ARM_OFFSET_IMM:
10319       as_bad_where (fixp->fx_file, fixp->fx_line,
10320                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
10321       return NULL;
10322
10323     default:
10324       {
10325         char * type;
10326
10327         switch (fixp->fx_r_type)
10328           {
10329           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
10330           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
10331           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
10332           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
10333           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
10334           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
10335           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
10336           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
10337           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
10338           default:                         type = _("<unknown>"); break;
10339           }
10340         as_bad_where (fixp->fx_file, fixp->fx_line,
10341                       _("cannot represent %s relocation in this object file format"),
10342                       type);
10343         return NULL;
10344       }
10345     }
10346
10347 #ifdef OBJ_ELF
10348   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
10349       && GOT_symbol
10350       && fixp->fx_addsy == GOT_symbol)
10351     {
10352       code = BFD_RELOC_ARM_GOTPC;
10353       reloc->addend = fixp->fx_offset = reloc->address;
10354     }
10355 #endif
10356
10357   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
10358
10359   if (reloc->howto == NULL)
10360     {
10361       as_bad_where (fixp->fx_file, fixp->fx_line,
10362                     _("cannot represent %s relocation in this object file format"),
10363                     bfd_get_reloc_code_name (code));
10364       return NULL;
10365     }
10366
10367   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
10368      vtable entry to be used in the relocation's section offset.  */
10369   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
10370     reloc->address = fixp->fx_offset;
10371
10372   return reloc;
10373 }
10374
10375 int
10376 md_estimate_size_before_relax (fragP, segtype)
10377      fragS * fragP ATTRIBUTE_UNUSED;
10378      segT    segtype ATTRIBUTE_UNUSED;
10379 {
10380   as_fatal (_("md_estimate_size_before_relax\n"));
10381   return 1;
10382 }
10383
10384 static void
10385 output_inst (str)
10386      const char *str;
10387 {
10388   char * to = NULL;
10389
10390   if (inst.error)
10391     {
10392       as_bad ("%s -- `%s'", inst.error, str);
10393       return;
10394     }
10395
10396   to = frag_more (inst.size);
10397
10398   if (thumb_mode && (inst.size > THUMB_SIZE))
10399     {
10400       assert (inst.size == (2 * THUMB_SIZE));
10401       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
10402       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
10403     }
10404   else if (inst.size > INSN_SIZE)
10405     {
10406       assert (inst.size == (2 * INSN_SIZE));
10407       md_number_to_chars (to, inst.instruction, INSN_SIZE);
10408       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
10409     }
10410   else
10411     md_number_to_chars (to, inst.instruction, inst.size);
10412
10413   if (inst.reloc.type != BFD_RELOC_NONE)
10414     fix_new_arm (frag_now, to - frag_now->fr_literal,
10415                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
10416                  inst.reloc.type);
10417
10418 #ifdef OBJ_ELF
10419   dwarf2_emit_insn (inst.size);
10420 #endif
10421 }
10422
10423 void
10424 md_assemble (str)
10425      char * str;
10426 {
10427   char  c;
10428   char *p;
10429   char *start;
10430
10431   /* Align the instruction.
10432      This may not be the right thing to do but ...  */
10433 #if 0
10434   arm_align (2, 0);
10435 #endif
10436
10437   /* Align the previous label if needed.  */
10438   if (last_label_seen != NULL)
10439     {
10440       symbol_set_frag (last_label_seen, frag_now);
10441       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
10442       S_SET_SEGMENT (last_label_seen, now_seg);
10443     }
10444
10445   memset (&inst, '\0', sizeof (inst));
10446   inst.reloc.type = BFD_RELOC_NONE;
10447
10448   skip_whitespace (str);
10449
10450   /* Scan up to the end of the op-code, which must end in white space or
10451      end of string.  */
10452   for (start = p = str; *p != '\0'; p++)
10453     if (*p == ' ')
10454       break;
10455
10456   if (p == str)
10457     {
10458       as_bad (_("no operator -- statement `%s'\n"), str);
10459       return;
10460     }
10461
10462   if (thumb_mode)
10463     {
10464       const struct thumb_opcode * opcode;
10465
10466       c = *p;
10467       *p = '\0';
10468       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
10469       *p = c;
10470
10471       if (opcode)
10472         {
10473           /* Check that this instruction is supported for this CPU.  */
10474           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
10475             {
10476               as_bad (_("selected processor does not support `%s'"), str);
10477               return;
10478             }
10479
10480           inst.instruction = opcode->value;
10481           inst.size = opcode->size;
10482           (*opcode->parms) (p);
10483           output_inst (str);
10484           return;
10485         }
10486     }
10487   else
10488     {
10489       const struct asm_opcode * opcode;
10490
10491       c = *p;
10492       *p = '\0';
10493       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
10494       *p = c;
10495
10496       if (opcode)
10497         {
10498           /* Check that this instruction is supported for this CPU.  */
10499           if ((opcode->variant & cpu_variant) == 0)
10500             {
10501               as_bad (_("selected processor does not support `%s'"), str);
10502               return;
10503             }
10504
10505           inst.instruction = opcode->value;
10506           inst.size = INSN_SIZE;
10507           (*opcode->parms) (p);
10508           output_inst (str);
10509           return;
10510         }
10511     }
10512
10513   /* It wasn't an instruction, but it might be a register alias of the form
10514      alias .req reg.  */
10515   if (create_register_alias (str, p))
10516     return;
10517
10518   as_bad (_("bad instruction `%s'"), start);
10519 }
10520
10521 /* md_parse_option
10522       Invocation line includes a switch not recognized by the base assembler.
10523       See if it's a processor-specific option.
10524
10525       This routine is somewhat complicated by the need for backwards
10526       compatibility (since older releases of gcc can't be changed).
10527       The new options try to make the interface as compatible as
10528       possible with GCC.
10529
10530       New options (supported) are:
10531
10532               -mcpu=<cpu name>           Assemble for selected processor
10533               -march=<architecture name> Assemble for selected architecture
10534               -mfpu=<fpu architecture>   Assemble for selected FPU.
10535               -EB/-mbig-endian           Big-endian
10536               -EL/-mlittle-endian        Little-endian
10537               -k                         Generate PIC code
10538               -mthumb                    Start in Thumb mode
10539               -mthumb-interwork          Code supports ARM/Thumb interworking
10540
10541       For now we will also provide support for:
10542
10543               -mapcs-32                  32-bit Program counter
10544               -mapcs-26                  26-bit Program counter
10545               -macps-float               Floats passed in FP registers
10546               -mapcs-reentrant           Reentrant code
10547               -matpcs
10548       (sometime these will probably be replaced with -mapcs=<list of options>
10549       and -matpcs=<list of options>)
10550
10551       The remaining options are only supported for back-wards compatibility.
10552       Cpu variants, the arm part is optional:
10553               -m[arm]1                Currently not supported.
10554               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
10555               -m[arm]3                Arm 3 processor
10556               -m[arm]6[xx],           Arm 6 processors
10557               -m[arm]7[xx][t][[d]m]   Arm 7 processors
10558               -m[arm]8[10]            Arm 8 processors
10559               -m[arm]9[20][tdmi]      Arm 9 processors
10560               -mstrongarm[110[0]]     StrongARM processors
10561               -mxscale                XScale processors
10562               -m[arm]v[2345[t[e]]]    Arm architectures
10563               -mall                   All (except the ARM1)
10564       FP variants:
10565               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
10566               -mfpe-old               (No float load/store multiples)
10567               -mvfpxd                 VFP Single precision
10568               -mvfp                   All VFP
10569               -mno-fpu                Disable all floating point instructions
10570
10571       The following CPU names are recognized:
10572               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
10573               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
10574               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
10575               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
10576               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
10577               arm10t arm10e, arm1020t, arm1020e, arm10200e,
10578               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
10579
10580       */
10581
10582 const char * md_shortopts = "m:k";
10583
10584 #ifdef ARM_BI_ENDIAN
10585 #define OPTION_EB (OPTION_MD_BASE + 0)
10586 #define OPTION_EL (OPTION_MD_BASE + 1)
10587 #else
10588 #if TARGET_BYTES_BIG_ENDIAN
10589 #define OPTION_EB (OPTION_MD_BASE + 0)
10590 #else
10591 #define OPTION_EL (OPTION_MD_BASE + 1)
10592 #endif
10593 #endif
10594
10595 struct option md_longopts[] =
10596 {
10597 #ifdef OPTION_EB
10598   {"EB", no_argument, NULL, OPTION_EB},
10599 #endif
10600 #ifdef OPTION_EL
10601   {"EL", no_argument, NULL, OPTION_EL},
10602 #endif
10603   {NULL, no_argument, NULL, 0}
10604 };
10605
10606 size_t md_longopts_size = sizeof (md_longopts);
10607
10608 struct arm_option_table
10609 {
10610   char *option;         /* Option name to match.  */
10611   char *help;           /* Help information.  */
10612   int  *var;            /* Variable to change.  */
10613   int   value;          /* What to change it to.  */
10614   char *deprecated;     /* If non-null, print this message.  */
10615 };
10616
10617 struct arm_option_table arm_opts[] =
10618 {
10619   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
10620   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
10621   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
10622    &support_interwork, 1, NULL},
10623   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
10624   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
10625   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
10626   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
10627    1, NULL},
10628   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
10629   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
10630   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
10631   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
10632    NULL},
10633
10634   /* These are recognized by the assembler, but have no affect on code.  */
10635   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
10636   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
10637
10638   /* DON'T add any new processors to this list -- we want the whole list
10639      to go away...  Add them to the processors table instead.  */
10640   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
10641   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
10642   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
10643   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
10644   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10645   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10646   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10647   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10648   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
10649   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
10650   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
10651   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
10652   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
10653   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
10654   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
10655   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
10656   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
10657   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
10658   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
10659   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
10660   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
10661   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
10662   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
10663   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
10664   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
10665   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
10666   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
10667   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
10668   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
10669   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
10670   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
10671   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
10672   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
10673   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
10674   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10675   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10676   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10677   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10678   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10679   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10680   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
10681   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
10682   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
10683   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
10684   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
10685   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
10686   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10687   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10688   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10689   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10690   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10691   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10692   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10693   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10694   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10695   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10696   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
10697   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
10698   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
10699   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
10700   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10701   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10702   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10703   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10704   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10705   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10706   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10707   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10708   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
10709   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
10710    N_("use -mcpu=strongarm110")},
10711   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
10712    N_("use -mcpu=strongarm1100")},
10713   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
10714    N_("use -mcpu=strongarm1110")},
10715   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
10716   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
10717
10718   /* Architecture variants -- don't add any more to this list either.  */
10719   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
10720   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
10721   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10722   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10723   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
10724   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
10725   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10726   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10727   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
10728   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
10729   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10730   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10731   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
10732   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
10733   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10734   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10735   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10736   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10737
10738   /* Floating point variants -- don't add any more to this list either.  */
10739   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
10740   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
10741   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
10742   {"mno-fpu",  NULL, &legacy_fpu, 0,
10743    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
10744
10745   {NULL, NULL, NULL, 0, NULL}
10746 };
10747
10748 struct arm_cpu_option_table
10749 {
10750   char *name;
10751   int   value;
10752   /* For some CPUs we assume an FPU unless the user explicitly sets
10753      -mfpu=...  */
10754   int   default_fpu;
10755 };
10756
10757 /* This list should, at a minimum, contain all the cpu names
10758    recognized by GCC.  */
10759 static struct arm_cpu_option_table arm_cpus[] =
10760 {
10761   {"all",               ARM_ANY,         FPU_ARCH_FPA},
10762   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
10763   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
10764   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
10765   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
10766   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
10767   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
10768   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10769   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10770   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10771   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
10772   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
10773   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
10774   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
10775   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10776   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
10777   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
10778   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10779   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
10780   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10781   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10782   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
10783   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10784   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10785   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
10786   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
10787   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
10788   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
10789   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
10790   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
10791   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
10792   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
10793   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
10794   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
10795   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
10796   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
10797   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
10798   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
10799   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
10800   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10801   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10802   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
10803   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
10804   /* For V5 or later processors we default to using VFP; but the user
10805      should really set the FPU type explicitly.  */
10806   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10807   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10808   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
10809   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10810   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10811   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10812   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10813   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
10814   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10815   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10816   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
10817   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
10818   /* ??? XSCALE is really an architecture.  */
10819   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10820   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10821   /* Maverick */
10822   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
10823   {NULL, 0, 0}
10824 };
10825
10826 struct arm_arch_option_table
10827 {
10828   char *name;
10829   int   value;
10830   int   default_fpu;
10831 };
10832
10833 /* This list should, at a minimum, contain all the architecture names
10834    recognized by GCC.  */
10835 static struct arm_arch_option_table arm_archs[] =
10836 {
10837   {"all",               ARM_ANY,         FPU_ARCH_FPA},
10838   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
10839   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
10840   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
10841   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
10842   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
10843   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
10844   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
10845   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
10846   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
10847   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
10848   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
10849   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
10850   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
10851   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
10852   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
10853   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
10854   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
10855   {NULL, 0, 0}
10856 };
10857
10858 /* ISA extensions in the co-processor space.  */
10859 struct arm_arch_extension_table
10860 {
10861   char *name;
10862   int value;
10863 };
10864
10865 static struct arm_arch_extension_table arm_extensions[] =
10866 {
10867   {"maverick",          ARM_CEXT_MAVERICK},
10868   {"xscale",            ARM_CEXT_XSCALE},
10869   {NULL,                0}
10870 };
10871
10872 struct arm_fpu_option_table
10873 {
10874   char *name;
10875   int   value;
10876 };
10877
10878 /* This list should, at a minimum, contain all the fpu names
10879    recognized by GCC.  */
10880 static struct arm_fpu_option_table arm_fpus[] =
10881 {
10882   {"softfpa",           FPU_NONE},
10883   {"fpe",               FPU_ARCH_FPE},
10884   {"fpe2",              FPU_ARCH_FPE},
10885   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
10886   {"fpa",               FPU_ARCH_FPA},
10887   {"fpa10",             FPU_ARCH_FPA},
10888   {"fpa11",             FPU_ARCH_FPA},
10889   {"arm7500fe",         FPU_ARCH_FPA},
10890   {"softvfp",           FPU_ARCH_VFP},
10891   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
10892   {"vfp",               FPU_ARCH_VFP_V2},
10893   {"vfp9",              FPU_ARCH_VFP_V2},
10894   {"vfp10",             FPU_ARCH_VFP_V2},
10895   {"vfp10-r0",          FPU_ARCH_VFP_V1},
10896   {"vfpxd",             FPU_ARCH_VFP_V1xD},
10897   {"arm1020t",          FPU_ARCH_VFP_V1},
10898   {"arm1020e",          FPU_ARCH_VFP_V2},
10899   {NULL, 0}
10900 };
10901
10902 struct arm_long_option_table
10903 {
10904   char *option;         /* Substring to match.  */
10905   char *help;           /* Help information.  */
10906   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
10907   char *deprecated;     /* If non-null, print this message.  */
10908 };
10909
10910 static int
10911 arm_parse_extension (str, opt_p)
10912      char *str;
10913      int *opt_p;
10914 {
10915   while (str != NULL && *str != 0)
10916     {
10917       struct arm_arch_extension_table *opt;
10918       char *ext;
10919       int optlen;
10920
10921       if (*str != '+')
10922         {
10923           as_bad (_("invalid architectural extension"));
10924           return 0;
10925         }
10926
10927       str++;
10928       ext = strchr (str, '+');
10929
10930       if (ext != NULL)
10931         optlen = ext - str;
10932       else
10933         optlen = strlen (str);
10934
10935       if (optlen == 0)
10936         {
10937           as_bad (_("missing architectural extension"));
10938           return 0;
10939         }
10940
10941       for (opt = arm_extensions; opt->name != NULL; opt++)
10942         if (strncmp (opt->name, str, optlen) == 0)
10943           {
10944             *opt_p |= opt->value;
10945             break;
10946           }
10947
10948       if (opt->name == NULL)
10949         {
10950           as_bad (_("unknown architectural extnsion `%s'"), str);
10951           return 0;
10952         }
10953
10954       str = ext;
10955     };
10956
10957   return 1;
10958 }
10959
10960 static int
10961 arm_parse_cpu (str)
10962      char *str;
10963 {
10964   struct arm_cpu_option_table *opt;
10965   char *ext = strchr (str, '+');
10966   int optlen;
10967
10968   if (ext != NULL)
10969     optlen = ext - str;
10970   else
10971     optlen = strlen (str);
10972
10973   if (optlen == 0)
10974     {
10975       as_bad (_("missing cpu name `%s'"), str);
10976       return 0;
10977     }
10978
10979   for (opt = arm_cpus; opt->name != NULL; opt++)
10980     if (strncmp (opt->name, str, optlen) == 0)
10981       {
10982         mcpu_cpu_opt = opt->value;
10983         mcpu_fpu_opt = opt->default_fpu;
10984
10985         if (ext != NULL)
10986           return arm_parse_extension (ext, &mcpu_cpu_opt);
10987
10988         return 1;
10989       }
10990
10991   as_bad (_("unknown cpu `%s'"), str);
10992   return 0;
10993 }
10994
10995 static int
10996 arm_parse_arch (str)
10997      char *str;
10998 {
10999   struct arm_arch_option_table *opt;
11000   char *ext = strchr (str, '+');
11001   int optlen;
11002
11003   if (ext != NULL)
11004     optlen = ext - str;
11005   else
11006     optlen = strlen (str);
11007
11008   if (optlen == 0)
11009     {
11010       as_bad (_("missing architecture name `%s'"), str);
11011       return 0;
11012     }
11013
11014
11015   for (opt = arm_archs; opt->name != NULL; opt++)
11016     if (strcmp (opt->name, str) == 0)
11017       {
11018         march_cpu_opt = opt->value;
11019         march_fpu_opt = opt->default_fpu;
11020
11021         if (ext != NULL)
11022           return arm_parse_extension (ext, &march_cpu_opt);
11023
11024         return 1;
11025       }
11026
11027   as_bad (_("unknown architecture `%s'\n"), str);
11028   return 0;
11029 }
11030
11031 static int
11032 arm_parse_fpu (str)
11033      char *str;
11034 {
11035   struct arm_fpu_option_table *opt;
11036
11037   for (opt = arm_fpus; opt->name != NULL; opt++)
11038     if (strcmp (opt->name, str) == 0)
11039       {
11040         mfpu_opt = opt->value;
11041         return 1;
11042       }
11043
11044   as_bad (_("unknown floating point format `%s'\n"), str);
11045   return 0;
11046 }
11047
11048 struct arm_long_option_table arm_long_opts[] =
11049 {
11050   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
11051    arm_parse_cpu, NULL},
11052   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
11053    arm_parse_arch, NULL},
11054   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
11055    arm_parse_fpu, NULL},
11056   {NULL, NULL, 0, NULL}
11057 };
11058
11059 int
11060 md_parse_option (c, arg)
11061      int    c;
11062      char * arg;
11063 {
11064   struct arm_option_table *opt;
11065   struct arm_long_option_table *lopt;
11066
11067   switch (c)
11068     {
11069 #ifdef OPTION_EB
11070     case OPTION_EB:
11071       target_big_endian = 1;
11072       break;
11073 #endif
11074
11075 #ifdef OPTION_EL
11076     case OPTION_EL:
11077       target_big_endian = 0;
11078       break;
11079 #endif
11080
11081     case 'a':
11082       /* Listing option.  Just ignore these, we don't support additional
11083          ones.  */
11084       return 0;
11085
11086     default:
11087       for (opt = arm_opts; opt->option != NULL; opt++)
11088         {
11089           if (c == opt->option[0]
11090               && ((arg == NULL && opt->option[1] == 0)
11091                   || strcmp (arg, opt->option + 1) == 0))
11092             {
11093 #if WARN_DEPRECATED
11094               /* If the option is deprecated, tell the user.  */
11095               if (opt->deprecated != NULL)
11096                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
11097                            arg ? arg : "", _(opt->deprecated));
11098 #endif
11099
11100               if (opt->var != NULL)
11101                 *opt->var = opt->value;
11102
11103               return 1;
11104             }
11105         }
11106
11107       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11108         {
11109           /* These options are expected to have an argument.  */
11110           if (c == lopt->option[0]
11111               && arg != NULL
11112               && strncmp (arg, lopt->option + 1,
11113                           strlen (lopt->option + 1)) == 0)
11114             {
11115 #if WARN_DEPRECATED
11116               /* If the option is deprecated, tell the user.  */
11117               if (lopt->deprecated != NULL)
11118                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
11119                            _(lopt->deprecated));
11120 #endif
11121
11122               /* Call the sup-option parser.  */
11123               return (*lopt->func)(arg + strlen (lopt->option) - 1);
11124             }
11125         }
11126
11127       as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
11128       return 0;
11129     }
11130
11131   return 1;
11132 }
11133
11134 void
11135 md_show_usage (fp)
11136      FILE * fp;
11137 {
11138   struct arm_option_table *opt;
11139   struct arm_long_option_table *lopt;
11140
11141   fprintf (fp, _(" ARM-specific assembler options:\n"));
11142
11143   for (opt = arm_opts; opt->option != NULL; opt++)
11144     if (opt->help != NULL)
11145       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
11146
11147   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11148     if (lopt->help != NULL)
11149       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
11150
11151 #ifdef OPTION_EB
11152   fprintf (fp, _("\
11153   -EB                     assemble code for a big-endian cpu\n"));
11154 #endif
11155
11156 #ifdef OPTION_EL
11157   fprintf (fp, _("\
11158   -EL                     assemble code for a little-endian cpu\n"));
11159 #endif
11160 }
11161
11162 /* We need to be able to fix up arbitrary expressions in some statements.
11163    This is so that we can handle symbols that are an arbitrary distance from
11164    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
11165    which returns part of an address in a form which will be valid for
11166    a data instruction.  We do this by pushing the expression into a symbol
11167    in the expr_section, and creating a fix for that.  */
11168
11169 static void
11170 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
11171      fragS *       frag;
11172      int           where;
11173      short int     size;
11174      expressionS * exp;
11175      int           pc_rel;
11176      int           reloc;
11177 {
11178   fixS *           new_fix;
11179   arm_fix_data *   arm_data;
11180
11181   switch (exp->X_op)
11182     {
11183     case O_constant:
11184     case O_symbol:
11185     case O_add:
11186     case O_subtract:
11187       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
11188       break;
11189
11190     default:
11191       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
11192                          pc_rel, reloc);
11193       break;
11194     }
11195
11196   /* Mark whether the fix is to a THUMB instruction, or an ARM
11197      instruction.  */
11198   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
11199   new_fix->tc_fix_data = (PTR) arm_data;
11200   arm_data->thumb_mode = thumb_mode;
11201
11202   return;
11203 }
11204
11205 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
11206
11207 void
11208 cons_fix_new_arm (frag, where, size, exp)
11209      fragS *       frag;
11210      int           where;
11211      int           size;
11212      expressionS * exp;
11213 {
11214   bfd_reloc_code_real_type type;
11215   int pcrel = 0;
11216
11217   /* Pick a reloc.
11218      FIXME: @@ Should look at CPU word size.  */
11219   switch (size)
11220     {
11221     case 1:
11222       type = BFD_RELOC_8;
11223       break;
11224     case 2:
11225       type = BFD_RELOC_16;
11226       break;
11227     case 4:
11228     default:
11229       type = BFD_RELOC_32;
11230       break;
11231     case 8:
11232       type = BFD_RELOC_64;
11233       break;
11234     }
11235
11236   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
11237 }
11238
11239 /* A good place to do this, although this was probably not intended
11240    for this kind of use.  We need to dump the literal pool before
11241    references are made to a null symbol pointer.  */
11242
11243 void
11244 arm_cleanup ()
11245 {
11246   literal_pool * pool;
11247
11248   for (pool = list_of_pools; pool; pool = pool->next)
11249     {
11250       /* Put it at the end of the relevent section.  */
11251       subseg_set (pool->section, pool->sub_section);
11252       s_ltorg (0);
11253     }
11254 }
11255
11256 void
11257 arm_start_line_hook ()
11258 {
11259   last_label_seen = NULL;
11260 }
11261
11262 void
11263 arm_frob_label (sym)
11264      symbolS * sym;
11265 {
11266   last_label_seen = sym;
11267
11268   ARM_SET_THUMB (sym, thumb_mode);
11269
11270 #if defined OBJ_COFF || defined OBJ_ELF
11271   ARM_SET_INTERWORK (sym, support_interwork);
11272 #endif
11273
11274   /* Note - do not allow local symbols (.Lxxx) to be labeled
11275      as Thumb functions.  This is because these labels, whilst
11276      they exist inside Thumb code, are not the entry points for
11277      possible ARM->Thumb calls.  Also, these labels can be used
11278      as part of a computed goto or switch statement.  eg gcc
11279      can generate code that looks like this:
11280
11281                 ldr  r2, [pc, .Laaa]
11282                 lsl  r3, r3, #2
11283                 ldr  r2, [r3, r2]
11284                 mov  pc, r2
11285
11286        .Lbbb:  .word .Lxxx
11287        .Lccc:  .word .Lyyy
11288        ..etc...
11289        .Laaa:   .word Lbbb
11290
11291      The first instruction loads the address of the jump table.
11292      The second instruction converts a table index into a byte offset.
11293      The third instruction gets the jump address out of the table.
11294      The fourth instruction performs the jump.
11295
11296      If the address stored at .Laaa is that of a symbol which has the
11297      Thumb_Func bit set, then the linker will arrange for this address
11298      to have the bottom bit set, which in turn would mean that the
11299      address computation performed by the third instruction would end
11300      up with the bottom bit set.  Since the ARM is capable of unaligned
11301      word loads, the instruction would then load the incorrect address
11302      out of the jump table, and chaos would ensue.  */
11303   if (label_is_thumb_function_name
11304       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
11305       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
11306     {
11307       /* When the address of a Thumb function is taken the bottom
11308          bit of that address should be set.  This will allow
11309          interworking between Arm and Thumb functions to work
11310          correctly.  */
11311
11312       THUMB_SET_FUNC (sym, 1);
11313
11314       label_is_thumb_function_name = FALSE;
11315     }
11316 }
11317
11318 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
11319    ARM ones.  */
11320
11321 void
11322 arm_adjust_symtab ()
11323 {
11324 #ifdef OBJ_COFF
11325   symbolS * sym;
11326
11327   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11328     {
11329       if (ARM_IS_THUMB (sym))
11330         {
11331           if (THUMB_IS_FUNC (sym))
11332             {
11333               /* Mark the symbol as a Thumb function.  */
11334               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
11335                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
11336                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
11337
11338               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
11339                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
11340               else
11341                 as_bad (_("%s: unexpected function type: %d"),
11342                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
11343             }
11344           else switch (S_GET_STORAGE_CLASS (sym))
11345             {
11346             case C_EXT:
11347               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
11348               break;
11349             case C_STAT:
11350               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
11351               break;
11352             case C_LABEL:
11353               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
11354               break;
11355             default:
11356               /* Do nothing.  */
11357               break;
11358             }
11359         }
11360
11361       if (ARM_IS_INTERWORK (sym))
11362         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
11363     }
11364 #endif
11365 #ifdef OBJ_ELF
11366   symbolS * sym;
11367   char      bind;
11368
11369   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11370     {
11371       if (ARM_IS_THUMB (sym))
11372         {
11373           elf_symbol_type * elf_sym;
11374
11375           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
11376           bind = ELF_ST_BIND (elf_sym);
11377
11378           /* If it's a .thumb_func, declare it as so,
11379              otherwise tag label as .code 16.  */
11380           if (THUMB_IS_FUNC (sym))
11381             elf_sym->internal_elf_sym.st_info =
11382               ELF_ST_INFO (bind, STT_ARM_TFUNC);
11383           else
11384             elf_sym->internal_elf_sym.st_info =
11385               ELF_ST_INFO (bind, STT_ARM_16BIT);
11386         }
11387     }
11388 #endif
11389 }
11390
11391 int
11392 arm_data_in_code ()
11393 {
11394   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
11395     {
11396       *input_line_pointer = '/';
11397       input_line_pointer += 5;
11398       *input_line_pointer = 0;
11399       return 1;
11400     }
11401
11402   return 0;
11403 }
11404
11405 char *
11406 arm_canonicalize_symbol_name (name)
11407      char * name;
11408 {
11409   int len;
11410
11411   if (thumb_mode && (len = strlen (name)) > 5
11412       && streq (name + len - 5, "/data"))
11413     *(name + len - 5) = 0;
11414
11415   return name;
11416 }
11417
11418 void
11419 arm_validate_fix (fixP)
11420      fixS * fixP;
11421 {
11422   /* If the destination of the branch is a defined symbol which does not have
11423      the THUMB_FUNC attribute, then we must be calling a function which has
11424      the (interfacearm) attribute.  We look for the Thumb entry point to that
11425      function and change the branch to refer to that function instead.  */
11426   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
11427       && fixP->fx_addsy != NULL
11428       && S_IS_DEFINED (fixP->fx_addsy)
11429       && ! THUMB_IS_FUNC (fixP->fx_addsy))
11430     {
11431       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
11432     }
11433 }
11434
11435 int
11436 arm_force_relocation (fixp)
11437      struct fix * fixp;
11438 {
11439 #if defined (OBJ_COFF) && defined (TE_PE)
11440   if (fixp->fx_r_type == BFD_RELOC_RVA)
11441     return 1;
11442 #endif
11443 #ifdef OBJ_ELF
11444   if (   fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11445       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
11446       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
11447       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
11448       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
11449       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
11450     return 1;
11451 #endif
11452
11453   /* Resolve these relocations even if the symbol is extern or weak.  */
11454   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
11455       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
11456     return 0;
11457
11458   return S_FORCE_RELOC (fixp->fx_addsy);
11459 }
11460
11461 #ifdef OBJ_COFF
11462 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
11463    local labels from being added to the output symbol table when they
11464    are used with the ADRL pseudo op.  The ADRL relocation should always
11465    be resolved before the binbary is emitted, so it is safe to say that
11466    it is adjustable.  */
11467
11468 bfd_boolean
11469 arm_fix_adjustable (fixP)
11470    fixS * fixP;
11471 {
11472   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
11473     return 1;
11474   return 0;
11475 }
11476 #endif
11477
11478 #ifdef OBJ_ELF
11479 /* Relocations against Thumb function names must be left unadjusted,
11480    so that the linker can use this information to correctly set the
11481    bottom bit of their addresses.  The MIPS version of this function
11482    also prevents relocations that are mips-16 specific, but I do not
11483    know why it does this.
11484
11485    FIXME:
11486    There is one other problem that ought to be addressed here, but
11487    which currently is not:  Taking the address of a label (rather
11488    than a function) and then later jumping to that address.  Such
11489    addresses also ought to have their bottom bit set (assuming that
11490    they reside in Thumb code), but at the moment they will not.  */
11491
11492 bfd_boolean
11493 arm_fix_adjustable (fixP)
11494    fixS * fixP;
11495 {
11496   if (fixP->fx_addsy == NULL)
11497     return 1;
11498
11499   if (THUMB_IS_FUNC (fixP->fx_addsy)
11500       && fixP->fx_subsy == NULL)
11501     return 0;
11502
11503   /* We need the symbol name for the VTABLE entries.  */
11504   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11505       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11506     return 0;
11507
11508   /* Don't allow symbols to be discarded on GOT related relocs.  */
11509   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
11510       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
11511       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
11512     return 0;
11513
11514   return 1;
11515 }
11516
11517 const char *
11518 elf32_arm_target_format ()
11519 {
11520   if (target_big_endian)
11521     {
11522       if (target_oabi)
11523         return "elf32-bigarm-oabi";
11524       else
11525         return "elf32-bigarm";
11526     }
11527   else
11528     {
11529       if (target_oabi)
11530         return "elf32-littlearm-oabi";
11531       else
11532         return "elf32-littlearm";
11533     }
11534 }
11535
11536 void
11537 armelf_frob_symbol (symp, puntp)
11538      symbolS * symp;
11539      int *     puntp;
11540 {
11541   elf_frob_symbol (symp, puntp);
11542 }
11543
11544 static bfd_reloc_code_real_type
11545 arm_parse_reloc ()
11546 {
11547   char         id [16];
11548   char *       ip;
11549   unsigned int i;
11550   static struct
11551   {
11552     char * str;
11553     int    len;
11554     bfd_reloc_code_real_type reloc;
11555   }
11556   reloc_map[] =
11557   {
11558 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
11559     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
11560     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
11561     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
11562        branch instructions generated by GCC for PLT relocs.  */
11563     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
11564     { NULL, 0,         BFD_RELOC_UNUSED }
11565 #undef MAP
11566   };
11567
11568   for (i = 0, ip = input_line_pointer;
11569        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
11570        i++, ip++)
11571     id[i] = TOLOWER (*ip);
11572
11573   for (i = 0; reloc_map[i].str; i++)
11574     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
11575       break;
11576
11577   input_line_pointer += reloc_map[i].len;
11578
11579   return reloc_map[i].reloc;
11580 }
11581
11582 static void
11583 s_arm_elf_cons (nbytes)
11584      int nbytes;
11585 {
11586   expressionS exp;
11587
11588 #ifdef md_flush_pending_output
11589   md_flush_pending_output ();
11590 #endif
11591
11592   if (is_it_end_of_statement ())
11593     {
11594       demand_empty_rest_of_line ();
11595       return;
11596     }
11597
11598 #ifdef md_cons_align
11599   md_cons_align (nbytes);
11600 #endif
11601
11602   do
11603     {
11604       bfd_reloc_code_real_type reloc;
11605
11606       expression (& exp);
11607
11608       if (exp.X_op == O_symbol
11609           && * input_line_pointer == '('
11610           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
11611         {
11612           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
11613           int size = bfd_get_reloc_size (howto);
11614
11615           if (size > nbytes)
11616             as_bad ("%s relocations do not fit in %d bytes",
11617                     howto->name, nbytes);
11618           else
11619             {
11620               register char *p = frag_more ((int) nbytes);
11621               int offset = nbytes - size;
11622
11623               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
11624                            &exp, 0, reloc);
11625             }
11626         }
11627       else
11628         emit_expr (&exp, (unsigned int) nbytes);
11629     }
11630   while (*input_line_pointer++ == ',');
11631
11632   /* Put terminator back into stream.  */
11633   input_line_pointer --;
11634   demand_empty_rest_of_line ();
11635 }
11636
11637 #endif /* OBJ_ELF */
11638
11639 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
11640    of an rs_align_code fragment.  */
11641
11642 void
11643 arm_handle_align (fragP)
11644      fragS *fragP;
11645 {
11646   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
11647   static char const thumb_noop[2] = { 0xc0, 0x46 };
11648   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
11649   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
11650
11651   int bytes, fix, noop_size;
11652   char * p;
11653   const char * noop;
11654
11655   if (fragP->fr_type != rs_align_code)
11656     return;
11657
11658   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
11659   p = fragP->fr_literal + fragP->fr_fix;
11660   fix = 0;
11661
11662   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
11663     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
11664
11665   if (fragP->tc_frag_data)
11666     {
11667       if (target_big_endian)
11668         noop = thumb_bigend_noop;
11669       else
11670         noop = thumb_noop;
11671       noop_size = sizeof (thumb_noop);
11672     }
11673   else
11674     {
11675       if (target_big_endian)
11676         noop = arm_bigend_noop;
11677       else
11678         noop = arm_noop;
11679       noop_size = sizeof (arm_noop);
11680     }
11681
11682   if (bytes & (noop_size - 1))
11683     {
11684       fix = bytes & (noop_size - 1);
11685       memset (p, 0, fix);
11686       p += fix;
11687       bytes -= fix;
11688     }
11689
11690   while (bytes >= noop_size)
11691     {
11692       memcpy (p, noop, noop_size);
11693       p += noop_size;
11694       bytes -= noop_size;
11695       fix += noop_size;
11696     }
11697
11698   fragP->fr_fix += fix;
11699   fragP->fr_var = noop_size;
11700 }
11701
11702 /* Called from md_do_align.  Used to create an alignment
11703    frag in a code section.  */
11704
11705 void
11706 arm_frag_align_code (n, max)
11707      int n;
11708      int max;
11709 {
11710   char * p;
11711
11712   /* We assume that there will never be a requirment
11713      to support alignments greater than 32 bytes.  */
11714   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
11715     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
11716
11717   p = frag_var (rs_align_code,
11718                 MAX_MEM_FOR_RS_ALIGN_CODE,
11719                 1,
11720                 (relax_substateT) max,
11721                 (symbolS *) NULL,
11722                 (offsetT) n,
11723                 (char *) NULL);
11724   *p = 0;
11725
11726 }
11727
11728 /* Perform target specific initialisation of a frag.  */
11729
11730 void
11731 arm_init_frag (fragP)
11732      fragS *fragP;
11733 {
11734   /* Record whether this frag is in an ARM or a THUMB area.  */
11735   fragP->tc_frag_data = thumb_mode;
11736 }
This page took 0.673229 seconds and 4 git commands to generate.