* config/tc-arm.c (arm_archs): Add armv6.
[external/binutils.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5         Modified by David Taylor (dtaylor@armltd.co.uk)
6         Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
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 #define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
59
60 /* Co-processor space extensions.  */
61 #define ARM_CEXT_XSCALE   0x00800000    /* Allow MIA etc.          */
62 #define ARM_CEXT_MAVERICK 0x00400000    /* Use Cirrus/DSP coprocessor.  */
63 #define ARM_CEXT_IWMMXT   0x00200000    /* Intel Wireless MMX technology coprocessor.   */
64
65 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
66    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
67    ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
68    three more to cover cores prior to ARM6.  Finally, there are cores which
69    implement further extensions in the co-processor space.  */
70 #define ARM_ARCH_V1                       ARM_EXT_V1
71 #define ARM_ARCH_V2     (ARM_ARCH_V1    | ARM_EXT_V2)
72 #define ARM_ARCH_V2S    (ARM_ARCH_V2    | ARM_EXT_V2S)
73 #define ARM_ARCH_V3     (ARM_ARCH_V2S   | ARM_EXT_V3)
74 #define ARM_ARCH_V3M    (ARM_ARCH_V3    | ARM_EXT_V3M)
75 #define ARM_ARCH_V4xM   (ARM_ARCH_V3    | ARM_EXT_V4)
76 #define ARM_ARCH_V4     (ARM_ARCH_V3M   | ARM_EXT_V4)
77 #define ARM_ARCH_V4TxM  (ARM_ARCH_V4xM  | ARM_EXT_V4T)
78 #define ARM_ARCH_V4T    (ARM_ARCH_V4    | ARM_EXT_V4T)
79 #define ARM_ARCH_V5xM   (ARM_ARCH_V4xM  | ARM_EXT_V5)
80 #define ARM_ARCH_V5     (ARM_ARCH_V4    | ARM_EXT_V5)
81 #define ARM_ARCH_V5TxM  (ARM_ARCH_V5xM  | ARM_EXT_V4T | ARM_EXT_V5T)
82 #define ARM_ARCH_V5T    (ARM_ARCH_V5    | ARM_EXT_V4T | ARM_EXT_V5T)
83 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T   | ARM_EXT_V5ExP)
84 #define ARM_ARCH_V5TE   (ARM_ARCH_V5TExP | ARM_EXT_V5E)
85 #define ARM_ARCH_V5TEJ  (ARM_ARCH_V5TE  | ARM_EXT_V5J)
86 #define ARM_ARCH_V6     (ARM_ARCH_V5TEJ | ARM_EXT_V6)
87
88 /* Processors with specific extensions in the co-processor space.  */
89 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE  | ARM_CEXT_XSCALE)
90 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
91
92 /* Some useful combinations:  */
93 #define ARM_ANY         0x0000ffff      /* Any basic core.  */
94 #define ARM_ALL         0x00ffffff      /* Any core + co-processor */
95 #define CPROC_ANY       0x00ff0000      /* Any co-processor */
96 #define FPU_ANY         0xff000000      /* Note this is ~ARM_ALL.  */
97
98
99 #define FPU_FPA_EXT_V1   0x80000000     /* Base FPA instruction set.  */
100 #define FPU_FPA_EXT_V2   0x40000000     /* LFM/SFM.                   */
101 #define FPU_VFP_EXT_NONE 0x20000000     /* Use VFP word-ordering.     */
102 #define FPU_VFP_EXT_V1xD 0x10000000     /* Base VFP instruction set.  */
103 #define FPU_VFP_EXT_V1   0x08000000     /* Double-precision insns.    */
104 #define FPU_VFP_EXT_V2   0x04000000     /* ARM10E VFPr1.              */
105 #define FPU_MAVERICK     0x02000000     /* Cirrus Maverick.           */
106 #define FPU_NONE         0
107
108 #define FPU_ARCH_FPE     FPU_FPA_EXT_V1
109 #define FPU_ARCH_FPA    (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
110
111 #define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
112 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
113 #define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
114 #define FPU_ARCH_VFP_V2   (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
115
116 #define FPU_ARCH_MAVERICK  FPU_MAVERICK
117
118 enum arm_float_abi
119 {
120   ARM_FLOAT_ABI_HARD,
121   ARM_FLOAT_ABI_SOFTFP,
122   ARM_FLOAT_ABI_SOFT
123 };
124
125 /* Types of processor to assemble for.  */
126 #define ARM_1           ARM_ARCH_V1
127 #define ARM_2           ARM_ARCH_V2
128 #define ARM_3           ARM_ARCH_V2S
129 #define ARM_250         ARM_ARCH_V2S
130 #define ARM_6           ARM_ARCH_V3
131 #define ARM_7           ARM_ARCH_V3
132 #define ARM_8           ARM_ARCH_V4
133 #define ARM_9           ARM_ARCH_V4T
134 #define ARM_STRONG      ARM_ARCH_V4
135 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
136
137 #ifndef CPU_DEFAULT
138 #if defined __XSCALE__
139 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
140 #else
141 #if defined __thumb__
142 #define CPU_DEFAULT     (ARM_ARCH_V5T)
143 #else
144 #define CPU_DEFAULT     ARM_ANY
145 #endif
146 #endif
147 #endif
148
149 #ifdef TE_LINUX
150 #define FPU_DEFAULT FPU_ARCH_FPA
151 #endif
152
153 #ifdef TE_NetBSD
154 #ifdef OBJ_ELF
155 #define FPU_DEFAULT FPU_ARCH_VFP        /* Soft-float, but VFP order.  */
156 #else
157 /* Legacy a.out format.  */
158 #define FPU_DEFAULT FPU_ARCH_FPA        /* Soft-float, but FPA order.  */
159 #endif
160 #endif
161
162 /* For backwards compatibility we default to the FPA.  */
163 #ifndef FPU_DEFAULT
164 #define FPU_DEFAULT FPU_ARCH_FPA
165 #endif
166
167 #define streq(a, b)           (strcmp (a, b) == 0)
168 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
169
170 static unsigned long cpu_variant;
171 static int target_oabi = 0;
172
173 /* Flags stored in private area of BFD structure.  */
174 static int uses_apcs_26      = FALSE;
175 static int atpcs             = FALSE;
176 static int support_interwork = FALSE;
177 static int uses_apcs_float   = FALSE;
178 static int pic_code          = FALSE;
179
180 /* Variables that we set while parsing command-line options.  Once all
181    options have been read we re-process these values to set the real
182    assembly flags.  */
183 static int legacy_cpu = -1;
184 static int legacy_fpu = -1;
185
186 static int mcpu_cpu_opt = -1;
187 static int mcpu_fpu_opt = -1;
188 static int march_cpu_opt = -1;
189 static int march_fpu_opt = -1;
190 static int mfpu_opt = -1;
191 static int mfloat_abi_opt = -1;
192
193 /* This array holds the chars that always start a comment.  If the
194    pre-processor is disabled, these aren't very useful.  */
195 const char comment_chars[] = "@";
196
197 /* This array holds the chars that only start a comment at the beginning of
198    a line.  If the line seems to have the form '# 123 filename'
199    .line and .file directives will appear in the pre-processed output.  */
200 /* Note that input_file.c hand checks for '#' at the beginning of the
201    first line of the input file.  This is because the compiler outputs
202    #NO_APP at the beginning of its output.  */
203 /* Also note that comments like this one will always work.  */
204 const char line_comment_chars[] = "#";
205
206 const char line_separator_chars[] = ";";
207
208 /* Chars that can be used to separate mant
209    from exp in floating point numbers.  */
210 const char EXP_CHARS[] = "eE";
211
212 /* Chars that mean this number is a floating point constant.  */
213 /* As in 0f12.456  */
214 /* or    0d1.2345e12  */
215
216 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
217
218 /* Prefix characters that indicate the start of an immediate
219    value.  */
220 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
221
222 #ifdef OBJ_ELF
223 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
224 symbolS * GOT_symbol;
225 #endif
226
227 /* Size of relocation record.  */
228 const int md_reloc_size = 8;
229
230 /* 0: assemble for ARM,
231    1: assemble for Thumb,
232    2: assemble for Thumb even though target CPU does not support thumb
233       instructions.  */
234 static int thumb_mode = 0;
235
236 typedef struct arm_fix
237 {
238   int thumb_mode;
239 } arm_fix_data;
240
241 struct arm_it
242 {
243   const char *  error;
244   unsigned long instruction;
245   int           size;
246   struct
247   {
248     bfd_reloc_code_real_type type;
249     expressionS              exp;
250     int                      pc_rel;
251   } reloc;
252 };
253
254 struct arm_it inst;
255
256 enum asm_shift_index
257 {
258   SHIFT_LSL = 0,
259   SHIFT_LSR,
260   SHIFT_ASR,
261   SHIFT_ROR,
262   SHIFT_RRX
263 };
264
265 struct asm_shift_properties
266 {
267   enum asm_shift_index index;
268   unsigned long        bit_field;
269   unsigned int         allows_0  : 1;
270   unsigned int         allows_32 : 1;
271 };
272
273 static const struct asm_shift_properties shift_properties [] =
274 {
275   { SHIFT_LSL, 0,    1, 0},
276   { SHIFT_LSR, 0x20, 0, 1},
277   { SHIFT_ASR, 0x40, 0, 1},
278   { SHIFT_ROR, 0x60, 0, 0},
279   { SHIFT_RRX, 0x60, 0, 0}
280 };
281
282 struct asm_shift_name
283 {
284   const char *                        name;
285   const struct asm_shift_properties * properties;
286 };
287
288 static const struct asm_shift_name shift_names [] =
289 {
290   { "asl", shift_properties + SHIFT_LSL },
291   { "lsl", shift_properties + SHIFT_LSL },
292   { "lsr", shift_properties + SHIFT_LSR },
293   { "asr", shift_properties + SHIFT_ASR },
294   { "ror", shift_properties + SHIFT_ROR },
295   { "rrx", shift_properties + SHIFT_RRX },
296   { "ASL", shift_properties + SHIFT_LSL },
297   { "LSL", shift_properties + SHIFT_LSL },
298   { "LSR", shift_properties + SHIFT_LSR },
299   { "ASR", shift_properties + SHIFT_ASR },
300   { "ROR", shift_properties + SHIFT_ROR },
301   { "RRX", shift_properties + SHIFT_RRX }
302 };
303
304 /* Any kind of shift is accepted.  */
305 #define NO_SHIFT_RESTRICT 1
306 /* The shift operand must be an immediate value, not a register.  */
307 #define SHIFT_IMMEDIATE   0
308 /* The shift must be LSL or ASR and the operand must be an immediate.  */
309 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
310 /* The shift must be ASR and the operand must be an immediate.  */
311 #define SHIFT_ASR_IMMEDIATE 3
312 /* The shift must be LSL and the operand must be an immediate.  */
313 #define SHIFT_LSL_IMMEDIATE 4
314
315 #define NUM_FLOAT_VALS 8
316
317 const char * fp_const[] =
318 {
319   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
320 };
321
322 /* Number of littlenums required to hold an extended precision number.  */
323 #define MAX_LITTLENUMS 6
324
325 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
326
327 #define FAIL    (-1)
328 #define SUCCESS (0)
329
330 /* Whether a Co-processor load/store operation accepts write-back forms.  */
331 #define CP_WB_OK 1
332 #define CP_NO_WB 0
333
334 #define SUFF_S 1
335 #define SUFF_D 2
336 #define SUFF_E 3
337 #define SUFF_P 4
338
339 #define CP_T_X   0x00008000
340 #define CP_T_Y   0x00400000
341 #define CP_T_Pre 0x01000000
342 #define CP_T_UD  0x00800000
343 #define CP_T_WB  0x00200000
344
345 #define CONDS_BIT        0x00100000
346 #define LOAD_BIT         0x00100000
347
348 #define DOUBLE_LOAD_FLAG 0x00000001
349
350 struct asm_cond
351 {
352   const char *  template;
353   unsigned long value;
354 };
355
356 #define COND_ALWAYS 0xe0000000
357 #define COND_MASK   0xf0000000
358
359 static const struct asm_cond conds[] =
360 {
361   {"eq", 0x00000000},
362   {"ne", 0x10000000},
363   {"cs", 0x20000000}, {"hs", 0x20000000},
364   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
365   {"mi", 0x40000000},
366   {"pl", 0x50000000},
367   {"vs", 0x60000000},
368   {"vc", 0x70000000},
369   {"hi", 0x80000000},
370   {"ls", 0x90000000},
371   {"ge", 0xa0000000},
372   {"lt", 0xb0000000},
373   {"gt", 0xc0000000},
374   {"le", 0xd0000000},
375   {"al", 0xe0000000},
376   {"nv", 0xf0000000}
377 };
378
379 struct asm_psr
380 {
381   const char *template;
382   bfd_boolean cpsr;
383   unsigned long field;
384 };
385
386 /* The bit that distinguishes CPSR and SPSR.  */
387 #define SPSR_BIT   (1 << 22)
388
389 /* How many bits to shift the PSR_xxx bits up by.  */
390 #define PSR_SHIFT  16
391
392 #define PSR_c   (1 << 0)
393 #define PSR_x   (1 << 1)
394 #define PSR_s   (1 << 2)
395 #define PSR_f   (1 << 3)
396
397 static const struct asm_psr psrs[] =
398 {
399   {"CPSR",      TRUE,  PSR_c | PSR_f},
400   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
401   {"SPSR",      FALSE, PSR_c | PSR_f},
402   {"SPSR_all",  FALSE, PSR_c | PSR_f},
403   {"CPSR_flg",  TRUE,  PSR_f},
404   {"CPSR_f",    TRUE,  PSR_f},
405   {"SPSR_flg",  FALSE, PSR_f},
406   {"SPSR_f",    FALSE, PSR_f},
407   {"CPSR_c",    TRUE,  PSR_c},
408   {"CPSR_ctl",  TRUE,  PSR_c},
409   {"SPSR_c",    FALSE, PSR_c},
410   {"SPSR_ctl",  FALSE, PSR_c},
411   {"CPSR_x",    TRUE,  PSR_x},
412   {"CPSR_s",    TRUE,  PSR_s},
413   {"SPSR_x",    FALSE, PSR_x},
414   {"SPSR_s",    FALSE, PSR_s},
415   /* Combinations of flags.  */
416   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
417   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
418   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
419   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
420   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
421   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
422   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
423   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
424   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
425   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
426   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
427   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
428   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
429   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
430   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
431   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
432   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
433   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
434   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
435   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
436   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
437   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
438   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
439   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
440   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
441   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
442   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
443   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
444   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
445   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
446   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
447   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
448   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
449   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
450   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
451   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
452   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
453   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
454   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
455   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
456   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
457   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
458   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
459   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
460   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
461   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
462   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
463   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
464   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
465   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
466   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
467   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
468   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
469   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
470   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
471   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
472   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
473   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
474   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
475   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
476   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
477   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
478   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
479   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
480   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
481   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
482   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
483   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
484   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
485   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
486   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
487   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
488   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
489   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
490   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
491   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
492   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
493   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
494   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
495   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
496   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
497   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
498   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
499   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
500   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
501   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
502   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
503   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
504   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
505   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
506   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
507   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
508   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
509   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
510   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
511   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
512   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
513   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
514   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
515   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
516   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
517   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
518   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
519   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
520   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
521   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
522   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
523   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
524   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
525   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
526   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
527   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
528   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
529   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
530   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
531   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
532   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
533   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
534   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
535   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
536 };
537
538 enum wreg_type
539   {
540     IWMMXT_REG_WR = 0,
541     IWMMXT_REG_WC = 1,
542     IWMMXT_REG_WR_OR_WC = 2,
543     IWMMXT_REG_WCG
544   };
545
546 enum iwmmxt_insn_type
547 {
548   check_rd,
549   check_wr,
550   check_wrwr,
551   check_wrwrwr,
552   check_wrwrwcg,
553   check_tbcst,
554   check_tmovmsk,
555   check_tmia,
556   check_tmcrr,
557   check_tmrrc,
558   check_tmcr,
559   check_tmrc,
560   check_tinsr,
561   check_textrc,
562   check_waligni,
563   check_textrm,
564   check_wshufh
565 };
566
567 enum vfp_dp_reg_pos
568 {
569   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
570 };
571
572 enum vfp_sp_reg_pos
573 {
574   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
575 };
576
577 enum vfp_ldstm_type
578 {
579   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
580 };
581
582 /* VFP system registers.  */
583 struct vfp_reg
584 {
585   const char *name;
586   unsigned long regno;
587 };
588
589 static const struct vfp_reg vfp_regs[] =
590 {
591   {"fpsid", 0x00000000},
592   {"FPSID", 0x00000000},
593   {"fpscr", 0x00010000},
594   {"FPSCR", 0x00010000},
595   {"fpexc", 0x00080000},
596   {"FPEXC", 0x00080000}
597 };
598
599 /* Structure for a hash table entry for a register.  */
600 struct reg_entry
601 {
602   const char * name;
603   int          number;
604   bfd_boolean  builtin;
605 };
606
607 /* Some well known registers that we refer to directly elsewhere.  */
608 #define REG_SP  13
609 #define REG_LR  14
610 #define REG_PC  15
611
612 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
613 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
614 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
615
616 /* These are the standard names.  Users can add aliases with .req.
617    and delete them with .unreq.  */
618
619 /* Integer Register Numbers.  */
620 static const struct reg_entry rn_table[] =
621 {
622   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
623   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
624   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
625   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
626   /* ATPCS Synonyms.  */
627   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
628   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
629   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
630   /* Well-known aliases.  */
631   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
632   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
633   {NULL, 0, TRUE}
634 };
635
636 #define WR_PREFIX 0x200
637 #define WC_PREFIX 0x400
638
639 static const struct reg_entry iwmmxt_table[] =
640 {
641   /* Intel Wireless MMX technology register names.  */
642   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
643   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
644   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
645   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
646   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
647   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
648   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
649   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
650   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
651   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
652   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
653   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
654
655   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
656   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
657   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
658   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
659   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
660   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
661   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
662   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
663   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
664   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
665   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
666   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
667   {NULL, 0, TRUE}
668 };
669
670 /* Co-processor Numbers.  */
671 static const struct reg_entry cp_table[] =
672 {
673   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
674   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
675   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
676   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
677   {NULL, 0, TRUE}
678 };
679
680 /* Co-processor Register Numbers.  */
681 static const struct reg_entry cn_table[] =
682 {
683   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
684   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
685   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
686   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
687   /* Not really valid, but kept for back-wards compatibility.  */
688   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
689   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
690   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
691   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
692   {NULL, 0, TRUE}
693 };
694
695 /* FPA Registers.  */
696 static const struct reg_entry fn_table[] =
697 {
698   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
699   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
700   {NULL, 0, TRUE}
701 };
702
703 /* VFP SP Registers.  */
704 static const struct reg_entry sn_table[] =
705 {
706   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
707   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
708   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
709   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
710   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
711   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
712   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
713   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
714   {NULL, 0, TRUE}
715 };
716
717 /* VFP DP Registers.  */
718 static const struct reg_entry dn_table[] =
719 {
720   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
721   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
722   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
723   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
724   {NULL, 0, TRUE}
725 };
726
727 /* Maverick DSP coprocessor registers.  */
728 static const struct reg_entry mav_mvf_table[] =
729 {
730   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
731   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
732   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
733   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
734   {NULL, 0, TRUE}
735 };
736
737 static const struct reg_entry mav_mvd_table[] =
738 {
739   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
740   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
741   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
742   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
743   {NULL, 0, TRUE}
744 };
745
746 static const struct reg_entry mav_mvfx_table[] =
747 {
748   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
749   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
750   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
751   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
752   {NULL, 0, TRUE}
753 };
754
755 static const struct reg_entry mav_mvdx_table[] =
756 {
757   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
758   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
759   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
760   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
761   {NULL, 0, TRUE}
762 };
763
764 static const struct reg_entry mav_mvax_table[] =
765 {
766   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
767   {NULL, 0, TRUE}
768 };
769
770 static const struct reg_entry mav_dspsc_table[] =
771 {
772   {"dspsc", 0, TRUE},
773   {NULL, 0, TRUE}
774 };
775
776 struct reg_map
777 {
778   const struct reg_entry *names;
779   int max_regno;
780   struct hash_control *htab;
781   const char *expected;
782 };
783
784 struct reg_map all_reg_maps[] =
785 {
786   {rn_table,        15, NULL, N_("ARM register expected")},
787   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
788   {cn_table,        15, NULL, N_("co-processor register expected")},
789   {fn_table,         7, NULL, N_("FPA register expected")},
790   {sn_table,        31, NULL, N_("VFP single precision register expected")},
791   {dn_table,        15, NULL, N_("VFP double precision register expected")},
792   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
793   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
794   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
795   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
796   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
797   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
798   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
799 };
800
801 /* Enumeration matching entries in table above.  */
802 enum arm_reg_type
803 {
804   REG_TYPE_RN = 0,
805 #define REG_TYPE_FIRST REG_TYPE_RN
806   REG_TYPE_CP = 1,
807   REG_TYPE_CN = 2,
808   REG_TYPE_FN = 3,
809   REG_TYPE_SN = 4,
810   REG_TYPE_DN = 5,
811   REG_TYPE_MVF = 6,
812   REG_TYPE_MVD = 7,
813   REG_TYPE_MVFX = 8,
814   REG_TYPE_MVDX = 9,
815   REG_TYPE_MVAX = 10,
816   REG_TYPE_DSPSC = 11,
817   REG_TYPE_IWMMXT = 12,
818
819   REG_TYPE_MAX = 13
820 };
821
822 /* Functions called by parser.  */
823 /* ARM instructions.  */
824 static void do_arit             PARAMS ((char *));
825 static void do_cmp              PARAMS ((char *));
826 static void do_mov              PARAMS ((char *));
827 static void do_ldst             PARAMS ((char *));
828 static void do_ldstt            PARAMS ((char *));
829 static void do_ldmstm           PARAMS ((char *));
830 static void do_branch           PARAMS ((char *));
831 static void do_swi              PARAMS ((char *));
832
833 /* Pseudo Op codes.  */
834 static void do_adr              PARAMS ((char *));
835 static void do_adrl             PARAMS ((char *));
836 static void do_empty            PARAMS ((char *));
837
838 /* ARM v2.  */
839 static void do_mul              PARAMS ((char *));
840 static void do_mla              PARAMS ((char *));
841
842 /* ARM v2S.  */
843 static void do_swap             PARAMS ((char *));
844
845 /* ARM v3.  */
846 static void do_msr              PARAMS ((char *));
847 static void do_mrs              PARAMS ((char *));
848
849 /* ARM v3M.  */
850 static void do_mull             PARAMS ((char *));
851
852 /* ARM v4.  */
853 static void do_ldstv4           PARAMS ((char *));
854
855 /* ARM v4T.  */
856 static void do_bx               PARAMS ((char *));
857
858 /* ARM v5T.  */
859 static void do_blx              PARAMS ((char *));
860 static void do_bkpt             PARAMS ((char *));
861 static void do_clz              PARAMS ((char *));
862 static void do_lstc2            PARAMS ((char *));
863 static void do_cdp2             PARAMS ((char *));
864 static void do_co_reg2          PARAMS ((char *));
865
866 /* ARM v5TExP.  */
867 static void do_smla             PARAMS ((char *));
868 static void do_smlal            PARAMS ((char *));
869 static void do_smul             PARAMS ((char *));
870 static void do_qadd             PARAMS ((char *));
871
872 /* ARM v5TE.  */
873 static void do_pld              PARAMS ((char *));
874 static void do_ldrd             PARAMS ((char *));
875 static void do_co_reg2c         PARAMS ((char *));
876
877 /* ARM v5TEJ.  */
878 static void do_bxj              PARAMS ((char *));
879
880 /* ARM V6. */
881 static void do_cps              PARAMS ((char *));
882 static void do_cpsi             PARAMS ((char *));
883 static void do_ldrex            PARAMS ((char *));
884 static void do_pkhbt            PARAMS ((char *));
885 static void do_pkhtb            PARAMS ((char *));
886 static void do_qadd16           PARAMS ((char *));
887 static void do_rev              PARAMS ((char *));
888 static void do_rfe              PARAMS ((char *));
889 static void do_sxtah            PARAMS ((char *));
890 static void do_sxth             PARAMS ((char *));
891 static void do_setend           PARAMS ((char *));
892 static void do_smlad            PARAMS ((char *));
893 static void do_smlald           PARAMS ((char *));
894 static void do_smmul            PARAMS ((char *));
895 static void do_ssat             PARAMS ((char *));
896 static void do_usat             PARAMS ((char *));
897 static void do_srs              PARAMS ((char *));
898 static void do_ssat16           PARAMS ((char *));
899 static void do_usat16           PARAMS ((char *));
900 static void do_strex            PARAMS ((char *));
901 static void do_umaal            PARAMS ((char *));
902
903 static void do_cps_mode         PARAMS ((char **));
904 static void do_cps_flags        PARAMS ((char **, int));
905 static int do_endian_specifier  PARAMS ((char *));
906 static void do_pkh_core         PARAMS ((char *, int));
907 static void do_sat              PARAMS ((char **, int));
908 static void do_sat16            PARAMS ((char **, int));
909
910 /* Coprocessor Instructions.  */
911 static void do_cdp              PARAMS ((char *));
912 static void do_lstc             PARAMS ((char *));
913 static void do_co_reg           PARAMS ((char *));
914
915 /* FPA instructions.  */
916 static void do_fpa_ctrl         PARAMS ((char *));
917 static void do_fpa_ldst         PARAMS ((char *));
918 static void do_fpa_ldmstm       PARAMS ((char *));
919 static void do_fpa_dyadic       PARAMS ((char *));
920 static void do_fpa_monadic      PARAMS ((char *));
921 static void do_fpa_cmp          PARAMS ((char *));
922 static void do_fpa_from_reg     PARAMS ((char *));
923 static void do_fpa_to_reg       PARAMS ((char *));
924
925 /* VFP instructions.  */
926 static void do_vfp_sp_monadic   PARAMS ((char *));
927 static void do_vfp_dp_monadic   PARAMS ((char *));
928 static void do_vfp_sp_dyadic    PARAMS ((char *));
929 static void do_vfp_dp_dyadic    PARAMS ((char *));
930 static void do_vfp_reg_from_sp  PARAMS ((char *));
931 static void do_vfp_sp_from_reg  PARAMS ((char *));
932 static void do_vfp_sp_reg2      PARAMS ((char *));
933 static void do_vfp_reg_from_dp  PARAMS ((char *));
934 static void do_vfp_reg2_from_dp PARAMS ((char *));
935 static void do_vfp_dp_from_reg  PARAMS ((char *));
936 static void do_vfp_dp_from_reg2 PARAMS ((char *));
937 static void do_vfp_reg_from_ctrl PARAMS ((char *));
938 static void do_vfp_ctrl_from_reg PARAMS ((char *));
939 static void do_vfp_sp_ldst      PARAMS ((char *));
940 static void do_vfp_dp_ldst      PARAMS ((char *));
941 static void do_vfp_sp_ldstmia   PARAMS ((char *));
942 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
943 static void do_vfp_dp_ldstmia   PARAMS ((char *));
944 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
945 static void do_vfp_xp_ldstmia   PARAMS ((char *));
946 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
947 static void do_vfp_sp_compare_z PARAMS ((char *));
948 static void do_vfp_dp_compare_z PARAMS ((char *));
949 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
950 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
951
952 /* XScale.  */
953 static void do_xsc_mia          PARAMS ((char *));
954 static void do_xsc_mar          PARAMS ((char *));
955 static void do_xsc_mra          PARAMS ((char *));
956
957 /* Maverick.  */
958 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
959                                          enum arm_reg_type));
960 static void do_mav_binops_1a    PARAMS ((char *));
961 static void do_mav_binops_1b    PARAMS ((char *));
962 static void do_mav_binops_1c    PARAMS ((char *));
963 static void do_mav_binops_1d    PARAMS ((char *));
964 static void do_mav_binops_1e    PARAMS ((char *));
965 static void do_mav_binops_1f    PARAMS ((char *));
966 static void do_mav_binops_1g    PARAMS ((char *));
967 static void do_mav_binops_1h    PARAMS ((char *));
968 static void do_mav_binops_1i    PARAMS ((char *));
969 static void do_mav_binops_1j    PARAMS ((char *));
970 static void do_mav_binops_1k    PARAMS ((char *));
971 static void do_mav_binops_1l    PARAMS ((char *));
972 static void do_mav_binops_1m    PARAMS ((char *));
973 static void do_mav_binops_1n    PARAMS ((char *));
974 static void do_mav_binops_1o    PARAMS ((char *));
975 static void do_mav_binops_2a    PARAMS ((char *));
976 static void do_mav_binops_2b    PARAMS ((char *));
977 static void do_mav_binops_2c    PARAMS ((char *));
978 static void do_mav_binops_3a    PARAMS ((char *));
979 static void do_mav_binops_3b    PARAMS ((char *));
980 static void do_mav_binops_3c    PARAMS ((char *));
981 static void do_mav_binops_3d    PARAMS ((char *));
982 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
983                                          enum arm_reg_type,
984                                          enum arm_reg_type));
985 static void do_mav_triple_4a    PARAMS ((char *));
986 static void do_mav_triple_4b    PARAMS ((char *));
987 static void do_mav_triple_5a    PARAMS ((char *));
988 static void do_mav_triple_5b    PARAMS ((char *));
989 static void do_mav_triple_5c    PARAMS ((char *));
990 static void do_mav_triple_5d    PARAMS ((char *));
991 static void do_mav_triple_5e    PARAMS ((char *));
992 static void do_mav_triple_5f    PARAMS ((char *));
993 static void do_mav_triple_5g    PARAMS ((char *));
994 static void do_mav_triple_5h    PARAMS ((char *));
995 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
996                                          enum arm_reg_type,
997                                          enum arm_reg_type,
998                                          enum arm_reg_type));
999 static void do_mav_quad_6a      PARAMS ((char *));
1000 static void do_mav_quad_6b      PARAMS ((char *));
1001 static void do_mav_dspsc_1      PARAMS ((char *));
1002 static void do_mav_dspsc_2      PARAMS ((char *));
1003 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
1004                                          enum arm_reg_type));
1005 static void do_mav_shift_1      PARAMS ((char *));
1006 static void do_mav_shift_2      PARAMS ((char *));
1007 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
1008 static void do_mav_ldst_1       PARAMS ((char *));
1009 static void do_mav_ldst_2       PARAMS ((char *));
1010 static void do_mav_ldst_3       PARAMS ((char *));
1011 static void do_mav_ldst_4       PARAMS ((char *));
1012
1013 static int mav_reg_required_here        PARAMS ((char **, int,
1014                                                  enum arm_reg_type));
1015 static int mav_parse_offset     PARAMS ((char **, int *));
1016
1017 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
1018                                          int, int));
1019 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
1020 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1021 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1022 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
1023                                          fragS *));
1024 static int add_to_lit_pool      PARAMS ((void));
1025 static unsigned validate_immediate PARAMS ((unsigned));
1026 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1027                                                     unsigned int *));
1028 static int validate_offset_imm  PARAMS ((unsigned int, int));
1029 static void opcode_select       PARAMS ((int));
1030 static void end_of_line         PARAMS ((char *));
1031 static int reg_required_here    PARAMS ((char **, int));
1032 static int psr_required_here    PARAMS ((char **));
1033 static int co_proc_number       PARAMS ((char **));
1034 static int cp_opc_expr          PARAMS ((char **, int, int));
1035 static int cp_reg_required_here PARAMS ((char **, int));
1036 static int fp_reg_required_here PARAMS ((char **, int));
1037 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1038 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1039 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1040 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
1041 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
1042 static long vfp_dp_reg_list     PARAMS ((char **));
1043 static int vfp_psr_required_here PARAMS ((char **str));
1044 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1045 static int cp_address_offset    PARAMS ((char **));
1046 static int cp_address_required_here     PARAMS ((char **, int));
1047 static int my_get_float_expression      PARAMS ((char **));
1048 static int skip_past_comma      PARAMS ((char **));
1049 static int walk_no_bignums      PARAMS ((symbolS *));
1050 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
1051 static int data_op2             PARAMS ((char **));
1052 static int fp_op2               PARAMS ((char **));
1053 static long reg_list            PARAMS ((char **));
1054 static void thumb_load_store    PARAMS ((char *, int, int));
1055 static int decode_shift         PARAMS ((char **, int));
1056 static int ldst_extend          PARAMS ((char **));
1057 static int ldst_extend_v4               PARAMS ((char **));
1058 static void thumb_add_sub       PARAMS ((char *, int));
1059 static void insert_reg          PARAMS ((const struct reg_entry *,
1060                                          struct hash_control *));
1061 static void thumb_shift         PARAMS ((char *, int));
1062 static void thumb_mov_compare   PARAMS ((char *, int));
1063 static void build_arm_ops_hsh   PARAMS ((void));
1064 static void set_constant_flonums        PARAMS ((void));
1065 static valueT md_chars_to_number        PARAMS ((char *, int));
1066 static void build_reg_hsh       PARAMS ((struct reg_map *));
1067 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
1068 static int create_register_alias        PARAMS ((char *, char *));
1069 static void output_inst         PARAMS ((const char *));
1070 static int accum0_required_here PARAMS ((char **));
1071 static int ld_mode_required_here PARAMS ((char **));
1072 static void do_branch25         PARAMS ((char *));
1073 static symbolS * find_real_start PARAMS ((symbolS *));
1074 #ifdef OBJ_ELF
1075 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1076 #endif
1077
1078 static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1079 static void do_iwmmxt_byte_addr PARAMS ((char *));
1080 static void do_iwmmxt_tandc     PARAMS ((char *));
1081 static void do_iwmmxt_tbcst     PARAMS ((char *));
1082 static void do_iwmmxt_textrc    PARAMS ((char *));
1083 static void do_iwmmxt_textrm    PARAMS ((char *));
1084 static void do_iwmmxt_tinsr     PARAMS ((char *));
1085 static void do_iwmmxt_tmcr      PARAMS ((char *));
1086 static void do_iwmmxt_tmcrr     PARAMS ((char *));
1087 static void do_iwmmxt_tmia      PARAMS ((char *));
1088 static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1089 static void do_iwmmxt_tmrc      PARAMS ((char *));
1090 static void do_iwmmxt_tmrrc     PARAMS ((char *));
1091 static void do_iwmmxt_torc      PARAMS ((char *));
1092 static void do_iwmmxt_waligni   PARAMS ((char *));
1093 static void do_iwmmxt_wmov      PARAMS ((char *));
1094 static void do_iwmmxt_word_addr PARAMS ((char *));
1095 static void do_iwmmxt_wrwr      PARAMS ((char *));
1096 static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1097 static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1098 static void do_iwmmxt_wshufh    PARAMS ((char *));
1099 static void do_iwmmxt_wzero     PARAMS ((char *));
1100 static int cp_byte_address_offset         PARAMS ((char **));
1101 static int cp_byte_address_required_here  PARAMS ((char **));
1102
1103 /* ARM instructions take 4bytes in the object file, Thumb instructions
1104    take 2:  */
1105 #define INSN_SIZE       4
1106
1107 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1108 #define MAV_MODE1       0x100c
1109
1110 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1111 #define MAV_MODE2       0x0c10
1112
1113 /* "INSN<cond> X,Y" where X:0, Y:bit16.  */
1114 #define MAV_MODE3       0x1000
1115
1116 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1117 #define MAV_MODE4       0x0c0010
1118
1119 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1120 #define MAV_MODE5       0x00100c
1121
1122 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1123 #define MAV_MODE6       0x00100c05
1124
1125 struct asm_opcode
1126 {
1127   /* Basic string to match.  */
1128   const char * template;
1129
1130   /* Basic instruction code.  */
1131   unsigned long value;
1132
1133   /* Offset into the template where the condition code (if any) will be.
1134      If zero, then the instruction is never conditional.  */
1135   unsigned cond_offset;
1136
1137   /* Which architecture variant provides this instruction.  */
1138   unsigned long variant;
1139
1140   /* Function to call to parse args.  */
1141   void (* parms) PARAMS ((char *));
1142 };
1143
1144 static const struct asm_opcode insns[] =
1145 {
1146   /* Core ARM Instructions.  */
1147   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1148   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1149   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1150   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1151   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1152   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1153   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1154   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1155   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1156   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1157   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1158   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1159   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1160   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1161   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1162   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1163   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1164   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1165   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1166   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1167
1168   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1169   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1170   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1171   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1172   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1173   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1174   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1175   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1176   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1177   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1178   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1179   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1180
1181   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1182   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1183   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1184   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1185
1186   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1187   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1188   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1189   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1190   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1191   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1192   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1193   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1194
1195   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1196   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1197   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1198   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1199   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1200   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1201   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1202   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1203
1204   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1205   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1206   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1207   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1208   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1209   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1210   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1211   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1212
1213   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1214 #ifdef TE_WINCE
1215   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1216   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1217   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1218 #else
1219   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1220   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1221 #endif
1222
1223   /* Pseudo ops.  */
1224   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1225   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1226   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1227
1228   /* ARM 2 multiplies.  */
1229   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1230   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1231   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1232   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1233
1234   /* Generic coprocessor instructions.  */
1235   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1236   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1237   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1238   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1239   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1240   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1241   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1242
1243   /* ARM 3 - swp instructions.  */
1244   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1245   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1246
1247   /* ARM 6 Status register instructions.  */
1248   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1249   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1250   /* ScottB: our code uses     0xe128f000 for msr.
1251      NickC:  but this is wrong because the bits 16 through 19 are
1252              handled by the PSR_xxx defines above.  */
1253
1254   /* ARM 7M long multiplies.  */
1255   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1256   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1257   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1258   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1259   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1260   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1261   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1262   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1263
1264   /* ARM Architecture 4.  */
1265   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1266   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1267   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1268   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1269
1270   /* ARM Architecture 4T.  */
1271   /* Note: bx (and blx) are required on V5, even if the processor does
1272      not support Thumb.  */
1273   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1274
1275   /*  ARM Architecture 5T.  */
1276   /* Note: blx has 2 variants, so the .value is set dynamically.
1277      Only one of the variants has conditional execution.  */
1278   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1279   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1280   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1281   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1282   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1283   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1284   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1285   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1286   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1287   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1288
1289   /*  ARM Architecture 5TExP.  */
1290   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1291   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1292   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1293   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1294
1295   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1296   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1297
1298   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1299   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1300   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1301   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1302
1303   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1304   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1305   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1306   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1307
1308   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1309   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1310
1311   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1312   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1313   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1314   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1315
1316   /*  ARM Architecture 5TE.  */
1317   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1318   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1319   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1320
1321   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1322   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1323
1324   /*  ARM Architecture 5TEJ.  */
1325   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1326
1327   /*  ARM V6.  */
1328   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1329   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1330   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1331   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1332   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1333   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1334   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1335   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1336   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1337   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1338   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1339   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1340   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1341   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1342   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1343   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1344   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1345   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1346   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1347   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1348   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1349   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1350   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1351   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1352   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1353   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1354   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1355   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1356   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1357   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1358   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1359   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1360   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1361   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1362   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1363   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1364   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1365   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1366   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1367   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1368   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1369   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1370   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1371   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1372   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1373   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1374   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1375   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1376   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1377   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1378   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1379   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1380   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1381   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1382   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1383   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1384   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1385   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1386   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1387   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1388   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1389   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1390   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1391   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1392   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1393   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1394   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1395   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1396   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1397   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1398   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1399   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1400   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1401   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1402   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1403   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1404   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1405   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1406   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1407   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1408   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1409   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1410   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1411   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1412   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1413   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1414   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1415   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1416   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1417   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1418   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1419   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1420   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1421   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1422   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1423   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1424   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1425   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1426   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1427
1428   /* Core FPA instruction set (V1).  */
1429   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1430   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1431   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1432   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1433
1434   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1435   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1436   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1437   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1438
1439   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1440   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1441   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1442   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1443
1444   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1445   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1446   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1447   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1448   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1449   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1450   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456
1457   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1460   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1463   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469
1470   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1473   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1476   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482
1483   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1486   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1489   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495
1496   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1499   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1502   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508
1509   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1512   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1515   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521
1522   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1525   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1528   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534
1535   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1538   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1541   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547
1548   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1551   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1554   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560
1561   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1564   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1567   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573
1574   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1577   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1580   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586
1587   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1588   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1589   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1590   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1591   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1592   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1593   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1594   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1595   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1596   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1597   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1598   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1599
1600   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1601   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1602   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1603   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1604   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1605   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1606   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1607   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1608   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1609   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1610   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1611   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1612
1613   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1614   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1615   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1616   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1617   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1618   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1619   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1620   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1621   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1622   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1623   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1624   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1625
1626   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1627   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1628   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1629   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1630   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1631   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1632   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1633   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1634   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1635   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1636   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1637   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1638
1639   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1640   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1641   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1642   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1643   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1644   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1645   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1646   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1647   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1648   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1649   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1650   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1651
1652   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1653   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1654   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1655   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1656   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1657   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1658   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664
1665   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1668   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1671   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677
1678   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1681   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1684   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690
1691   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1694   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1697   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703
1704   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1707   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1710   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716
1717   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1720   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1723   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729
1730   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1733   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1736   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742
1743   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1746   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1749   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755
1756   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1757   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1758   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1759   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1760   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1761   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1762   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1763   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1764   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1765   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1766   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1767   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1768
1769   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1770   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1771   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1772   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1773   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1774   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1775   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1776   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1777   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1778   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1779   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1780   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1781
1782   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1783   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1784   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1785   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1786   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1787   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1788   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1789   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1790   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1791   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1792   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1793   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1794
1795   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1796   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1797   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1798   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1799   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1800   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1801   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1802   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1803   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1804   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1805   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1806   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1807
1808   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1809   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1810   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1811   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1812   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1813   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1814   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1815   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1816   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1817   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1818   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1819   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1820
1821   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1822   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1823   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1824   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1825   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1826      not be an optional suffix, but part of the instruction.  To be
1827      compatible, we accept either.  */
1828   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1829   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1830
1831   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1832   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1833   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1834   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1835   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1836   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1837   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1838   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1839   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1840   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1841   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1842   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1843
1844   /* The implementation of the FIX instruction is broken on some
1845      assemblers, in that it accepts a precision specifier as well as a
1846      rounding specifier, despite the fact that this is meaningless.
1847      To be more compatible, we accept it as well, though of course it
1848      does not set any bits.  */
1849   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1850   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1851   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1852   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1853   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1854   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1855   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1856   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1857   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1858   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1859   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1860   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1861   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1862
1863   /* Instructions that were new with the real FPA, call them V2.  */
1864   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1865   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1866   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1867   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1868   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1869   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1870
1871   /* VFP V1xD (single precision).  */
1872   /* Moves and type conversions.  */
1873   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1874   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1875   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1876   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1877   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1878   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1879   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1880   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1881   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1882   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1883   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1884   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1885
1886   /* Memory operations.  */
1887   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1888   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1889   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1890   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1891   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1892   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1893   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1894   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1895   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1896   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1897   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1898   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1899   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1900   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1901   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1902   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1903   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1904   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1905
1906   /* Monadic operations.  */
1907   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1908   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1909   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1910
1911   /* Dyadic operations.  */
1912   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1913   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1914   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1915   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1916   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1917   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1918   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921
1922   /* Comparisons.  */
1923   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1924   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1925   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1926   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1927
1928   /* VFP V1 (Double precision).  */
1929   /* Moves and type conversions.  */
1930   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1931   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1932   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1933   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1934   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1935   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1936   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1937   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1938   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1939   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1940   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1941   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1942   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1943
1944   /* Memory operations.  */
1945   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1946   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1947   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1948   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1949   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1950   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1951   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1952   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1953   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1954   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1955
1956   /* Monadic operations.  */
1957   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1958   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1959   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1960
1961   /* Dyadic operations.  */
1962   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1963   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1964   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1965   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1966   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1967   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1968   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1969   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1970   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1971
1972   /* Comparisons.  */
1973   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1974   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1975   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1976   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1977
1978   /* VFP V2.  */
1979   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp_reg2},
1980   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp_reg2},
1981   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1982   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1983
1984   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1985   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1986   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1987   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1988   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1989   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1990   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1991   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1992   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1993
1994   /* Intel Wireless MMX technology instructions.  */
1995   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1996   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1997   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1998   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1999   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2000   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2001   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2002   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2003   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2004   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2005   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2006   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2007   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2008   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2009   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2010   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2011   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2012   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2013   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2014   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2015   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2016   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2017   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2018   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2019   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2020   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2021   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2022   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2023   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2024   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2025   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2026   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2027   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2028   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2029   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2030   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2031   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2032   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2033   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2034   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2035   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2036   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2042   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2045   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2062   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2063   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2064   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2065   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2066   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2067   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2068   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2069   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2084   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2087   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2097   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2099   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2100   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2101   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2102   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2103   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2104   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2105   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2106   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2107   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2108   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2109   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2110   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2111   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2112   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2113   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2114   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2115   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2116   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2117   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2118   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2119   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2120   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2121   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2122   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2123   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2124   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2125   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2126   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2127   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2128   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2129   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2130   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2131   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2132   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2133   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2134   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2138   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2139   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2140   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2141   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2142   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2143   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2144   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2145   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2146   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2147   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2148   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2149   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2150   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2151   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2152   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2153   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2154   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2155   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2156   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2157
2158   /* Cirrus Maverick instructions.  */
2159   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2160   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2161   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2162   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2163   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2164   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2165   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2166   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2167   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2168   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2169   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2170   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2171   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2172   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2173   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2174   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2175   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2176   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2177   {"cfmval32",   0xee100610, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2178   {"cfmv32al",   0xee000610, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2179   {"cfmvam32",   0xee100630, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2180   {"cfmv32am",   0xee000630, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2181   {"cfmvah32",   0xee100650, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2182   {"cfmv32ah",   0xee000650, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2183   {"cfmva32",    0xee100670, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2184   {"cfmv32a",    0xee000670, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2185   {"cfmva64",    0xee100690, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2186   {"cfmv64a",    0xee000690, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2187   {"cfmvsc32",   0xee1006b0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2188   {"cfmv32sc",   0xee0006b0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2189   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2190   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2191   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2192   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2193   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2194   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2195   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2196   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2197   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2198   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2199   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2200   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2201   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2202   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2203   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2204   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2205   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2206   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2207   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2208   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2209   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2210   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2211   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2212   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2213   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2214   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2215   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2216   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2217   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2218   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2219   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2220   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2221   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2222   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2223   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2224   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2225   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2226   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2227   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2228   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2229   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2230   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2231   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2232   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2233   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2234   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2235 };
2236
2237 /* Defines for various bits that we will want to toggle.  */
2238 #define INST_IMMEDIATE  0x02000000
2239 #define OFFSET_REG      0x02000000
2240 #define HWOFFSET_IMM    0x00400000
2241 #define SHIFT_BY_REG    0x00000010
2242 #define PRE_INDEX       0x01000000
2243 #define INDEX_UP        0x00800000
2244 #define WRITE_BACK      0x00200000
2245 #define LDM_TYPE_2_OR_3 0x00400000
2246
2247 #define LITERAL_MASK    0xf000f000
2248 #define OPCODE_MASK     0xfe1fffff
2249 #define V4_STR_BIT      0x00000020
2250
2251 #define DATA_OP_SHIFT   21
2252
2253 /* Codes to distinguish the arithmetic instructions.  */
2254 #define OPCODE_AND      0
2255 #define OPCODE_EOR      1
2256 #define OPCODE_SUB      2
2257 #define OPCODE_RSB      3
2258 #define OPCODE_ADD      4
2259 #define OPCODE_ADC      5
2260 #define OPCODE_SBC      6
2261 #define OPCODE_RSC      7
2262 #define OPCODE_TST      8
2263 #define OPCODE_TEQ      9
2264 #define OPCODE_CMP      10
2265 #define OPCODE_CMN      11
2266 #define OPCODE_ORR      12
2267 #define OPCODE_MOV      13
2268 #define OPCODE_BIC      14
2269 #define OPCODE_MVN      15
2270
2271 /* Thumb v1 (ARMv4T).  */
2272 static void do_t_nop            PARAMS ((char *));
2273 static void do_t_arit           PARAMS ((char *));
2274 static void do_t_add            PARAMS ((char *));
2275 static void do_t_asr            PARAMS ((char *));
2276 static void do_t_branch9        PARAMS ((char *));
2277 static void do_t_branch12       PARAMS ((char *));
2278 static void do_t_branch23       PARAMS ((char *));
2279 static void do_t_bx             PARAMS ((char *));
2280 static void do_t_compare        PARAMS ((char *));
2281 static void do_t_ldmstm         PARAMS ((char *));
2282 static void do_t_ldr            PARAMS ((char *));
2283 static void do_t_ldrb           PARAMS ((char *));
2284 static void do_t_ldrh           PARAMS ((char *));
2285 static void do_t_lds            PARAMS ((char *));
2286 static void do_t_lsl            PARAMS ((char *));
2287 static void do_t_lsr            PARAMS ((char *));
2288 static void do_t_mov            PARAMS ((char *));
2289 static void do_t_push_pop       PARAMS ((char *));
2290 static void do_t_str            PARAMS ((char *));
2291 static void do_t_strb           PARAMS ((char *));
2292 static void do_t_strh           PARAMS ((char *));
2293 static void do_t_sub            PARAMS ((char *));
2294 static void do_t_swi            PARAMS ((char *));
2295 static void do_t_adr            PARAMS ((char *));
2296
2297 /* Thumb v2 (ARMv5T).  */
2298 static void do_t_blx            PARAMS ((char *));
2299 static void do_t_bkpt           PARAMS ((char *));
2300
2301 /* ARM V6.  */
2302 static void do_t_cps            PARAMS ((char *));
2303 static void do_t_cpy            PARAMS ((char *));
2304 static void do_t_setend         PARAMS ((char *));;
2305
2306 #define T_OPCODE_MUL 0x4340
2307 #define T_OPCODE_TST 0x4200
2308 #define T_OPCODE_CMN 0x42c0
2309 #define T_OPCODE_NEG 0x4240
2310 #define T_OPCODE_MVN 0x43c0
2311
2312 #define T_OPCODE_ADD_R3 0x1800
2313 #define T_OPCODE_SUB_R3 0x1a00
2314 #define T_OPCODE_ADD_HI 0x4400
2315 #define T_OPCODE_ADD_ST 0xb000
2316 #define T_OPCODE_SUB_ST 0xb080
2317 #define T_OPCODE_ADD_SP 0xa800
2318 #define T_OPCODE_ADD_PC 0xa000
2319 #define T_OPCODE_ADD_I8 0x3000
2320 #define T_OPCODE_SUB_I8 0x3800
2321 #define T_OPCODE_ADD_I3 0x1c00
2322 #define T_OPCODE_SUB_I3 0x1e00
2323
2324 #define T_OPCODE_ASR_R  0x4100
2325 #define T_OPCODE_LSL_R  0x4080
2326 #define T_OPCODE_LSR_R  0x40c0
2327 #define T_OPCODE_ASR_I  0x1000
2328 #define T_OPCODE_LSL_I  0x0000
2329 #define T_OPCODE_LSR_I  0x0800
2330
2331 #define T_OPCODE_MOV_I8 0x2000
2332 #define T_OPCODE_CMP_I8 0x2800
2333 #define T_OPCODE_CMP_LR 0x4280
2334 #define T_OPCODE_MOV_HR 0x4600
2335 #define T_OPCODE_CMP_HR 0x4500
2336
2337 #define T_OPCODE_LDR_PC 0x4800
2338 #define T_OPCODE_LDR_SP 0x9800
2339 #define T_OPCODE_STR_SP 0x9000
2340 #define T_OPCODE_LDR_IW 0x6800
2341 #define T_OPCODE_STR_IW 0x6000
2342 #define T_OPCODE_LDR_IH 0x8800
2343 #define T_OPCODE_STR_IH 0x8000
2344 #define T_OPCODE_LDR_IB 0x7800
2345 #define T_OPCODE_STR_IB 0x7000
2346 #define T_OPCODE_LDR_RW 0x5800
2347 #define T_OPCODE_STR_RW 0x5000
2348 #define T_OPCODE_LDR_RH 0x5a00
2349 #define T_OPCODE_STR_RH 0x5200
2350 #define T_OPCODE_LDR_RB 0x5c00
2351 #define T_OPCODE_STR_RB 0x5400
2352
2353 #define T_OPCODE_PUSH   0xb400
2354 #define T_OPCODE_POP    0xbc00
2355
2356 #define T_OPCODE_BRANCH 0xe7fe
2357
2358 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
2359
2360 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
2361 #define THUMB_REG_LO    0x1
2362 #define THUMB_REG_HI    0x2
2363 #define THUMB_REG_ANY   0x3
2364
2365 #define THUMB_H1        0x0080
2366 #define THUMB_H2        0x0040
2367
2368 #define THUMB_ASR 0
2369 #define THUMB_LSL 1
2370 #define THUMB_LSR 2
2371
2372 #define THUMB_MOVE 0
2373 #define THUMB_COMPARE 1
2374 #define THUMB_CPY 2
2375
2376 #define THUMB_LOAD 0
2377 #define THUMB_STORE 1
2378
2379 #define THUMB_PP_PC_LR 0x0100
2380
2381 /* These three are used for immediate shifts, do not alter.  */
2382 #define THUMB_WORD 2
2383 #define THUMB_HALFWORD 1
2384 #define THUMB_BYTE 0
2385
2386 struct thumb_opcode
2387 {
2388   /* Basic string to match.  */
2389   const char * template;
2390
2391   /* Basic instruction code.  */
2392   unsigned long value;
2393
2394   int size;
2395
2396   /* Which CPU variants this exists for.  */
2397   unsigned long variant;
2398
2399   /* Function to call to parse args.  */
2400   void (* parms) PARAMS ((char *));
2401 };
2402
2403 static const struct thumb_opcode tinsns[] =
2404 {
2405   /* Thumb v1 (ARMv4T).  */
2406   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
2407   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
2408   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
2409   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
2410   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
2411   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
2412   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
2413   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2414   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2415   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2416   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2417   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2418   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
2419   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
2420   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
2421   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
2422   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
2423   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
2424   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
2425   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
2426   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
2427   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
2428   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
2429   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
2430   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
2431   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
2432   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2433   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2434   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2435   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2436   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2437   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2438   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2439   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2440   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2441   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2442   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2443   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2444   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2445   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2446   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2447   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2448   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2449   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2450   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2451   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2452   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2453   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2454   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2455   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2456   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2457   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2458   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2459   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2460   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2461   /* Pseudo ops:  */
2462   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2463   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2464   /* Thumb v2 (ARMv5T).  */
2465   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2466   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2467
2468   /* ARM V6.  */
2469   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
2470   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
2471   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
2472   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
2473   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
2474   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
2475   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
2476   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
2477   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
2478   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
2479   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
2480 };
2481
2482 #define BAD_ARGS        _("bad arguments to instruction")
2483 #define BAD_PC          _("r15 not allowed here")
2484 #define BAD_COND        _("instruction is not conditional")
2485 #define ERR_NO_ACCUM    _("acc0 expected")
2486
2487 static struct hash_control * arm_ops_hsh   = NULL;
2488 static struct hash_control * arm_tops_hsh  = NULL;
2489 static struct hash_control * arm_cond_hsh  = NULL;
2490 static struct hash_control * arm_shift_hsh = NULL;
2491 static struct hash_control * arm_psr_hsh   = NULL;
2492
2493 /* This table describes all the machine specific pseudo-ops the assembler
2494    has to support.  The fields are:
2495      pseudo-op name without dot
2496      function to call to execute this pseudo-op
2497      Integer arg to pass to the function.  */
2498
2499 static void s_req PARAMS ((int));
2500 static void s_unreq PARAMS ((int));
2501 static void s_align PARAMS ((int));
2502 static void s_bss PARAMS ((int));
2503 static void s_even PARAMS ((int));
2504 static void s_ltorg PARAMS ((int));
2505 static void s_arm PARAMS ((int));
2506 static void s_thumb PARAMS ((int));
2507 static void s_code PARAMS ((int));
2508 static void s_force_thumb PARAMS ((int));
2509 static void s_thumb_func PARAMS ((int));
2510 static void s_thumb_set PARAMS ((int));
2511 #ifdef OBJ_ELF
2512 static void s_arm_elf_cons PARAMS ((int));
2513 #endif
2514
2515 static int my_get_expression PARAMS ((expressionS *, char **));
2516
2517 const pseudo_typeS md_pseudo_table[] =
2518 {
2519   /* Never called because '.req' does not start a line.  */
2520   { "req",         s_req,         0 },
2521   { "unreq",       s_unreq,       0 },
2522   { "bss",         s_bss,         0 },
2523   { "align",       s_align,       0 },
2524   { "arm",         s_arm,         0 },
2525   { "thumb",       s_thumb,       0 },
2526   { "code",        s_code,        0 },
2527   { "force_thumb", s_force_thumb, 0 },
2528   { "thumb_func",  s_thumb_func,  0 },
2529   { "thumb_set",   s_thumb_set,   0 },
2530   { "even",        s_even,        0 },
2531   { "ltorg",       s_ltorg,       0 },
2532   { "pool",        s_ltorg,       0 },
2533 #ifdef OBJ_ELF
2534   { "word",        s_arm_elf_cons, 4 },
2535   { "long",        s_arm_elf_cons, 4 },
2536 #else
2537   { "word",        cons, 4},
2538 #endif
2539   { "extend",      float_cons, 'x' },
2540   { "ldouble",     float_cons, 'x' },
2541   { "packed",      float_cons, 'p' },
2542   { 0, 0, 0 }
2543 };
2544
2545 /* Other internal functions.  */
2546 static int arm_parse_extension PARAMS ((char *, int *));
2547 static int arm_parse_cpu PARAMS ((char *));
2548 static int arm_parse_arch PARAMS ((char *));
2549 static int arm_parse_fpu PARAMS ((char *));
2550 static int arm_parse_float_abi PARAMS ((char *));
2551 #if 0 /* Suppressed - for now.  */
2552 #if defined OBJ_COFF || defined OBJ_ELF
2553 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2554 #endif
2555 #endif
2556
2557 /* Stuff needed to resolve the label ambiguity
2558    As:
2559      ...
2560      label:   <insn>
2561    may differ from:
2562      ...
2563      label:
2564               <insn>
2565 */
2566
2567 symbolS *  last_label_seen;
2568 static int label_is_thumb_function_name = FALSE;
2569
2570 /* Literal Pool stuff.  */
2571
2572 #define MAX_LITERAL_POOL_SIZE 1024
2573
2574 /* Literal pool structure.  Held on a per-section
2575    and per-sub-section basis.  */
2576 typedef struct literal_pool
2577 {
2578   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2579   unsigned int   next_free_entry;
2580   unsigned int   id;
2581   symbolS *      symbol;
2582   segT           section;
2583   subsegT        sub_section;
2584   struct literal_pool * next;
2585 } literal_pool;
2586
2587 /* Pointer to a linked list of literal pools.  */
2588 literal_pool * list_of_pools = NULL;
2589
2590 static literal_pool * find_literal_pool PARAMS ((void));
2591 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2592
2593 static literal_pool *
2594 find_literal_pool ()
2595 {
2596   literal_pool * pool;
2597
2598   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2599     {
2600       if (pool->section == now_seg
2601           && pool->sub_section == now_subseg)
2602         break;
2603     }
2604
2605   return pool;
2606 }
2607
2608 static literal_pool *
2609 find_or_make_literal_pool ()
2610 {
2611   /* Next literal pool ID number.  */
2612   static unsigned int latest_pool_num = 1;
2613   literal_pool *      pool;
2614
2615   pool = find_literal_pool ();
2616
2617   if (pool == NULL)
2618     {
2619       /* Create a new pool.  */
2620       pool = (literal_pool *) xmalloc (sizeof (* pool));
2621       if (! pool)
2622         return NULL;
2623
2624       pool->next_free_entry = 0;
2625       pool->section         = now_seg;
2626       pool->sub_section     = now_subseg;
2627       pool->next            = list_of_pools;
2628       pool->symbol          = NULL;
2629
2630       /* Add it to the list.  */
2631       list_of_pools = pool;
2632     }
2633
2634   /* New pools, and emptied pools, will have a NULL symbol.  */
2635   if (pool->symbol == NULL)
2636     {
2637       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2638                                     (valueT) 0, &zero_address_frag);
2639       pool->id = latest_pool_num ++;
2640     }
2641
2642   /* Done.  */
2643   return pool;
2644 }
2645
2646 /* Add the literal in the global 'inst'
2647    structure to the relevent literal pool.  */
2648 static int
2649 add_to_lit_pool ()
2650 {
2651   literal_pool * pool;
2652   unsigned int entry;
2653
2654   pool = find_or_make_literal_pool ();
2655
2656   /* Check if this literal value is already in the pool.  */
2657   for (entry = 0; entry < pool->next_free_entry; entry ++)
2658     {
2659       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2660           && (inst.reloc.exp.X_op == O_constant)
2661           && (pool->literals[entry].X_add_number
2662               == inst.reloc.exp.X_add_number)
2663           && (pool->literals[entry].X_unsigned
2664               == inst.reloc.exp.X_unsigned))
2665         break;
2666
2667       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2668           && (inst.reloc.exp.X_op == O_symbol)
2669           && (pool->literals[entry].X_add_number
2670               == inst.reloc.exp.X_add_number)
2671           && (pool->literals[entry].X_add_symbol
2672               == inst.reloc.exp.X_add_symbol)
2673           && (pool->literals[entry].X_op_symbol
2674               == inst.reloc.exp.X_op_symbol))
2675         break;
2676     }
2677
2678   /* Do we need to create a new entry?  */
2679   if (entry == pool->next_free_entry)
2680     {
2681       if (entry >= MAX_LITERAL_POOL_SIZE)
2682         {
2683           inst.error = _("literal pool overflow");
2684           return FAIL;
2685         }
2686
2687       pool->literals[entry] = inst.reloc.exp;
2688       pool->next_free_entry += 1;
2689     }
2690
2691   inst.reloc.exp.X_op         = O_symbol;
2692   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2693   inst.reloc.exp.X_add_symbol = pool->symbol;
2694
2695   return SUCCESS;
2696 }
2697
2698 /* Can't use symbol_new here, so have to create a symbol and then at
2699    a later date assign it a value. Thats what these functions do.  */
2700
2701 static void
2702 symbol_locate (symbolP, name, segment, valu, frag)
2703      symbolS *    symbolP;
2704      const char * name;         /* It is copied, the caller can modify.  */
2705      segT         segment;      /* Segment identifier (SEG_<something>).  */
2706      valueT       valu;         /* Symbol value.  */
2707      fragS *      frag;         /* Associated fragment.  */
2708 {
2709   unsigned int name_length;
2710   char * preserved_copy_of_name;
2711
2712   name_length = strlen (name) + 1;   /* +1 for \0.  */
2713   obstack_grow (&notes, name, name_length);
2714   preserved_copy_of_name = obstack_finish (&notes);
2715 #ifdef STRIP_UNDERSCORE
2716   if (preserved_copy_of_name[0] == '_')
2717     preserved_copy_of_name++;
2718 #endif
2719
2720 #ifdef tc_canonicalize_symbol_name
2721   preserved_copy_of_name =
2722     tc_canonicalize_symbol_name (preserved_copy_of_name);
2723 #endif
2724
2725   S_SET_NAME (symbolP, preserved_copy_of_name);
2726
2727   S_SET_SEGMENT (symbolP, segment);
2728   S_SET_VALUE (symbolP, valu);
2729   symbol_clear_list_pointers (symbolP);
2730
2731   symbol_set_frag (symbolP, frag);
2732
2733   /* Link to end of symbol chain.  */
2734   {
2735     extern int symbol_table_frozen;
2736     if (symbol_table_frozen)
2737       abort ();
2738   }
2739
2740   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2741
2742   obj_symbol_new_hook (symbolP);
2743
2744 #ifdef tc_symbol_new_hook
2745   tc_symbol_new_hook (symbolP);
2746 #endif
2747
2748 #ifdef DEBUG_SYMS
2749   verify_symbol_chain (symbol_rootP, symbol_lastP);
2750 #endif /* DEBUG_SYMS  */
2751 }
2752
2753 /* Check that an immediate is valid.
2754    If so, convert it to the right format.  */
2755
2756 static unsigned int
2757 validate_immediate (val)
2758      unsigned int val;
2759 {
2760   unsigned int a;
2761   unsigned int i;
2762
2763 #define rotate_left(v, n) (v << n | v >> (32 - n))
2764
2765   for (i = 0; i < 32; i += 2)
2766     if ((a = rotate_left (val, i)) <= 0xff)
2767       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2768
2769   return FAIL;
2770 }
2771
2772 /* Check to see if an immediate can be computed as two separate immediate
2773    values, added together.  We already know that this value cannot be
2774    computed by just one ARM instruction.  */
2775
2776 static unsigned int
2777 validate_immediate_twopart (val, highpart)
2778      unsigned int   val;
2779      unsigned int * highpart;
2780 {
2781   unsigned int a;
2782   unsigned int i;
2783
2784   for (i = 0; i < 32; i += 2)
2785     if (((a = rotate_left (val, i)) & 0xff) != 0)
2786       {
2787         if (a & 0xff00)
2788           {
2789             if (a & ~ 0xffff)
2790               continue;
2791             * highpart = (a  >> 8) | ((i + 24) << 7);
2792           }
2793         else if (a & 0xff0000)
2794           {
2795             if (a & 0xff000000)
2796               continue;
2797             * highpart = (a >> 16) | ((i + 16) << 7);
2798           }
2799         else
2800           {
2801             assert (a & 0xff000000);
2802             * highpart = (a >> 24) | ((i + 8) << 7);
2803           }
2804
2805         return (a & 0xff) | (i << 7);
2806       }
2807
2808   return FAIL;
2809 }
2810
2811 static int
2812 validate_offset_imm (val, hwse)
2813      unsigned int val;
2814      int hwse;
2815 {
2816   if ((hwse && val > 255) || val > 4095)
2817     return FAIL;
2818   return val;
2819 }
2820
2821 \f
2822 #ifdef OBJ_ELF
2823 enum mstate
2824 {
2825   MAP_DATA,
2826   MAP_ARM,
2827   MAP_THUMB
2828 };
2829
2830 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2831    (This text is taken from version B-02 of the spec):
2832
2833       4.4.7 Mapping and tagging symbols
2834
2835       A section of an ARM ELF file can contain a mixture of ARM code,
2836       Thumb code, and data.  There are inline transitions between code
2837       and data at literal pool boundaries. There can also be inline
2838       transitions between ARM code and Thumb code, for example in
2839       ARM-Thumb inter-working veneers.  Linkers, machine-level
2840       debuggers, profiling tools, and disassembly tools need to map
2841       images accurately. For example, setting an ARM breakpoint on a
2842       Thumb location, or in a literal pool, can crash the program
2843       being debugged, ruining the debugging session.
2844
2845       ARM ELF entities are mapped (see section 4.4.7.1 below) and
2846       tagged (see section 4.4.7.2 below) using local symbols (with
2847       binding STB_LOCAL).  To assist consumers, mapping and tagging
2848       symbols should be collated first in the symbol table, before
2849       other symbols with binding STB_LOCAL.
2850
2851       To allow properly collated mapping and tagging symbols to be
2852       skipped by consumers that have no interest in them, the first
2853       such symbol should have the name $m and its st_value field equal
2854       to the total number of mapping and tagging symbols (including
2855       the $m) in the symbol table.
2856
2857       4.4.7.1 Mapping symbols
2858
2859       $a    Labels the first byte of a sequence of ARM instructions.
2860             Its type is STT_FUNC.
2861
2862       $d    Labels the first byte of a sequence of data items.
2863             Its type is STT_OBJECT.
2864
2865       $t    Labels the first byte of a sequence of Thumb instructions.
2866             Its type is STT_FUNC.
2867
2868       This list of mapping symbols may be extended in the future.
2869
2870       Section-relative mapping symbols
2871
2872       Mapping symbols defined in a section define a sequence of
2873       half-open address intervals that cover the address range of the
2874       section. Each interval starts at the address defined by a
2875       mapping symbol, and continues up to, but not including, the
2876       address defined by the next (in address order) mapping symbol or
2877       the end of the section. A corollary is that there must be a
2878       mapping symbol defined at the beginning of each section.
2879       Consumers can ignore the size of a section-relative mapping
2880       symbol. Producers can set it to 0.
2881
2882       Absolute mapping symbols
2883
2884       Because of the need to crystallize a Thumb address with the
2885       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2886       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2887       or $t.
2888
2889       The extent of a mapping symbol defined in SHN_ABS is [st_value,
2890       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2891       where [x, y) denotes the half-open address range from x,
2892       inclusive, to y, exclusive.
2893
2894       In the absence of a mapping symbol, a consumer can interpret a
2895       function symbol with an odd value as the Thumb code address
2896       obtained by clearing the least significant bit of the
2897       value. This interpretation is deprecated, and it may not work in
2898       the future.
2899
2900    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2901    the EABI (which is still under development), so they are not
2902    implemented here.  */
2903
2904 static void
2905 mapping_state (enum mstate state)
2906 {
2907   static enum mstate mapstate = MAP_DATA;
2908   symbolS * symbolP;
2909   const char * symname;
2910   int type;
2911
2912   if (mapstate == state)
2913     /* The mapping symbol has already been emitted.
2914        There is nothing else to do.  */
2915     return;
2916
2917   mapstate = state;
2918
2919   switch (state)
2920     {
2921     case MAP_DATA:
2922       symname = "$d";
2923       type = BSF_OBJECT;
2924       break;
2925     case MAP_ARM:
2926       symname = "$a";
2927       type = BSF_FUNCTION;
2928       break;
2929     case MAP_THUMB:
2930       symname = "$t";
2931       type = BSF_FUNCTION;
2932       break;
2933     default:
2934       abort ();
2935     }
2936
2937   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2938   symbol_table_insert (symbolP);
2939   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2940   
2941   switch (state)
2942     {
2943     case MAP_ARM:
2944       THUMB_SET_FUNC (symbolP, 0);
2945       ARM_SET_THUMB (symbolP, 0);
2946       ARM_SET_INTERWORK (symbolP, support_interwork);
2947       break;
2948       
2949     case MAP_THUMB:
2950       THUMB_SET_FUNC (symbolP, 1);
2951       ARM_SET_THUMB (symbolP, 1);
2952       ARM_SET_INTERWORK (symbolP, support_interwork);
2953       break;
2954       
2955     case MAP_DATA:
2956     default:
2957       return;
2958     }
2959 }
2960
2961 /* When we change sections we need to issue a new mapping symbol.  */
2962
2963 void
2964 arm_elf_change_section (void)
2965 {
2966   flagword flags;
2967
2968   if (!SEG_NORMAL (now_seg))
2969     return;
2970
2971   flags = bfd_get_section_flags (stdoutput, now_seg);
2972
2973   /* We can ignore sections that only contain debug info.  */
2974   if ((flags & SEC_ALLOC) == 0)
2975     return;
2976
2977   if (flags & SEC_CODE)
2978     {
2979       if (thumb_mode)
2980         mapping_state (MAP_THUMB);
2981       else
2982         mapping_state (MAP_ARM);
2983     }
2984   else
2985     /* This section does not contain code.  Therefore it must contain data.  */
2986     mapping_state (MAP_DATA);    
2987 }
2988 #else
2989 #define mapping_state(a)
2990 #endif /* OBJ_ELF */
2991 \f
2992
2993 static void
2994 s_req (a)
2995      int a ATTRIBUTE_UNUSED;
2996 {
2997   as_bad (_("invalid syntax for .req directive"));
2998 }
2999
3000 /* The .unreq directive deletes an alias which was previously defined
3001    by .req.  For example:
3002
3003        my_alias .req r11
3004        .unreq my_alias    */
3005
3006 static void
3007 s_unreq (int a ATTRIBUTE_UNUSED)
3008 {
3009   char *name;
3010   char saved_char;
3011
3012   skip_whitespace (input_line_pointer);
3013   name = input_line_pointer;
3014
3015   while (*input_line_pointer != 0
3016          && *input_line_pointer != ' '
3017          && *input_line_pointer != '\n')
3018     ++input_line_pointer;
3019
3020   saved_char = *input_line_pointer;
3021   *input_line_pointer = 0;
3022
3023   if (*name)
3024     {
3025       enum arm_reg_type req_type = arm_reg_parse_any (name);
3026
3027       if (req_type != REG_TYPE_MAX)
3028         {
3029           char *temp_name = name;
3030           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3031
3032           if (req_no != FAIL)
3033             {
3034               struct reg_entry *req_entry;
3035
3036               /* Check to see if this alias is a builtin one.  */
3037               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3038
3039               if (!req_entry)
3040                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
3041               else if (req_entry->builtin)
3042                 /* FIXME: We are deleting a built in register alias which
3043                    points to a const data structure, so we only need to
3044                    free up the memory used by the key in the hash table.
3045                    Unfortunately we have not recorded this value, so this
3046                    is a memory leak.  */
3047                   /* FIXME: Should we issue a warning message ?  */
3048                 ;
3049               else
3050                 {
3051                   /* Deleting a user defined alias.  We need to free the
3052                      key and the value, but fortunately the key is the same
3053                      as the value->name field.  */
3054                   free ((char *) req_entry->name);
3055                   free (req_entry);
3056                 }
3057             }
3058           else
3059             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3060         }
3061       else
3062         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3063     }
3064   else
3065     as_bad (_("invalid syntax for .unreq directive"));
3066
3067   *input_line_pointer = saved_char;
3068   demand_empty_rest_of_line ();
3069 }
3070
3071 static void
3072 s_bss (ignore)
3073      int ignore ATTRIBUTE_UNUSED;
3074 {
3075   /* We don't support putting frags in the BSS segment, we fake it by
3076      marking in_bss, then looking at s_skip for clues.  */
3077   subseg_set (bss_section, 0);
3078   demand_empty_rest_of_line ();
3079   mapping_state (MAP_DATA);
3080 }
3081
3082 static void
3083 s_even (ignore)
3084      int ignore ATTRIBUTE_UNUSED;
3085 {
3086   /* Never make frag if expect extra pass.  */
3087   if (!need_pass_2)
3088     frag_align (1, 0, 0);
3089
3090   record_alignment (now_seg, 1);
3091
3092   demand_empty_rest_of_line ();
3093 }
3094
3095 static void
3096 s_ltorg (ignored)
3097      int ignored ATTRIBUTE_UNUSED;
3098 {
3099   unsigned int entry;
3100   literal_pool * pool;
3101   char sym_name[20];
3102
3103   pool = find_literal_pool ();
3104   if (pool == NULL
3105       || pool->symbol == NULL
3106       || pool->next_free_entry == 0)
3107     return;
3108
3109   /* Align pool as you have word accesses.
3110      Only make a frag if we have to.  */
3111   if (!need_pass_2)
3112     frag_align (2, 0, 0);
3113
3114   record_alignment (now_seg, 2);
3115
3116   sprintf (sym_name, "$$lit_\002%x", pool->id);
3117
3118   symbol_locate (pool->symbol, sym_name, now_seg,
3119                  (valueT) frag_now_fix (), frag_now);
3120   symbol_table_insert (pool->symbol);
3121
3122   ARM_SET_THUMB (pool->symbol, thumb_mode);
3123
3124 #if defined OBJ_COFF || defined OBJ_ELF
3125   ARM_SET_INTERWORK (pool->symbol, support_interwork);
3126 #endif
3127
3128   for (entry = 0; entry < pool->next_free_entry; entry ++)
3129     /* First output the expression in the instruction to the pool.  */
3130     emit_expr (&(pool->literals[entry]), 4); /* .word  */
3131
3132   /* Mark the pool as empty.  */
3133   pool->next_free_entry = 0;
3134   pool->symbol = NULL;
3135 }
3136
3137 /* Same as s_align_ptwo but align 0 => align 2.  */
3138
3139 static void
3140 s_align (unused)
3141      int unused ATTRIBUTE_UNUSED;
3142 {
3143   register int temp;
3144   register long temp_fill;
3145   long max_alignment = 15;
3146
3147   temp = get_absolute_expression ();
3148   if (temp > max_alignment)
3149     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3150   else if (temp < 0)
3151     {
3152       as_bad (_("alignment negative. 0 assumed."));
3153       temp = 0;
3154     }
3155
3156   if (*input_line_pointer == ',')
3157     {
3158       input_line_pointer++;
3159       temp_fill = get_absolute_expression ();
3160     }
3161   else
3162     temp_fill = 0;
3163
3164   if (!temp)
3165     temp = 2;
3166
3167   /* Only make a frag if we HAVE to.  */
3168   if (temp && !need_pass_2)
3169     frag_align (temp, (int) temp_fill, 0);
3170   demand_empty_rest_of_line ();
3171
3172   record_alignment (now_seg, temp);
3173 }
3174
3175 static void
3176 s_force_thumb (ignore)
3177      int ignore ATTRIBUTE_UNUSED;
3178 {
3179   /* If we are not already in thumb mode go into it, EVEN if
3180      the target processor does not support thumb instructions.
3181      This is used by gcc/config/arm/lib1funcs.asm for example
3182      to compile interworking support functions even if the
3183      target processor should not support interworking.  */
3184   if (! thumb_mode)
3185     {
3186       thumb_mode = 2;
3187
3188       record_alignment (now_seg, 1);
3189     }
3190
3191   demand_empty_rest_of_line ();
3192 }
3193
3194 static void
3195 s_thumb_func (ignore)
3196      int ignore ATTRIBUTE_UNUSED;
3197 {
3198   if (! thumb_mode)
3199     opcode_select (16);
3200
3201   /* The following label is the name/address of the start of a Thumb function.
3202      We need to know this for the interworking support.  */
3203   label_is_thumb_function_name = TRUE;
3204
3205   demand_empty_rest_of_line ();
3206 }
3207
3208 /* Perform a .set directive, but also mark the alias as
3209    being a thumb function.  */
3210
3211 static void
3212 s_thumb_set (equiv)
3213      int equiv;
3214 {
3215   /* XXX the following is a duplicate of the code for s_set() in read.c
3216      We cannot just call that code as we need to get at the symbol that
3217      is created.  */
3218   register char *    name;
3219   register char      delim;
3220   register char *    end_name;
3221   register symbolS * symbolP;
3222
3223   /* Especial apologies for the random logic:
3224      This just grew, and could be parsed much more simply!
3225      Dean - in haste.  */
3226   name      = input_line_pointer;
3227   delim     = get_symbol_end ();
3228   end_name  = input_line_pointer;
3229   *end_name = delim;
3230
3231   SKIP_WHITESPACE ();
3232
3233   if (*input_line_pointer != ',')
3234     {
3235       *end_name = 0;
3236       as_bad (_("expected comma after name \"%s\""), name);
3237       *end_name = delim;
3238       ignore_rest_of_line ();
3239       return;
3240     }
3241
3242   input_line_pointer++;
3243   *end_name = 0;
3244
3245   if (name[0] == '.' && name[1] == '\0')
3246     {
3247       /* XXX - this should not happen to .thumb_set.  */
3248       abort ();
3249     }
3250
3251   if ((symbolP = symbol_find (name)) == NULL
3252       && (symbolP = md_undefined_symbol (name)) == NULL)
3253     {
3254 #ifndef NO_LISTING
3255       /* When doing symbol listings, play games with dummy fragments living
3256          outside the normal fragment chain to record the file and line info
3257          for this symbol.  */
3258       if (listing & LISTING_SYMBOLS)
3259         {
3260           extern struct list_info_struct * listing_tail;
3261           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3262
3263           memset (dummy_frag, 0, sizeof (fragS));
3264           dummy_frag->fr_type = rs_fill;
3265           dummy_frag->line = listing_tail;
3266           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3267           dummy_frag->fr_symbol = symbolP;
3268         }
3269       else
3270 #endif
3271         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3272
3273 #ifdef OBJ_COFF
3274       /* "set" symbols are local unless otherwise specified.  */
3275       SF_SET_LOCAL (symbolP);
3276 #endif /* OBJ_COFF  */
3277     }                           /* Make a new symbol.  */
3278
3279   symbol_table_insert (symbolP);
3280
3281   * end_name = delim;
3282
3283   if (equiv
3284       && S_IS_DEFINED (symbolP)
3285       && S_GET_SEGMENT (symbolP) != reg_section)
3286     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3287
3288   pseudo_set (symbolP);
3289
3290   demand_empty_rest_of_line ();
3291
3292   /* XXX Now we come to the Thumb specific bit of code.  */
3293
3294   THUMB_SET_FUNC (symbolP, 1);
3295   ARM_SET_THUMB (symbolP, 1);
3296 #if defined OBJ_ELF || defined OBJ_COFF
3297   ARM_SET_INTERWORK (symbolP, support_interwork);
3298 #endif
3299 }
3300
3301 static void
3302 opcode_select (width)
3303      int width;
3304 {
3305   switch (width)
3306     {
3307     case 16:
3308       if (! thumb_mode)
3309         {
3310           if (! (cpu_variant & ARM_EXT_V4T))
3311             as_bad (_("selected processor does not support THUMB opcodes"));
3312
3313           thumb_mode = 1;
3314           /* No need to force the alignment, since we will have been
3315              coming from ARM mode, which is word-aligned.  */
3316           record_alignment (now_seg, 1);
3317         }
3318       mapping_state (MAP_THUMB);
3319       break;
3320
3321     case 32:
3322       if (thumb_mode)
3323         {
3324           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3325             as_bad (_("selected processor does not support ARM opcodes"));
3326
3327           thumb_mode = 0;
3328
3329           if (!need_pass_2)
3330             frag_align (2, 0, 0);
3331
3332           record_alignment (now_seg, 1);
3333         }
3334       mapping_state (MAP_ARM);
3335       break;
3336
3337     default:
3338       as_bad (_("invalid instruction size selected (%d)"), width);
3339     }
3340 }
3341
3342 static void
3343 s_arm (ignore)
3344      int ignore ATTRIBUTE_UNUSED;
3345 {
3346   opcode_select (32);
3347   demand_empty_rest_of_line ();
3348 }
3349
3350 static void
3351 s_thumb (ignore)
3352      int ignore ATTRIBUTE_UNUSED;
3353 {
3354   opcode_select (16);
3355   demand_empty_rest_of_line ();
3356 }
3357
3358 static void
3359 s_code (unused)
3360      int unused ATTRIBUTE_UNUSED;
3361 {
3362   register int temp;
3363
3364   temp = get_absolute_expression ();
3365   switch (temp)
3366     {
3367     case 16:
3368     case 32:
3369       opcode_select (temp);
3370       break;
3371
3372     default:
3373       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3374     }
3375 }
3376
3377 static void
3378 end_of_line (str)
3379      char *str;
3380 {
3381   skip_whitespace (str);
3382
3383   if (*str != '\0' && !inst.error)
3384     inst.error = _("garbage following instruction");
3385 }
3386
3387 static int
3388 skip_past_comma (str)
3389      char ** str;
3390 {
3391   char * p = * str, c;
3392   int comma = 0;
3393
3394   while ((c = *p) == ' ' || c == ',')
3395     {
3396       p++;
3397       if (c == ',' && comma++)
3398         return FAIL;
3399     }
3400
3401   if (c == '\0')
3402     return FAIL;
3403
3404   *str = p;
3405   return comma ? SUCCESS : FAIL;
3406 }
3407
3408 /* A standard register must be given at this point.
3409    SHIFT is the place to put it in inst.instruction.
3410    Restores input start point on error.
3411    Returns the reg#, or FAIL.  */
3412
3413 static int
3414 reg_required_here (str, shift)
3415      char ** str;
3416      int     shift;
3417 {
3418   static char buff [128]; /* XXX  */
3419   int         reg;
3420   char *      start = * str;
3421
3422   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3423     {
3424       if (shift >= 0)
3425         inst.instruction |= reg << shift;
3426       return reg;
3427     }
3428
3429   /* Restore the start point, we may have got a reg of the wrong class.  */
3430   *str = start;
3431
3432   /* In the few cases where we might be able to accept something else
3433      this error can be overridden.  */
3434   sprintf (buff, _("register expected, not '%.100s'"), start);
3435   inst.error = buff;
3436
3437   return FAIL;
3438 }
3439
3440 /* A Intel Wireless MMX technology register
3441    must be given at this point.
3442    Shift is the place to put it in inst.instruction.
3443    Restores input start point on err.
3444    Returns the reg#, or FAIL.  */
3445
3446 static int
3447 wreg_required_here (str, shift, reg_type)
3448      char ** str;
3449      int     shift;
3450      enum wreg_type reg_type;
3451 {
3452   static char buff [128];
3453   int    reg;
3454   char * start = *str;
3455
3456   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3457     {
3458       if (wr_register (reg)
3459           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3460         {
3461           if (shift >= 0)
3462             inst.instruction |= (reg ^ WR_PREFIX) << shift;
3463           return reg;
3464         }
3465       else if (wc_register (reg)
3466                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3467         {
3468           if (shift >= 0)
3469             inst.instruction |= (reg ^ WC_PREFIX) << shift;
3470           return reg;
3471         }
3472       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3473         {
3474           if (shift >= 0)
3475             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3476           return reg;
3477         }
3478     }
3479
3480   /* Restore the start point, we may have got a reg of the wrong class.  */
3481   *str = start;
3482
3483   /* In the few cases where we might be able to accept
3484      something else this error can be overridden.  */
3485   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3486   inst.error = buff;
3487
3488   return FAIL;
3489 }
3490
3491 static const struct asm_psr *
3492 arm_psr_parse (ccp)
3493      register char ** ccp;
3494 {
3495   char * start = * ccp;
3496   char   c;
3497   char * p;
3498   const struct asm_psr * psr;
3499
3500   p = start;
3501
3502   /* Skip to the end of the next word in the input stream.  */
3503   do
3504     {
3505       c = *p++;
3506     }
3507   while (ISALPHA (c) || c == '_');
3508
3509   /* Terminate the word.  */
3510   *--p = 0;
3511
3512   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3513      feature for ease of use and backwards compatibility.  */
3514   if (!strncmp (start, "cpsr", 4))
3515     strncpy (start, "CPSR", 4);
3516   else if (!strncmp (start, "spsr", 4))
3517     strncpy (start, "SPSR", 4);
3518
3519   /* Now locate the word in the psr hash table.  */
3520   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3521
3522   /* Restore the input stream.  */
3523   *p = c;
3524
3525   /* If we found a valid match, advance the
3526      stream pointer past the end of the word.  */
3527   *ccp = p;
3528
3529   return psr;
3530 }
3531
3532 /* Parse the input looking for a PSR flag.  */
3533
3534 static int
3535 psr_required_here (str)
3536      char ** str;
3537 {
3538   char * start = * str;
3539   const struct asm_psr * psr;
3540
3541   psr = arm_psr_parse (str);
3542
3543   if (psr)
3544     {
3545       /* If this is the SPSR that is being modified, set the R bit.  */
3546       if (! psr->cpsr)
3547         inst.instruction |= SPSR_BIT;
3548
3549       /* Set the psr flags in the MSR instruction.  */
3550       inst.instruction |= psr->field << PSR_SHIFT;
3551
3552       return SUCCESS;
3553     }
3554
3555   /* In the few cases where we might be able to accept
3556      something else this error can be overridden.  */
3557   inst.error = _("flag for {c}psr instruction expected");
3558
3559   /* Restore the start point.  */
3560   *str = start;
3561   return FAIL;
3562 }
3563
3564 static int
3565 co_proc_number (str)
3566      char **str;
3567 {
3568   int processor, pchar;
3569   char *start;
3570
3571   skip_whitespace (*str);
3572   start = *str;
3573
3574   /* The data sheet seems to imply that just a number on its own is valid
3575      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3576      accept either.  */
3577   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3578       == FAIL)
3579     {
3580       *str = start;
3581
3582       pchar = *(*str)++;
3583       if (pchar >= '0' && pchar <= '9')
3584         {
3585           processor = pchar - '0';
3586           if (**str >= '0' && **str <= '9')
3587             {
3588               processor = processor * 10 + *(*str)++ - '0';
3589               if (processor > 15)
3590                 {
3591                   inst.error = _("illegal co-processor number");
3592                   return FAIL;
3593                 }
3594             }
3595         }
3596       else
3597         {
3598           inst.error = _("bad or missing co-processor number");
3599           return FAIL;
3600         }
3601     }
3602
3603   inst.instruction |= processor << 8;
3604   return SUCCESS;
3605 }
3606
3607 static int
3608 cp_opc_expr (str, where, length)
3609      char ** str;
3610      int where;
3611      int length;
3612 {
3613   expressionS expr;
3614
3615   skip_whitespace (* str);
3616
3617   memset (&expr, '\0', sizeof (expr));
3618
3619   if (my_get_expression (&expr, str))
3620     return FAIL;
3621   if (expr.X_op != O_constant)
3622     {
3623       inst.error = _("bad or missing expression");
3624       return FAIL;
3625     }
3626
3627   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3628     {
3629       inst.error = _("immediate co-processor expression too large");
3630       return FAIL;
3631     }
3632
3633   inst.instruction |= expr.X_add_number << where;
3634   return SUCCESS;
3635 }
3636
3637 static int
3638 cp_reg_required_here (str, where)
3639      char ** str;
3640      int     where;
3641 {
3642   int    reg;
3643   char * start = *str;
3644
3645   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3646     {
3647       inst.instruction |= reg << where;
3648       return reg;
3649     }
3650
3651   /* In the few cases where we might be able to accept something else
3652      this error can be overridden.  */
3653   inst.error = _("co-processor register expected");
3654
3655   /* Restore the start point.  */
3656   *str = start;
3657   return FAIL;
3658 }
3659
3660 static int
3661 fp_reg_required_here (str, where)
3662      char ** str;
3663      int     where;
3664 {
3665   int    reg;
3666   char * start = * str;
3667
3668   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3669     {
3670       inst.instruction |= reg << where;
3671       return reg;
3672     }
3673
3674   /* In the few cases where we might be able to accept something else
3675      this error can be overridden.  */
3676   inst.error = _("floating point register expected");
3677
3678   /* Restore the start point.  */
3679   *str = start;
3680   return FAIL;
3681 }
3682
3683 static int
3684 cp_address_offset (str)
3685      char ** str;
3686 {
3687   int offset;
3688
3689   skip_whitespace (* str);
3690
3691   if (! is_immediate_prefix (**str))
3692     {
3693       inst.error = _("immediate expression expected");
3694       return FAIL;
3695     }
3696
3697   (*str)++;
3698
3699   if (my_get_expression (& inst.reloc.exp, str))
3700     return FAIL;
3701
3702   if (inst.reloc.exp.X_op == O_constant)
3703     {
3704       offset = inst.reloc.exp.X_add_number;
3705
3706       if (offset & 3)
3707         {
3708           inst.error = _("co-processor address must be word aligned");
3709           return FAIL;
3710         }
3711
3712       if (offset > 1023 || offset < -1023)
3713         {
3714           inst.error = _("offset too large");
3715           return FAIL;
3716         }
3717
3718       if (offset >= 0)
3719         inst.instruction |= INDEX_UP;
3720       else
3721         offset = -offset;
3722
3723       inst.instruction |= offset >> 2;
3724     }
3725   else
3726     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3727
3728   return SUCCESS;
3729 }
3730
3731 static int
3732 cp_address_required_here (str, wb_ok)
3733      char ** str;
3734      int wb_ok;
3735 {
3736   char * p = * str;
3737   int    pre_inc = 0;
3738   int    write_back = 0;
3739
3740   if (*p == '[')
3741     {
3742       int reg;
3743
3744       p++;
3745       skip_whitespace (p);
3746
3747       if ((reg = reg_required_here (& p, 16)) == FAIL)
3748         return FAIL;
3749
3750       skip_whitespace (p);
3751
3752       if (*p == ']')
3753         {
3754           p++;
3755
3756           skip_whitespace (p);
3757
3758           if (*p == '\0')
3759             {
3760               /* As an extension to the official ARM syntax we allow:
3761                  
3762                    [Rn]
3763                    
3764                  as a short hand for:
3765
3766                    [Rn,#0]  */
3767               inst.instruction |= PRE_INDEX | INDEX_UP;
3768               *str = p;
3769               return SUCCESS;
3770             }
3771           
3772           if (skip_past_comma (& p) == FAIL)
3773             {
3774               inst.error = _("comma expected after closing square bracket");
3775               return FAIL;
3776             }
3777
3778           skip_whitespace (p);
3779
3780           if (*p == '#')
3781             {
3782               if (wb_ok)
3783                 {
3784                   /* [Rn], #expr  */
3785                   write_back = WRITE_BACK;
3786
3787                   if (reg == REG_PC)
3788                     {
3789                       inst.error = _("pc may not be used in post-increment");
3790                       return FAIL;
3791                     }
3792
3793                   if (cp_address_offset (& p) == FAIL)
3794                     return FAIL;
3795                 }
3796               else
3797                 pre_inc = PRE_INDEX | INDEX_UP;
3798             }
3799           else if (*p == '{')
3800             {
3801               int option;
3802
3803               /* [Rn], {<expr>}  */
3804               p++;
3805
3806               skip_whitespace (p);
3807
3808               if (my_get_expression (& inst.reloc.exp, & p))
3809                 return FAIL;
3810
3811               if (inst.reloc.exp.X_op == O_constant)
3812                 {
3813                   option = inst.reloc.exp.X_add_number;
3814
3815                   if (option > 255 || option < 0)
3816                     {
3817                       inst.error = _("'option' field too large");
3818                       return FAIL;
3819                     }
3820
3821                   skip_whitespace (p);
3822
3823                   if (*p != '}')
3824                     {
3825                       inst.error = _("'}' expected at end of 'option' field");
3826                       return FAIL;
3827                     }
3828                   else
3829                     {
3830                       p++;
3831                       inst.instruction |= option;
3832                       inst.instruction |= INDEX_UP;
3833                     }
3834                 }
3835               else
3836                 {
3837                   inst.error = _("non-constant expressions for 'option' field not supported");
3838                   return FAIL;
3839                 }
3840             }
3841           else
3842             {
3843               inst.error = _("# or { expected after comma");
3844               return FAIL;            
3845             }
3846         }
3847       else
3848         {
3849           /* '['Rn, #expr']'[!]  */
3850
3851           if (skip_past_comma (& p) == FAIL)
3852             {
3853               inst.error = _("pre-indexed expression expected");
3854               return FAIL;
3855             }
3856
3857           pre_inc = PRE_INDEX;
3858
3859           if (cp_address_offset (& p) == FAIL)
3860             return FAIL;
3861
3862           skip_whitespace (p);
3863
3864           if (*p++ != ']')
3865             {
3866               inst.error = _("missing ]");
3867               return FAIL;
3868             }
3869
3870           skip_whitespace (p);
3871
3872           if (wb_ok && *p == '!')
3873             {
3874               if (reg == REG_PC)
3875                 {
3876                   inst.error = _("pc may not be used with write-back");
3877                   return FAIL;
3878                 }
3879
3880               p++;
3881               write_back = WRITE_BACK;
3882             }
3883         }
3884     }
3885   else
3886     {
3887       if (my_get_expression (&inst.reloc.exp, &p))
3888         return FAIL;
3889
3890       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3891       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3892       inst.reloc.pc_rel = 1;
3893       inst.instruction |= (REG_PC << 16);
3894       pre_inc = PRE_INDEX;
3895     }
3896
3897   inst.instruction |= write_back | pre_inc;
3898   *str = p;
3899   return SUCCESS;
3900 }
3901
3902 static int
3903 cp_byte_address_offset (str)
3904      char ** str;
3905 {
3906   int offset;
3907
3908   skip_whitespace (* str);
3909
3910   if (! is_immediate_prefix (**str))
3911     {
3912       inst.error = _("immediate expression expected");
3913       return FAIL;
3914     }
3915
3916   (*str)++;
3917   
3918   if (my_get_expression (& inst.reloc.exp, str))
3919     return FAIL;
3920   
3921   if (inst.reloc.exp.X_op == O_constant)
3922     {
3923       offset = inst.reloc.exp.X_add_number;
3924       
3925       if (offset > 255 || offset < -255)
3926         {
3927           inst.error = _("offset too large");
3928           return FAIL;
3929         }
3930
3931       if (offset >= 0)
3932         inst.instruction |= INDEX_UP;
3933       else
3934         offset = -offset;
3935
3936       inst.instruction |= offset;
3937     }
3938   else
3939     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3940
3941   return SUCCESS;
3942 }
3943
3944 static int
3945 cp_byte_address_required_here (str)
3946      char ** str;
3947 {
3948   char * p = * str;
3949   int    pre_inc = 0;
3950   int    write_back = 0;
3951
3952   if (*p == '[')
3953     {
3954       int reg;
3955
3956       p++;
3957       skip_whitespace (p);
3958
3959       if ((reg = reg_required_here (& p, 16)) == FAIL)
3960         return FAIL;
3961
3962       skip_whitespace (p);
3963
3964       if (*p == ']')
3965         {
3966           p++;
3967           
3968           if (skip_past_comma (& p) == SUCCESS)
3969             {
3970               /* [Rn], #expr */
3971               write_back = WRITE_BACK;
3972               
3973               if (reg == REG_PC)
3974                 {
3975                   inst.error = _("pc may not be used in post-increment");
3976                   return FAIL;
3977                 }
3978
3979               if (cp_byte_address_offset (& p) == FAIL)
3980                 return FAIL;
3981             }
3982           else
3983             pre_inc = PRE_INDEX | INDEX_UP;
3984         }
3985       else
3986         {
3987           /* '['Rn, #expr']'[!] */
3988
3989           if (skip_past_comma (& p) == FAIL)
3990             {
3991               inst.error = _("pre-indexed expression expected");
3992               return FAIL;
3993             }
3994
3995           pre_inc = PRE_INDEX;
3996           
3997           if (cp_byte_address_offset (& p) == FAIL)
3998             return FAIL;
3999
4000           skip_whitespace (p);
4001
4002           if (*p++ != ']')
4003             {
4004               inst.error = _("missing ]");
4005               return FAIL;
4006             }
4007
4008           skip_whitespace (p);
4009
4010           if (*p == '!')
4011             {
4012               if (reg == REG_PC)
4013                 {
4014                   inst.error = _("pc may not be used with write-back");
4015                   return FAIL;
4016                 }
4017
4018               p++;
4019               write_back = WRITE_BACK;
4020             }
4021         }
4022     }
4023   else
4024     {
4025       if (my_get_expression (&inst.reloc.exp, &p))
4026         return FAIL;
4027
4028       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4029       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
4030       inst.reloc.pc_rel = 1;
4031       inst.instruction |= (REG_PC << 16);
4032       pre_inc = PRE_INDEX;
4033     }
4034
4035   inst.instruction |= write_back | pre_inc;
4036   *str = p;
4037   return SUCCESS;
4038 }
4039
4040 static void
4041 do_empty (str)
4042      char * str;
4043 {
4044   /* Do nothing really.  */
4045   end_of_line (str);
4046 }
4047
4048 static void
4049 do_mrs (str)
4050      char *str;
4051 {
4052   int skip = 0;
4053
4054   /* Only one syntax.  */
4055   skip_whitespace (str);
4056
4057   if (reg_required_here (&str, 12) == FAIL)
4058     {
4059       inst.error = BAD_ARGS;
4060       return;
4061     }
4062
4063   if (skip_past_comma (&str) == FAIL)
4064     {
4065       inst.error = _("comma expected after register name");
4066       return;
4067     }
4068
4069   skip_whitespace (str);
4070
4071   if (   strcmp (str, "CPSR") == 0
4072       || strcmp (str, "SPSR") == 0
4073          /* Lower case versions for backwards compatibility.  */
4074       || strcmp (str, "cpsr") == 0
4075       || strcmp (str, "spsr") == 0)
4076     skip = 4;
4077
4078   /* This is for backwards compatibility with older toolchains.  */
4079   else if (   strcmp (str, "cpsr_all") == 0
4080            || strcmp (str, "spsr_all") == 0)
4081     skip = 8;
4082   else
4083     {
4084       inst.error = _("CPSR or SPSR expected");
4085       return;
4086     }
4087
4088   if (* str == 's' || * str == 'S')
4089     inst.instruction |= SPSR_BIT;
4090   str += skip;
4091
4092   end_of_line (str);
4093 }
4094
4095 /* Two possible forms:
4096       "{C|S}PSR_<field>, Rm",
4097       "{C|S}PSR_f, #expression".  */
4098
4099 static void
4100 do_msr (str)
4101      char * str;
4102 {
4103   skip_whitespace (str);
4104
4105   if (psr_required_here (& str) == FAIL)
4106     return;
4107
4108   if (skip_past_comma (& str) == FAIL)
4109     {
4110       inst.error = _("comma missing after psr flags");
4111       return;
4112     }
4113
4114   skip_whitespace (str);
4115
4116   if (reg_required_here (& str, 0) != FAIL)
4117     {
4118       inst.error = NULL;
4119       end_of_line (str);
4120       return;
4121     }
4122
4123   if (! is_immediate_prefix (* str))
4124     {
4125       inst.error =
4126         _("only a register or immediate value can follow a psr flag");
4127       return;
4128     }
4129
4130   str ++;
4131   inst.error = NULL;
4132
4133   if (my_get_expression (& inst.reloc.exp, & str))
4134     {
4135       inst.error =
4136         _("only a register or immediate value can follow a psr flag");
4137       return;
4138     }
4139
4140 #if 0  /* The first edition of the ARM architecture manual stated that
4141           writing anything other than the flags with an immediate operation
4142           had UNPREDICTABLE effects.  This constraint was removed in the
4143           second edition of the specification.  */
4144   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4145       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4146     {
4147       inst.error = _("immediate value cannot be used to set this field");
4148       return;
4149     }
4150 #endif
4151
4152   inst.instruction |= INST_IMMEDIATE;
4153
4154   if (inst.reloc.exp.X_add_symbol)
4155     {
4156       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4157       inst.reloc.pc_rel = 0;
4158     }
4159   else
4160     {
4161       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4162
4163       if (value == (unsigned) FAIL)
4164         {
4165           inst.error = _("invalid constant");
4166           return;
4167         }
4168
4169       inst.instruction |= value;
4170     }
4171
4172   inst.error = NULL;
4173   end_of_line (str);
4174 }
4175
4176 /* Long Multiply Parser
4177    UMULL RdLo, RdHi, Rm, Rs
4178    SMULL RdLo, RdHi, Rm, Rs
4179    UMLAL RdLo, RdHi, Rm, Rs
4180    SMLAL RdLo, RdHi, Rm, Rs.  */
4181
4182 static void
4183 do_mull (str)
4184      char * str;
4185 {
4186   int rdlo, rdhi, rm, rs;
4187
4188   /* Only one format "rdlo, rdhi, rm, rs".  */
4189   skip_whitespace (str);
4190
4191   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4192     {
4193       inst.error = BAD_ARGS;
4194       return;
4195     }
4196
4197   if (skip_past_comma (&str) == FAIL
4198       || (rdhi = reg_required_here (&str, 16)) == FAIL)
4199     {
4200       inst.error = BAD_ARGS;
4201       return;
4202     }
4203
4204   if (skip_past_comma (&str) == FAIL
4205       || (rm = reg_required_here (&str, 0)) == FAIL)
4206     {
4207       inst.error = BAD_ARGS;
4208       return;
4209     }
4210
4211   /* rdhi, rdlo and rm must all be different.  */
4212   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4213     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4214
4215   if (skip_past_comma (&str) == FAIL
4216       || (rs = reg_required_here (&str, 8)) == FAIL)
4217     {
4218       inst.error = BAD_ARGS;
4219       return;
4220     }
4221
4222   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4223     {
4224       inst.error = BAD_PC;
4225       return;
4226     }
4227
4228   end_of_line (str);
4229 }
4230
4231 static void
4232 do_mul (str)
4233      char * str;
4234 {
4235   int rd, rm;
4236
4237   /* Only one format "rd, rm, rs".  */
4238   skip_whitespace (str);
4239
4240   if ((rd = reg_required_here (&str, 16)) == FAIL)
4241     {
4242       inst.error = BAD_ARGS;
4243       return;
4244     }
4245
4246   if (rd == REG_PC)
4247     {
4248       inst.error = BAD_PC;
4249       return;
4250     }
4251
4252   if (skip_past_comma (&str) == FAIL
4253       || (rm = reg_required_here (&str, 0)) == FAIL)
4254     {
4255       inst.error = BAD_ARGS;
4256       return;
4257     }
4258
4259   if (rm == REG_PC)
4260     {
4261       inst.error = BAD_PC;
4262       return;
4263     }
4264
4265   if (rm == rd)
4266     as_tsktsk (_("rd and rm should be different in mul"));
4267
4268   if (skip_past_comma (&str) == FAIL
4269       || (rm = reg_required_here (&str, 8)) == FAIL)
4270     {
4271       inst.error = BAD_ARGS;
4272       return;
4273     }
4274
4275   if (rm == REG_PC)
4276     {
4277       inst.error = BAD_PC;
4278       return;
4279     }
4280
4281   end_of_line (str);
4282 }
4283
4284 static void
4285 do_mla (str)
4286      char * str;
4287 {
4288   int rd, rm;
4289
4290   /* Only one format "rd, rm, rs, rn".  */
4291   skip_whitespace (str);
4292
4293   if ((rd = reg_required_here (&str, 16)) == FAIL)
4294     {
4295       inst.error = BAD_ARGS;
4296       return;
4297     }
4298
4299   if (rd == REG_PC)
4300     {
4301       inst.error = BAD_PC;
4302       return;
4303     }
4304
4305   if (skip_past_comma (&str) == FAIL
4306       || (rm = reg_required_here (&str, 0)) == FAIL)
4307     {
4308       inst.error = BAD_ARGS;
4309       return;
4310     }
4311
4312   if (rm == REG_PC)
4313     {
4314       inst.error = BAD_PC;
4315       return;
4316     }
4317
4318   if (rm == rd)
4319     as_tsktsk (_("rd and rm should be different in mla"));
4320
4321   if (skip_past_comma (&str) == FAIL
4322       || (rd = reg_required_here (&str, 8)) == FAIL
4323       || skip_past_comma (&str) == FAIL
4324       || (rm = reg_required_here (&str, 12)) == FAIL)
4325     {
4326       inst.error = BAD_ARGS;
4327       return;
4328     }
4329
4330   if (rd == REG_PC || rm == REG_PC)
4331     {
4332       inst.error = BAD_PC;
4333       return;
4334     }
4335
4336   end_of_line (str);
4337 }
4338
4339 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4340    Advances *str to the next non-alphanumeric.
4341    Returns 0, or else FAIL (in which case sets inst.error).
4342
4343   (In a future XScale, there may be accumulators other than zero.
4344   At that time this routine and its callers can be upgraded to suit.)  */
4345
4346 static int
4347 accum0_required_here (str)
4348      char ** str;
4349 {
4350   static char buff [128];       /* Note the address is taken.  Hence, static.  */
4351   char * p = * str;
4352   char   c;
4353   int result = 0;               /* The accum number.  */
4354
4355   skip_whitespace (p);
4356
4357   *str = p;                     /* Advance caller's string pointer too.  */
4358   c = *p++;
4359   while (ISALNUM (c))
4360     c = *p++;
4361
4362   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
4363
4364   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4365     {
4366       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4367       inst.error = buff;
4368       result = FAIL;
4369     }
4370
4371   *p = c;                       /* Unzap.  */
4372   *str = p;                     /* Caller's string pointer to after match.  */
4373   return result;
4374 }
4375
4376 /* Expects **str -> after a comma. May be leading blanks.
4377    Advances *str, recognizing a load  mode, and setting inst.instruction.
4378    Returns rn, or else FAIL (in which case may set inst.error
4379    and not advance str)
4380
4381    Note: doesn't know Rd, so no err checks that require such knowledge.  */
4382
4383 static int
4384 ld_mode_required_here (string)
4385      char ** string;
4386 {
4387   char * str = * string;
4388   int    rn;
4389   int    pre_inc = 0;
4390
4391   skip_whitespace (str);
4392
4393   if (* str == '[')
4394     {
4395       str++;
4396
4397       skip_whitespace (str);
4398
4399       if ((rn = reg_required_here (& str, 16)) == FAIL)
4400         return FAIL;
4401
4402       skip_whitespace (str);
4403
4404       if (* str == ']')
4405         {
4406           str ++;
4407
4408           if (skip_past_comma (& str) == SUCCESS)
4409             {
4410               /* [Rn],... (post inc) */
4411               if (ldst_extend_v4 (&str) == FAIL)
4412                 return FAIL;
4413             }
4414           else        /* [Rn] */
4415             {
4416               skip_whitespace (str);
4417
4418               if (* str == '!')
4419                 {
4420                   str ++;
4421                   inst.instruction |= WRITE_BACK;
4422                 }
4423
4424               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4425               pre_inc = 1;
4426             }
4427         }
4428       else        /* [Rn,...] */
4429         {
4430           if (skip_past_comma (& str) == FAIL)
4431             {
4432               inst.error = _("pre-indexed expression expected");
4433               return FAIL;
4434             }
4435
4436           pre_inc = 1;
4437
4438           if (ldst_extend_v4 (&str) == FAIL)
4439             return FAIL;
4440
4441           skip_whitespace (str);
4442
4443           if (* str ++ != ']')
4444             {
4445               inst.error = _("missing ]");
4446               return FAIL;
4447             }
4448
4449           skip_whitespace (str);
4450
4451           if (* str == '!')
4452             {
4453               str ++;
4454               inst.instruction |= WRITE_BACK;
4455             }
4456         }
4457     }
4458   else if (* str == '=')        /* ldr's "r,=label" syntax */
4459     /* We should never reach here, because <text> = <expression> is
4460        caught gas/read.c read_a_source_file() as a .set operation.  */
4461     return FAIL;
4462   else                          /* PC +- 8 bit immediate offset.  */
4463     {
4464       if (my_get_expression (& inst.reloc.exp, & str))
4465         return FAIL;
4466
4467       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
4468       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4469       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
4470       inst.reloc.pc_rel            = 1;
4471       inst.instruction            |= (REG_PC << 16);
4472
4473       rn = REG_PC;
4474       pre_inc = 1;
4475     }
4476
4477   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4478   * string = str;
4479
4480   return rn;
4481 }
4482
4483 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4484    SMLAxy{cond} Rd,Rm,Rs,Rn
4485    SMLAWy{cond} Rd,Rm,Rs,Rn
4486    Error if any register is R15.  */
4487
4488 static void
4489 do_smla (str)
4490      char *        str;
4491 {
4492   int rd, rm, rs, rn;
4493
4494   skip_whitespace (str);
4495
4496   if ((rd = reg_required_here (& str, 16)) == FAIL
4497       || skip_past_comma (& str) == FAIL
4498       || (rm = reg_required_here (& str, 0)) == FAIL
4499       || skip_past_comma (& str) == FAIL
4500       || (rs = reg_required_here (& str, 8)) == FAIL
4501       || skip_past_comma (& str) == FAIL
4502       || (rn = reg_required_here (& str, 12)) == FAIL)
4503     inst.error = BAD_ARGS;
4504
4505   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4506     inst.error = BAD_PC;
4507
4508   else
4509     end_of_line (str);
4510 }
4511
4512 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4513    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4514    Error if any register is R15.
4515    Warning if Rdlo == Rdhi.  */
4516
4517 static void
4518 do_smlal (str)
4519      char *        str;
4520 {
4521   int rdlo, rdhi, rm, rs;
4522
4523   skip_whitespace (str);
4524
4525   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4526       || skip_past_comma (& str) == FAIL
4527       || (rdhi = reg_required_here (& str, 16)) == FAIL
4528       || skip_past_comma (& str) == FAIL
4529       || (rm = reg_required_here (& str, 0)) == FAIL
4530       || skip_past_comma (& str) == FAIL
4531       || (rs = reg_required_here (& str, 8)) == FAIL)
4532     {
4533       inst.error = BAD_ARGS;
4534       return;
4535     }
4536
4537   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4538     {
4539       inst.error = BAD_PC;
4540       return;
4541     }
4542
4543   if (rdlo == rdhi)
4544     as_tsktsk (_("rdhi and rdlo must be different"));
4545
4546   end_of_line (str);
4547 }
4548
4549 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4550    SMULxy{cond} Rd,Rm,Rs
4551    Error if any register is R15.  */
4552
4553 static void
4554 do_smul (str)
4555      char *        str;
4556 {
4557   int rd, rm, rs;
4558
4559   skip_whitespace (str);
4560
4561   if ((rd = reg_required_here (& str, 16)) == FAIL
4562       || skip_past_comma (& str) == FAIL
4563       || (rm = reg_required_here (& str, 0)) == FAIL
4564       || skip_past_comma (& str) == FAIL
4565       || (rs = reg_required_here (& str, 8)) == FAIL)
4566     inst.error = BAD_ARGS;
4567
4568   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4569     inst.error = BAD_PC;
4570
4571   else
4572     end_of_line (str);
4573 }
4574
4575 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4576    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4577    Error if any register is R15.  */
4578
4579 static void
4580 do_qadd (str)
4581      char *        str;
4582 {
4583   int rd, rm, rn;
4584
4585   skip_whitespace (str);
4586
4587   if ((rd = reg_required_here (& str, 12)) == FAIL
4588       || skip_past_comma (& str) == FAIL
4589       || (rm = reg_required_here (& str, 0)) == FAIL
4590       || skip_past_comma (& str) == FAIL
4591       || (rn = reg_required_here (& str, 16)) == FAIL)
4592     inst.error = BAD_ARGS;
4593
4594   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4595     inst.error = BAD_PC;
4596
4597   else
4598     end_of_line (str);
4599 }
4600
4601 /* ARM V5E (el Segundo)
4602    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4603    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4604
4605    These are equivalent to the XScale instructions MAR and MRA,
4606    respectively, when coproc == 0, opcode == 0, and CRm == 0.
4607
4608    Result unpredicatable if Rd or Rn is R15.  */
4609
4610 static void
4611 do_co_reg2c (str)
4612      char *        str;
4613 {
4614   int rd, rn;
4615
4616   skip_whitespace (str);
4617
4618   if (co_proc_number (& str) == FAIL)
4619     {
4620       if (!inst.error)
4621         inst.error = BAD_ARGS;
4622       return;
4623     }
4624
4625   if (skip_past_comma (& str) == FAIL
4626       || cp_opc_expr (& str, 4, 4) == FAIL)
4627     {
4628       if (!inst.error)
4629         inst.error = BAD_ARGS;
4630       return;
4631     }
4632
4633   if (skip_past_comma (& str) == FAIL
4634       || (rd = reg_required_here (& str, 12)) == FAIL)
4635     {
4636       if (!inst.error)
4637         inst.error = BAD_ARGS;
4638       return;
4639     }
4640
4641   if (skip_past_comma (& str) == FAIL
4642       || (rn = reg_required_here (& str, 16)) == FAIL)
4643     {
4644       if (!inst.error)
4645         inst.error = BAD_ARGS;
4646       return;
4647     }
4648
4649   /* Unpredictable result if rd or rn is R15.  */
4650   if (rd == REG_PC || rn == REG_PC)
4651     as_tsktsk
4652       (_("Warning: instruction unpredictable when using r15"));
4653
4654   if (skip_past_comma (& str) == FAIL
4655       || cp_reg_required_here (& str, 0) == FAIL)
4656     {
4657       if (!inst.error)
4658         inst.error = BAD_ARGS;
4659       return;
4660     }
4661
4662   end_of_line (str);
4663 }
4664
4665 /* ARM V5 count-leading-zeroes instruction (argument parse)
4666      CLZ{<cond>} <Rd>, <Rm>
4667      Condition defaults to COND_ALWAYS.
4668      Error if Rd or Rm are R15.  */
4669
4670 static void
4671 do_clz (str)
4672      char *        str;
4673 {
4674   int rd, rm;
4675
4676   skip_whitespace (str);
4677
4678   if (((rd = reg_required_here (& str, 12)) == FAIL)
4679       || (skip_past_comma (& str) == FAIL)
4680       || ((rm = reg_required_here (& str, 0)) == FAIL))
4681     inst.error = BAD_ARGS;
4682
4683   else if (rd == REG_PC || rm == REG_PC )
4684     inst.error = BAD_PC;
4685
4686   else
4687     end_of_line (str);
4688 }
4689
4690 /* ARM V5 (argument parse)
4691      LDC2{L} <coproc>, <CRd>, <addressing mode>
4692      STC2{L} <coproc>, <CRd>, <addressing mode>
4693      Instruction is not conditional, and has 0xf in the condition field.
4694      Otherwise, it's the same as LDC/STC.  */
4695
4696 static void
4697 do_lstc2 (str)
4698      char *        str;
4699 {
4700   skip_whitespace (str);
4701
4702   if (co_proc_number (& str) == FAIL)
4703     {
4704       if (!inst.error)
4705         inst.error = BAD_ARGS;
4706     }
4707   else if (skip_past_comma (& str) == FAIL
4708            || cp_reg_required_here (& str, 12) == FAIL)
4709     {
4710       if (!inst.error)
4711         inst.error = BAD_ARGS;
4712     }
4713   else if (skip_past_comma (& str) == FAIL
4714            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4715     {
4716       if (! inst.error)
4717         inst.error = BAD_ARGS;
4718     }
4719   else
4720     end_of_line (str);
4721 }
4722
4723 /* ARM V5 (argument parse)
4724      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4725      Instruction is not conditional, and has 0xf in the condition field.
4726      Otherwise, it's the same as CDP.  */
4727
4728 static void
4729 do_cdp2 (str)
4730      char *        str;
4731 {
4732   skip_whitespace (str);
4733
4734   if (co_proc_number (& str) == FAIL)
4735     {
4736       if (!inst.error)
4737         inst.error = BAD_ARGS;
4738       return;
4739     }
4740
4741   if (skip_past_comma (& str) == FAIL
4742       || cp_opc_expr (& str, 20,4) == FAIL)
4743     {
4744       if (!inst.error)
4745         inst.error = BAD_ARGS;
4746       return;
4747     }
4748
4749   if (skip_past_comma (& str) == FAIL
4750       || cp_reg_required_here (& str, 12) == FAIL)
4751     {
4752       if (!inst.error)
4753         inst.error = BAD_ARGS;
4754       return;
4755     }
4756
4757   if (skip_past_comma (& str) == FAIL
4758       || cp_reg_required_here (& str, 16) == FAIL)
4759     {
4760       if (!inst.error)
4761         inst.error = BAD_ARGS;
4762       return;
4763     }
4764
4765   if (skip_past_comma (& str) == FAIL
4766       || cp_reg_required_here (& str, 0) == FAIL)
4767     {
4768       if (!inst.error)
4769         inst.error = BAD_ARGS;
4770       return;
4771     }
4772
4773   if (skip_past_comma (& str) == SUCCESS)
4774     {
4775       if (cp_opc_expr (& str, 5, 3) == FAIL)
4776         {
4777           if (!inst.error)
4778             inst.error = BAD_ARGS;
4779           return;
4780         }
4781     }
4782
4783   end_of_line (str);
4784 }
4785
4786 /* ARM V5 (argument parse)
4787      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4788      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4789      Instruction is not conditional, and has 0xf in the condition field.
4790      Otherwise, it's the same as MCR/MRC.  */
4791
4792 static void
4793 do_co_reg2 (str)
4794      char *        str;
4795 {
4796   skip_whitespace (str);
4797
4798   if (co_proc_number (& str) == FAIL)
4799     {
4800       if (!inst.error)
4801         inst.error = BAD_ARGS;
4802       return;
4803     }
4804
4805   if (skip_past_comma (& str) == FAIL
4806       || cp_opc_expr (& str, 21, 3) == FAIL)
4807     {
4808       if (!inst.error)
4809         inst.error = BAD_ARGS;
4810       return;
4811     }
4812
4813   if (skip_past_comma (& str) == FAIL
4814       || reg_required_here (& str, 12) == FAIL)
4815     {
4816       if (!inst.error)
4817         inst.error = BAD_ARGS;
4818       return;
4819     }
4820
4821   if (skip_past_comma (& str) == FAIL
4822       || cp_reg_required_here (& str, 16) == FAIL)
4823     {
4824       if (!inst.error)
4825         inst.error = BAD_ARGS;
4826       return;
4827     }
4828
4829   if (skip_past_comma (& str) == FAIL
4830       || cp_reg_required_here (& str, 0) == FAIL)
4831     {
4832       if (!inst.error)
4833         inst.error = BAD_ARGS;
4834       return;
4835     }
4836
4837   if (skip_past_comma (& str) == SUCCESS)
4838     {
4839       if (cp_opc_expr (& str, 5, 3) == FAIL)
4840         {
4841           if (!inst.error)
4842             inst.error = BAD_ARGS;
4843           return;
4844         }
4845     }
4846
4847   end_of_line (str);
4848 }
4849
4850 /* ARM v5TEJ.  Jump to Jazelle code.  */
4851 static void
4852 do_bxj (str)
4853      char * str;
4854 {
4855   int reg;
4856
4857   skip_whitespace (str);
4858
4859   if ((reg = reg_required_here (&str, 0)) == FAIL)
4860     {
4861       inst.error = BAD_ARGS;
4862       return;
4863     }
4864
4865   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4866   if (reg == REG_PC)
4867     as_tsktsk (_("use of r15 in bxj is not really useful"));
4868
4869   end_of_line (str);
4870 }
4871
4872 /* ARM V6 umaal (argument parse). */
4873
4874 static void
4875 do_umaal (str)
4876      char *str;
4877 {
4878
4879   int rdlo, rdhi, rm, rs;
4880
4881   skip_whitespace (str);
4882   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4883       || skip_past_comma (& str) == FAIL
4884       || (rdhi = reg_required_here (& str, 16)) == FAIL
4885       || skip_past_comma (& str) == FAIL
4886       || (rm = reg_required_here (& str, 0)) == FAIL
4887       || skip_past_comma (& str) == FAIL
4888       || (rs = reg_required_here (& str, 8)) == FAIL)
4889     {
4890       inst.error = BAD_ARGS;
4891       return;      
4892     }
4893
4894   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4895     {
4896       inst.error = BAD_PC;
4897       return;
4898     }
4899
4900   end_of_line (str);
4901 }
4902
4903 /* ARM V6 strex (argument parse). */
4904
4905 static void 
4906 do_strex (str)
4907      char *str;
4908 {
4909   int rd, rm, rn;
4910
4911   /* Parse Rd, Rm,. */
4912   skip_whitespace (str);
4913   if ((rd = reg_required_here (& str, 12)) == FAIL
4914       || skip_past_comma (& str) == FAIL
4915       || (rm = reg_required_here (& str, 0)) == FAIL
4916       || skip_past_comma (& str) == FAIL)
4917     {
4918       inst.error = BAD_ARGS;
4919       return;
4920     }
4921   if (rd == REG_PC || rm == REG_PC)
4922     {
4923       inst.error = BAD_PC;
4924       return;
4925     }
4926   if (rd == rm)
4927     {
4928       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4929       return;
4930     }
4931
4932   /* Skip past '['. */
4933   if ((strlen (str) >= 1) 
4934       && strncmp (str, "[", 1) == 0)
4935     str+=1;
4936   skip_whitespace (str);  
4937
4938   /* Parse Rn. */
4939   if ((rn = reg_required_here (& str, 16)) == FAIL)
4940     {
4941       inst.error = BAD_ARGS;
4942       return;
4943     }
4944   else if (rn == REG_PC)
4945     {
4946       inst.error = BAD_PC;
4947       return;
4948     }
4949   if (rd == rn)
4950     {
4951       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4952       return;
4953     }
4954   skip_whitespace (str);  
4955
4956   /* Skip past ']'. */
4957   if ((strlen (str) >= 1) 
4958       && strncmp (str, "]", 1) == 0)
4959     str+=1;
4960   
4961   end_of_line (str);
4962 }
4963
4964 /* ARM V6 ssat (argument parse). */
4965
4966 static void
4967 do_ssat (str)
4968      char* str;
4969 {
4970   do_sat (&str, /*bias=*/-1);
4971   end_of_line (str);
4972 }
4973
4974 /* ARM V6 usat (argument parse). */
4975
4976 static void
4977 do_usat (str)
4978      char* str;
4979 {
4980   do_sat (&str, /*bias=*/0);
4981   end_of_line (str);
4982 }
4983
4984 static void
4985 do_sat (str, bias)
4986      char **str;
4987      int    bias;
4988 {
4989   int rd, rm;
4990   expressionS expr;
4991
4992   skip_whitespace (*str);
4993   
4994   /* Parse <Rd>, field. */
4995   if ((rd = reg_required_here (str, 12)) == FAIL
4996       || skip_past_comma (str) == FAIL)
4997     {
4998       inst.error = BAD_ARGS;
4999       return;
5000     }
5001   if (rd == REG_PC)
5002     {
5003       inst.error = BAD_PC;
5004       return;
5005     }
5006
5007   /* Parse #<immed>,  field. */
5008   if (is_immediate_prefix (**str))
5009     (*str)++;
5010   else
5011     {
5012       inst.error = _("immediate expression expected");
5013       return;
5014     }
5015   if (my_get_expression (&expr, str))
5016     {
5017       inst.error = _("bad expression");
5018       return;
5019     }
5020   if (expr.X_op != O_constant)
5021     {
5022       inst.error = _("constant expression expected");
5023       return;
5024     }
5025   if (expr.X_add_number + bias < 0
5026       || expr.X_add_number + bias > 31)
5027     {
5028       inst.error = _("immediate value out of range");
5029       return;
5030     }
5031   inst.instruction |= (expr.X_add_number + bias) << 16;
5032   if (skip_past_comma (str) == FAIL)
5033     {
5034       inst.error = BAD_ARGS;
5035       return;
5036     }
5037
5038   /* Parse <Rm> field. */
5039   if ((rm = reg_required_here (str, 0)) == FAIL)
5040     {
5041       inst.error = BAD_ARGS;
5042       return;
5043     }
5044   if (rm == REG_PC)
5045     {
5046       inst.error = BAD_PC;
5047       return;
5048     }
5049
5050   if (skip_past_comma (str) == SUCCESS)
5051     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5052 }
5053
5054 /* ARM V6 ssat16 (argument parse). */
5055
5056 static void
5057 do_ssat16 (str)
5058      char *str;
5059 {
5060   do_sat16 (&str, /*bias=*/-1);
5061   end_of_line (str);
5062 }
5063
5064 static void
5065 do_usat16 (str)
5066      char *str;
5067 {
5068   do_sat16 (&str, /*bias=*/0);
5069   end_of_line (str);
5070 }
5071
5072 static void
5073 do_sat16 (str, bias)
5074      char **str;
5075      int bias;
5076 {
5077   int rd, rm;
5078   expressionS expr;
5079
5080   skip_whitespace (*str);
5081
5082   /* Parse the <Rd> field. */
5083   if ((rd = reg_required_here (str, 12)) == FAIL
5084       || skip_past_comma (str) == FAIL)
5085     {
5086       inst.error = BAD_ARGS;
5087       return;
5088     }
5089   if (rd == REG_PC)
5090     {
5091       inst.error = BAD_PC;
5092       return;
5093     }
5094
5095   /* Parse #<immed>, field. */
5096   if (is_immediate_prefix (**str))
5097     (*str)++;
5098   else
5099     {
5100       inst.error = _("immediate expression expected");
5101       return;
5102     }
5103   if (my_get_expression (&expr, str))
5104     {
5105       inst.error = _("bad expression");
5106       return;
5107     }
5108   if (expr.X_op != O_constant)
5109     {
5110       inst.error = _("constant expression expected");
5111       return;
5112     }
5113   if (expr.X_add_number + bias < 0
5114       || expr.X_add_number + bias > 15)
5115     {
5116       inst.error = _("immediate value out of range");
5117       return;
5118     }
5119   inst.instruction |= (expr.X_add_number + bias) << 16;
5120   if (skip_past_comma (str) == FAIL)
5121     {
5122       inst.error = BAD_ARGS;
5123       return;
5124     }
5125
5126   /* Parse <Rm> field. */
5127   if ((rm = reg_required_here (str, 0)) == FAIL)
5128     {
5129       inst.error = BAD_ARGS;
5130       return;
5131     }
5132   if (rm == REG_PC)
5133     {
5134       inst.error = BAD_PC;
5135       return;
5136     }
5137 }
5138
5139 /* ARM V6 srs (argument parse). */
5140
5141 static void
5142 do_srs (str)
5143      char* str;
5144 {
5145   char *exclam;
5146   skip_whitespace (str);
5147   exclam = strchr (str, '!');
5148   if (exclam)
5149     *exclam = '\0';
5150   do_cps_mode (&str);
5151   if (exclam)
5152     *exclam = '!';
5153   if (*str == '!') 
5154     {
5155       inst.instruction |= WRITE_BACK;
5156       str++;
5157     }
5158   end_of_line (str);
5159 }
5160
5161 /* ARM V6 SMMUL (argument parse). */
5162
5163 static void
5164 do_smmul (str)
5165      char* str;
5166 {
5167   int rd, rm, rs;
5168   
5169   skip_whitespace (str);
5170   if ((rd = reg_required_here (&str, 16)) == FAIL
5171       || skip_past_comma (&str) == FAIL
5172       || (rm = reg_required_here (&str, 0)) == FAIL
5173       || skip_past_comma (&str) == FAIL
5174       || (rs = reg_required_here (&str, 8)) == FAIL)
5175     {
5176       inst.error = BAD_ARGS;
5177       return;
5178     }
5179
5180   if (rd == REG_PC 
5181       || rm == REG_PC
5182       || rs == REG_PC)
5183     {
5184       inst.error = BAD_PC;
5185       return;
5186     }
5187
5188   end_of_line (str);
5189   
5190 }
5191
5192 /* ARM V6 SMLALD (argument parse). */
5193
5194 static void
5195 do_smlald (str)
5196     char* str;
5197 {
5198   int rdlo, rdhi, rm, rs;
5199   skip_whitespace (str);
5200   if ((rdlo = reg_required_here (&str, 12)) == FAIL
5201       || skip_past_comma (&str) == FAIL
5202       || (rdhi = reg_required_here (&str, 16)) == FAIL
5203       || skip_past_comma (&str) == FAIL
5204       || (rm = reg_required_here (&str, 0)) == FAIL
5205       || skip_past_comma (&str) == FAIL
5206       || (rs = reg_required_here (&str, 8)) == FAIL)
5207     {
5208       inst.error = BAD_ARGS;
5209       return;
5210     }
5211
5212   if (rdlo == REG_PC 
5213       || rdhi == REG_PC 
5214       || rm == REG_PC
5215       || rs == REG_PC)
5216     {
5217       inst.error = BAD_PC;
5218       return;
5219     }
5220
5221   end_of_line (str);
5222 }
5223
5224 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
5225    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5226
5227 static void 
5228 do_smlad (str)
5229      char *str;
5230 {
5231   int rd, rm, rs, rn;
5232   
5233   skip_whitespace (str);
5234   if ((rd = reg_required_here (&str, 16)) == FAIL
5235       || skip_past_comma (&str) == FAIL
5236       || (rm = reg_required_here (&str, 0)) == FAIL
5237       || skip_past_comma (&str) == FAIL
5238       || (rs = reg_required_here (&str, 8)) == FAIL
5239       || skip_past_comma (&str) == FAIL
5240       || (rn = reg_required_here (&str, 12)) == FAIL)
5241     {
5242       inst.error = BAD_ARGS;
5243       return;
5244     }
5245   
5246   if (rd == REG_PC 
5247       || rn == REG_PC 
5248       || rs == REG_PC
5249       || rm == REG_PC)
5250     {
5251       inst.error = BAD_PC;
5252       return;
5253     }
5254
5255   end_of_line (str);
5256
5257
5258 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5259    preserving the other bits.
5260
5261    setend <endian_specifier>, where <endian_specifier> is either 
5262    BE or LE. */
5263
5264 static void 
5265 do_setend (str)
5266      char *str;
5267 {
5268   if (do_endian_specifier (str))
5269     inst.instruction |= 0x200;
5270 }
5271
5272 /* Returns true if the endian-specifier indicates big-endianness.  */
5273
5274 static int
5275 do_endian_specifier (str)
5276      char *str;
5277 {
5278   int big_endian = 0;
5279
5280   skip_whitespace (str);
5281   if (strlen (str) < 2)
5282     inst.error = _("missing endian specifier");
5283   else if (strncasecmp (str, "BE", 2) == 0)
5284     {
5285       str += 2;
5286       big_endian = 1;
5287     }
5288   else if (strncasecmp (str, "LE", 2) == 0)
5289     str += 2;
5290   else
5291     inst.error = _("valid endian specifiers are be or le");
5292
5293   end_of_line (str);
5294
5295   return big_endian;
5296 }
5297
5298 /* ARM V6 SXTH.
5299
5300    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5301    Condition defaults to COND_ALWAYS.
5302    Error if any register uses R15. */
5303
5304 static void 
5305 do_sxth (str)
5306      char *str;
5307 {
5308   int rd, rm;
5309   expressionS expr;
5310   int rotation_clear_mask = 0xfffff3ff;
5311   int rotation_eight_mask = 0x00000400;
5312   int rotation_sixteen_mask = 0x00000800;
5313   int rotation_twenty_four_mask = 0x00000c00;
5314   
5315   skip_whitespace (str);
5316   if ((rd = reg_required_here (&str, 12)) == FAIL
5317       || skip_past_comma (&str) == FAIL
5318       || (rm = reg_required_here (&str, 0)) == FAIL)
5319     {
5320       inst.error = BAD_ARGS;
5321       return;
5322     }
5323
5324   else if (rd == REG_PC || rm == REG_PC)
5325     {
5326       inst.error = BAD_PC;
5327       return;
5328     }
5329   
5330   /* Zero out the rotation field. */
5331   inst.instruction &= rotation_clear_mask;
5332   
5333   /* Check for lack of optional rotation field. */
5334   if (skip_past_comma (&str) == FAIL)
5335     {
5336       end_of_line (str);
5337       return;
5338     }
5339   
5340   /* Move past 'ROR'. */
5341   skip_whitespace (str);
5342   if (strncasecmp (str, "ROR", 3) == 0)
5343     str+=3;
5344   else
5345     {
5346       inst.error = _("missing rotation field after comma");
5347       return;
5348     }
5349   
5350   /* Get the immediate constant. */
5351   skip_whitespace (str);
5352   if (is_immediate_prefix (* str))
5353     str++;
5354   else
5355     {
5356       inst.error = _("immediate expression expected");
5357       return;
5358     }
5359   
5360   if (my_get_expression (&expr, &str))
5361     {
5362       inst.error = _("bad expression");
5363       return;
5364     }
5365
5366   if (expr.X_op != O_constant)
5367     {
5368       inst.error = _("constant expression expected");
5369       return;
5370     }
5371   
5372   switch (expr.X_add_number) 
5373     {
5374     case 0:
5375       /* Rotation field has already been zeroed. */
5376       break;
5377     case 8:
5378       inst.instruction |= rotation_eight_mask;
5379       break;
5380
5381     case 16:
5382       inst.instruction |= rotation_sixteen_mask;
5383       break;
5384       
5385     case 24:
5386       inst.instruction |= rotation_twenty_four_mask;
5387       break;
5388
5389     default:
5390       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5391       break;
5392     }
5393
5394   end_of_line (str);
5395   
5396 }
5397
5398 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5399    extends it to 32-bits, and adds the result to a value in another
5400    register.  You can specify a rotation by 0, 8, 16, or 24 bits
5401    before extracting the 16-bit value.
5402    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5403    Condition defaults to COND_ALWAYS.
5404    Error if any register uses R15. */
5405
5406 static void 
5407 do_sxtah (str)
5408      char *str;
5409 {
5410   int rd, rn, rm;
5411   expressionS expr;
5412   int rotation_clear_mask = 0xfffff3ff;
5413   int rotation_eight_mask = 0x00000400;
5414   int rotation_sixteen_mask = 0x00000800;
5415   int rotation_twenty_four_mask = 0x00000c00;
5416   
5417   skip_whitespace (str);
5418   if ((rd = reg_required_here (&str, 12)) == FAIL
5419       || skip_past_comma (&str) == FAIL
5420       || (rn = reg_required_here (&str, 16)) == FAIL
5421       || skip_past_comma (&str) == FAIL
5422       || (rm = reg_required_here (&str, 0)) == FAIL)
5423     {
5424       inst.error = BAD_ARGS;
5425       return;
5426     }
5427
5428   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5429     {
5430       inst.error = BAD_PC;
5431       return;
5432     }
5433   
5434   /* Zero out the rotation field. */
5435   inst.instruction &= rotation_clear_mask;
5436   
5437   /* Check for lack of optional rotation field. */
5438   if (skip_past_comma (&str) == FAIL)
5439     {
5440       end_of_line (str);
5441       return;
5442     }
5443   
5444   /* Move past 'ROR'. */
5445   skip_whitespace (str);
5446   if (strncasecmp (str, "ROR", 3) == 0)
5447     str+=3;
5448   else
5449     {
5450       inst.error = _("missing rotation field after comma");
5451       return;
5452     }
5453   
5454   /* Get the immediate constant. */
5455   skip_whitespace (str);
5456   if (is_immediate_prefix (* str))
5457     str++;
5458   else
5459     {
5460       inst.error = _("immediate expression expected");
5461       return;
5462     }
5463   
5464   if (my_get_expression (&expr, &str))
5465     {
5466       inst.error = _("bad expression");
5467       return;
5468     }
5469
5470   if (expr.X_op != O_constant)
5471     {
5472       inst.error = _("constant expression expected");
5473       return;
5474     }
5475   
5476   switch (expr.X_add_number) 
5477     {
5478     case 0:
5479       /* Rotation field has already been zeroed. */
5480       break;
5481
5482     case 8:
5483       inst.instruction |= rotation_eight_mask;
5484       break;
5485
5486     case 16:
5487       inst.instruction |= rotation_sixteen_mask;
5488       break;
5489       
5490     case 24:
5491       inst.instruction |= rotation_twenty_four_mask;
5492       break;
5493
5494     default:
5495       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5496       break;
5497     }
5498
5499   end_of_line (str);
5500   
5501 }
5502    
5503
5504 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5505    word at the specified address and the following word
5506    respectively. 
5507    Unconditionally executed.
5508    Error if Rn is R15.   
5509 */
5510
5511 static void
5512 do_rfe (str)
5513      char *str;
5514 {
5515   int rn;
5516
5517   skip_whitespace (str);
5518   
5519   if ((rn = reg_required_here (&str, 16)) == FAIL)
5520     return;
5521
5522   if (rn == REG_PC)
5523     {
5524       inst.error = BAD_PC;
5525       return;
5526     }
5527
5528   skip_whitespace (str);
5529   
5530   if (*str == '!')
5531     {
5532       inst.instruction |= WRITE_BACK;
5533       str++;
5534     }
5535   end_of_line (str);
5536 }
5537
5538 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5539    register (argument parse).
5540    REV{<cond>} Rd, Rm.
5541    Condition defaults to COND_ALWAYS.
5542    Error if Rd or Rm are R15. */ 
5543
5544 static void
5545 do_rev (str)
5546      char* str;
5547 {
5548   int rd, rm;
5549
5550   skip_whitespace (str);
5551
5552   if ((rd = reg_required_here (&str, 12)) == FAIL
5553       || skip_past_comma (&str) == FAIL
5554       || (rm = reg_required_here (&str, 0)) == FAIL)
5555     inst.error = BAD_ARGS;
5556
5557   else if (rd == REG_PC || rm == REG_PC)
5558     inst.error = BAD_PC;
5559
5560   else
5561     end_of_line (str);
5562 }
5563
5564 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5565    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
5566    Condition defaults to COND_ALWAYS.
5567    Error if Rd, Rn or Rm are R15.  */
5568
5569 static void
5570 do_qadd16 (str) 
5571      char* str;
5572 {
5573   int rd, rm, rn;
5574
5575   skip_whitespace (str);
5576
5577   if ((rd = reg_required_here (&str, 12)) == FAIL
5578       || skip_past_comma (&str) == FAIL
5579       || (rn = reg_required_here (&str, 16)) == FAIL
5580       || skip_past_comma (&str) == FAIL
5581       || (rm = reg_required_here (&str, 0)) == FAIL)
5582     inst.error = BAD_ARGS;
5583
5584   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5585     inst.error = BAD_PC;
5586
5587   else
5588     end_of_line (str);
5589 }
5590
5591 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5592    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
5593    Condition defaults to COND_ALWAYS.
5594    Error if Rd, Rn or Rm are R15.  */
5595
5596 static void 
5597 do_pkhbt (str)
5598      char* str;
5599 {
5600   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5601 }
5602
5603 /* ARM V6 PKHTB (Argument Parse). */
5604
5605 static void 
5606 do_pkhtb (str)
5607      char* str;
5608 {
5609   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5610 }
5611
5612 static void
5613 do_pkh_core (str, shift)
5614      char* str;
5615      int shift;
5616 {
5617   int rd, rn, rm;
5618
5619   skip_whitespace (str);
5620   if (((rd = reg_required_here (&str, 12)) == FAIL)
5621       || (skip_past_comma (&str) == FAIL)
5622       || ((rn = reg_required_here (&str, 16)) == FAIL)
5623       || (skip_past_comma (&str) == FAIL)
5624       || ((rm = reg_required_here (&str, 0)) == FAIL))
5625     {
5626       inst.error = BAD_ARGS;
5627       return;
5628     }
5629
5630   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5631     {
5632       inst.error = BAD_PC;
5633       return;
5634     }
5635
5636   /* Check for optional shift immediate constant. */
5637   if (skip_past_comma (&str) == FAIL) 
5638     {
5639       if (shift == SHIFT_ASR_IMMEDIATE)
5640         {
5641           /* If the shift specifier is ommited, turn the instruction
5642              into pkhbt rd, rm, rn.  First, switch the instruction
5643              code, and clear the rn and rm fields.  */
5644           inst.instruction &= 0xfff0f010;
5645           /* Now, re-encode the registers.  */
5646           inst.instruction |= (rm << 16) | rn;
5647         }
5648       return;
5649     }
5650
5651   decode_shift (&str, shift);
5652 }
5653
5654 /* ARM V6 Load Register Exclusive instruction (argument parse).
5655    LDREX{<cond>} <Rd, [<Rn>]
5656    Condition defaults to COND_ALWAYS.
5657    Error if Rd or Rn are R15. 
5658    See ARMARMv6 A4.1.27: LDREX. */
5659
5660
5661 static void
5662 do_ldrex (str)
5663      char * str;
5664 {
5665   int rd, rn;
5666
5667   skip_whitespace (str);
5668
5669   /* Parse Rd. */
5670   if (((rd = reg_required_here (&str, 12)) == FAIL)
5671       || (skip_past_comma (&str) == FAIL))
5672     {
5673       inst.error = BAD_ARGS;
5674       return;
5675     }
5676   else if (rd == REG_PC)
5677     {
5678       inst.error = BAD_PC;
5679       return;
5680     }
5681   skip_whitespace (str);  
5682
5683   /* Skip past '['. */
5684   if ((strlen (str) >= 1) 
5685       &&strncmp (str, "[", 1) == 0)
5686     str+=1;
5687   skip_whitespace (str);  
5688
5689   /* Parse Rn. */
5690   if ((rn = reg_required_here (&str, 16)) == FAIL)
5691     {
5692       inst.error = BAD_ARGS;
5693       return;
5694     }
5695   else if (rn == REG_PC)
5696     {
5697       inst.error = BAD_PC;
5698       return;
5699     }
5700   skip_whitespace (str);  
5701
5702   /* Skip past ']'. */
5703   if ((strlen (str) >= 1) 
5704       && strncmp (str, "]", 1) == 0)
5705     str+=1;
5706   
5707   end_of_line (str);
5708 }
5709
5710 /* ARM V6 change processor state instruction (argument parse)
5711       CPS, CPSIE, CSPID . */
5712
5713 static void
5714 do_cps (str)
5715      char * str;
5716 {
5717   do_cps_mode (&str);
5718   end_of_line (str);
5719 }
5720
5721 static void
5722 do_cpsi (str)
5723      char * str;
5724 {
5725   do_cps_flags (&str, /*thumb_p=*/0);
5726
5727   if (skip_past_comma (&str) == SUCCESS)
5728     {
5729       skip_whitespace (str);
5730       do_cps_mode (&str);
5731     }
5732   end_of_line (str);
5733 }
5734
5735 static void
5736 do_cps_mode (str)
5737      char **str;
5738 {
5739   expressionS expr;
5740
5741   skip_whitespace (*str);
5742
5743   if (! is_immediate_prefix (**str))
5744     {
5745       inst.error = _("immediate expression expected");
5746       return;
5747     }
5748
5749   (*str)++; /* Strip off the immediate signifier. */
5750   if (my_get_expression (&expr, str))
5751     {
5752       inst.error = _("bad expression");
5753       return;
5754     }
5755
5756   if (expr.X_op != O_constant)
5757     {
5758       inst.error = _("constant expression expected");
5759       return;
5760     }
5761   
5762   /* The mode is a 5 bit field.  Valid values are 0-31. */
5763   if (((unsigned) expr.X_add_number) > 31
5764       || (inst.reloc.exp.X_add_number) < 0)
5765     {
5766       inst.error = _("invalid constant");
5767       return;
5768     }
5769   
5770   inst.instruction |= expr.X_add_number;
5771 }
5772
5773 static void
5774 do_cps_flags (str, thumb_p)
5775      char **str;
5776      int    thumb_p;
5777 {
5778   struct cps_flag { 
5779     char character;
5780     unsigned long arm_value;
5781     unsigned long thumb_value;
5782   };
5783   static struct cps_flag flag_table[] = {
5784     {'a', 0x100, 0x4 },
5785     {'i', 0x080, 0x2 },
5786     {'f', 0x040, 0x1 }
5787   };
5788
5789   int saw_a_flag = 0;
5790
5791   skip_whitespace (*str);
5792
5793   /* Get the a, f and i flags. */
5794   while (**str && **str != ',')
5795     {
5796       struct cps_flag *p;
5797       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5798       for (p = flag_table; p < q; ++p)
5799         if (strncasecmp (*str, &p->character, 1) == 0)
5800           {
5801             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5802             saw_a_flag = 1;
5803             break;
5804           }
5805       if (p == q)
5806         {
5807           inst.error = _("unrecognized flag");
5808           return;
5809         }
5810       (*str)++;
5811     }
5812   if (!saw_a_flag) 
5813     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5814 }
5815
5816 /* THUMB V5 breakpoint instruction (argument parse)
5817         BKPT <immed_8>.  */
5818
5819 static void
5820 do_t_bkpt (str)
5821      char * str;
5822 {
5823   expressionS expr;
5824   unsigned long number;
5825
5826   skip_whitespace (str);
5827
5828   /* Allow optional leading '#'.  */
5829   if (is_immediate_prefix (*str))
5830     str ++;
5831
5832   memset (& expr, '\0', sizeof (expr));
5833   if (my_get_expression (& expr, & str)
5834       || (expr.X_op != O_constant
5835           /* As a convenience we allow 'bkpt' without an operand.  */
5836           && expr.X_op != O_absent))
5837     {
5838       inst.error = _("bad expression");
5839       return;
5840     }
5841
5842   number = expr.X_add_number;
5843
5844   /* Check it fits an 8 bit unsigned.  */
5845   if (number != (number & 0xff))
5846     {
5847       inst.error = _("immediate value out of range");
5848       return;
5849     }
5850
5851   inst.instruction |= number;
5852
5853   end_of_line (str);
5854 }
5855
5856 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5857    Expects inst.instruction is set for BLX(1).
5858    Note: this is cloned from do_branch, and the reloc changed to be a
5859         new one that can cope with setting one extra bit (the H bit).  */
5860
5861 static void
5862 do_branch25 (str)
5863      char *        str;
5864 {
5865   if (my_get_expression (& inst.reloc.exp, & str))
5866     return;
5867
5868 #ifdef OBJ_ELF
5869   {
5870     char * save_in;
5871
5872     /* ScottB: February 5, 1998 */
5873     /* Check to see of PLT32 reloc required for the instruction.  */
5874
5875     /* arm_parse_reloc() works on input_line_pointer.
5876        We actually want to parse the operands to the branch instruction
5877        passed in 'str'.  Save the input pointer and restore it later.  */
5878     save_in = input_line_pointer;
5879     input_line_pointer = str;
5880
5881     if (inst.reloc.exp.X_op == O_symbol
5882         && *str == '('
5883         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5884       {
5885         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5886         inst.reloc.pc_rel = 0;
5887         /* Modify str to point to after parsed operands, otherwise
5888            end_of_line() will complain about the (PLT) left in str.  */
5889         str = input_line_pointer;
5890       }
5891     else
5892       {
5893         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5894         inst.reloc.pc_rel = 1;
5895       }
5896
5897     input_line_pointer = save_in;
5898   }
5899 #else
5900   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5901   inst.reloc.pc_rel = 1;
5902 #endif /* OBJ_ELF */
5903
5904   end_of_line (str);
5905 }
5906
5907 /* ARM V5 branch-link-exchange instruction (argument parse)
5908      BLX <target_addr>          ie BLX(1)
5909      BLX{<condition>} <Rm>      ie BLX(2)
5910    Unfortunately, there are two different opcodes for this mnemonic.
5911    So, the insns[].value is not used, and the code here zaps values
5912         into inst.instruction.
5913    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5914
5915 static void
5916 do_blx (str)
5917      char *        str;
5918 {
5919   char * mystr = str;
5920   int rm;
5921
5922   skip_whitespace (mystr);
5923   rm = reg_required_here (& mystr, 0);
5924
5925   /* The above may set inst.error.  Ignore his opinion.  */
5926   inst.error = 0;
5927
5928   if (rm != FAIL)
5929     {
5930       /* Arg is a register.
5931          Use the condition code our caller put in inst.instruction.
5932          Pass ourselves off as a BX with a funny opcode.  */
5933       inst.instruction |= 0x012fff30;
5934       do_bx (str);
5935     }
5936   else
5937     {
5938       /* This must be is BLX <target address>, no condition allowed.  */
5939       if (inst.instruction != COND_ALWAYS)
5940         {
5941           inst.error = BAD_COND;
5942           return;
5943         }
5944
5945       inst.instruction = 0xfafffffe;
5946
5947       /* Process like a B/BL, but with a different reloc.
5948          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5949       do_branch25 (str);
5950     }
5951 }
5952
5953 /* ARM V5 Thumb BLX (argument parse)
5954         BLX <target_addr>       which is BLX(1)
5955         BLX <Rm>                which is BLX(2)
5956    Unfortunately, there are two different opcodes for this mnemonic.
5957    So, the tinsns[].value is not used, and the code here zaps values
5958         into inst.instruction.  */
5959
5960 static void
5961 do_t_blx (str)
5962      char * str;
5963 {
5964   char * mystr = str;
5965   int rm;
5966
5967   skip_whitespace (mystr);
5968   inst.instruction = 0x4780;
5969
5970   /* Note that this call is to the ARM register recognizer.  BLX(2)
5971      uses the ARM register space, not the Thumb one, so a call to
5972      thumb_reg() would be wrong.  */
5973   rm = reg_required_here (& mystr, 3);
5974   inst.error = 0;
5975
5976   if (rm != FAIL)
5977     {
5978       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5979       inst.size = 2;
5980     }
5981   else
5982     {
5983       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5984       inst.instruction = 0xf7ffeffe;
5985       inst.size = 4;
5986
5987       if (my_get_expression (& inst.reloc.exp, & mystr))
5988         return;
5989
5990       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5991       inst.reloc.pc_rel = 1;
5992     }
5993
5994   end_of_line (mystr);
5995 }
5996
5997 /* ARM V5 breakpoint instruction (argument parse)
5998      BKPT <16 bit unsigned immediate>
5999      Instruction is not conditional.
6000         The bit pattern given in insns[] has the COND_ALWAYS condition,
6001         and it is an error if the caller tried to override that.  */
6002
6003 static void
6004 do_bkpt (str)
6005      char *        str;
6006 {
6007   expressionS expr;
6008   unsigned long number;
6009
6010   skip_whitespace (str);
6011
6012   /* Allow optional leading '#'.  */
6013   if (is_immediate_prefix (* str))
6014     str++;
6015
6016   memset (& expr, '\0', sizeof (expr));
6017
6018   if (my_get_expression (& expr, & str)
6019       || (expr.X_op != O_constant
6020           /* As a convenience we allow 'bkpt' without an operand.  */
6021           && expr.X_op != O_absent))
6022     {
6023       inst.error = _("bad expression");
6024       return;
6025     }
6026
6027   number = expr.X_add_number;
6028
6029   /* Check it fits a 16 bit unsigned.  */
6030   if (number != (number & 0xffff))
6031     {
6032       inst.error = _("immediate value out of range");
6033       return;
6034     }
6035
6036   /* Top 12 of 16 bits to bits 19:8.  */
6037   inst.instruction |= (number & 0xfff0) << 4;
6038
6039   /* Bottom 4 of 16 bits to bits 3:0.  */
6040   inst.instruction |= number & 0xf;
6041
6042   end_of_line (str);
6043 }
6044
6045 /* THUMB CPS instruction (argument parse).  */
6046
6047 static void
6048 do_t_cps (str)
6049      char *str;
6050 {
6051   do_cps_flags (&str, /*thumb_p=*/1);
6052   end_of_line (str);
6053 }
6054
6055 /* THUMB CPY instruction (argument parse).  */
6056
6057 static void
6058 do_t_cpy (str)
6059      char *str;
6060 {
6061   thumb_mov_compare (str, THUMB_CPY);
6062 }
6063
6064 /* THUMB SETEND instruction (argument parse).  */
6065
6066 static void
6067 do_t_setend (str)
6068      char *str;
6069 {
6070   if (do_endian_specifier (str))
6071     inst.instruction |= 0x8;
6072 }
6073
6074 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6075
6076 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6077
6078 static unsigned long
6079 check_iwmmxt_insn (str, insn_type, immediate_size)
6080      char * str;
6081      enum iwmmxt_insn_type insn_type;
6082      int immediate_size;
6083 {
6084   int reg = 0;
6085   const char *  inst_error;
6086   expressionS expr;
6087   unsigned long number;
6088
6089   inst_error = inst.error;
6090   if (!inst.error)
6091     inst.error = BAD_ARGS;
6092   skip_whitespace (str);
6093
6094   switch (insn_type)
6095     {
6096     case check_rd:
6097       if ((reg = reg_required_here (&str, 12)) == FAIL)
6098         return FAIL;
6099       break;
6100       
6101     case check_wr:
6102        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6103          return FAIL;
6104        break;
6105        
6106     case check_wrwr:
6107       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6108            || skip_past_comma (&str) == FAIL
6109            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6110         return FAIL;
6111       break;
6112       
6113     case check_wrwrwr:
6114       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6115            || skip_past_comma (&str) == FAIL
6116            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6117            || skip_past_comma (&str) == FAIL
6118            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6119         return FAIL;
6120       break;
6121       
6122     case check_wrwrwcg:
6123       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6124            || skip_past_comma (&str) == FAIL
6125            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6126            || skip_past_comma (&str) == FAIL
6127            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6128         return FAIL;
6129       break;
6130       
6131     case check_tbcst:
6132       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6133            || skip_past_comma (&str) == FAIL
6134            || reg_required_here (&str, 12) == FAIL))
6135         return FAIL;
6136       break;
6137       
6138     case check_tmovmsk:
6139       if ((reg_required_here (&str, 12) == FAIL
6140            || skip_past_comma (&str) == FAIL
6141            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6142         return FAIL;
6143       break;
6144       
6145     case check_tmia:
6146       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6147            || skip_past_comma (&str) == FAIL
6148            || reg_required_here (&str, 0) == FAIL
6149            || skip_past_comma (&str) == FAIL
6150            || reg_required_here (&str, 12) == FAIL))
6151         return FAIL;
6152       break;
6153       
6154     case check_tmcrr:
6155       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6156            || skip_past_comma (&str) == FAIL
6157            || reg_required_here (&str, 12) == FAIL
6158            || skip_past_comma (&str) == FAIL
6159            || reg_required_here (&str, 16) == FAIL))
6160         return FAIL;
6161       break;
6162       
6163     case check_tmrrc:
6164       if ((reg_required_here (&str, 12) == FAIL
6165            || skip_past_comma (&str) == FAIL
6166            || reg_required_here (&str, 16) == FAIL
6167            || skip_past_comma (&str) == FAIL
6168            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6169         return FAIL;
6170       break;
6171       
6172     case check_tmcr:
6173       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6174            || skip_past_comma (&str) == FAIL
6175            || reg_required_here (&str, 12) == FAIL))
6176         return FAIL;
6177       break;
6178       
6179     case check_tmrc:
6180       if ((reg_required_here (&str, 12) == FAIL
6181            || skip_past_comma (&str) == FAIL
6182            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6183         return FAIL;
6184       break;
6185       
6186     case check_tinsr:
6187       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6188            || skip_past_comma (&str) == FAIL
6189            || reg_required_here (&str, 12) == FAIL
6190            || skip_past_comma (&str) == FAIL))
6191         return FAIL;
6192       break;
6193       
6194     case check_textrc:
6195       if ((reg_required_here (&str, 12) == FAIL
6196            || skip_past_comma (&str) == FAIL))
6197         return FAIL;
6198       break;
6199       
6200     case check_waligni:
6201       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6202            || skip_past_comma (&str) == FAIL
6203            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6204            || skip_past_comma (&str) == FAIL
6205            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6206            || skip_past_comma (&str) == FAIL))
6207         return FAIL;
6208       break;
6209       
6210     case check_textrm:
6211       if ((reg_required_here (&str, 12) == FAIL
6212            || skip_past_comma (&str) == FAIL
6213            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6214            || skip_past_comma (&str) == FAIL))
6215         return FAIL;
6216       break;
6217       
6218     case check_wshufh:
6219       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6220            || skip_past_comma (&str) == FAIL
6221            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6222            || skip_past_comma (&str) == FAIL))
6223         return FAIL;
6224       break;
6225     }
6226   
6227   if (immediate_size == 0)
6228     {
6229       end_of_line (str);
6230       inst.error = inst_error;
6231       return reg;
6232     }
6233   else
6234     {
6235       skip_whitespace (str);      
6236   
6237       /* Allow optional leading '#'. */
6238       if (is_immediate_prefix (* str))
6239         str++;
6240
6241       memset (& expr, '\0', sizeof (expr));
6242   
6243       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6244         {
6245           inst.error = _("bad or missing expression");
6246           return FAIL;
6247         }
6248   
6249       number = expr.X_add_number;
6250   
6251       if (number != (number & immediate_size))
6252         {
6253           inst.error = _("immediate value out of range");
6254           return FAIL;
6255         }
6256       end_of_line (str);
6257       inst.error = inst_error;
6258       return number;
6259     }
6260 }
6261
6262 static void
6263 do_iwmmxt_byte_addr (str)
6264      char * str;
6265 {
6266   int op = (inst.instruction & 0x300) >> 8;
6267   int reg;
6268
6269   inst.instruction &= ~0x300;
6270   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6271
6272   skip_whitespace (str);
6273
6274   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6275       || skip_past_comma (& str) == FAIL
6276       || cp_byte_address_required_here (&str) == FAIL)
6277     {
6278       if (! inst.error)
6279         inst.error = BAD_ARGS;
6280     }
6281   else
6282     end_of_line (str);
6283
6284   if (wc_register (reg))
6285     {
6286       as_bad (_("non-word size not supported with control register"));
6287       inst.instruction |=  0xf0000100;
6288       inst.instruction &= ~0x00400000;
6289     }
6290 }
6291
6292 static void
6293 do_iwmmxt_tandc (str)
6294      char * str;
6295 {
6296   int reg;
6297
6298   reg = check_iwmmxt_insn (str, check_rd, 0);
6299
6300   if (reg != REG_PC && !inst.error)
6301     inst.error = _("only r15 allowed here");
6302 }
6303
6304 static void
6305 do_iwmmxt_tbcst (str)
6306      char * str;
6307 {
6308   check_iwmmxt_insn (str, check_tbcst, 0);
6309 }
6310
6311 static void
6312 do_iwmmxt_textrc (str)
6313      char * str;
6314 {
6315   unsigned long number;
6316
6317   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6318     return;
6319
6320   inst.instruction |= number & 0x7;
6321 }
6322
6323 static void
6324 do_iwmmxt_textrm (str)
6325      char * str;
6326 {
6327   unsigned long number;
6328
6329   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6330     return;
6331
6332   inst.instruction |= number & 0x7;
6333 }
6334
6335 static void
6336 do_iwmmxt_tinsr (str)
6337      char * str;
6338 {
6339   unsigned long number;
6340
6341   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6342     return;
6343
6344   inst.instruction |= number & 0x7;
6345 }
6346
6347 static void
6348 do_iwmmxt_tmcr (str)
6349      char * str;
6350 {
6351   check_iwmmxt_insn (str, check_tmcr, 0);
6352 }
6353
6354 static void
6355 do_iwmmxt_tmcrr (str)
6356      char * str;
6357 {
6358   check_iwmmxt_insn (str, check_tmcrr, 0);
6359 }
6360
6361 static void
6362 do_iwmmxt_tmia (str)
6363      char * str;
6364 {
6365   check_iwmmxt_insn (str, check_tmia, 0);
6366 }
6367
6368 static void
6369 do_iwmmxt_tmovmsk (str)
6370      char * str;
6371 {
6372   check_iwmmxt_insn (str, check_tmovmsk, 0);
6373 }
6374
6375 static void
6376 do_iwmmxt_tmrc (str)
6377      char * str;
6378 {
6379   check_iwmmxt_insn (str, check_tmrc, 0);
6380 }
6381
6382 static void
6383 do_iwmmxt_tmrrc (str)
6384      char * str;
6385 {
6386   check_iwmmxt_insn (str, check_tmrrc, 0);
6387 }
6388
6389 static void
6390 do_iwmmxt_torc (str)
6391      char * str;
6392 {
6393   check_iwmmxt_insn (str, check_rd, 0);
6394 }
6395
6396 static void
6397 do_iwmmxt_waligni (str)
6398      char * str;
6399 {
6400   unsigned long number;
6401
6402   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6403     return;
6404
6405   inst.instruction |= ((number & 0x7) << 20);
6406 }
6407
6408 static void
6409 do_iwmmxt_wmov (str)
6410      char * str;
6411 {
6412   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6413     return;
6414   
6415   inst.instruction |= ((inst.instruction >> 16) & 0xf);
6416 }
6417
6418 static void
6419 do_iwmmxt_word_addr (str)
6420      char * str;
6421 {
6422   int op = (inst.instruction & 0x300) >> 8;
6423   int reg;
6424
6425   inst.instruction &= ~0x300;
6426   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6427
6428   skip_whitespace (str);
6429
6430   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6431       || skip_past_comma (& str) == FAIL
6432       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6433     {
6434       if (! inst.error)
6435         inst.error = BAD_ARGS;
6436     }
6437   else
6438     end_of_line (str);
6439
6440   if (wc_register (reg))
6441     {
6442       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6443         as_bad (_("conditional execution not supported with control register"));
6444       if (op != 2)
6445         as_bad (_("non-word size not supported with control register"));
6446       inst.instruction |=  0xf0000100;
6447       inst.instruction &= ~0x00400000;
6448     }
6449 }
6450
6451 static void
6452 do_iwmmxt_wrwr (str)
6453      char * str;
6454 {
6455   check_iwmmxt_insn (str, check_wrwr, 0);
6456 }
6457
6458 static void
6459 do_iwmmxt_wrwrwcg (str)
6460      char * str;
6461 {
6462   check_iwmmxt_insn (str, check_wrwrwcg, 0);
6463 }
6464
6465 static void
6466 do_iwmmxt_wrwrwr (str)
6467      char * str;
6468 {
6469   check_iwmmxt_insn (str, check_wrwrwr, 0);
6470 }
6471
6472 static void
6473 do_iwmmxt_wshufh (str)
6474      char * str;
6475 {
6476   unsigned long number;
6477
6478   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6479     return;
6480
6481   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6482 }
6483
6484 static void
6485 do_iwmmxt_wzero (str)
6486      char * str;
6487 {
6488   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6489     return;
6490
6491   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6492 }
6493
6494 /* Xscale multiply-accumulate (argument parse)
6495      MIAcc   acc0,Rm,Rs
6496      MIAPHcc acc0,Rm,Rs
6497      MIAxycc acc0,Rm,Rs.  */
6498
6499 static void
6500 do_xsc_mia (str)
6501      char * str;
6502 {
6503   int rs;
6504   int rm;
6505
6506   if (accum0_required_here (& str) == FAIL)
6507     inst.error = ERR_NO_ACCUM;
6508
6509   else if (skip_past_comma (& str) == FAIL
6510            || (rm = reg_required_here (& str, 0)) == FAIL)
6511     inst.error = BAD_ARGS;
6512
6513   else if (skip_past_comma (& str) == FAIL
6514            || (rs = reg_required_here (& str, 12)) == FAIL)
6515     inst.error = BAD_ARGS;
6516
6517   /* inst.instruction has now been zapped with both rm and rs.  */
6518   else if (rm == REG_PC || rs == REG_PC)
6519     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
6520
6521   else
6522     end_of_line (str);
6523 }
6524
6525 /* Xscale move-accumulator-register (argument parse)
6526
6527      MARcc   acc0,RdLo,RdHi.  */
6528
6529 static void
6530 do_xsc_mar (str)
6531      char * str;
6532 {
6533   int rdlo, rdhi;
6534
6535   if (accum0_required_here (& str) == FAIL)
6536     inst.error = ERR_NO_ACCUM;
6537
6538   else if (skip_past_comma (& str) == FAIL
6539            || (rdlo = reg_required_here (& str, 12)) == FAIL)
6540     inst.error = BAD_ARGS;
6541
6542   else if (skip_past_comma (& str) == FAIL
6543            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6544     inst.error = BAD_ARGS;
6545
6546   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6547   else if (rdlo == REG_PC || rdhi == REG_PC)
6548     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6549
6550   else
6551     end_of_line (str);
6552 }
6553
6554 /* Xscale move-register-accumulator (argument parse)
6555
6556      MRAcc   RdLo,RdHi,acc0.  */
6557
6558 static void
6559 do_xsc_mra (str)
6560      char * str;
6561 {
6562   int rdlo;
6563   int rdhi;
6564
6565   skip_whitespace (str);
6566
6567   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6568     inst.error = BAD_ARGS;
6569
6570   else if (skip_past_comma (& str) == FAIL
6571            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6572     inst.error = BAD_ARGS;
6573
6574   else if  (skip_past_comma (& str) == FAIL
6575             || accum0_required_here (& str) == FAIL)
6576     inst.error = ERR_NO_ACCUM;
6577
6578   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6579   else if (rdlo == rdhi)
6580     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
6581
6582   else if (rdlo == REG_PC || rdhi == REG_PC)
6583     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6584   else
6585     end_of_line (str);
6586 }
6587
6588 /* ARMv5TE: Preload-Cache
6589
6590     PLD <addr_mode>
6591
6592   Syntactically, like LDR with B=1, W=0, L=1.  */
6593
6594 static void
6595 do_pld (str)
6596      char * str;
6597 {
6598   int rd;
6599
6600   skip_whitespace (str);
6601
6602   if (* str != '[')
6603     {
6604       inst.error = _("'[' expected after PLD mnemonic");
6605       return;
6606     }
6607
6608   ++str;
6609   skip_whitespace (str);
6610
6611   if ((rd = reg_required_here (& str, 16)) == FAIL)
6612     return;
6613
6614   skip_whitespace (str);
6615
6616   if (*str == ']')
6617     {
6618       /* [Rn], ... ?  */
6619       ++str;
6620       skip_whitespace (str);
6621
6622       /* Post-indexed addressing is not allowed with PLD.  */
6623       if (skip_past_comma (&str) == SUCCESS)
6624         {
6625           inst.error
6626             = _("post-indexed expression used in preload instruction");
6627           return;
6628         }
6629       else if (*str == '!') /* [Rn]! */
6630         {
6631           inst.error = _("writeback used in preload instruction");
6632           ++str;
6633         }
6634       else /* [Rn] */
6635         inst.instruction |= INDEX_UP | PRE_INDEX;
6636     }
6637   else /* [Rn, ...] */
6638     {
6639       if (skip_past_comma (& str) == FAIL)
6640         {
6641           inst.error = _("pre-indexed expression expected");
6642           return;
6643         }
6644
6645       if (ldst_extend (&str) == FAIL)
6646         return;
6647
6648       skip_whitespace (str);
6649
6650       if (* str != ']')
6651         {
6652           inst.error = _("missing ]");
6653           return;
6654         }
6655
6656       ++ str;
6657       skip_whitespace (str);
6658
6659       if (* str == '!') /* [Rn]! */
6660         {
6661           inst.error = _("writeback used in preload instruction");
6662           ++ str;
6663         }
6664
6665       inst.instruction |= PRE_INDEX;
6666     }
6667
6668   end_of_line (str);
6669 }
6670
6671 /* ARMv5TE load-consecutive (argument parse)
6672    Mode is like LDRH.
6673
6674      LDRccD R, mode
6675      STRccD R, mode.  */
6676
6677 static void
6678 do_ldrd (str)
6679      char * str;
6680 {
6681   int rd;
6682   int rn;
6683
6684   skip_whitespace (str);
6685
6686   if ((rd = reg_required_here (& str, 12)) == FAIL)
6687     {
6688       inst.error = BAD_ARGS;
6689       return;
6690     }
6691
6692   if (skip_past_comma (& str) == FAIL
6693       || (rn = ld_mode_required_here (& str)) == FAIL)
6694     {
6695       if (!inst.error)
6696         inst.error = BAD_ARGS;
6697       return;
6698     }
6699
6700   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6701   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
6702     {
6703       inst.error = _("destination register must be even");
6704       return;
6705     }
6706
6707   if (rd == REG_LR)
6708     {
6709       inst.error = _("r14 not allowed here");
6710       return;
6711     }
6712
6713   if (((rd == rn) || (rd + 1 == rn))
6714       && ((inst.instruction & WRITE_BACK)
6715           || (!(inst.instruction & PRE_INDEX))))
6716     as_warn (_("pre/post-indexing used when modified address register is destination"));
6717
6718   /* For an index-register load, the index register must not overlap the
6719      destination (even if not write-back).  */
6720   if ((inst.instruction & V4_STR_BIT) == 0
6721       && (inst.instruction & HWOFFSET_IMM) == 0)
6722     {
6723       int rm = inst.instruction & 0x0000000f;
6724
6725       if (rm == rd || (rm == rd + 1))
6726         as_warn (_("ldrd destination registers must not overlap index register"));
6727     }
6728
6729   end_of_line (str);
6730 }
6731
6732 /* Returns the index into fp_values of a floating point number,
6733    or -1 if not in the table.  */
6734
6735 static int
6736 my_get_float_expression (str)
6737      char ** str;
6738 {
6739   LITTLENUM_TYPE words[MAX_LITTLENUMS];
6740   char *         save_in;
6741   expressionS    exp;
6742   int            i;
6743   int            j;
6744
6745   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6746
6747   /* Look for a raw floating point number.  */
6748   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6749       && is_end_of_line[(unsigned char) *save_in])
6750     {
6751       for (i = 0; i < NUM_FLOAT_VALS; i++)
6752         {
6753           for (j = 0; j < MAX_LITTLENUMS; j++)
6754             {
6755               if (words[j] != fp_values[i][j])
6756                 break;
6757             }
6758
6759           if (j == MAX_LITTLENUMS)
6760             {
6761               *str = save_in;
6762               return i;
6763             }
6764         }
6765     }
6766
6767   /* Try and parse a more complex expression, this will probably fail
6768      unless the code uses a floating point prefix (eg "0f").  */
6769   save_in = input_line_pointer;
6770   input_line_pointer = *str;
6771   if (expression (&exp) == absolute_section
6772       && exp.X_op == O_big
6773       && exp.X_add_number < 0)
6774     {
6775       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6776          Ditto for 15.  */
6777       if (gen_to_words (words, 5, (long) 15) == 0)
6778         {
6779           for (i = 0; i < NUM_FLOAT_VALS; i++)
6780             {
6781               for (j = 0; j < MAX_LITTLENUMS; j++)
6782                 {
6783                   if (words[j] != fp_values[i][j])
6784                     break;
6785                 }
6786
6787               if (j == MAX_LITTLENUMS)
6788                 {
6789                   *str = input_line_pointer;
6790                   input_line_pointer = save_in;
6791                   return i;
6792                 }
6793             }
6794         }
6795     }
6796
6797   *str = input_line_pointer;
6798   input_line_pointer = save_in;
6799   return -1;
6800 }
6801
6802 /* Return TRUE if anything in the expression is a bignum.  */
6803
6804 static int
6805 walk_no_bignums (sp)
6806      symbolS * sp;
6807 {
6808   if (symbol_get_value_expression (sp)->X_op == O_big)
6809     return 1;
6810
6811   if (symbol_get_value_expression (sp)->X_add_symbol)
6812     {
6813       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6814               || (symbol_get_value_expression (sp)->X_op_symbol
6815                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6816     }
6817
6818   return 0;
6819 }
6820
6821 static int in_my_get_expression = 0;
6822
6823 static int
6824 my_get_expression (ep, str)
6825      expressionS * ep;
6826      char ** str;
6827 {
6828   char * save_in;
6829   segT   seg;
6830
6831   save_in = input_line_pointer;
6832   input_line_pointer = *str;
6833   in_my_get_expression = 1;
6834   seg = expression (ep);
6835   in_my_get_expression = 0;
6836
6837   if (ep->X_op == O_illegal)
6838     {
6839       /* We found a bad expression in md_operand().  */
6840       *str = input_line_pointer;
6841       input_line_pointer = save_in;
6842       return 1;
6843     }
6844
6845 #ifdef OBJ_AOUT
6846   if (seg != absolute_section
6847       && seg != text_section
6848       && seg != data_section
6849       && seg != bss_section
6850       && seg != undefined_section)
6851     {
6852       inst.error = _("bad_segment");
6853       *str = input_line_pointer;
6854       input_line_pointer = save_in;
6855       return 1;
6856     }
6857 #endif
6858
6859   /* Get rid of any bignums now, so that we don't generate an error for which
6860      we can't establish a line number later on.  Big numbers are never valid
6861      in instructions, which is where this routine is always called.  */
6862   if (ep->X_op == O_big
6863       || (ep->X_add_symbol
6864           && (walk_no_bignums (ep->X_add_symbol)
6865               || (ep->X_op_symbol
6866                   && walk_no_bignums (ep->X_op_symbol)))))
6867     {
6868       inst.error = _("invalid constant");
6869       *str = input_line_pointer;
6870       input_line_pointer = save_in;
6871       return 1;
6872     }
6873
6874   *str = input_line_pointer;
6875   input_line_pointer = save_in;
6876   return 0;
6877 }
6878
6879 /* We handle all bad expressions here, so that we can report the faulty
6880    instruction in the error message.  */
6881 void
6882 md_operand (expr)
6883      expressionS *expr;
6884 {
6885   if (in_my_get_expression)
6886     {
6887       expr->X_op = O_illegal;
6888       if (inst.error == NULL)
6889         inst.error = _("bad expression");
6890     }
6891 }
6892
6893 /* KIND indicates what kind of shifts are accepted.  */
6894
6895 static int
6896 decode_shift (str, kind)
6897      char ** str;
6898      int     kind;
6899 {
6900   const struct asm_shift_name * shift;
6901   char * p;
6902   char   c;
6903
6904   skip_whitespace (* str);
6905
6906   for (p = * str; ISALPHA (* p); p ++)
6907     ;
6908
6909   if (p == * str)
6910     {
6911       inst.error = _("shift expression expected");
6912       return FAIL;
6913     }
6914
6915   c = * p;
6916   * p = '\0';
6917   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6918   * p = c;
6919
6920   if (shift == NULL)
6921     {
6922       inst.error = _("shift expression expected");
6923       return FAIL;
6924     }
6925
6926   assert (shift->properties->index == shift_properties[shift->properties->index].index);
6927
6928   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6929       && shift->properties->index != SHIFT_LSL
6930       && shift->properties->index != SHIFT_ASR)
6931     {
6932       inst.error = _("'LSL' or 'ASR' required");
6933       return FAIL;
6934     }
6935   else if (kind == SHIFT_LSL_IMMEDIATE
6936            && shift->properties->index != SHIFT_LSL)
6937     {
6938       inst.error = _("'LSL' required");
6939       return FAIL;
6940     }
6941   else if (kind == SHIFT_ASR_IMMEDIATE
6942            && shift->properties->index != SHIFT_ASR)
6943     {
6944       inst.error = _("'ASR' required");
6945       return FAIL;
6946     }
6947     
6948   if (shift->properties->index == SHIFT_RRX)
6949     {
6950       * str = p;
6951       inst.instruction |= shift->properties->bit_field;
6952       return SUCCESS;
6953     }
6954
6955   skip_whitespace (p);
6956
6957   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6958     {
6959       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6960       * str = p;
6961       return SUCCESS;
6962     }
6963   else if (! is_immediate_prefix (* p))
6964     {
6965       inst.error = (NO_SHIFT_RESTRICT
6966                     ? _("shift requires register or #expression")
6967                     : _("shift requires #expression"));
6968       * str = p;
6969       return FAIL;
6970     }
6971
6972   inst.error = NULL;
6973   p ++;
6974
6975   if (my_get_expression (& inst.reloc.exp, & p))
6976     return FAIL;
6977
6978   /* Validate some simple #expressions.  */
6979   if (inst.reloc.exp.X_op == O_constant)
6980     {
6981       unsigned num = inst.reloc.exp.X_add_number;
6982
6983       /* Reject operations greater than 32.  */
6984       if (num > 32
6985           /* Reject a shift of 0 unless the mode allows it.  */
6986           || (num == 0 && shift->properties->allows_0 == 0)
6987           /* Reject a shift of 32 unless the mode allows it.  */
6988           || (num == 32 && shift->properties->allows_32 == 0)
6989           )
6990         {
6991           /* As a special case we allow a shift of zero for
6992              modes that do not support it to be recoded as an
6993              logical shift left of zero (ie nothing).  We warn
6994              about this though.  */
6995           if (num == 0)
6996             {
6997               as_warn (_("shift of 0 ignored."));
6998               shift = & shift_names[0];
6999               assert (shift->properties->index == SHIFT_LSL);
7000             }
7001           else
7002             {
7003               inst.error = _("invalid immediate shift");
7004               return FAIL;
7005             }
7006         }
7007
7008       /* Shifts of 32 are encoded as 0, for those shifts that
7009          support it.  */
7010       if (num == 32)
7011         num = 0;
7012
7013       inst.instruction |= (num << 7) | shift->properties->bit_field;
7014     }
7015   else
7016     {
7017       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
7018       inst.reloc.pc_rel = 0;
7019       inst.instruction |= shift->properties->bit_field;
7020     }
7021
7022   * str = p;
7023   return SUCCESS;
7024 }
7025
7026 /* Do those data_ops which can take a negative immediate constant
7027    by altering the instruction.  A bit of a hack really.
7028         MOV <-> MVN
7029         AND <-> BIC
7030         ADC <-> SBC
7031         by inverting the second operand, and
7032         ADD <-> SUB
7033         CMP <-> CMN
7034         by negating the second operand.  */
7035
7036 static int
7037 negate_data_op (instruction, value)
7038      unsigned long * instruction;
7039      unsigned long   value;
7040 {
7041   int op, new_inst;
7042   unsigned long negated, inverted;
7043
7044   negated = validate_immediate (-value);
7045   inverted = validate_immediate (~value);
7046
7047   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7048   switch (op)
7049     {
7050       /* First negates.  */
7051     case OPCODE_SUB:             /* ADD <-> SUB  */
7052       new_inst = OPCODE_ADD;
7053       value = negated;
7054       break;
7055
7056     case OPCODE_ADD:
7057       new_inst = OPCODE_SUB;
7058       value = negated;
7059       break;
7060
7061     case OPCODE_CMP:             /* CMP <-> CMN  */
7062       new_inst = OPCODE_CMN;
7063       value = negated;
7064       break;
7065
7066     case OPCODE_CMN:
7067       new_inst = OPCODE_CMP;
7068       value = negated;
7069       break;
7070
7071       /* Now Inverted ops.  */
7072     case OPCODE_MOV:             /* MOV <-> MVN  */
7073       new_inst = OPCODE_MVN;
7074       value = inverted;
7075       break;
7076
7077     case OPCODE_MVN:
7078       new_inst = OPCODE_MOV;
7079       value = inverted;
7080       break;
7081
7082     case OPCODE_AND:             /* AND <-> BIC  */
7083       new_inst = OPCODE_BIC;
7084       value = inverted;
7085       break;
7086
7087     case OPCODE_BIC:
7088       new_inst = OPCODE_AND;
7089       value = inverted;
7090       break;
7091
7092     case OPCODE_ADC:              /* ADC <-> SBC  */
7093       new_inst = OPCODE_SBC;
7094       value = inverted;
7095       break;
7096
7097     case OPCODE_SBC:
7098       new_inst = OPCODE_ADC;
7099       value = inverted;
7100       break;
7101
7102       /* We cannot do anything.  */
7103     default:
7104       return FAIL;
7105     }
7106
7107   if (value == (unsigned) FAIL)
7108     return FAIL;
7109
7110   *instruction &= OPCODE_MASK;
7111   *instruction |= new_inst << DATA_OP_SHIFT;
7112   return value;
7113 }
7114
7115 static int
7116 data_op2 (str)
7117      char ** str;
7118 {
7119   int value;
7120   expressionS expr;
7121
7122   skip_whitespace (* str);
7123
7124   if (reg_required_here (str, 0) != FAIL)
7125     {
7126       if (skip_past_comma (str) == SUCCESS)
7127         /* Shift operation on register.  */
7128         return decode_shift (str, NO_SHIFT_RESTRICT);
7129
7130       return SUCCESS;
7131     }
7132   else
7133     {
7134       /* Immediate expression.  */
7135       if (is_immediate_prefix (**str))
7136         {
7137           (*str)++;
7138           inst.error = NULL;
7139
7140           if (my_get_expression (&inst.reloc.exp, str))
7141             return FAIL;
7142
7143           if (inst.reloc.exp.X_add_symbol)
7144             {
7145               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7146               inst.reloc.pc_rel = 0;
7147             }
7148           else
7149             {
7150               if (skip_past_comma (str) == SUCCESS)
7151                 {
7152                   /* #x, y -- ie explicit rotation by Y.  */
7153                   if (my_get_expression (&expr, str))
7154                     return FAIL;
7155
7156                   if (expr.X_op != O_constant)
7157                     {
7158                       inst.error = _("constant expression expected");
7159                       return FAIL;
7160                     }
7161
7162                   /* Rotate must be a multiple of 2.  */
7163                   if (((unsigned) expr.X_add_number) > 30
7164                       || (expr.X_add_number & 1) != 0
7165                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7166                     {
7167                       inst.error = _("invalid constant");
7168                       return FAIL;
7169                     }
7170                   inst.instruction |= INST_IMMEDIATE;
7171                   inst.instruction |= inst.reloc.exp.X_add_number;
7172                   inst.instruction |= expr.X_add_number << 7;
7173                   return SUCCESS;
7174                 }
7175
7176               /* Implicit rotation, select a suitable one.  */
7177               value = validate_immediate (inst.reloc.exp.X_add_number);
7178
7179               if (value == FAIL)
7180                 {
7181                   /* Can't be done.  Perhaps the code reads something like
7182                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7183                   if ((value = negate_data_op (&inst.instruction,
7184                                                inst.reloc.exp.X_add_number))
7185                       == FAIL)
7186                     {
7187                       inst.error = _("invalid constant");
7188                       return FAIL;
7189                     }
7190                 }
7191
7192               inst.instruction |= value;
7193             }
7194
7195           inst.instruction |= INST_IMMEDIATE;
7196           return SUCCESS;
7197         }
7198
7199       (*str)++;
7200       inst.error = _("register or shift expression expected");
7201       return FAIL;
7202     }
7203 }
7204
7205 static int
7206 fp_op2 (str)
7207      char ** str;
7208 {
7209   skip_whitespace (* str);
7210
7211   if (fp_reg_required_here (str, 0) != FAIL)
7212     return SUCCESS;
7213   else
7214     {
7215       /* Immediate expression.  */
7216       if (*((*str)++) == '#')
7217         {
7218           int i;
7219
7220           inst.error = NULL;
7221
7222           skip_whitespace (* str);
7223
7224           /* First try and match exact strings, this is to guarantee
7225              that some formats will work even for cross assembly.  */
7226
7227           for (i = 0; fp_const[i]; i++)
7228             {
7229               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7230                 {
7231                   char *start = *str;
7232
7233                   *str += strlen (fp_const[i]);
7234                   if (is_end_of_line[(unsigned char) **str])
7235                     {
7236                       inst.instruction |= i + 8;
7237                       return SUCCESS;
7238                     }
7239                   *str = start;
7240                 }
7241             }
7242
7243           /* Just because we didn't get a match doesn't mean that the
7244              constant isn't valid, just that it is in a format that we
7245              don't automatically recognize.  Try parsing it with
7246              the standard expression routines.  */
7247           if ((i = my_get_float_expression (str)) >= 0)
7248             {
7249               inst.instruction |= i + 8;
7250               return SUCCESS;
7251             }
7252
7253           inst.error = _("invalid floating point immediate expression");
7254           return FAIL;
7255         }
7256       inst.error =
7257         _("floating point register or immediate expression expected");
7258       return FAIL;
7259     }
7260 }
7261
7262 static void
7263 do_arit (str)
7264      char * str;
7265 {
7266   skip_whitespace (str);
7267
7268   if (reg_required_here (&str, 12) == FAIL
7269       || skip_past_comma (&str) == FAIL
7270       || reg_required_here (&str, 16) == FAIL
7271       || skip_past_comma (&str) == FAIL
7272       || data_op2 (&str) == FAIL)
7273     {
7274       if (!inst.error)
7275         inst.error = BAD_ARGS;
7276       return;
7277     }
7278
7279   end_of_line (str);
7280 }
7281
7282 static void
7283 do_adr (str)
7284      char * str;
7285 {
7286   /* This is a pseudo-op of the form "adr rd, label" to be converted
7287      into a relative address of the form "add rd, pc, #label-.-8".  */
7288   skip_whitespace (str);
7289
7290   if (reg_required_here (&str, 12) == FAIL
7291       || skip_past_comma (&str) == FAIL
7292       || my_get_expression (&inst.reloc.exp, &str))
7293     {
7294       if (!inst.error)
7295         inst.error = BAD_ARGS;
7296       return;
7297     }
7298
7299   /* Frag hacking will turn this into a sub instruction if the offset turns
7300      out to be negative.  */
7301   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7302 #ifndef TE_WINCE
7303   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7304 #endif
7305   inst.reloc.pc_rel = 1;
7306
7307   end_of_line (str);
7308 }
7309
7310 static void
7311 do_adrl (str)
7312      char * str;
7313 {
7314   /* This is a pseudo-op of the form "adrl rd, label" to be converted
7315      into a relative address of the form:
7316      add rd, pc, #low(label-.-8)"
7317      add rd, rd, #high(label-.-8)"  */
7318
7319   skip_whitespace (str);
7320
7321   if (reg_required_here (&str, 12) == FAIL
7322       || skip_past_comma (&str) == FAIL
7323       || my_get_expression (&inst.reloc.exp, &str))
7324     {
7325       if (!inst.error)
7326         inst.error = BAD_ARGS;
7327
7328       return;
7329     }
7330
7331   end_of_line (str);
7332   /* Frag hacking will turn this into a sub instruction if the offset turns
7333      out to be negative.  */
7334   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7335 #ifndef TE_WINCE  
7336   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7337 #endif
7338   inst.reloc.pc_rel            = 1;
7339   inst.size                    = INSN_SIZE * 2;
7340 }
7341
7342 static void
7343 do_cmp (str)
7344      char * str;
7345 {
7346   skip_whitespace (str);
7347
7348   if (reg_required_here (&str, 16) == FAIL)
7349     {
7350       if (!inst.error)
7351         inst.error = BAD_ARGS;
7352       return;
7353     }
7354
7355   if (skip_past_comma (&str) == FAIL
7356       || data_op2 (&str) == FAIL)
7357     {
7358       if (!inst.error)
7359         inst.error = BAD_ARGS;
7360       return;
7361     }
7362
7363   end_of_line (str);
7364 }
7365
7366 static void
7367 do_mov (str)
7368      char * str;
7369 {
7370   skip_whitespace (str);
7371
7372   if (reg_required_here (&str, 12) == FAIL)
7373     {
7374       if (!inst.error)
7375         inst.error = BAD_ARGS;
7376       return;
7377     }
7378
7379   if (skip_past_comma (&str) == FAIL
7380       || data_op2 (&str) == FAIL)
7381     {
7382       if (!inst.error)
7383         inst.error = BAD_ARGS;
7384       return;
7385     }
7386
7387   end_of_line (str);
7388 }
7389
7390 static int
7391 ldst_extend (str)
7392      char ** str;
7393 {
7394   int add = INDEX_UP;
7395
7396   switch (**str)
7397     {
7398     case '#':
7399     case '$':
7400       (*str)++;
7401       if (my_get_expression (& inst.reloc.exp, str))
7402         return FAIL;
7403
7404       if (inst.reloc.exp.X_op == O_constant)
7405         {
7406           int value = inst.reloc.exp.X_add_number;
7407
7408           if (value < -4095 || value > 4095)
7409             {
7410               inst.error = _("address offset too large");
7411               return FAIL;
7412             }
7413
7414           if (value < 0)
7415             {
7416               value = -value;
7417               add = 0;
7418             }
7419
7420           inst.instruction |= add | value;
7421         }
7422       else
7423         {
7424           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7425           inst.reloc.pc_rel = 0;
7426         }
7427       return SUCCESS;
7428
7429     case '-':
7430       add = 0;
7431       /* Fall through.  */
7432
7433     case '+':
7434       (*str)++;
7435       /* Fall through.  */
7436
7437     default:
7438       if (reg_required_here (str, 0) == FAIL)
7439         return FAIL;
7440
7441       inst.instruction |= add | OFFSET_REG;
7442       if (skip_past_comma (str) == SUCCESS)
7443         return decode_shift (str, SHIFT_IMMEDIATE);
7444
7445       return SUCCESS;
7446     }
7447 }
7448
7449 static void
7450 do_ldst (str)
7451      char *        str;
7452 {
7453   int pre_inc = 0;
7454   int conflict_reg;
7455   int value;
7456
7457   skip_whitespace (str);
7458
7459   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7460     {
7461       if (!inst.error)
7462         inst.error = BAD_ARGS;
7463       return;
7464     }
7465
7466   if (skip_past_comma (&str) == FAIL)
7467     {
7468       inst.error = _("address expected");
7469       return;
7470     }
7471
7472   if (*str == '[')
7473     {
7474       int reg;
7475
7476       str++;
7477
7478       skip_whitespace (str);
7479
7480       if ((reg = reg_required_here (&str, 16)) == FAIL)
7481         return;
7482
7483       /* Conflicts can occur on stores as well as loads.  */
7484       conflict_reg = (conflict_reg == reg);
7485
7486       skip_whitespace (str);
7487
7488       if (*str == ']')
7489         {
7490           str ++;
7491
7492           if (skip_past_comma (&str) == SUCCESS)
7493             {
7494               /* [Rn],... (post inc)  */
7495               if (ldst_extend (&str) == FAIL)
7496                 return;
7497               if (conflict_reg)
7498                 as_warn (_("%s register same as write-back base"),
7499                          ((inst.instruction & LOAD_BIT)
7500                           ? _("destination") : _("source")));
7501             }
7502           else
7503             {
7504               /* [Rn]  */
7505               skip_whitespace (str);
7506
7507               if (*str == '!')
7508                 {
7509                   if (conflict_reg)
7510                     as_warn (_("%s register same as write-back base"),
7511                              ((inst.instruction & LOAD_BIT)
7512                               ? _("destination") : _("source")));
7513                   str++;
7514                   inst.instruction |= WRITE_BACK;
7515                 }
7516
7517               inst.instruction |= INDEX_UP;
7518               pre_inc = 1;
7519             }
7520         }
7521       else
7522         {
7523           /* [Rn,...]  */
7524           if (skip_past_comma (&str) == FAIL)
7525             {
7526               inst.error = _("pre-indexed expression expected");
7527               return;
7528             }
7529
7530           pre_inc = 1;
7531           if (ldst_extend (&str) == FAIL)
7532             return;
7533
7534           skip_whitespace (str);
7535
7536           if (*str++ != ']')
7537             {
7538               inst.error = _("missing ]");
7539               return;
7540             }
7541
7542           skip_whitespace (str);
7543
7544           if (*str == '!')
7545             {
7546               if (conflict_reg)
7547                 as_warn (_("%s register same as write-back base"),
7548                          ((inst.instruction & LOAD_BIT)
7549                           ? _("destination") : _("source")));
7550               str++;
7551               inst.instruction |= WRITE_BACK;
7552             }
7553         }
7554     }
7555   else if (*str == '=')
7556     {
7557       if ((inst.instruction & LOAD_BIT) == 0)
7558         {
7559           inst.error = _("invalid pseudo operation");
7560           return;
7561         }
7562
7563       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7564       str++;
7565
7566       skip_whitespace (str);
7567
7568       if (my_get_expression (&inst.reloc.exp, &str))
7569         return;
7570
7571       if (inst.reloc.exp.X_op != O_constant
7572           && inst.reloc.exp.X_op != O_symbol)
7573         {
7574           inst.error = _("constant expression expected");
7575           return;
7576         }
7577
7578       if (inst.reloc.exp.X_op == O_constant)
7579         {
7580           value = validate_immediate (inst.reloc.exp.X_add_number);
7581
7582           if (value != FAIL)
7583             {
7584               /* This can be done with a mov instruction.  */
7585               inst.instruction &= LITERAL_MASK;
7586               inst.instruction |= (INST_IMMEDIATE
7587                                    | (OPCODE_MOV << DATA_OP_SHIFT));
7588               inst.instruction |= value & 0xfff;
7589               end_of_line (str);
7590               return;
7591             }
7592
7593           value = validate_immediate (~inst.reloc.exp.X_add_number);
7594
7595           if (value != FAIL)
7596             {
7597               /* This can be done with a mvn instruction.  */
7598               inst.instruction &= LITERAL_MASK;
7599               inst.instruction |= (INST_IMMEDIATE
7600                                    | (OPCODE_MVN << DATA_OP_SHIFT));
7601               inst.instruction |= value & 0xfff;
7602               end_of_line (str);
7603               return;
7604             }
7605         }
7606
7607       /* Insert into literal pool.  */
7608       if (add_to_lit_pool () == FAIL)
7609         {
7610           if (!inst.error)
7611             inst.error = _("literal pool insertion failed");
7612           return;
7613         }
7614
7615       /* Change the instruction exp to point to the pool.  */
7616       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7617       inst.reloc.pc_rel = 1;
7618       inst.instruction |= (REG_PC << 16);
7619       pre_inc = 1;
7620     }
7621   else
7622     {
7623       if (my_get_expression (&inst.reloc.exp, &str))
7624         return;
7625
7626       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7627 #ifndef TE_WINCE
7628       /* PC rel adjust.  */
7629       inst.reloc.exp.X_add_number -= 8;
7630 #endif
7631       inst.reloc.pc_rel = 1;
7632       inst.instruction |= (REG_PC << 16);
7633       pre_inc = 1;
7634     }
7635
7636   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7637   end_of_line (str);
7638 }
7639
7640 static void
7641 do_ldstt (str)
7642      char *        str;
7643 {
7644   int conflict_reg;
7645
7646   skip_whitespace (str);
7647
7648   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7649     {
7650       if (!inst.error)
7651         inst.error = BAD_ARGS;
7652       return;
7653     }
7654
7655   if (skip_past_comma (& str) == FAIL)
7656     {
7657       inst.error = _("address expected");
7658       return;
7659     }
7660
7661   if (*str == '[')
7662     {
7663       int reg;
7664
7665       str++;
7666
7667       skip_whitespace (str);
7668
7669       if ((reg = reg_required_here (&str, 16)) == FAIL)
7670         return;
7671
7672       /* ldrt/strt always use post-indexed addressing, so if the base is
7673          the same as Rd, we warn.  */
7674       if (conflict_reg == reg)
7675         as_warn (_("%s register same as write-back base"),
7676                  ((inst.instruction & LOAD_BIT)
7677                   ? _("destination") : _("source")));
7678
7679       skip_whitespace (str);
7680
7681       if (*str == ']')
7682         {
7683           str ++;
7684
7685           if (skip_past_comma (&str) == SUCCESS)
7686             {
7687               /* [Rn],... (post inc)  */
7688               if (ldst_extend (&str) == FAIL)
7689                 return;
7690             }
7691           else
7692             {
7693               /* [Rn]  */
7694               skip_whitespace (str);
7695
7696               /* Skip a write-back '!'.  */
7697               if (*str == '!')
7698                 str++;
7699
7700               inst.instruction |= INDEX_UP;
7701             }
7702         }
7703       else
7704         {
7705           inst.error = _("post-indexed expression expected");
7706           return;
7707         }
7708     }
7709   else
7710     {
7711       inst.error = _("post-indexed expression expected");
7712       return;
7713     }
7714
7715   end_of_line (str);
7716 }
7717
7718 static int
7719 ldst_extend_v4 (str)
7720      char ** str;
7721 {
7722   int add = INDEX_UP;
7723
7724   switch (**str)
7725     {
7726     case '#':
7727     case '$':
7728       (*str)++;
7729       if (my_get_expression (& inst.reloc.exp, str))
7730         return FAIL;
7731
7732       if (inst.reloc.exp.X_op == O_constant)
7733         {
7734           int value = inst.reloc.exp.X_add_number;
7735
7736           if (value < -255 || value > 255)
7737             {
7738               inst.error = _("address offset too large");
7739               return FAIL;
7740             }
7741
7742           if (value < 0)
7743             {
7744               value = -value;
7745               add = 0;
7746             }
7747
7748           /* Halfword and signextension instructions have the
7749              immediate value split across bits 11..8 and bits 3..0.  */
7750           inst.instruction |= (add | HWOFFSET_IMM
7751                                | ((value >> 4) << 8) | (value & 0xF));
7752         }
7753       else
7754         {
7755           inst.instruction |= HWOFFSET_IMM;
7756           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7757           inst.reloc.pc_rel = 0;
7758         }
7759       return SUCCESS;
7760
7761     case '-':
7762       add = 0;
7763       /* Fall through.  */
7764
7765     case '+':
7766       (*str)++;
7767       /* Fall through.  */
7768
7769     default:
7770       if (reg_required_here (str, 0) == FAIL)
7771         return FAIL;
7772
7773       inst.instruction |= add;
7774       return SUCCESS;
7775     }
7776 }
7777
7778 /* Halfword and signed-byte load/store operations.  */
7779 static void
7780 do_ldstv4 (str)
7781      char *        str;
7782 {
7783   int pre_inc = 0;
7784   int conflict_reg;
7785   int value;
7786
7787   skip_whitespace (str);
7788
7789   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7790     {
7791       if (!inst.error)
7792         inst.error = BAD_ARGS;
7793       return;
7794     }
7795
7796   if (skip_past_comma (& str) == FAIL)
7797     {
7798       inst.error = _("address expected");
7799       return;
7800     }
7801
7802   if (*str == '[')
7803     {
7804       int reg;
7805
7806       str++;
7807
7808       skip_whitespace (str);
7809
7810       if ((reg = reg_required_here (&str, 16)) == FAIL)
7811         return;
7812
7813       /* Conflicts can occur on stores as well as loads.  */
7814       conflict_reg = (conflict_reg == reg);
7815
7816       skip_whitespace (str);
7817
7818       if (*str == ']')
7819         {
7820           str ++;
7821
7822           if (skip_past_comma (&str) == SUCCESS)
7823             {
7824               /* [Rn],... (post inc)  */
7825               if (ldst_extend_v4 (&str) == FAIL)
7826                 return;
7827               if (conflict_reg)
7828                 as_warn (_("%s register same as write-back base"),
7829                          ((inst.instruction & LOAD_BIT)
7830                           ? _("destination") : _("source")));
7831             }
7832           else
7833             {
7834               /* [Rn]  */
7835               inst.instruction |= HWOFFSET_IMM;
7836
7837               skip_whitespace (str);
7838
7839               if (*str == '!')
7840                 {
7841                   if (conflict_reg)
7842                     as_warn (_("%s register same as write-back base"),
7843                              ((inst.instruction & LOAD_BIT)
7844                               ? _("destination") : _("source")));
7845                   str++;
7846                   inst.instruction |= WRITE_BACK;
7847                 }
7848
7849               inst.instruction |= INDEX_UP;
7850               pre_inc = 1;
7851             }
7852         }
7853       else
7854         {
7855           /* [Rn,...]  */
7856           if (skip_past_comma (&str) == FAIL)
7857             {
7858               inst.error = _("pre-indexed expression expected");
7859               return;
7860             }
7861
7862           pre_inc = 1;
7863           if (ldst_extend_v4 (&str) == FAIL)
7864             return;
7865
7866           skip_whitespace (str);
7867
7868           if (*str++ != ']')
7869             {
7870               inst.error = _("missing ]");
7871               return;
7872             }
7873
7874           skip_whitespace (str);
7875
7876           if (*str == '!')
7877             {
7878               if (conflict_reg)
7879                 as_warn (_("%s register same as write-back base"),
7880                          ((inst.instruction & LOAD_BIT)
7881                           ? _("destination") : _("source")));
7882               str++;
7883               inst.instruction |= WRITE_BACK;
7884             }
7885         }
7886     }
7887   else if (*str == '=')
7888     {
7889       if ((inst.instruction & LOAD_BIT) == 0)
7890         {
7891           inst.error = _("invalid pseudo operation");
7892           return;
7893         }
7894
7895       /* XXX Does this work correctly for half-word/byte ops?  */
7896       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7897       str++;
7898
7899       skip_whitespace (str);
7900
7901       if (my_get_expression (&inst.reloc.exp, &str))
7902         return;
7903
7904       if (inst.reloc.exp.X_op != O_constant
7905           && inst.reloc.exp.X_op != O_symbol)
7906         {
7907           inst.error = _("constant expression expected");
7908           return;
7909         }
7910
7911       if (inst.reloc.exp.X_op == O_constant)
7912         {
7913           value = validate_immediate (inst.reloc.exp.X_add_number);
7914
7915           if (value != FAIL)
7916             {
7917               /* This can be done with a mov instruction.  */
7918               inst.instruction &= LITERAL_MASK;
7919               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7920               inst.instruction |= value & 0xfff;
7921               end_of_line (str);
7922               return;
7923             }
7924
7925           value = validate_immediate (~ inst.reloc.exp.X_add_number);
7926
7927           if (value != FAIL)
7928             {
7929               /* This can be done with a mvn instruction.  */
7930               inst.instruction &= LITERAL_MASK;
7931               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7932               inst.instruction |= value & 0xfff;
7933               end_of_line (str);
7934               return;
7935             }
7936         }
7937
7938       /* Insert into literal pool.  */
7939       if (add_to_lit_pool () == FAIL)
7940         {
7941           if (!inst.error)
7942             inst.error = _("literal pool insertion failed");
7943           return;
7944         }
7945
7946       /* Change the instruction exp to point to the pool.  */
7947       inst.instruction |= HWOFFSET_IMM;
7948       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7949       inst.reloc.pc_rel = 1;
7950       inst.instruction |= (REG_PC << 16);
7951       pre_inc = 1;
7952     }
7953   else
7954     {
7955       if (my_get_expression (&inst.reloc.exp, &str))
7956         return;
7957
7958       inst.instruction |= HWOFFSET_IMM;
7959       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7960 #ifndef TE_WINCE
7961       /* PC rel adjust.  */
7962       inst.reloc.exp.X_add_number -= 8;
7963 #endif
7964       inst.reloc.pc_rel = 1;
7965       inst.instruction |= (REG_PC << 16);
7966       pre_inc = 1;
7967     }
7968
7969   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7970   end_of_line (str);
7971 }
7972
7973 static long
7974 reg_list (strp)
7975      char ** strp;
7976 {
7977   char * str = * strp;
7978   long   range = 0;
7979   int    another_range;
7980
7981   /* We come back here if we get ranges concatenated by '+' or '|'.  */
7982   do
7983     {
7984       another_range = 0;
7985
7986       if (*str == '{')
7987         {
7988           int in_range = 0;
7989           int cur_reg = -1;
7990
7991           str++;
7992           do
7993             {
7994               int reg;
7995
7996               skip_whitespace (str);
7997
7998               if ((reg = reg_required_here (& str, -1)) == FAIL)
7999                 return FAIL;
8000
8001               if (in_range)
8002                 {
8003                   int i;
8004
8005                   if (reg <= cur_reg)
8006                     {
8007                       inst.error = _("bad range in register list");
8008                       return FAIL;
8009                     }
8010
8011                   for (i = cur_reg + 1; i < reg; i++)
8012                     {
8013                       if (range & (1 << i))
8014                         as_tsktsk
8015                           (_("Warning: duplicated register (r%d) in register list"),
8016                            i);
8017                       else
8018                         range |= 1 << i;
8019                     }
8020                   in_range = 0;
8021                 }
8022
8023               if (range & (1 << reg))
8024                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8025                            reg);
8026               else if (reg <= cur_reg)
8027                 as_tsktsk (_("Warning: register range not in ascending order"));
8028
8029               range |= 1 << reg;
8030               cur_reg = reg;
8031             }
8032           while (skip_past_comma (&str) != FAIL
8033                  || (in_range = 1, *str++ == '-'));
8034           str--;
8035           skip_whitespace (str);
8036
8037           if (*str++ != '}')
8038             {
8039               inst.error = _("missing `}'");
8040               return FAIL;
8041             }
8042         }
8043       else
8044         {
8045           expressionS expr;
8046
8047           if (my_get_expression (&expr, &str))
8048             return FAIL;
8049
8050           if (expr.X_op == O_constant)
8051             {
8052               if (expr.X_add_number
8053                   != (expr.X_add_number & 0x0000ffff))
8054                 {
8055                   inst.error = _("invalid register mask");
8056                   return FAIL;
8057                 }
8058
8059               if ((range & expr.X_add_number) != 0)
8060                 {
8061                   int regno = range & expr.X_add_number;
8062
8063                   regno &= -regno;
8064                   regno = (1 << regno) - 1;
8065                   as_tsktsk
8066                     (_("Warning: duplicated register (r%d) in register list"),
8067                      regno);
8068                 }
8069
8070               range |= expr.X_add_number;
8071             }
8072           else
8073             {
8074               if (inst.reloc.type != 0)
8075                 {
8076                   inst.error = _("expression too complex");
8077                   return FAIL;
8078                 }
8079
8080               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8081               inst.reloc.type = BFD_RELOC_ARM_MULTI;
8082               inst.reloc.pc_rel = 0;
8083             }
8084         }
8085
8086       skip_whitespace (str);
8087
8088       if (*str == '|' || *str == '+')
8089         {
8090           str++;
8091           another_range = 1;
8092         }
8093     }
8094   while (another_range);
8095
8096   *strp = str;
8097   return range;
8098 }
8099
8100 static void
8101 do_ldmstm (str)
8102      char * str;
8103 {
8104   int base_reg;
8105   long range;
8106
8107   skip_whitespace (str);
8108
8109   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8110     return;
8111
8112   if (base_reg == REG_PC)
8113     {
8114       inst.error = _("r15 not allowed as base register");
8115       return;
8116     }
8117
8118   skip_whitespace (str);
8119
8120   if (*str == '!')
8121     {
8122       inst.instruction |= WRITE_BACK;
8123       str++;
8124     }
8125
8126   if (skip_past_comma (&str) == FAIL
8127       || (range = reg_list (&str)) == FAIL)
8128     {
8129       if (! inst.error)
8130         inst.error = BAD_ARGS;
8131       return;
8132     }
8133
8134   if (*str == '^')
8135     {
8136       str++;
8137       inst.instruction |= LDM_TYPE_2_OR_3;
8138     }
8139
8140   if (inst.instruction & WRITE_BACK)
8141     {
8142       /* Check for unpredictable uses of writeback.  */
8143       if (inst.instruction & LOAD_BIT)
8144         {
8145           /* Not allowed in LDM type 2.  */
8146           if ((inst.instruction & LDM_TYPE_2_OR_3)
8147               && ((range & (1 << REG_PC)) == 0))
8148             as_warn (_("writeback of base register is UNPREDICTABLE"));
8149           /* Only allowed if base reg not in list for other types.  */
8150           else if (range & (1 << base_reg))
8151             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8152         }
8153       else /* STM.  */
8154         {
8155           /* Not allowed for type 2.  */
8156           if (inst.instruction & LDM_TYPE_2_OR_3)
8157             as_warn (_("writeback of base register is UNPREDICTABLE"));
8158           /* Only allowed if base reg not in list, or first in list.  */
8159           else if ((range & (1 << base_reg))
8160                    && (range & ((1 << base_reg) - 1)))
8161             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8162         }
8163     }
8164
8165   inst.instruction |= range;
8166   end_of_line (str);
8167 }
8168
8169 static void
8170 do_swi (str)
8171      char * str;
8172 {
8173   skip_whitespace (str);
8174
8175   /* Allow optional leading '#'.  */
8176   if (is_immediate_prefix (*str))
8177     str++;
8178
8179   if (my_get_expression (& inst.reloc.exp, & str))
8180     return;
8181
8182   inst.reloc.type = BFD_RELOC_ARM_SWI;
8183   inst.reloc.pc_rel = 0;
8184   end_of_line (str);
8185 }
8186
8187 static void
8188 do_swap (str)
8189      char * str;
8190 {
8191   int reg;
8192
8193   skip_whitespace (str);
8194
8195   if ((reg = reg_required_here (&str, 12)) == FAIL)
8196     return;
8197
8198   if (reg == REG_PC)
8199     {
8200       inst.error = _("r15 not allowed in swap");
8201       return;
8202     }
8203
8204   if (skip_past_comma (&str) == FAIL
8205       || (reg = reg_required_here (&str, 0)) == FAIL)
8206     {
8207       if (!inst.error)
8208         inst.error = BAD_ARGS;
8209       return;
8210     }
8211
8212   if (reg == REG_PC)
8213     {
8214       inst.error = _("r15 not allowed in swap");
8215       return;
8216     }
8217
8218   if (skip_past_comma (&str) == FAIL
8219       || *str++ != '[')
8220     {
8221       inst.error = BAD_ARGS;
8222       return;
8223     }
8224
8225   skip_whitespace (str);
8226
8227   if ((reg = reg_required_here (&str, 16)) == FAIL)
8228     return;
8229
8230   if (reg == REG_PC)
8231     {
8232       inst.error = BAD_PC;
8233       return;
8234     }
8235
8236   skip_whitespace (str);
8237
8238   if (*str++ != ']')
8239     {
8240       inst.error = _("missing ]");
8241       return;
8242     }
8243
8244   end_of_line (str);
8245 }
8246
8247 static void
8248 do_branch (str)
8249      char * str;
8250 {
8251   if (my_get_expression (&inst.reloc.exp, &str))
8252     return;
8253
8254 #ifdef OBJ_ELF
8255   {
8256     char * save_in;
8257
8258     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8259        required for the instruction.  */
8260
8261     /* arm_parse_reloc () works on input_line_pointer.
8262        We actually want to parse the operands to the branch instruction
8263        passed in 'str'.  Save the input pointer and restore it later.  */
8264     save_in = input_line_pointer;
8265     input_line_pointer = str;
8266     if (inst.reloc.exp.X_op == O_symbol
8267         && *str == '('
8268         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8269       {
8270         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8271         inst.reloc.pc_rel = 0;
8272         /* Modify str to point to after parsed operands, otherwise
8273            end_of_line() will complain about the (PLT) left in str.  */
8274         str = input_line_pointer;
8275       }
8276     else
8277       {
8278         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8279         inst.reloc.pc_rel = 1;
8280       }
8281     input_line_pointer = save_in;
8282   }
8283 #else
8284   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8285   inst.reloc.pc_rel = 1;
8286 #endif /* OBJ_ELF  */
8287
8288   end_of_line (str);
8289 }
8290
8291 static void
8292 do_bx (str)
8293      char * str;
8294 {
8295   int reg;
8296
8297   skip_whitespace (str);
8298
8299   if ((reg = reg_required_here (&str, 0)) == FAIL)
8300     {
8301       inst.error = BAD_ARGS;
8302       return;
8303     }
8304
8305   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8306   if (reg == REG_PC)
8307     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8308
8309   end_of_line (str);
8310 }
8311
8312 static void
8313 do_cdp (str)
8314      char * str;
8315 {
8316   /* Co-processor data operation.
8317      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8318   skip_whitespace (str);
8319
8320   if (co_proc_number (&str) == FAIL)
8321     {
8322       if (!inst.error)
8323         inst.error = BAD_ARGS;
8324       return;
8325     }
8326
8327   if (skip_past_comma (&str) == FAIL
8328       || cp_opc_expr (&str, 20,4) == FAIL)
8329     {
8330       if (!inst.error)
8331         inst.error = BAD_ARGS;
8332       return;
8333     }
8334
8335   if (skip_past_comma (&str) == FAIL
8336       || cp_reg_required_here (&str, 12) == FAIL)
8337     {
8338       if (!inst.error)
8339         inst.error = BAD_ARGS;
8340       return;
8341     }
8342
8343   if (skip_past_comma (&str) == FAIL
8344       || cp_reg_required_here (&str, 16) == FAIL)
8345     {
8346       if (!inst.error)
8347         inst.error = BAD_ARGS;
8348       return;
8349     }
8350
8351   if (skip_past_comma (&str) == FAIL
8352       || cp_reg_required_here (&str, 0) == FAIL)
8353     {
8354       if (!inst.error)
8355         inst.error = BAD_ARGS;
8356       return;
8357     }
8358
8359   if (skip_past_comma (&str) == SUCCESS)
8360     {
8361       if (cp_opc_expr (&str, 5, 3) == FAIL)
8362         {
8363           if (!inst.error)
8364             inst.error = BAD_ARGS;
8365           return;
8366         }
8367     }
8368
8369   end_of_line (str);
8370 }
8371
8372 static void
8373 do_lstc (str)
8374      char * str;
8375 {
8376   /* Co-processor register load/store.
8377      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8378
8379   skip_whitespace (str);
8380
8381   if (co_proc_number (&str) == FAIL)
8382     {
8383       if (!inst.error)
8384         inst.error = BAD_ARGS;
8385       return;
8386     }
8387
8388   if (skip_past_comma (&str) == FAIL
8389       || cp_reg_required_here (&str, 12) == FAIL)
8390     {
8391       if (!inst.error)
8392         inst.error = BAD_ARGS;
8393       return;
8394     }
8395
8396   if (skip_past_comma (&str) == FAIL
8397       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8398     {
8399       if (! inst.error)
8400         inst.error = BAD_ARGS;
8401       return;
8402     }
8403
8404   end_of_line (str);
8405 }
8406
8407 static void
8408 do_co_reg (str)
8409      char * str;
8410 {
8411   /* Co-processor register transfer.
8412      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8413
8414   skip_whitespace (str);
8415
8416   if (co_proc_number (&str) == FAIL)
8417     {
8418       if (!inst.error)
8419         inst.error = BAD_ARGS;
8420       return;
8421     }
8422
8423   if (skip_past_comma (&str) == FAIL
8424       || cp_opc_expr (&str, 21, 3) == FAIL)
8425     {
8426       if (!inst.error)
8427         inst.error = BAD_ARGS;
8428       return;
8429     }
8430
8431   if (skip_past_comma (&str) == FAIL
8432       || reg_required_here (&str, 12) == FAIL)
8433     {
8434       if (!inst.error)
8435         inst.error = BAD_ARGS;
8436       return;
8437     }
8438
8439   if (skip_past_comma (&str) == FAIL
8440       || cp_reg_required_here (&str, 16) == FAIL)
8441     {
8442       if (!inst.error)
8443         inst.error = BAD_ARGS;
8444       return;
8445     }
8446
8447   if (skip_past_comma (&str) == FAIL
8448       || cp_reg_required_here (&str, 0) == FAIL)
8449     {
8450       if (!inst.error)
8451         inst.error = BAD_ARGS;
8452       return;
8453     }
8454
8455   if (skip_past_comma (&str) == SUCCESS)
8456     {
8457       if (cp_opc_expr (&str, 5, 3) == FAIL)
8458         {
8459           if (!inst.error)
8460             inst.error = BAD_ARGS;
8461           return;
8462         }
8463     }
8464
8465   end_of_line (str);
8466 }
8467
8468 static void
8469 do_fpa_ctrl (str)
8470      char * str;
8471 {
8472   /* FP control registers.
8473      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8474
8475   skip_whitespace (str);
8476
8477   if (reg_required_here (&str, 12) == FAIL)
8478     {
8479       if (!inst.error)
8480         inst.error = BAD_ARGS;
8481       return;
8482     }
8483
8484   end_of_line (str);
8485 }
8486
8487 static void
8488 do_fpa_ldst (str)
8489      char * str;
8490 {
8491   skip_whitespace (str);
8492
8493   if (fp_reg_required_here (&str, 12) == FAIL)
8494     {
8495       if (!inst.error)
8496         inst.error = BAD_ARGS;
8497       return;
8498     }
8499
8500   if (skip_past_comma (&str) == FAIL
8501       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8502     {
8503       if (!inst.error)
8504         inst.error = BAD_ARGS;
8505       return;
8506     }
8507
8508   end_of_line (str);
8509 }
8510
8511 static void
8512 do_fpa_ldmstm (str)
8513      char * str;
8514 {
8515   int num_regs;
8516
8517   skip_whitespace (str);
8518
8519   if (fp_reg_required_here (&str, 12) == FAIL)
8520     {
8521       if (! inst.error)
8522         inst.error = BAD_ARGS;
8523       return;
8524     }
8525
8526   /* Get Number of registers to transfer.  */
8527   if (skip_past_comma (&str) == FAIL
8528       || my_get_expression (&inst.reloc.exp, &str))
8529     {
8530       if (! inst.error)
8531         inst.error = _("constant expression expected");
8532       return;
8533     }
8534
8535   if (inst.reloc.exp.X_op != O_constant)
8536     {
8537       inst.error = _("constant value required for number of registers");
8538       return;
8539     }
8540
8541   num_regs = inst.reloc.exp.X_add_number;
8542
8543   if (num_regs < 1 || num_regs > 4)
8544     {
8545       inst.error = _("number of registers must be in the range [1:4]");
8546       return;
8547     }
8548
8549   switch (num_regs)
8550     {
8551     case 1:
8552       inst.instruction |= CP_T_X;
8553       break;
8554     case 2:
8555       inst.instruction |= CP_T_Y;
8556       break;
8557     case 3:
8558       inst.instruction |= CP_T_Y | CP_T_X;
8559       break;
8560     case 4:
8561       break;
8562     default:
8563       abort ();
8564     }
8565
8566   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8567     {
8568       int reg;
8569       int write_back;
8570       int offset;
8571
8572       /* The instruction specified "ea" or "fd", so we can only accept
8573          [Rn]{!}.  The instruction does not really support stacking or
8574          unstacking, so we have to emulate these by setting appropriate
8575          bits and offsets.  */
8576       if (skip_past_comma (&str) == FAIL
8577           || *str != '[')
8578         {
8579           if (! inst.error)
8580             inst.error = BAD_ARGS;
8581           return;
8582         }
8583
8584       str++;
8585       skip_whitespace (str);
8586
8587       if ((reg = reg_required_here (&str, 16)) == FAIL)
8588         return;
8589
8590       skip_whitespace (str);
8591
8592       if (*str != ']')
8593         {
8594           inst.error = BAD_ARGS;
8595           return;
8596         }
8597
8598       str++;
8599       if (*str == '!')
8600         {
8601           write_back = 1;
8602           str++;
8603           if (reg == REG_PC)
8604             {
8605               inst.error =
8606                 _("r15 not allowed as base register with write-back");
8607               return;
8608             }
8609         }
8610       else
8611         write_back = 0;
8612
8613       if (inst.instruction & CP_T_Pre)
8614         {
8615           /* Pre-decrement.  */
8616           offset = 3 * num_regs;
8617           if (write_back)
8618             inst.instruction |= CP_T_WB;
8619         }
8620       else
8621         {
8622           /* Post-increment.  */
8623           if (write_back)
8624             {
8625               inst.instruction |= CP_T_WB;
8626               offset = 3 * num_regs;
8627             }
8628           else
8629             {
8630               /* No write-back, so convert this into a standard pre-increment
8631                  instruction -- aesthetically more pleasing.  */
8632               inst.instruction |= CP_T_Pre | CP_T_UD;
8633               offset = 0;
8634             }
8635         }
8636
8637       inst.instruction |= offset;
8638     }
8639   else if (skip_past_comma (&str) == FAIL
8640            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8641     {
8642       if (! inst.error)
8643         inst.error = BAD_ARGS;
8644       return;
8645     }
8646
8647   end_of_line (str);
8648 }
8649
8650 static void
8651 do_fpa_dyadic (str)
8652      char * str;
8653 {
8654   skip_whitespace (str);
8655
8656   if (fp_reg_required_here (&str, 12) == FAIL)
8657     {
8658       if (! inst.error)
8659         inst.error = BAD_ARGS;
8660       return;
8661     }
8662
8663   if (skip_past_comma (&str) == FAIL
8664       || fp_reg_required_here (&str, 16) == FAIL)
8665     {
8666       if (! inst.error)
8667         inst.error = BAD_ARGS;
8668       return;
8669     }
8670
8671   if (skip_past_comma (&str) == FAIL
8672       || fp_op2 (&str) == FAIL)
8673     {
8674       if (! inst.error)
8675         inst.error = BAD_ARGS;
8676       return;
8677     }
8678
8679   end_of_line (str);
8680 }
8681
8682 static void
8683 do_fpa_monadic (str)
8684      char * str;
8685 {
8686   skip_whitespace (str);
8687
8688   if (fp_reg_required_here (&str, 12) == FAIL)
8689     {
8690       if (! inst.error)
8691         inst.error = BAD_ARGS;
8692       return;
8693     }
8694
8695   if (skip_past_comma (&str) == FAIL
8696       || fp_op2 (&str) == FAIL)
8697     {
8698       if (! inst.error)
8699         inst.error = BAD_ARGS;
8700       return;
8701     }
8702
8703   end_of_line (str);
8704 }
8705
8706 static void
8707 do_fpa_cmp (str)
8708      char * str;
8709 {
8710   skip_whitespace (str);
8711
8712   if (fp_reg_required_here (&str, 16) == FAIL)
8713     {
8714       if (! inst.error)
8715         inst.error = BAD_ARGS;
8716       return;
8717     }
8718
8719   if (skip_past_comma (&str) == FAIL
8720       || fp_op2 (&str) == FAIL)
8721     {
8722       if (! inst.error)
8723         inst.error = BAD_ARGS;
8724       return;
8725     }
8726
8727   end_of_line (str);
8728 }
8729
8730 static void
8731 do_fpa_from_reg (str)
8732      char * str;
8733 {
8734   skip_whitespace (str);
8735
8736   if (fp_reg_required_here (&str, 16) == FAIL)
8737     {
8738       if (! inst.error)
8739         inst.error = BAD_ARGS;
8740       return;
8741     }
8742
8743   if (skip_past_comma (&str) == FAIL
8744       || reg_required_here (&str, 12) == FAIL)
8745     {
8746       if (! inst.error)
8747         inst.error = BAD_ARGS;
8748       return;
8749     }
8750
8751   end_of_line (str);
8752 }
8753
8754 static void
8755 do_fpa_to_reg (str)
8756      char * str;
8757 {
8758   skip_whitespace (str);
8759
8760   if (reg_required_here (&str, 12) == FAIL)
8761     return;
8762
8763   if (skip_past_comma (&str) == FAIL
8764       || fp_reg_required_here (&str, 0) == FAIL)
8765     {
8766       if (! inst.error)
8767         inst.error = BAD_ARGS;
8768       return;
8769     }
8770
8771   end_of_line (str);
8772 }
8773
8774 static int
8775 vfp_sp_reg_required_here (str, pos)
8776      char **str;
8777      enum vfp_sp_reg_pos pos;
8778 {
8779   int    reg;
8780   char *start = *str;
8781
8782   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8783     {
8784       switch (pos)
8785         {
8786         case VFP_REG_Sd:
8787           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8788           break;
8789
8790         case VFP_REG_Sn:
8791           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8792           break;
8793
8794         case VFP_REG_Sm:
8795           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8796           break;
8797
8798         default:
8799           abort ();
8800         }
8801       return reg;
8802     }
8803
8804   /* In the few cases where we might be able to accept something else
8805      this error can be overridden.  */
8806   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8807
8808   /* Restore the start point.  */
8809   *str = start;
8810   return FAIL;
8811 }
8812
8813 static int
8814 vfp_dp_reg_required_here (str, pos)
8815      char **str;
8816      enum vfp_dp_reg_pos pos;
8817 {
8818   int   reg;
8819   char *start = *str;
8820
8821   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8822     {
8823       switch (pos)
8824         {
8825         case VFP_REG_Dd:
8826           inst.instruction |= reg << 12;
8827           break;
8828
8829         case VFP_REG_Dn:
8830           inst.instruction |= reg << 16;
8831           break;
8832
8833         case VFP_REG_Dm:
8834           inst.instruction |= reg << 0;
8835           break;
8836
8837         default:
8838           abort ();
8839         }
8840       return reg;
8841     }
8842
8843   /* In the few cases where we might be able to accept something else
8844      this error can be overridden.  */
8845   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8846
8847   /* Restore the start point.  */
8848   *str = start;
8849   return FAIL;
8850 }
8851
8852 static void
8853 do_vfp_sp_monadic (str)
8854      char *str;
8855 {
8856   skip_whitespace (str);
8857
8858   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8859     return;
8860
8861   if (skip_past_comma (&str) == FAIL
8862       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8863     {
8864       if (! inst.error)
8865         inst.error = BAD_ARGS;
8866       return;
8867     }
8868
8869   end_of_line (str);
8870 }
8871
8872 static void
8873 do_vfp_dp_monadic (str)
8874      char *str;
8875 {
8876   skip_whitespace (str);
8877
8878   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8879     return;
8880
8881   if (skip_past_comma (&str) == FAIL
8882       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8883     {
8884       if (! inst.error)
8885         inst.error = BAD_ARGS;
8886       return;
8887     }
8888
8889   end_of_line (str);
8890 }
8891
8892 static void
8893 do_vfp_sp_dyadic (str)
8894      char *str;
8895 {
8896   skip_whitespace (str);
8897
8898   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8899     return;
8900
8901   if (skip_past_comma (&str) == FAIL
8902       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8903       || skip_past_comma (&str) == FAIL
8904       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8905     {
8906       if (! inst.error)
8907         inst.error = BAD_ARGS;
8908       return;
8909     }
8910
8911   end_of_line (str);
8912 }
8913
8914 static void
8915 do_vfp_dp_dyadic (str)
8916      char *str;
8917 {
8918   skip_whitespace (str);
8919
8920   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8921     return;
8922
8923   if (skip_past_comma (&str) == FAIL
8924       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8925       || skip_past_comma (&str) == FAIL
8926       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8927     {
8928       if (! inst.error)
8929         inst.error = BAD_ARGS;
8930       return;
8931     }
8932
8933   end_of_line (str);
8934 }
8935
8936 static void
8937 do_vfp_reg_from_sp (str)
8938      char *str;
8939 {
8940   skip_whitespace (str);
8941
8942   if (reg_required_here (&str, 12) == FAIL)
8943     return;
8944
8945   if (skip_past_comma (&str) == FAIL
8946       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8947     {
8948       if (! inst.error)
8949         inst.error = BAD_ARGS;
8950       return;
8951     }
8952
8953   end_of_line (str);
8954 }
8955
8956 static void
8957 do_vfp_sp_reg2 (str)
8958      char *str;
8959 {
8960   skip_whitespace (str);
8961
8962   if (reg_required_here (&str, 12) == FAIL)
8963     return;
8964
8965   if (skip_past_comma (&str) == FAIL
8966       || reg_required_here (&str, 16) == FAIL
8967       || skip_past_comma (&str) == FAIL)
8968     {
8969       if (! inst.error)
8970         inst.error = BAD_ARGS;
8971       return;
8972     }
8973
8974   /* We require exactly two consecutive SP registers.  */
8975   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8976     {
8977       if (! inst.error)
8978         inst.error = _("only two consecutive VFP SP registers allowed here");
8979     }
8980
8981   end_of_line (str);
8982 }
8983
8984 static void
8985 do_vfp_sp_from_reg (str)
8986      char *str;
8987 {
8988   skip_whitespace (str);
8989
8990   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8991     return;
8992
8993   if (skip_past_comma (&str) == FAIL
8994       || reg_required_here (&str, 12) == FAIL)
8995     {
8996       if (! inst.error)
8997         inst.error = BAD_ARGS;
8998       return;
8999     }
9000
9001   end_of_line (str);
9002 }
9003
9004 static void
9005 do_vfp_reg_from_dp (str)
9006      char *str;
9007 {
9008   skip_whitespace (str);
9009
9010   if (reg_required_here (&str, 12) == FAIL)
9011     return;
9012
9013   if (skip_past_comma (&str) == FAIL
9014       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9015     {
9016       if (! inst.error)
9017         inst.error = BAD_ARGS;
9018       return;
9019     }
9020
9021   end_of_line (str);
9022 }
9023
9024 static void
9025 do_vfp_reg2_from_dp (str)
9026      char *str;
9027 {
9028   skip_whitespace (str);
9029
9030   if (reg_required_here (&str, 12) == FAIL)
9031     return;
9032
9033   if (skip_past_comma (&str) == FAIL
9034       || reg_required_here (&str, 16) == FAIL
9035       || skip_past_comma (&str) == FAIL
9036       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9037     {
9038       if (! inst.error)
9039         inst.error = BAD_ARGS;
9040       return;
9041     }
9042
9043   end_of_line (str);
9044 }
9045
9046 static void
9047 do_vfp_dp_from_reg (str)
9048      char *str;
9049 {
9050   skip_whitespace (str);
9051
9052   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9053     return;
9054
9055   if (skip_past_comma (&str) == FAIL
9056       || reg_required_here (&str, 12) == FAIL)
9057     {
9058       if (! inst.error)
9059         inst.error = BAD_ARGS;
9060       return;
9061     }
9062
9063   end_of_line (str);
9064 }
9065
9066 static void
9067 do_vfp_dp_from_reg2 (str)
9068      char *str;
9069 {
9070   skip_whitespace (str);
9071
9072   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9073     return;
9074
9075   if (skip_past_comma (&str) == FAIL
9076       || reg_required_here (&str, 12) == FAIL
9077       || skip_past_comma (&str) == FAIL
9078       || reg_required_here (&str, 16))
9079     {
9080       if (! inst.error)
9081         inst.error = BAD_ARGS;
9082       return;
9083     }
9084
9085   end_of_line (str);
9086 }
9087
9088 static const struct vfp_reg *
9089 vfp_psr_parse (str)
9090      char **str;
9091 {
9092   char *start = *str;
9093   char  c;
9094   char *p;
9095   const struct vfp_reg *vreg;
9096
9097   p = start;
9098
9099   /* Find the end of the current token.  */
9100   do
9101     {
9102       c = *p++;
9103     }
9104   while (ISALPHA (c));
9105
9106   /* Mark it.  */
9107   *--p = 0;
9108
9109   for (vreg = vfp_regs + 0;
9110        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9111        vreg++)
9112     {
9113       if (strcmp (start, vreg->name) == 0)
9114         {
9115           *p = c;
9116           *str = p;
9117           return vreg;
9118         }
9119     }
9120
9121   *p = c;
9122   return NULL;
9123 }
9124
9125 static int
9126 vfp_psr_required_here (str)
9127      char **str;
9128 {
9129   char *start = *str;
9130   const struct vfp_reg *vreg;
9131
9132   vreg = vfp_psr_parse (str);
9133
9134   if (vreg)
9135     {
9136       inst.instruction |= vreg->regno;
9137       return SUCCESS;
9138     }
9139
9140   inst.error = _("VFP system register expected");
9141
9142   *str = start;
9143   return FAIL;
9144 }
9145
9146 static void
9147 do_vfp_reg_from_ctrl (str)
9148      char *str;
9149 {
9150   skip_whitespace (str);
9151
9152   if (reg_required_here (&str, 12) == FAIL)
9153     return;
9154
9155   if (skip_past_comma (&str) == FAIL
9156       || vfp_psr_required_here (&str) == FAIL)
9157     {
9158       if (! inst.error)
9159         inst.error = BAD_ARGS;
9160       return;
9161     }
9162
9163   end_of_line (str);
9164 }
9165
9166 static void
9167 do_vfp_ctrl_from_reg (str)
9168      char *str;
9169 {
9170   skip_whitespace (str);
9171
9172   if (vfp_psr_required_here (&str) == FAIL)
9173     return;
9174
9175   if (skip_past_comma (&str) == FAIL
9176       || reg_required_here (&str, 12) == FAIL)
9177     {
9178       if (! inst.error)
9179         inst.error = BAD_ARGS;
9180       return;
9181     }
9182
9183   end_of_line (str);
9184 }
9185
9186 static void
9187 do_vfp_sp_ldst (str)
9188      char *str;
9189 {
9190   skip_whitespace (str);
9191
9192   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9193     {
9194       if (!inst.error)
9195         inst.error = BAD_ARGS;
9196       return;
9197     }
9198
9199   if (skip_past_comma (&str) == FAIL
9200       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9201     {
9202       if (!inst.error)
9203         inst.error = BAD_ARGS;
9204       return;
9205     }
9206
9207   end_of_line (str);
9208 }
9209
9210 static void
9211 do_vfp_dp_ldst (str)
9212      char *str;
9213 {
9214   skip_whitespace (str);
9215
9216   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9217     {
9218       if (!inst.error)
9219         inst.error = BAD_ARGS;
9220       return;
9221     }
9222
9223   if (skip_past_comma (&str) == FAIL
9224       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9225     {
9226       if (!inst.error)
9227         inst.error = BAD_ARGS;
9228       return;
9229     }
9230
9231   end_of_line (str);
9232 }
9233
9234 /* Parse and encode a VFP SP register list, storing the initial
9235    register in position POS and returning the range as the result.  If
9236    the string is invalid return FAIL (an invalid range).  */
9237 static long
9238 vfp_sp_reg_list (str, pos)
9239      char **str;
9240      enum vfp_sp_reg_pos pos;
9241 {
9242   long range = 0;
9243   int base_reg = 0;
9244   int new_base;
9245   long base_bits = 0;
9246   int count = 0;
9247   long tempinst;
9248   unsigned long mask = 0;
9249   int warned = 0;
9250
9251   if (**str != '{')
9252     return FAIL;
9253
9254   (*str)++;
9255   skip_whitespace (*str);
9256
9257   tempinst = inst.instruction;
9258
9259   do
9260     {
9261       inst.instruction = 0;
9262
9263       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9264         return FAIL;
9265
9266       if (count == 0 || base_reg > new_base)
9267         {
9268           base_reg = new_base;
9269           base_bits = inst.instruction;
9270         }
9271
9272       if (mask & (1 << new_base))
9273         {
9274           inst.error = _("invalid register list");
9275           return FAIL;
9276         }
9277
9278       if ((mask >> new_base) != 0 && ! warned)
9279         {
9280           as_tsktsk (_("register list not in ascending order"));
9281           warned = 1;
9282         }
9283
9284       mask |= 1 << new_base;
9285       count++;
9286
9287       skip_whitespace (*str);
9288
9289       if (**str == '-') /* We have the start of a range expression */
9290         {
9291           int high_range;
9292
9293           (*str)++;
9294
9295           if ((high_range
9296                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9297               == FAIL)
9298             {
9299               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9300               return FAIL;
9301             }
9302
9303           if (high_range <= new_base)
9304             {
9305               inst.error = _("register range not in ascending order");
9306               return FAIL;
9307             }
9308
9309           for (new_base++; new_base <= high_range; new_base++)
9310             {
9311               if (mask & (1 << new_base))
9312                 {
9313                   inst.error = _("invalid register list");
9314                   return FAIL;
9315                 }
9316
9317               mask |= 1 << new_base;
9318               count++;
9319             }
9320         }
9321     }
9322   while (skip_past_comma (str) != FAIL);
9323
9324   if (**str != '}')
9325     {
9326       inst.error = _("invalid register list");
9327       return FAIL;
9328     }
9329
9330   (*str)++;
9331
9332   range = count;
9333
9334   /* Sanity check -- should have raised a parse error above.  */
9335   if (count == 0 || count > 32)
9336     abort ();
9337
9338   /* Final test -- the registers must be consecutive.  */
9339   while (count--)
9340     {
9341       if ((mask & (1 << base_reg++)) == 0)
9342         {
9343           inst.error = _("non-contiguous register range");
9344           return FAIL;
9345         }
9346     }
9347
9348   inst.instruction = tempinst | base_bits;
9349   return range;
9350 }
9351
9352 static long
9353 vfp_dp_reg_list (str)
9354      char **str;
9355 {
9356   long range = 0;
9357   int base_reg = 0;
9358   int new_base;
9359   int count = 0;
9360   long tempinst;
9361   unsigned long mask = 0;
9362   int warned = 0;
9363
9364   if (**str != '{')
9365     return FAIL;
9366
9367   (*str)++;
9368   skip_whitespace (*str);
9369
9370   tempinst = inst.instruction;
9371
9372   do
9373     {
9374       inst.instruction = 0;
9375
9376       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9377         return FAIL;
9378
9379       if (count == 0 || base_reg > new_base)
9380         {
9381           base_reg = new_base;
9382           range = inst.instruction;
9383         }
9384
9385       if (mask & (1 << new_base))
9386         {
9387           inst.error = _("invalid register list");
9388           return FAIL;
9389         }
9390
9391       if ((mask >> new_base) != 0 && ! warned)
9392         {
9393           as_tsktsk (_("register list not in ascending order"));
9394           warned = 1;
9395         }
9396
9397       mask |= 1 << new_base;
9398       count++;
9399
9400       skip_whitespace (*str);
9401
9402       if (**str == '-') /* We have the start of a range expression */
9403         {
9404           int high_range;
9405
9406           (*str)++;
9407
9408           if ((high_range
9409                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9410               == FAIL)
9411             {
9412               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9413               return FAIL;
9414             }
9415
9416           if (high_range <= new_base)
9417             {
9418               inst.error = _("register range not in ascending order");
9419               return FAIL;
9420             }
9421
9422           for (new_base++; new_base <= high_range; new_base++)
9423             {
9424               if (mask & (1 << new_base))
9425                 {
9426                   inst.error = _("invalid register list");
9427                   return FAIL;
9428                 }
9429
9430               mask |= 1 << new_base;
9431               count++;
9432             }
9433         }
9434     }
9435   while (skip_past_comma (str) != FAIL);
9436
9437   if (**str != '}')
9438     {
9439       inst.error = _("invalid register list");
9440       return FAIL;
9441     }
9442
9443   (*str)++;
9444
9445   range |= 2 * count;
9446
9447   /* Sanity check -- should have raised a parse error above.  */
9448   if (count == 0 || count > 16)
9449     abort ();
9450
9451   /* Final test -- the registers must be consecutive.  */
9452   while (count--)
9453     {
9454       if ((mask & (1 << base_reg++)) == 0)
9455         {
9456           inst.error = _("non-contiguous register range");
9457           return FAIL;
9458         }
9459     }
9460
9461   inst.instruction = tempinst;
9462   return range;
9463 }
9464
9465 static void
9466 vfp_sp_ldstm (str, ldstm_type)
9467      char *str;
9468      enum vfp_ldstm_type ldstm_type;
9469 {
9470   long range;
9471
9472   skip_whitespace (str);
9473
9474   if (reg_required_here (&str, 16) == FAIL)
9475     return;
9476
9477   skip_whitespace (str);
9478
9479   if (*str == '!')
9480     {
9481       inst.instruction |= WRITE_BACK;
9482       str++;
9483     }
9484   else if (ldstm_type != VFP_LDSTMIA)
9485     {
9486       inst.error = _("this addressing mode requires base-register writeback");
9487       return;
9488     }
9489
9490   if (skip_past_comma (&str) == FAIL
9491       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9492     {
9493       if (!inst.error)
9494         inst.error = BAD_ARGS;
9495       return;
9496     }
9497
9498   inst.instruction |= range;
9499   end_of_line (str);
9500 }
9501
9502 static void
9503 vfp_dp_ldstm (str, ldstm_type)
9504      char *str;
9505      enum vfp_ldstm_type ldstm_type;
9506 {
9507   long range;
9508
9509   skip_whitespace (str);
9510
9511   if (reg_required_here (&str, 16) == FAIL)
9512     return;
9513
9514   skip_whitespace (str);
9515
9516   if (*str == '!')
9517     {
9518       inst.instruction |= WRITE_BACK;
9519       str++;
9520     }
9521   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9522     {
9523       inst.error = _("this addressing mode requires base-register writeback");
9524       return;
9525     }
9526
9527   if (skip_past_comma (&str) == FAIL
9528       || (range = vfp_dp_reg_list (&str)) == FAIL)
9529     {
9530       if (!inst.error)
9531         inst.error = BAD_ARGS;
9532       return;
9533     }
9534
9535   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9536     range += 1;
9537
9538   inst.instruction |= range;
9539   end_of_line (str);
9540 }
9541
9542 static void
9543 do_vfp_sp_ldstmia (str)
9544      char *str;
9545 {
9546   vfp_sp_ldstm (str, VFP_LDSTMIA);
9547 }
9548
9549 static void
9550 do_vfp_sp_ldstmdb (str)
9551      char *str;
9552 {
9553   vfp_sp_ldstm (str, VFP_LDSTMDB);
9554 }
9555
9556 static void
9557 do_vfp_dp_ldstmia (str)
9558      char *str;
9559 {
9560   vfp_dp_ldstm (str, VFP_LDSTMIA);
9561 }
9562
9563 static void
9564 do_vfp_dp_ldstmdb (str)
9565      char *str;
9566 {
9567   vfp_dp_ldstm (str, VFP_LDSTMDB);
9568 }
9569
9570 static void
9571 do_vfp_xp_ldstmia (str)
9572      char *str;
9573 {
9574   vfp_dp_ldstm (str, VFP_LDSTMIAX);
9575 }
9576
9577 static void
9578 do_vfp_xp_ldstmdb (str)
9579      char *str;
9580 {
9581   vfp_dp_ldstm (str, VFP_LDSTMDBX);
9582 }
9583
9584 static void
9585 do_vfp_sp_compare_z (str)
9586      char *str;
9587 {
9588   skip_whitespace (str);
9589
9590   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9591     {
9592       if (!inst.error)
9593         inst.error = BAD_ARGS;
9594       return;
9595     }
9596
9597   end_of_line (str);
9598 }
9599
9600 static void
9601 do_vfp_dp_compare_z (str)
9602      char *str;
9603 {
9604   skip_whitespace (str);
9605
9606   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9607     {
9608       if (!inst.error)
9609         inst.error = BAD_ARGS;
9610       return;
9611     }
9612
9613   end_of_line (str);
9614 }
9615
9616 static void
9617 do_vfp_dp_sp_cvt (str)
9618      char *str;
9619 {
9620   skip_whitespace (str);
9621
9622   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9623     return;
9624
9625   if (skip_past_comma (&str) == FAIL
9626       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9627     {
9628       if (! inst.error)
9629         inst.error = BAD_ARGS;
9630       return;
9631     }
9632
9633   end_of_line (str);
9634 }
9635
9636 static void
9637 do_vfp_sp_dp_cvt (str)
9638      char *str;
9639 {
9640   skip_whitespace (str);
9641
9642   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9643     return;
9644
9645   if (skip_past_comma (&str) == FAIL
9646       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9647     {
9648       if (! inst.error)
9649         inst.error = BAD_ARGS;
9650       return;
9651     }
9652
9653   end_of_line (str);
9654 }
9655
9656 /* Thumb specific routines.  */
9657
9658 /* Parse and validate that a register is of the right form, this saves
9659    repeated checking of this information in many similar cases.
9660    Unlike the 32-bit case we do not insert the register into the opcode
9661    here, since the position is often unknown until the full instruction
9662    has been parsed.  */
9663
9664 static int
9665 thumb_reg (strp, hi_lo)
9666      char ** strp;
9667      int     hi_lo;
9668 {
9669   int reg;
9670
9671   if ((reg = reg_required_here (strp, -1)) == FAIL)
9672     return FAIL;
9673
9674   switch (hi_lo)
9675     {
9676     case THUMB_REG_LO:
9677       if (reg > 7)
9678         {
9679           inst.error = _("lo register required");
9680           return FAIL;
9681         }
9682       break;
9683
9684     case THUMB_REG_HI:
9685       if (reg < 8)
9686         {
9687           inst.error = _("hi register required");
9688           return FAIL;
9689         }
9690       break;
9691
9692     default:
9693       break;
9694     }
9695
9696   return reg;
9697 }
9698
9699 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9700    was SUB.  */
9701
9702 static void
9703 thumb_add_sub (str, subtract)
9704      char * str;
9705      int    subtract;
9706 {
9707   int Rd, Rs, Rn = FAIL;
9708
9709   skip_whitespace (str);
9710
9711   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9712       || skip_past_comma (&str) == FAIL)
9713     {
9714       if (! inst.error)
9715         inst.error = BAD_ARGS;
9716       return;
9717     }
9718
9719   if (is_immediate_prefix (*str))
9720     {
9721       Rs = Rd;
9722       str++;
9723       if (my_get_expression (&inst.reloc.exp, &str))
9724         return;
9725     }
9726   else
9727     {
9728       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9729         return;
9730
9731       if (skip_past_comma (&str) == FAIL)
9732         {
9733           /* Two operand format, shuffle the registers
9734              and pretend there are 3.  */
9735           Rn = Rs;
9736           Rs = Rd;
9737         }
9738       else if (is_immediate_prefix (*str))
9739         {
9740           str++;
9741           if (my_get_expression (&inst.reloc.exp, &str))
9742             return;
9743         }
9744       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9745         return;
9746     }
9747
9748   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9749      for the latter case, EXPR contains the immediate that was found.  */
9750   if (Rn != FAIL)
9751     {
9752       /* All register format.  */
9753       if (Rd > 7 || Rs > 7 || Rn > 7)
9754         {
9755           if (Rs != Rd)
9756             {
9757               inst.error = _("dest and source1 must be the same register");
9758               return;
9759             }
9760
9761           /* Can't do this for SUB.  */
9762           if (subtract)
9763             {
9764               inst.error = _("subtract valid only on lo regs");
9765               return;
9766             }
9767
9768           inst.instruction = (T_OPCODE_ADD_HI
9769                               | (Rd > 7 ? THUMB_H1 : 0)
9770                               | (Rn > 7 ? THUMB_H2 : 0));
9771           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9772         }
9773       else
9774         {
9775           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9776           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9777         }
9778     }
9779   else
9780     {
9781       /* Immediate expression, now things start to get nasty.  */
9782
9783       /* First deal with HI regs, only very restricted cases allowed:
9784          Adjusting SP, and using PC or SP to get an address.  */
9785       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9786           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9787         {
9788           inst.error = _("invalid Hi register with immediate");
9789           return;
9790         }
9791
9792       if (inst.reloc.exp.X_op != O_constant)
9793         {
9794           /* Value isn't known yet, all we can do is store all the fragments
9795              we know about in the instruction and let the reloc hacking
9796              work it all out.  */
9797           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9798           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9799         }
9800       else
9801         {
9802           int offset = inst.reloc.exp.X_add_number;
9803
9804           if (subtract)
9805             offset = - offset;
9806
9807           if (offset < 0)
9808             {
9809               offset = - offset;
9810               subtract = 1;
9811
9812               /* Quick check, in case offset is MIN_INT.  */
9813               if (offset < 0)
9814                 {
9815                   inst.error = _("immediate value out of range");
9816                   return;
9817                 }
9818             }
9819           /* Note - you cannot convert a subtract of 0 into an
9820              add of 0 because the carry flag is set differently.  */
9821           else if (offset > 0)
9822             subtract = 0;
9823
9824           if (Rd == REG_SP)
9825             {
9826               if (offset & ~0x1fc)
9827                 {
9828                   inst.error = _("invalid immediate value for stack adjust");
9829                   return;
9830                 }
9831               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9832               inst.instruction |= offset >> 2;
9833             }
9834           else if (Rs == REG_PC || Rs == REG_SP)
9835             {
9836               if (subtract
9837                   || (offset & ~0x3fc))
9838                 {
9839                   inst.error = _("invalid immediate for address calculation");
9840                   return;
9841                 }
9842               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9843                                   : T_OPCODE_ADD_SP);
9844               inst.instruction |= (Rd << 8) | (offset >> 2);
9845             }
9846           else if (Rs == Rd)
9847             {
9848               if (offset & ~0xff)
9849                 {
9850                   inst.error = _("immediate value out of range");
9851                   return;
9852                 }
9853               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9854               inst.instruction |= (Rd << 8) | offset;
9855             }
9856           else
9857             {
9858               if (offset & ~0x7)
9859                 {
9860                   inst.error = _("immediate value out of range");
9861                   return;
9862                 }
9863               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9864               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9865             }
9866         }
9867     }
9868
9869   end_of_line (str);
9870 }
9871
9872 static void
9873 thumb_shift (str, shift)
9874      char * str;
9875      int    shift;
9876 {
9877   int Rd, Rs, Rn = FAIL;
9878
9879   skip_whitespace (str);
9880
9881   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9882       || skip_past_comma (&str) == FAIL)
9883     {
9884       if (! inst.error)
9885         inst.error = BAD_ARGS;
9886       return;
9887     }
9888
9889   if (is_immediate_prefix (*str))
9890     {
9891       /* Two operand immediate format, set Rs to Rd.  */
9892       Rs = Rd;
9893       str ++;
9894       if (my_get_expression (&inst.reloc.exp, &str))
9895         return;
9896     }
9897   else
9898     {
9899       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9900         return;
9901
9902       if (skip_past_comma (&str) == FAIL)
9903         {
9904           /* Two operand format, shuffle the registers
9905              and pretend there are 3.  */
9906           Rn = Rs;
9907           Rs = Rd;
9908         }
9909       else if (is_immediate_prefix (*str))
9910         {
9911           str++;
9912           if (my_get_expression (&inst.reloc.exp, &str))
9913             return;
9914         }
9915       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9916         return;
9917     }
9918
9919   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9920      for the latter case, EXPR contains the immediate that was found.  */
9921
9922   if (Rn != FAIL)
9923     {
9924       if (Rs != Rd)
9925         {
9926           inst.error = _("source1 and dest must be same register");
9927           return;
9928         }
9929
9930       switch (shift)
9931         {
9932         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9933         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9934         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9935         }
9936
9937       inst.instruction |= Rd | (Rn << 3);
9938     }
9939   else
9940     {
9941       switch (shift)
9942         {
9943         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9944         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9945         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9946         }
9947
9948       if (inst.reloc.exp.X_op != O_constant)
9949         {
9950           /* Value isn't known yet, create a dummy reloc and let reloc
9951              hacking fix it up.  */
9952           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9953         }
9954       else
9955         {
9956           unsigned shift_value = inst.reloc.exp.X_add_number;
9957
9958           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9959             {
9960               inst.error = _("invalid immediate for shift");
9961               return;
9962             }
9963
9964           /* Shifts of zero are handled by converting to LSL.  */
9965           if (shift_value == 0)
9966             inst.instruction = T_OPCODE_LSL_I;
9967
9968           /* Shifts of 32 are encoded as a shift of zero.  */
9969           if (shift_value == 32)
9970             shift_value = 0;
9971
9972           inst.instruction |= shift_value << 6;
9973         }
9974
9975       inst.instruction |= Rd | (Rs << 3);
9976     }
9977
9978   end_of_line (str);
9979 }
9980
9981 static void
9982 thumb_mov_compare (str, move)
9983      char * str;
9984      int    move;
9985 {
9986   int Rd, Rs = FAIL;
9987
9988   skip_whitespace (str);
9989
9990   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9991       || skip_past_comma (&str) == FAIL)
9992     {
9993       if (! inst.error)
9994         inst.error = BAD_ARGS;
9995       return;
9996     }
9997
9998   if (move != THUMB_CPY && is_immediate_prefix (*str))
9999     {
10000       str++;
10001       if (my_get_expression (&inst.reloc.exp, &str))
10002         return;
10003     }
10004   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10005     return;
10006
10007   if (Rs != FAIL)
10008     {
10009       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10010         {
10011           if (move == THUMB_MOVE)
10012             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10013                since a MOV instruction produces unpredictable results.  */
10014             inst.instruction = T_OPCODE_ADD_I3;
10015           else
10016             inst.instruction = T_OPCODE_CMP_LR;
10017           inst.instruction |= Rd | (Rs << 3);
10018         }
10019       else
10020         {
10021           if (move == THUMB_MOVE)
10022             inst.instruction = T_OPCODE_MOV_HR;
10023           else if (move != THUMB_CPY)
10024             inst.instruction = T_OPCODE_CMP_HR;
10025
10026           if (Rd > 7)
10027             inst.instruction |= THUMB_H1;
10028
10029           if (Rs > 7)
10030             inst.instruction |= THUMB_H2;
10031
10032           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10033         }
10034     }
10035   else
10036     {
10037       if (Rd > 7)
10038         {
10039           inst.error = _("only lo regs allowed with immediate");
10040           return;
10041         }
10042
10043       if (move == THUMB_MOVE)
10044         inst.instruction = T_OPCODE_MOV_I8;
10045       else
10046         inst.instruction = T_OPCODE_CMP_I8;
10047
10048       inst.instruction |= Rd << 8;
10049
10050       if (inst.reloc.exp.X_op != O_constant)
10051         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10052       else
10053         {
10054           unsigned value = inst.reloc.exp.X_add_number;
10055
10056           if (value > 255)
10057             {
10058               inst.error = _("invalid immediate");
10059               return;
10060             }
10061
10062           inst.instruction |= value;
10063         }
10064     }
10065
10066   end_of_line (str);
10067 }
10068
10069 static void
10070 thumb_load_store (str, load_store, size)
10071      char * str;
10072      int    load_store;
10073      int    size;
10074 {
10075   int Rd, Rb, Ro = FAIL;
10076
10077   skip_whitespace (str);
10078
10079   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10080       || skip_past_comma (&str) == FAIL)
10081     {
10082       if (! inst.error)
10083         inst.error = BAD_ARGS;
10084       return;
10085     }
10086
10087   if (*str == '[')
10088     {
10089       str++;
10090       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10091         return;
10092
10093       if (skip_past_comma (&str) != FAIL)
10094         {
10095           if (is_immediate_prefix (*str))
10096             {
10097               str++;
10098               if (my_get_expression (&inst.reloc.exp, &str))
10099                 return;
10100             }
10101           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10102             return;
10103         }
10104       else
10105         {
10106           inst.reloc.exp.X_op = O_constant;
10107           inst.reloc.exp.X_add_number = 0;
10108         }
10109
10110       if (*str != ']')
10111         {
10112           inst.error = _("expected ']'");
10113           return;
10114         }
10115       str++;
10116     }
10117   else if (*str == '=')
10118     {
10119       if (load_store != THUMB_LOAD)
10120         {
10121           inst.error = _("invalid pseudo operation");
10122           return;
10123         }
10124
10125       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10126       str++;
10127
10128       skip_whitespace (str);
10129
10130       if (my_get_expression (& inst.reloc.exp, & str))
10131         return;
10132
10133       end_of_line (str);
10134
10135       if (   inst.reloc.exp.X_op != O_constant
10136           && inst.reloc.exp.X_op != O_symbol)
10137         {
10138           inst.error = "Constant expression expected";
10139           return;
10140         }
10141
10142       if (inst.reloc.exp.X_op == O_constant
10143           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10144         {
10145           /* This can be done with a mov instruction.  */
10146
10147           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10148           inst.instruction |= inst.reloc.exp.X_add_number;
10149           return;
10150         }
10151
10152       /* Insert into literal pool.  */
10153       if (add_to_lit_pool () == FAIL)
10154         {
10155           if (!inst.error)
10156             inst.error = "literal pool insertion failed";
10157           return;
10158         }
10159
10160       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10161       inst.reloc.pc_rel = 1;
10162       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10163       /* Adjust ARM pipeline offset to Thumb.  */
10164       inst.reloc.exp.X_add_number += 4;
10165
10166       return;
10167     }
10168   else
10169     {
10170       if (my_get_expression (&inst.reloc.exp, &str))
10171         return;
10172
10173       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10174       inst.reloc.pc_rel = 1;
10175       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10176       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10177       end_of_line (str);
10178       return;
10179     }
10180
10181   if (Rb == REG_PC || Rb == REG_SP)
10182     {
10183       if (size != THUMB_WORD)
10184         {
10185           inst.error = _("byte or halfword not valid for base register");
10186           return;
10187         }
10188       else if (Rb == REG_PC && load_store != THUMB_LOAD)
10189         {
10190           inst.error = _("r15 based store not allowed");
10191           return;
10192         }
10193       else if (Ro != FAIL)
10194         {
10195           inst.error = _("invalid base register for register offset");
10196           return;
10197         }
10198
10199       if (Rb == REG_PC)
10200         inst.instruction = T_OPCODE_LDR_PC;
10201       else if (load_store == THUMB_LOAD)
10202         inst.instruction = T_OPCODE_LDR_SP;
10203       else
10204         inst.instruction = T_OPCODE_STR_SP;
10205
10206       inst.instruction |= Rd << 8;
10207       if (inst.reloc.exp.X_op == O_constant)
10208         {
10209           unsigned offset = inst.reloc.exp.X_add_number;
10210
10211           if (offset & ~0x3fc)
10212             {
10213               inst.error = _("invalid offset");
10214               return;
10215             }
10216
10217           inst.instruction |= offset >> 2;
10218         }
10219       else
10220         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10221     }
10222   else if (Rb > 7)
10223     {
10224       inst.error = _("invalid base register in load/store");
10225       return;
10226     }
10227   else if (Ro == FAIL)
10228     {
10229       /* Immediate offset.  */
10230       if (size == THUMB_WORD)
10231         inst.instruction = (load_store == THUMB_LOAD
10232                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10233       else if (size == THUMB_HALFWORD)
10234         inst.instruction = (load_store == THUMB_LOAD
10235                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10236       else
10237         inst.instruction = (load_store == THUMB_LOAD
10238                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10239
10240       inst.instruction |= Rd | (Rb << 3);
10241
10242       if (inst.reloc.exp.X_op == O_constant)
10243         {
10244           unsigned offset = inst.reloc.exp.X_add_number;
10245
10246           if (offset & ~(0x1f << size))
10247             {
10248               inst.error = _("invalid offset");
10249               return;
10250             }
10251           inst.instruction |= (offset >> size) << 6;
10252         }
10253       else
10254         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10255     }
10256   else
10257     {
10258       /* Register offset.  */
10259       if (size == THUMB_WORD)
10260         inst.instruction = (load_store == THUMB_LOAD
10261                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10262       else if (size == THUMB_HALFWORD)
10263         inst.instruction = (load_store == THUMB_LOAD
10264                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10265       else
10266         inst.instruction = (load_store == THUMB_LOAD
10267                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10268
10269       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10270     }
10271
10272   end_of_line (str);
10273 }
10274
10275 /* A register must be given at this point.
10276
10277    Shift is the place to put it in inst.instruction.
10278
10279    Restores input start point on err.
10280    Returns the reg#, or FAIL.  */
10281
10282 static int
10283 mav_reg_required_here (str, shift, regtype)
10284      char ** str;
10285      int shift;
10286      enum arm_reg_type regtype;
10287 {
10288   int   reg;
10289   char *start = *str;
10290
10291   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10292     {
10293       if (shift >= 0)
10294         inst.instruction |= reg << shift;
10295
10296       return reg;
10297     }
10298
10299   /* Restore the start point.  */
10300   *str = start;
10301
10302   /* In the few cases where we might be able to accept something else
10303      this error can be overridden.  */
10304   inst.error = _(all_reg_maps[regtype].expected);
10305
10306   return FAIL;
10307 }
10308
10309 /* Cirrus Maverick Instructions.  */
10310
10311 /* Wrapper functions.  */
10312
10313 static void
10314 do_mav_binops_1a (str)
10315      char * str;
10316 {
10317   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10318 }
10319
10320 static void
10321 do_mav_binops_1b (str)
10322      char * str;
10323 {
10324   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10325 }
10326
10327 static void
10328 do_mav_binops_1c (str)
10329      char * str;
10330 {
10331   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10332 }
10333
10334 static void
10335 do_mav_binops_1d (str)
10336      char * str;
10337 {
10338   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10339 }
10340
10341 static void
10342 do_mav_binops_1e (str)
10343      char * str;
10344 {
10345   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10346 }
10347
10348 static void
10349 do_mav_binops_1f (str)
10350      char * str;
10351 {
10352   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10353 }
10354
10355 static void
10356 do_mav_binops_1g (str)
10357      char * str;
10358 {
10359   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10360 }
10361
10362 static void
10363 do_mav_binops_1h (str)
10364      char * str;
10365 {
10366   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10367 }
10368
10369 static void
10370 do_mav_binops_1i (str)
10371      char * str;
10372 {
10373   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10374 }
10375
10376 static void
10377 do_mav_binops_1j (str)
10378      char * str;
10379 {
10380   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10381 }
10382
10383 static void
10384 do_mav_binops_1k (str)
10385      char * str;
10386 {
10387   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10388 }
10389
10390 static void
10391 do_mav_binops_1l (str)
10392      char * str;
10393 {
10394   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10395 }
10396
10397 static void
10398 do_mav_binops_1m (str)
10399      char * str;
10400 {
10401   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10402 }
10403
10404 static void
10405 do_mav_binops_1n (str)
10406      char * str;
10407 {
10408   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10409 }
10410
10411 static void
10412 do_mav_binops_1o (str)
10413      char * str;
10414 {
10415   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10416 }
10417
10418 static void
10419 do_mav_binops_2a (str)
10420      char * str;
10421 {
10422   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10423 }
10424
10425 static void
10426 do_mav_binops_2b (str)
10427      char * str;
10428 {
10429   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10430 }
10431
10432 static void
10433 do_mav_binops_2c (str)
10434      char * str;
10435 {
10436   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10437 }
10438
10439 static void
10440 do_mav_binops_3a (str)
10441      char * str;
10442 {
10443   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10444 }
10445
10446 static void
10447 do_mav_binops_3b (str)
10448      char * str;
10449 {
10450   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10451 }
10452
10453 static void
10454 do_mav_binops_3c (str)
10455      char * str;
10456 {
10457   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10458 }
10459
10460 static void
10461 do_mav_binops_3d (str)
10462      char * str;
10463 {
10464   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10465 }
10466
10467 static void
10468 do_mav_triple_4a (str)
10469      char * str;
10470 {
10471   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10472 }
10473
10474 static void
10475 do_mav_triple_4b (str)
10476      char * str;
10477 {
10478   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10479 }
10480
10481 static void
10482 do_mav_triple_5a (str)
10483      char * str;
10484 {
10485   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10486 }
10487
10488 static void
10489 do_mav_triple_5b (str)
10490      char * str;
10491 {
10492   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10493 }
10494
10495 static void
10496 do_mav_triple_5c (str)
10497      char * str;
10498 {
10499   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10500 }
10501
10502 static void
10503 do_mav_triple_5d (str)
10504      char * str;
10505 {
10506   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10507 }
10508
10509 static void
10510 do_mav_triple_5e (str)
10511      char * str;
10512 {
10513   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10514 }
10515
10516 static void
10517 do_mav_triple_5f (str)
10518      char * str;
10519 {
10520   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10521 }
10522
10523 static void
10524 do_mav_triple_5g (str)
10525      char * str;
10526 {
10527   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10528 }
10529
10530 static void
10531 do_mav_triple_5h (str)
10532      char * str;
10533 {
10534   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10535 }
10536
10537 static void
10538 do_mav_quad_6a (str)
10539      char * str;
10540 {
10541   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10542              REG_TYPE_MVFX);
10543 }
10544
10545 static void
10546 do_mav_quad_6b (str)
10547      char * str;
10548 {
10549   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10550              REG_TYPE_MVFX);
10551 }
10552
10553 /* cfmvsc32<cond> DSPSC,MVFX[15:0].  */
10554 static void
10555 do_mav_dspsc_1 (str)
10556      char * str;
10557 {
10558   skip_whitespace (str);
10559
10560   /* cfmvsc32.  */
10561   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10562       || skip_past_comma (&str) == FAIL
10563       || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
10564     {
10565       if (!inst.error)
10566         inst.error = BAD_ARGS;
10567
10568       return;
10569     }
10570
10571   end_of_line (str);
10572 }
10573
10574 /* cfmv32sc<cond> MVFX[15:0],DSPSC.  */
10575 static void
10576 do_mav_dspsc_2 (str)
10577      char * str;
10578 {
10579   skip_whitespace (str);
10580
10581   /* cfmv32sc.  */
10582   if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
10583       || skip_past_comma (&str) == FAIL
10584       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10585     {
10586       if (!inst.error)
10587         inst.error = BAD_ARGS;
10588
10589       return;
10590     }
10591
10592   end_of_line (str);
10593 }
10594
10595 static void
10596 do_mav_shift_1 (str)
10597      char * str;
10598 {
10599   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10600 }
10601
10602 static void
10603 do_mav_shift_2 (str)
10604      char * str;
10605 {
10606   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10607 }
10608
10609 static void
10610 do_mav_ldst_1 (str)
10611      char * str;
10612 {
10613   do_mav_ldst (str, REG_TYPE_MVF);
10614 }
10615
10616 static void
10617 do_mav_ldst_2 (str)
10618      char * str;
10619 {
10620   do_mav_ldst (str, REG_TYPE_MVD);
10621 }
10622
10623 static void
10624 do_mav_ldst_3 (str)
10625      char * str;
10626 {
10627   do_mav_ldst (str, REG_TYPE_MVFX);
10628 }
10629
10630 static void
10631 do_mav_ldst_4 (str)
10632      char * str;
10633 {
10634   do_mav_ldst (str, REG_TYPE_MVDX);
10635 }
10636
10637 /* Isnsn like "foo X,Y".  */
10638
10639 static void
10640 do_mav_binops (str, mode, reg0, reg1)
10641      char * str;
10642      int mode;
10643      enum arm_reg_type reg0;
10644      enum arm_reg_type reg1;
10645 {
10646   int shift0, shift1;
10647
10648   shift0 = mode & 0xff;
10649   shift1 = (mode >> 8) & 0xff;
10650
10651   skip_whitespace (str);
10652
10653   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10654       || skip_past_comma (&str) == FAIL
10655       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10656     {
10657       if (!inst.error)
10658         inst.error = BAD_ARGS;
10659     }
10660   else
10661     end_of_line (str);
10662 }
10663
10664 /* Isnsn like "foo X,Y,Z".  */
10665
10666 static void
10667 do_mav_triple (str, mode, reg0, reg1, reg2)
10668      char * str;
10669      int mode;
10670      enum arm_reg_type reg0;
10671      enum arm_reg_type reg1;
10672      enum arm_reg_type reg2;
10673 {
10674   int shift0, shift1, shift2;
10675
10676   shift0 = mode & 0xff;
10677   shift1 = (mode >> 8) & 0xff;
10678   shift2 = (mode >> 16) & 0xff;
10679
10680   skip_whitespace (str);
10681
10682   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10683       || skip_past_comma (&str) == FAIL
10684       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10685       || skip_past_comma (&str) == FAIL
10686       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10687     {
10688       if (!inst.error)
10689         inst.error = BAD_ARGS;
10690     }
10691   else
10692     end_of_line (str);
10693 }
10694
10695 /* Isnsn like "foo W,X,Y,Z".
10696     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10697
10698 static void
10699 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10700      char * str;
10701      int mode;
10702      enum arm_reg_type reg0;
10703      enum arm_reg_type reg1;
10704      enum arm_reg_type reg2;
10705      enum arm_reg_type reg3;
10706 {
10707   int shift0, shift1, shift2, shift3;
10708
10709   shift0= mode & 0xff;
10710   shift1 = (mode >> 8) & 0xff;
10711   shift2 = (mode >> 16) & 0xff;
10712   shift3 = (mode >> 24) & 0xff;
10713
10714   skip_whitespace (str);
10715
10716   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10717       || skip_past_comma (&str) == FAIL
10718       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10719       || skip_past_comma (&str) == FAIL
10720       || mav_reg_required_here (&str, shift2, reg2) == FAIL
10721       || skip_past_comma (&str) == FAIL
10722       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10723     {
10724       if (!inst.error)
10725         inst.error = BAD_ARGS;
10726     }
10727   else
10728     end_of_line (str);
10729 }
10730
10731 /* Maverick shift immediate instructions.
10732    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10733    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10734
10735 static void
10736 do_mav_shift (str, reg0, reg1)
10737      char * str;
10738      enum arm_reg_type reg0;
10739      enum arm_reg_type reg1;
10740 {
10741   int error;
10742   int imm, neg = 0;
10743
10744   skip_whitespace (str);
10745
10746   error = 0;
10747
10748   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10749       || skip_past_comma (&str) == FAIL
10750       || mav_reg_required_here (&str, 16, reg1) == FAIL
10751       || skip_past_comma  (&str) == FAIL)
10752     {
10753       if (!inst.error)
10754         inst.error = BAD_ARGS;
10755       return;
10756     }
10757
10758   /* Calculate the immediate operand.
10759      The operand is a 7bit signed number.  */
10760   skip_whitespace (str);
10761
10762   if (*str == '#')
10763     ++str;
10764
10765   if (!ISDIGIT (*str) && *str != '-')
10766     {
10767       inst.error = _("expecting immediate, 7bit operand");
10768       return;
10769     }
10770
10771   if (*str == '-')
10772     {
10773       neg = 1;
10774       ++str;
10775     }
10776
10777   for (imm = 0; *str && ISDIGIT (*str); ++str)
10778     imm = imm * 10 + *str - '0';
10779
10780   if (imm > 64)
10781     {
10782       inst.error = _("immediate out of range");
10783       return;
10784     }
10785
10786   /* Make negative imm's into 7bit signed numbers.  */
10787   if (neg)
10788     {
10789       imm = -imm;
10790       imm &= 0x0000007f;
10791     }
10792
10793   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10794      Bits 5-7 of the insn should have bits 4-6 of the immediate.
10795      Bit 4 should be 0.  */
10796   imm = (imm & 0xf) | ((imm & 0x70) << 1);
10797
10798   inst.instruction |= imm;
10799   end_of_line (str);
10800 }
10801
10802 static int
10803 mav_parse_offset (str, negative)
10804      char ** str;
10805      int *negative;
10806 {
10807   char * p = *str;
10808   int offset;
10809
10810   *negative = 0;
10811
10812   skip_whitespace (p);
10813
10814   if (*p == '#')
10815     ++p;
10816
10817   if (*p == '-')
10818     {
10819       *negative = 1;
10820       ++p;
10821     }
10822
10823   if (!ISDIGIT (*p))
10824     {
10825       inst.error = _("offset expected");
10826       return 0;
10827     }
10828
10829   for (offset = 0; *p && ISDIGIT (*p); ++p)
10830     offset = offset * 10 + *p - '0';
10831
10832   if (offset > 0xff)
10833     {
10834       inst.error = _("offset out of range");
10835       return 0;
10836     }
10837
10838   *str = p;
10839
10840   return *negative ? -offset : offset;
10841 }
10842
10843 /* Maverick load/store instructions.
10844   <insn><cond> CRd,[Rn,<offset>]{!}.
10845   <insn><cond> CRd,[Rn],<offset>.  */
10846
10847 static void
10848 do_mav_ldst (str, reg0)
10849      char * str;
10850      enum arm_reg_type reg0;
10851 {
10852   int offset, negative;
10853
10854   skip_whitespace (str);
10855
10856   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10857       || skip_past_comma (&str) == FAIL
10858       || *str++ != '['
10859       || reg_required_here (&str, 16) == FAIL)
10860     goto fail_ldst;
10861
10862   if (skip_past_comma (&str) == SUCCESS)
10863     {
10864       /* You are here: "<offset>]{!}".  */
10865       inst.instruction |= PRE_INDEX;
10866
10867       offset = mav_parse_offset (&str, &negative);
10868
10869       if (inst.error)
10870         return;
10871
10872       if (*str++ != ']')
10873         {
10874           inst.error = _("missing ]");
10875           return;
10876         }
10877
10878       if (*str == '!')
10879         {
10880           inst.instruction |= WRITE_BACK;
10881           ++str;
10882         }
10883     }
10884   else
10885     {
10886       /* You are here: "], <offset>".  */
10887       if (*str++ != ']')
10888         {
10889           inst.error = _("missing ]");
10890           return;
10891         }
10892
10893       if (skip_past_comma (&str) == FAIL
10894           || (offset = mav_parse_offset (&str, &negative), inst.error))
10895         goto fail_ldst;
10896
10897       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10898     }
10899
10900   if (negative)
10901     offset = -offset;
10902   else
10903     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10904
10905   inst.instruction |= offset >> 2;
10906   end_of_line (str);
10907   return;
10908
10909 fail_ldst:
10910   if (!inst.error)
10911      inst.error = BAD_ARGS;
10912 }
10913
10914 static void
10915 do_t_nop (str)
10916      char * str;
10917 {
10918   /* Do nothing.  */
10919   end_of_line (str);
10920 }
10921
10922 /* Handle the Format 4 instructions that do not have equivalents in other
10923    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10924    BIC and MVN.  */
10925
10926 static void
10927 do_t_arit (str)
10928      char * str;
10929 {
10930   int Rd, Rs, Rn;
10931
10932   skip_whitespace (str);
10933
10934   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10935       || skip_past_comma (&str) == FAIL
10936       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10937     {
10938       inst.error = BAD_ARGS;
10939       return;
10940     }
10941
10942   if (skip_past_comma (&str) != FAIL)
10943     {
10944       /* Three operand format not allowed for TST, CMN, NEG and MVN.
10945          (It isn't allowed for CMP either, but that isn't handled by this
10946          function.)  */
10947       if (inst.instruction == T_OPCODE_TST
10948           || inst.instruction == T_OPCODE_CMN
10949           || inst.instruction == T_OPCODE_NEG
10950           || inst.instruction == T_OPCODE_MVN)
10951         {
10952           inst.error = BAD_ARGS;
10953           return;
10954         }
10955
10956       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10957         return;
10958
10959       if (Rs != Rd)
10960         {
10961           inst.error = _("dest and source1 must be the same register");
10962           return;
10963         }
10964       Rs = Rn;
10965     }
10966
10967   if (inst.instruction == T_OPCODE_MUL
10968       && Rs == Rd)
10969     as_tsktsk (_("Rs and Rd must be different in MUL"));
10970
10971   inst.instruction |= Rd | (Rs << 3);
10972   end_of_line (str);
10973 }
10974
10975 static void
10976 do_t_add (str)
10977      char * str;
10978 {
10979   thumb_add_sub (str, 0);
10980 }
10981
10982 static void
10983 do_t_asr (str)
10984      char * str;
10985 {
10986   thumb_shift (str, THUMB_ASR);
10987 }
10988
10989 static void
10990 do_t_branch9 (str)
10991      char * str;
10992 {
10993   if (my_get_expression (&inst.reloc.exp, &str))
10994     return;
10995   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
10996   inst.reloc.pc_rel = 1;
10997   end_of_line (str);
10998 }
10999
11000 static void
11001 do_t_branch12 (str)
11002      char * str;
11003 {
11004   if (my_get_expression (&inst.reloc.exp, &str))
11005     return;
11006   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11007   inst.reloc.pc_rel = 1;
11008   end_of_line (str);
11009 }
11010
11011 /* Find the real, Thumb encoded start of a Thumb function.  */
11012
11013 static symbolS *
11014 find_real_start (symbolP)
11015      symbolS * symbolP;
11016 {
11017   char *       real_start;
11018   const char * name = S_GET_NAME (symbolP);
11019   symbolS *    new_target;
11020
11021   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11022 #define STUB_NAME ".real_start_of"
11023
11024   if (name == NULL)
11025     abort ();
11026
11027   /* Names that start with '.' are local labels, not function entry points.
11028      The compiler may generate BL instructions to these labels because it
11029      needs to perform a branch to a far away location.  */
11030   if (name[0] == '.')
11031     return symbolP;
11032
11033   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11034   sprintf (real_start, "%s%s", STUB_NAME, name);
11035
11036   new_target = symbol_find (real_start);
11037
11038   if (new_target == NULL)
11039     {
11040       as_warn ("Failed to find real start of function: %s\n", name);
11041       new_target = symbolP;
11042     }
11043
11044   free (real_start);
11045
11046   return new_target;
11047 }
11048
11049 static void
11050 do_t_branch23 (str)
11051      char * str;
11052 {
11053   if (my_get_expression (& inst.reloc.exp, & str))
11054     return;
11055
11056   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11057   inst.reloc.pc_rel = 1;
11058   end_of_line (str);
11059
11060   /* If the destination of the branch is a defined symbol which does not have
11061      the THUMB_FUNC attribute, then we must be calling a function which has
11062      the (interfacearm) attribute.  We look for the Thumb entry point to that
11063      function and change the branch to refer to that function instead.  */
11064   if (   inst.reloc.exp.X_op == O_symbol
11065       && inst.reloc.exp.X_add_symbol != NULL
11066       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11067       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11068     inst.reloc.exp.X_add_symbol =
11069       find_real_start (inst.reloc.exp.X_add_symbol);
11070 }
11071
11072 static void
11073 do_t_bx (str)
11074      char * str;
11075 {
11076   int reg;
11077
11078   skip_whitespace (str);
11079
11080   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11081     return;
11082
11083   /* This sets THUMB_H2 from the top bit of reg.  */
11084   inst.instruction |= reg << 3;
11085
11086   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11087      should cause the alignment to be checked once it is known.  This is
11088      because BX PC only works if the instruction is word aligned.  */
11089
11090   end_of_line (str);
11091 }
11092
11093 static void
11094 do_t_compare (str)
11095      char * str;
11096 {
11097   thumb_mov_compare (str, THUMB_COMPARE);
11098 }
11099
11100 static void
11101 do_t_ldmstm (str)
11102      char * str;
11103 {
11104   int Rb;
11105   long range;
11106
11107   skip_whitespace (str);
11108
11109   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11110     return;
11111
11112   if (*str != '!')
11113     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11114   else
11115     str++;
11116
11117   if (skip_past_comma (&str) == FAIL
11118       || (range = reg_list (&str)) == FAIL)
11119     {
11120       if (! inst.error)
11121         inst.error = BAD_ARGS;
11122       return;
11123     }
11124
11125   if (inst.reloc.type != BFD_RELOC_NONE)
11126     {
11127       /* This really doesn't seem worth it.  */
11128       inst.reloc.type = BFD_RELOC_NONE;
11129       inst.error = _("expression too complex");
11130       return;
11131     }
11132
11133   if (range & ~0xff)
11134     {
11135       inst.error = _("only lo-regs valid in load/store multiple");
11136       return;
11137     }
11138
11139   inst.instruction |= (Rb << 8) | range;
11140   end_of_line (str);
11141 }
11142
11143 static void
11144 do_t_ldr (str)
11145      char * str;
11146 {
11147   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11148 }
11149
11150 static void
11151 do_t_ldrb (str)
11152      char * str;
11153 {
11154   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11155 }
11156
11157 static void
11158 do_t_ldrh (str)
11159      char * str;
11160 {
11161   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11162 }
11163
11164 static void
11165 do_t_lds (str)
11166      char * str;
11167 {
11168   int Rd, Rb, Ro;
11169
11170   skip_whitespace (str);
11171
11172   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11173       || skip_past_comma (&str) == FAIL
11174       || *str++ != '['
11175       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11176       || skip_past_comma (&str) == FAIL
11177       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11178       || *str++ != ']')
11179     {
11180       if (! inst.error)
11181         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11182       return;
11183     }
11184
11185   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11186   end_of_line (str);
11187 }
11188
11189 static void
11190 do_t_lsl (str)
11191      char * str;
11192 {
11193   thumb_shift (str, THUMB_LSL);
11194 }
11195
11196 static void
11197 do_t_lsr (str)
11198      char * str;
11199 {
11200   thumb_shift (str, THUMB_LSR);
11201 }
11202
11203 static void
11204 do_t_mov (str)
11205      char * str;
11206 {
11207   thumb_mov_compare (str, THUMB_MOVE);
11208 }
11209
11210 static void
11211 do_t_push_pop (str)
11212      char * str;
11213 {
11214   long range;
11215
11216   skip_whitespace (str);
11217
11218   if ((range = reg_list (&str)) == FAIL)
11219     {
11220       if (! inst.error)
11221         inst.error = BAD_ARGS;
11222       return;
11223     }
11224
11225   if (inst.reloc.type != BFD_RELOC_NONE)
11226     {
11227       /* This really doesn't seem worth it.  */
11228       inst.reloc.type = BFD_RELOC_NONE;
11229       inst.error = _("expression too complex");
11230       return;
11231     }
11232
11233   if (range & ~0xff)
11234     {
11235       if ((inst.instruction == T_OPCODE_PUSH
11236            && (range & ~0xff) == 1 << REG_LR)
11237           || (inst.instruction == T_OPCODE_POP
11238               && (range & ~0xff) == 1 << REG_PC))
11239         {
11240           inst.instruction |= THUMB_PP_PC_LR;
11241           range &= 0xff;
11242         }
11243       else
11244         {
11245           inst.error = _("invalid register list to push/pop instruction");
11246           return;
11247         }
11248     }
11249
11250   inst.instruction |= range;
11251   end_of_line (str);
11252 }
11253
11254 static void
11255 do_t_str (str)
11256      char * str;
11257 {
11258   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11259 }
11260
11261 static void
11262 do_t_strb (str)
11263      char * str;
11264 {
11265   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11266 }
11267
11268 static void
11269 do_t_strh (str)
11270      char * str;
11271 {
11272   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11273 }
11274
11275 static void
11276 do_t_sub (str)
11277      char * str;
11278 {
11279   thumb_add_sub (str, 1);
11280 }
11281
11282 static void
11283 do_t_swi (str)
11284      char * str;
11285 {
11286   skip_whitespace (str);
11287
11288   if (my_get_expression (&inst.reloc.exp, &str))
11289     return;
11290
11291   inst.reloc.type = BFD_RELOC_ARM_SWI;
11292   end_of_line (str);
11293 }
11294
11295 static void
11296 do_t_adr (str)
11297      char * str;
11298 {
11299   int reg;
11300
11301   /* This is a pseudo-op of the form "adr rd, label" to be converted
11302      into a relative address of the form "add rd, pc, #label-.-4".  */
11303   skip_whitespace (str);
11304
11305   /* Store Rd in temporary location inside instruction.  */
11306   if ((reg = reg_required_here (&str, 4)) == FAIL
11307       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11308       || skip_past_comma (&str) == FAIL
11309       || my_get_expression (&inst.reloc.exp, &str))
11310     {
11311       if (!inst.error)
11312         inst.error = BAD_ARGS;
11313       return;
11314     }
11315
11316   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11317   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11318   inst.reloc.pc_rel = 1;
11319   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11320
11321   end_of_line (str);
11322 }
11323
11324 static void
11325 insert_reg (r, htab)
11326      const struct reg_entry *r;
11327      struct hash_control *htab;
11328 {
11329   int    len  = strlen (r->name) + 2;
11330   char * buf  = (char *) xmalloc (len);
11331   char * buf2 = (char *) xmalloc (len);
11332   int    i    = 0;
11333
11334 #ifdef REGISTER_PREFIX
11335   buf[i++] = REGISTER_PREFIX;
11336 #endif
11337
11338   strcpy (buf + i, r->name);
11339
11340   for (i = 0; buf[i]; i++)
11341     buf2[i] = TOUPPER (buf[i]);
11342
11343   buf2[i] = '\0';
11344
11345   hash_insert (htab, buf,  (PTR) r);
11346   hash_insert (htab, buf2, (PTR) r);
11347 }
11348
11349 static void
11350 build_reg_hsh (map)
11351      struct reg_map *map;
11352 {
11353   const struct reg_entry *r;
11354
11355   if ((map->htab = hash_new ()) == NULL)
11356     as_fatal (_("virtual memory exhausted"));
11357
11358   for (r = map->names; r->name != NULL; r++)
11359     insert_reg (r, map->htab);
11360 }
11361
11362 static void
11363 insert_reg_alias (str, regnum, htab)
11364      char *str;
11365      int regnum;
11366      struct hash_control *htab;
11367 {
11368   const char *error;
11369   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11370   const char *name = xmalloc (strlen (str) + 1);
11371   
11372   strcpy ((char *) name, str);
11373   
11374   new->name = name;
11375   new->number = regnum;
11376   new->builtin = FALSE;
11377
11378   error = hash_insert (htab, name, (PTR) new);
11379   if (error)
11380     {
11381       as_bad (_("failed to create an alias for %s, reason: %s"),
11382             str, error);
11383       free ((char *) name);
11384       free (new);
11385     }
11386 }
11387
11388 /* Look for the .req directive.  This is of the form:
11389
11390         new_register_name .req existing_register_name
11391
11392    If we find one, or if it looks sufficiently like one that we want to
11393    handle any error here, return non-zero.  Otherwise return zero.  */
11394 static int
11395 create_register_alias (newname, p)
11396      char *newname;
11397      char *p;
11398 {
11399   char *q;
11400   char c;
11401
11402   q = p;
11403   skip_whitespace (q);
11404
11405   c = *p;
11406   *p = '\0';
11407
11408   if (*q && !strncmp (q, ".req ", 5))
11409     {
11410       char *copy_of_str;
11411       char *r;
11412
11413 #ifdef IGNORE_OPCODE_CASE
11414       newname = original_case_string;
11415 #endif
11416       copy_of_str = newname;
11417
11418       q += 4;
11419       skip_whitespace (q);
11420
11421       for (r = q; *r != '\0'; r++)
11422         if (*r == ' ')
11423           break;
11424
11425       if (r != q)
11426         {
11427           enum arm_reg_type new_type, old_type;
11428           int old_regno;
11429           char d = *r;
11430
11431           *r = '\0';
11432           old_type = arm_reg_parse_any (q);
11433           *r = d;
11434
11435           new_type = arm_reg_parse_any (newname);
11436
11437           if (new_type == REG_TYPE_MAX)
11438             {
11439               if (old_type != REG_TYPE_MAX)
11440                 {
11441                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11442                   insert_reg_alias (newname, old_regno,
11443                                     all_reg_maps[old_type].htab);
11444                 }
11445               else
11446                 as_warn (_("register '%s' does not exist\n"), q);
11447             }
11448           else if (old_type == REG_TYPE_MAX)
11449             {
11450               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11451                        copy_of_str, q);
11452             }
11453           else
11454             {
11455               /* Do not warn about redefinitions to the same alias.  */
11456               if (new_type != old_type
11457                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11458                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11459                 as_warn (_("ignoring redefinition of register alias '%s'"),
11460                          copy_of_str);
11461
11462             }
11463         }
11464       else
11465         as_warn (_("ignoring incomplete .req pseuso op"));
11466
11467       *p = c;
11468       return 1;
11469     }
11470   
11471   *p = c;
11472   return 0;
11473 }
11474
11475 static void
11476 set_constant_flonums ()
11477 {
11478   int i;
11479
11480   for (i = 0; i < NUM_FLOAT_VALS; i++)
11481     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11482       abort ();
11483 }
11484
11485 /* Iterate over the base tables to create the instruction patterns.  */
11486 static void
11487 build_arm_ops_hsh ()
11488 {
11489   unsigned int i;
11490   unsigned int j;
11491   static struct obstack insn_obstack;
11492
11493   obstack_begin (&insn_obstack, 4000);
11494
11495   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11496     {
11497       const struct asm_opcode *insn = insns + i;
11498
11499       if (insn->cond_offset != 0)
11500         {
11501           /* Insn supports conditional execution.  Build the varaints
11502              and insert them in the hash table.  */
11503           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11504             {
11505               unsigned len = strlen (insn->template);
11506               struct asm_opcode *new;
11507               char *template;
11508
11509               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11510               /* All condition codes are two characters.  */
11511               template = obstack_alloc (&insn_obstack, len + 3);
11512
11513               strncpy (template, insn->template, insn->cond_offset);
11514               strcpy (template + insn->cond_offset, conds[j].template);
11515               if (len > insn->cond_offset)
11516                 strcpy (template + insn->cond_offset + 2,
11517                         insn->template + insn->cond_offset);
11518               new->template = template;
11519               new->cond_offset = 0;
11520               new->variant = insn->variant;
11521               new->parms = insn->parms;
11522               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11523
11524               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11525             }
11526         }
11527       /* Finally, insert the unconditional insn in the table directly;
11528          no need to build a copy.  */
11529       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11530     }
11531 }
11532
11533 #if 0 /* Suppressed - for now.  */
11534 #if defined OBJ_ELF || defined OBJ_COFF
11535
11536 #ifdef OBJ_ELF
11537 #define arm_Note Elf_External_Note
11538 #else
11539 typedef struct
11540 {
11541   unsigned char namesz[4];      /* Size of entry's owner string.  */
11542   unsigned char descsz[4];      /* Size of the note descriptor.  */
11543   unsigned char type[4];        /* Interpretation of the descriptor.  */
11544   char          name[1];        /* Start of the name+desc data.  */
11545 } arm_Note;
11546 #endif
11547
11548 /* The description is kept to a fix sized in order to make updating
11549    it and merging it easier.  */
11550 #define ARM_NOTE_DESCRIPTION_LENGTH     8
11551
11552 static void
11553 arm_add_note (name, description, type)
11554      const char * name;
11555      const char * description;
11556      unsigned int type;
11557 {
11558   arm_Note     note ATTRIBUTE_UNUSED;
11559   char *       p;
11560   unsigned int name_len;
11561
11562   name_len = (strlen (name) + 1 + 3) & ~3;
11563   
11564   p = frag_more (sizeof (note.namesz));
11565   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11566
11567   p = frag_more (sizeof (note.descsz));
11568   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11569
11570   p = frag_more (sizeof (note.type));
11571   md_number_to_chars (p, (valueT) type, sizeof (note.type));
11572
11573   p = frag_more (name_len);
11574   strcpy (p, name);
11575
11576   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11577   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11578   frag_align (2, 0, 0);
11579 }
11580 #endif
11581 #endif
11582
11583 void
11584 md_begin ()
11585 {
11586   unsigned mach;
11587   unsigned int i;
11588
11589   if (   (arm_ops_hsh = hash_new ()) == NULL
11590       || (arm_tops_hsh = hash_new ()) == NULL
11591       || (arm_cond_hsh = hash_new ()) == NULL
11592       || (arm_shift_hsh = hash_new ()) == NULL
11593       || (arm_psr_hsh = hash_new ()) == NULL)
11594     as_fatal (_("virtual memory exhausted"));
11595
11596   build_arm_ops_hsh ();
11597   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11598     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11599   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11600     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11601   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11602     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11603   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11604     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11605
11606   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11607     build_reg_hsh (all_reg_maps + i);
11608
11609   set_constant_flonums ();
11610
11611   /* Set the cpu variant based on the command-line options.  We prefer
11612      -mcpu= over -march= if both are set (as for GCC); and we prefer
11613      -mfpu= over any other way of setting the floating point unit.
11614      Use of legacy options with new options are faulted.  */
11615   if (legacy_cpu != -1)
11616     {
11617       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11618         as_bad (_("use of old and new-style options to set CPU type"));
11619
11620       mcpu_cpu_opt = legacy_cpu;
11621     }
11622   else if (mcpu_cpu_opt == -1)
11623     mcpu_cpu_opt = march_cpu_opt;
11624
11625   if (legacy_fpu != -1)
11626     {
11627       if (mfpu_opt != -1)
11628         as_bad (_("use of old and new-style options to set FPU type"));
11629
11630       mfpu_opt = legacy_fpu;
11631     }
11632   else if (mfpu_opt == -1)
11633     {
11634 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11635       /* Some environments specify a default FPU.  If they don't, infer it
11636          from the processor.  */
11637       if (mcpu_fpu_opt != -1)
11638         mfpu_opt = mcpu_fpu_opt;
11639       else
11640         mfpu_opt = march_fpu_opt;
11641 #else
11642       mfpu_opt = FPU_DEFAULT;
11643 #endif
11644     }
11645
11646   if (mfpu_opt == -1)
11647     {
11648       if (mcpu_cpu_opt == -1)
11649         mfpu_opt = FPU_DEFAULT;
11650       else if (mcpu_cpu_opt & ARM_EXT_V5)
11651         mfpu_opt = FPU_ARCH_VFP_V2;
11652       else
11653         mfpu_opt = FPU_ARCH_FPA;
11654     }
11655
11656   if (mcpu_cpu_opt == -1)
11657     mcpu_cpu_opt = CPU_DEFAULT;
11658
11659   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11660
11661 #if defined OBJ_COFF || defined OBJ_ELF
11662   {
11663     unsigned int flags = 0;
11664
11665     /* Set the flags in the private structure.  */
11666     if (uses_apcs_26)      flags |= F_APCS26;
11667     if (support_interwork) flags |= F_INTERWORK;
11668     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11669     if (pic_code)          flags |= F_PIC;
11670     if ((cpu_variant & FPU_ANY) == FPU_NONE
11671          || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11672       {
11673         flags |= F_SOFT_FLOAT;
11674       }
11675     switch (mfloat_abi_opt)
11676       {
11677       case ARM_FLOAT_ABI_SOFT:
11678       case ARM_FLOAT_ABI_SOFTFP:
11679         flags |= F_SOFT_FLOAT;
11680         break;
11681
11682       case ARM_FLOAT_ABI_HARD:
11683         if (flags & F_SOFT_FLOAT)
11684           as_bad (_("hard-float conflicts with specified fpu"));
11685         break;
11686       }
11687     /* Using VFP conventions (even if soft-float).  */
11688     if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
11689
11690 #if defined OBJ_ELF
11691     if (cpu_variant & FPU_ARCH_MAVERICK)
11692         flags |= EF_ARM_MAVERICK_FLOAT;
11693 #endif
11694
11695     bfd_set_private_flags (stdoutput, flags);
11696
11697     /* We have run out flags in the COFF header to encode the
11698        status of ATPCS support, so instead we create a dummy,
11699        empty, debug section called .arm.atpcs.  */
11700     if (atpcs)
11701       {
11702         asection * sec;
11703
11704         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11705
11706         if (sec != NULL)
11707           {
11708             bfd_set_section_flags
11709               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11710             bfd_set_section_size (stdoutput, sec, 0);
11711             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11712           }
11713       }
11714   }
11715 #endif
11716
11717   /* Record the CPU type as well.  */
11718   switch (cpu_variant & ARM_CPU_MASK)
11719     {
11720     case ARM_2:
11721       mach = bfd_mach_arm_2;
11722       break;
11723
11724     case ARM_3:                 /* Also ARM_250.  */
11725       mach = bfd_mach_arm_2a;
11726       break;
11727
11728     case ARM_6:                 /* Also ARM_7.  */
11729       mach = bfd_mach_arm_3;
11730       break;
11731
11732     default:
11733       mach = bfd_mach_arm_unknown;
11734       break;
11735     }
11736
11737   /* Catch special cases.  */
11738   if (cpu_variant & ARM_CEXT_IWMMXT)
11739     mach = bfd_mach_arm_iWMMXt;
11740   else if (cpu_variant & ARM_CEXT_XSCALE)
11741     mach = bfd_mach_arm_XScale;
11742   else if (cpu_variant & ARM_CEXT_MAVERICK)
11743     mach = bfd_mach_arm_ep9312;
11744   else if (cpu_variant & ARM_EXT_V5E)
11745     mach = bfd_mach_arm_5TE;
11746   else if (cpu_variant & ARM_EXT_V5)
11747     {
11748       if (cpu_variant & ARM_EXT_V4T)
11749         mach = bfd_mach_arm_5T;
11750       else
11751         mach = bfd_mach_arm_5;
11752     }
11753   else if (cpu_variant & ARM_EXT_V4)
11754     {
11755       if (cpu_variant & ARM_EXT_V4T)
11756         mach = bfd_mach_arm_4T;
11757       else
11758         mach = bfd_mach_arm_4;
11759     }
11760   else if (cpu_variant & ARM_EXT_V3M)
11761     mach = bfd_mach_arm_3M;
11762
11763 #if 0 /* Suppressed - for now.  */
11764 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11765
11766   /* Create a .note section to fully identify this arm binary.  */
11767
11768 #define NOTE_ARCH_STRING        "arch: "
11769
11770 #if defined OBJ_COFF && ! defined NT_VERSION
11771 #define NT_VERSION  1
11772 #define NT_ARCH     2
11773 #endif
11774   
11775   {
11776     segT current_seg = now_seg;
11777     subsegT current_subseg = now_subseg;
11778     asection * arm_arch;
11779     const char * arch_string;
11780
11781     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11782
11783 #ifdef OBJ_COFF
11784     bfd_set_section_flags (stdoutput, arm_arch,
11785                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11786                            | SEC_HAS_CONTENTS);
11787 #endif
11788     arm_arch->output_section = arm_arch;
11789     subseg_set (arm_arch, 0);
11790
11791     switch (mach)
11792       {
11793       default:
11794       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11795       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11796       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11797       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11798       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11799       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11800       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11801       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11802       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11803       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11804       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11805       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11806       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break; 
11807       }
11808
11809     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11810
11811     subseg_set (current_seg, current_subseg);
11812   }
11813 #endif
11814 #endif /* Suppressed code.  */
11815   
11816   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11817 }
11818
11819 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11820    for use in the a.out file, and stores them in the array pointed to by buf.
11821    This knows about the endian-ness of the target machine and does
11822    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11823    2 (short) and 4 (long)  Floating numbers are put out as a series of
11824    LITTLENUMS (shorts, here at least).  */
11825
11826 void
11827 md_number_to_chars (buf, val, n)
11828      char * buf;
11829      valueT val;
11830      int    n;
11831 {
11832   if (target_big_endian)
11833     number_to_chars_bigendian (buf, val, n);
11834   else
11835     number_to_chars_littleendian (buf, val, n);
11836 }
11837
11838 static valueT
11839 md_chars_to_number (buf, n)
11840      char * buf;
11841      int    n;
11842 {
11843   valueT result = 0;
11844   unsigned char * where = (unsigned char *) buf;
11845
11846   if (target_big_endian)
11847     {
11848       while (n--)
11849         {
11850           result <<= 8;
11851           result |= (*where++ & 255);
11852         }
11853     }
11854   else
11855     {
11856       while (n--)
11857         {
11858           result <<= 8;
11859           result |= (where[n] & 255);
11860         }
11861     }
11862
11863   return result;
11864 }
11865
11866 /* Turn a string in input_line_pointer into a floating point constant
11867    of type TYPE, and store the appropriate bytes in *LITP.  The number
11868    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11869    returned, or NULL on OK.
11870
11871    Note that fp constants aren't represent in the normal way on the ARM.
11872    In big endian mode, things are as expected.  However, in little endian
11873    mode fp constants are big-endian word-wise, and little-endian byte-wise
11874    within the words.  For example, (double) 1.1 in big endian mode is
11875    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11876    the byte sequence 99 99 f1 3f 9a 99 99 99.
11877
11878    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11879
11880 char *
11881 md_atof (type, litP, sizeP)
11882      char   type;
11883      char * litP;
11884      int *  sizeP;
11885 {
11886   int prec;
11887   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11888   char *t;
11889   int i;
11890
11891   switch (type)
11892     {
11893     case 'f':
11894     case 'F':
11895     case 's':
11896     case 'S':
11897       prec = 2;
11898       break;
11899
11900     case 'd':
11901     case 'D':
11902     case 'r':
11903     case 'R':
11904       prec = 4;
11905       break;
11906
11907     case 'x':
11908     case 'X':
11909       prec = 6;
11910       break;
11911
11912     case 'p':
11913     case 'P':
11914       prec = 6;
11915       break;
11916
11917     default:
11918       *sizeP = 0;
11919       return _("bad call to MD_ATOF()");
11920     }
11921
11922   t = atof_ieee (input_line_pointer, type, words);
11923   if (t)
11924     input_line_pointer = t;
11925   *sizeP = prec * 2;
11926
11927   if (target_big_endian)
11928     {
11929       for (i = 0; i < prec; i++)
11930         {
11931           md_number_to_chars (litP, (valueT) words[i], 2);
11932           litP += 2;
11933         }
11934     }
11935   else
11936     {
11937       if (cpu_variant & FPU_ARCH_VFP)
11938         for (i = prec - 1; i >= 0; i--)
11939           {
11940             md_number_to_chars (litP, (valueT) words[i], 2);
11941             litP += 2;
11942           }
11943       else
11944         /* For a 4 byte float the order of elements in `words' is 1 0.
11945            For an 8 byte float the order is 1 0 3 2.  */
11946         for (i = 0; i < prec; i += 2)
11947           {
11948             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11949             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11950             litP += 4;
11951           }
11952     }
11953
11954   return 0;
11955 }
11956
11957 /* The knowledge of the PC's pipeline offset is built into the insns
11958    themselves.  */
11959
11960 long
11961 md_pcrel_from (fixP)
11962      fixS * fixP;
11963 {
11964   if (fixP->fx_addsy
11965       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11966       && fixP->fx_subsy == NULL)
11967     return 0;
11968
11969   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11970     {
11971       /* PC relative addressing on the Thumb is slightly odd
11972          as the bottom two bits of the PC are forced to zero
11973          for the calculation.  */
11974       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11975     }
11976
11977 #ifdef TE_WINCE
11978   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11979      so we un-adjust here to compensate for the accommodation.  */
11980   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11981 #else
11982   return fixP->fx_where + fixP->fx_frag->fr_address;
11983 #endif
11984 }
11985
11986 /* Round up a section size to the appropriate boundary.  */
11987
11988 valueT
11989 md_section_align (segment, size)
11990      segT   segment ATTRIBUTE_UNUSED;
11991      valueT size;
11992 {
11993 #ifdef OBJ_ELF
11994   return size;
11995 #else
11996   /* Round all sects to multiple of 4.  */
11997   return (size + 3) & ~3;
11998 #endif
11999 }
12000
12001 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12002    Otherwise we have no need to default values of symbols.  */
12003
12004 symbolS *
12005 md_undefined_symbol (name)
12006      char * name ATTRIBUTE_UNUSED;
12007 {
12008 #ifdef OBJ_ELF
12009   if (name[0] == '_' && name[1] == 'G'
12010       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12011     {
12012       if (!GOT_symbol)
12013         {
12014           if (symbol_find (name))
12015             as_bad ("GOT already in the symbol table");
12016
12017           GOT_symbol = symbol_new (name, undefined_section,
12018                                    (valueT) 0, & zero_address_frag);
12019         }
12020
12021       return GOT_symbol;
12022     }
12023 #endif
12024
12025   return 0;
12026 }
12027
12028 /* arm_reg_parse () := if it looks like a register, return its token and
12029    advance the pointer.  */
12030
12031 static int
12032 arm_reg_parse (ccp, htab)
12033      register char ** ccp;
12034      struct hash_control *htab;
12035 {
12036   char * start = * ccp;
12037   char   c;
12038   char * p;
12039   struct reg_entry * reg;
12040
12041 #ifdef REGISTER_PREFIX
12042   if (*start != REGISTER_PREFIX)
12043     return FAIL;
12044   p = start + 1;
12045 #else
12046   p = start;
12047 #ifdef OPTIONAL_REGISTER_PREFIX
12048   if (*p == OPTIONAL_REGISTER_PREFIX)
12049     p++, start++;
12050 #endif
12051 #endif
12052   if (!ISALPHA (*p) || !is_name_beginner (*p))
12053     return FAIL;
12054
12055   c = *p++;
12056   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12057     c = *p++;
12058
12059   *--p = 0;
12060   reg = (struct reg_entry *) hash_find (htab, start);
12061   *p = c;
12062
12063   if (reg)
12064     {
12065       *ccp = p;
12066       return reg->number;
12067     }
12068
12069   return FAIL;
12070 }
12071
12072 /* Search for the following register name in each of the possible reg name
12073    tables.  Return the classification if found, or REG_TYPE_MAX if not
12074    present.  */
12075 static enum arm_reg_type
12076 arm_reg_parse_any (cp)
12077      char *cp;
12078 {
12079   int i;
12080
12081   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12082     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12083       return (enum arm_reg_type) i;
12084
12085   return REG_TYPE_MAX;
12086 }
12087
12088 void
12089 md_apply_fix3 (fixP, valP, seg)
12090      fixS *   fixP;
12091      valueT * valP;
12092      segT     seg;
12093 {
12094   offsetT        value = * valP;
12095   offsetT        newval;
12096   unsigned int   newimm;
12097   unsigned long  temp;
12098   int            sign;
12099   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12100   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12101
12102   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12103
12104   /* Note whether this will delete the relocation.  */
12105 #if 0
12106   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12107      doesn't work fully.)  */
12108   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12109       && !fixP->fx_pcrel)
12110 #else
12111   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12112 #endif
12113     fixP->fx_done = 1;
12114
12115   /* If this symbol is in a different section then we need to leave it for
12116      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12117      so we have to undo it's effects here.  */
12118   if (fixP->fx_pcrel)
12119     {
12120       if (fixP->fx_addsy != NULL
12121           && S_IS_DEFINED (fixP->fx_addsy)
12122           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12123         {
12124           if (target_oabi
12125               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12126                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12127                   ))
12128             value = 0;
12129           else
12130             value += md_pcrel_from (fixP);
12131         }
12132     }
12133
12134   /* Remember value for emit_reloc.  */
12135   fixP->fx_addnumber = value;
12136
12137   switch (fixP->fx_r_type)
12138     {
12139     case BFD_RELOC_ARM_IMMEDIATE:
12140       newimm = validate_immediate (value);
12141       temp = md_chars_to_number (buf, INSN_SIZE);
12142
12143       /* If the instruction will fail, see if we can fix things up by
12144          changing the opcode.  */
12145       if (newimm == (unsigned int) FAIL
12146           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12147         {
12148           as_bad_where (fixP->fx_file, fixP->fx_line,
12149                         _("invalid constant (%lx) after fixup"),
12150                         (unsigned long) value);
12151           break;
12152         }
12153
12154       newimm |= (temp & 0xfffff000);
12155       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12156       fixP->fx_done = 1;
12157       break;
12158
12159     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12160       {
12161         unsigned int highpart = 0;
12162         unsigned int newinsn  = 0xe1a00000; /* nop.  */
12163
12164         newimm = validate_immediate (value);
12165         temp = md_chars_to_number (buf, INSN_SIZE);
12166
12167         /* If the instruction will fail, see if we can fix things up by
12168            changing the opcode.  */
12169         if (newimm == (unsigned int) FAIL
12170             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12171           {
12172             /* No ?  OK - try using two ADD instructions to generate
12173                the value.  */
12174             newimm = validate_immediate_twopart (value, & highpart);
12175
12176             /* Yes - then make sure that the second instruction is
12177                also an add.  */
12178             if (newimm != (unsigned int) FAIL)
12179               newinsn = temp;
12180             /* Still No ?  Try using a negated value.  */
12181             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12182               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12183             /* Otherwise - give up.  */
12184             else
12185               {
12186                 as_bad_where (fixP->fx_file, fixP->fx_line,
12187                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12188                               (long) value);
12189                 break;
12190               }
12191
12192             /* Replace the first operand in the 2nd instruction (which
12193                is the PC) with the destination register.  We have
12194                already added in the PC in the first instruction and we
12195                do not want to do it again.  */
12196             newinsn &= ~ 0xf0000;
12197             newinsn |= ((newinsn & 0x0f000) << 4);
12198           }
12199
12200         newimm |= (temp & 0xfffff000);
12201         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12202
12203         highpart |= (newinsn & 0xfffff000);
12204         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12205       }
12206       break;
12207
12208     case BFD_RELOC_ARM_OFFSET_IMM:
12209       sign = value >= 0;
12210
12211       if (value < 0)
12212         value = - value;
12213
12214       if (validate_offset_imm (value, 0) == FAIL)
12215         {
12216           as_bad_where (fixP->fx_file, fixP->fx_line,
12217                         _("bad immediate value for offset (%ld)"),
12218                         (long) value);
12219           break;
12220         }
12221
12222       newval = md_chars_to_number (buf, INSN_SIZE);
12223       newval &= 0xff7ff000;
12224       newval |= value | (sign ? INDEX_UP : 0);
12225       md_number_to_chars (buf, newval, INSN_SIZE);
12226       break;
12227
12228     case BFD_RELOC_ARM_OFFSET_IMM8:
12229     case BFD_RELOC_ARM_HWLITERAL:
12230       sign = value >= 0;
12231
12232       if (value < 0)
12233         value = - value;
12234
12235       if (validate_offset_imm (value, 1) == FAIL)
12236         {
12237           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12238             as_bad_where (fixP->fx_file, fixP->fx_line,
12239                           _("invalid literal constant: pool needs to be closer"));
12240           else
12241             as_bad (_("bad immediate value for half-word offset (%ld)"),
12242                     (long) value);
12243           break;
12244         }
12245
12246       newval = md_chars_to_number (buf, INSN_SIZE);
12247       newval &= 0xff7ff0f0;
12248       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12249       md_number_to_chars (buf, newval, INSN_SIZE);
12250       break;
12251
12252     case BFD_RELOC_ARM_LITERAL:
12253       sign = value >= 0;
12254
12255       if (value < 0)
12256         value = - value;
12257
12258       if (validate_offset_imm (value, 0) == FAIL)
12259         {
12260           as_bad_where (fixP->fx_file, fixP->fx_line,
12261                         _("invalid literal constant: pool needs to be closer"));
12262           break;
12263         }
12264
12265       newval = md_chars_to_number (buf, INSN_SIZE);
12266       newval &= 0xff7ff000;
12267       newval |= value | (sign ? INDEX_UP : 0);
12268       md_number_to_chars (buf, newval, INSN_SIZE);
12269       break;
12270
12271     case BFD_RELOC_ARM_SHIFT_IMM:
12272       newval = md_chars_to_number (buf, INSN_SIZE);
12273       if (((unsigned long) value) > 32
12274           || (value == 32
12275               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12276         {
12277           as_bad_where (fixP->fx_file, fixP->fx_line,
12278                         _("shift expression is too large"));
12279           break;
12280         }
12281
12282       if (value == 0)
12283         /* Shifts of zero must be done as lsl.  */
12284         newval &= ~0x60;
12285       else if (value == 32)
12286         value = 0;
12287       newval &= 0xfffff07f;
12288       newval |= (value & 0x1f) << 7;
12289       md_number_to_chars (buf, newval, INSN_SIZE);
12290       break;
12291
12292     case BFD_RELOC_ARM_SWI:
12293       if (arm_data->thumb_mode)
12294         {
12295           if (((unsigned long) value) > 0xff)
12296             as_bad_where (fixP->fx_file, fixP->fx_line,
12297                           _("invalid swi expression"));
12298           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12299           newval |= value;
12300           md_number_to_chars (buf, newval, THUMB_SIZE);
12301         }
12302       else
12303         {
12304           if (((unsigned long) value) > 0x00ffffff)
12305             as_bad_where (fixP->fx_file, fixP->fx_line,
12306                           _("invalid swi expression"));
12307           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12308           newval |= value;
12309           md_number_to_chars (buf, newval, INSN_SIZE);
12310         }
12311       break;
12312
12313     case BFD_RELOC_ARM_MULTI:
12314       if (((unsigned long) value) > 0xffff)
12315         as_bad_where (fixP->fx_file, fixP->fx_line,
12316                       _("invalid expression in load/store multiple"));
12317       newval = value | md_chars_to_number (buf, INSN_SIZE);
12318       md_number_to_chars (buf, newval, INSN_SIZE);
12319       break;
12320
12321     case BFD_RELOC_ARM_PCREL_BRANCH:
12322       newval = md_chars_to_number (buf, INSN_SIZE);
12323
12324       /* Sign-extend a 24-bit number.  */
12325 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12326
12327 #ifdef OBJ_ELF
12328       if (! target_oabi)
12329         value = fixP->fx_offset;
12330 #endif
12331
12332       /* We are going to store value (shifted right by two) in the
12333          instruction, in a 24 bit, signed field.  Thus we need to check
12334          that none of the top 8 bits of the shifted value (top 7 bits of
12335          the unshifted, unsigned value) are set, or that they are all set.  */
12336       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12337           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12338         {
12339 #ifdef OBJ_ELF
12340           /* Normally we would be stuck at this point, since we cannot store
12341              the absolute address that is the destination of the branch in the
12342              24 bits of the branch instruction.  If however, we happen to know
12343              that the destination of the branch is in the same section as the
12344              branch instruction itself, then we can compute the relocation for
12345              ourselves and not have to bother the linker with it.
12346
12347              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12348              because I have not worked out how to do this for OBJ_COFF or
12349              target_oabi.  */
12350           if (! target_oabi
12351               && fixP->fx_addsy != NULL
12352               && S_IS_DEFINED (fixP->fx_addsy)
12353               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12354             {
12355               /* Get pc relative value to go into the branch.  */
12356               value = * valP;
12357
12358               /* Permit a backward branch provided that enough bits
12359                  are set.  Allow a forwards branch, provided that
12360                  enough bits are clear.  */
12361               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12362                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12363                 fixP->fx_done = 1;
12364             }
12365
12366           if (! fixP->fx_done)
12367 #endif
12368             as_bad_where (fixP->fx_file, fixP->fx_line,
12369                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12370         }
12371
12372       value >>= 2;
12373       value += SEXT24 (newval);
12374
12375       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12376           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12377         as_bad_where (fixP->fx_file, fixP->fx_line,
12378                       _("out of range branch"));
12379
12380       newval = (value & 0x00ffffff) | (newval & 0xff000000);
12381       md_number_to_chars (buf, newval, INSN_SIZE);
12382       break;
12383
12384     case BFD_RELOC_ARM_PCREL_BLX:
12385       {
12386         offsetT hbit;
12387         newval = md_chars_to_number (buf, INSN_SIZE);
12388
12389 #ifdef OBJ_ELF
12390         if (! target_oabi)
12391           value = fixP->fx_offset;
12392 #endif
12393         hbit   = (value >> 1) & 1;
12394         value  = (value >> 2) & 0x00ffffff;
12395         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12396         newval = value | (newval & 0xfe000000) | (hbit << 24);
12397         md_number_to_chars (buf, newval, INSN_SIZE);
12398       }
12399       break;
12400
12401     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12402       newval = md_chars_to_number (buf, THUMB_SIZE);
12403       {
12404         addressT diff = (newval & 0xff) << 1;
12405         if (diff & 0x100)
12406           diff |= ~0xff;
12407
12408         value += diff;
12409         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12410           as_bad_where (fixP->fx_file, fixP->fx_line,
12411                         _("branch out of range"));
12412         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12413       }
12414       md_number_to_chars (buf, newval, THUMB_SIZE);
12415       break;
12416
12417     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12418       newval = md_chars_to_number (buf, THUMB_SIZE);
12419       {
12420         addressT diff = (newval & 0x7ff) << 1;
12421         if (diff & 0x800)
12422           diff |= ~0x7ff;
12423
12424         value += diff;
12425         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12426           as_bad_where (fixP->fx_file, fixP->fx_line,
12427                         _("branch out of range"));
12428         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12429       }
12430       md_number_to_chars (buf, newval, THUMB_SIZE);
12431       break;
12432
12433     case BFD_RELOC_THUMB_PCREL_BLX:
12434     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12435       {
12436         offsetT newval2;
12437         addressT diff;
12438
12439         newval  = md_chars_to_number (buf, THUMB_SIZE);
12440         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12441         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12442         if (diff & 0x400000)
12443           diff |= ~0x3fffff;
12444 #ifdef OBJ_ELF
12445         value = fixP->fx_offset;
12446 #endif
12447         value += diff;
12448
12449         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12450           as_bad_where (fixP->fx_file, fixP->fx_line,
12451                         _("branch with link out of range"));
12452
12453         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12454         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12455         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12456           /* For a BLX instruction, make sure that the relocation is rounded up
12457              to a word boundary.  This follows the semantics of the instruction
12458              which specifies that bit 1 of the target address will come from bit
12459              1 of the base address.  */
12460           newval2 = (newval2 + 1) & ~ 1;
12461         md_number_to_chars (buf, newval, THUMB_SIZE);
12462         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12463       }
12464       break;
12465
12466     case BFD_RELOC_8:
12467       if (fixP->fx_done || fixP->fx_pcrel)
12468         md_number_to_chars (buf, value, 1);
12469 #ifdef OBJ_ELF
12470       else if (!target_oabi)
12471         {
12472           value = fixP->fx_offset;
12473           md_number_to_chars (buf, value, 1);
12474         }
12475 #endif
12476       break;
12477
12478     case BFD_RELOC_16:
12479       if (fixP->fx_done || fixP->fx_pcrel)
12480         md_number_to_chars (buf, value, 2);
12481 #ifdef OBJ_ELF
12482       else if (!target_oabi)
12483         {
12484           value = fixP->fx_offset;
12485           md_number_to_chars (buf, value, 2);
12486         }
12487 #endif
12488       break;
12489
12490 #ifdef OBJ_ELF
12491     case BFD_RELOC_ARM_GOT32:
12492     case BFD_RELOC_ARM_GOTOFF:
12493       md_number_to_chars (buf, 0, 4);
12494       break;
12495 #endif
12496
12497     case BFD_RELOC_RVA:
12498     case BFD_RELOC_32:
12499       if (fixP->fx_done || fixP->fx_pcrel)
12500         md_number_to_chars (buf, value, 4);
12501 #ifdef OBJ_ELF
12502       else if (!target_oabi)
12503         {
12504           value = fixP->fx_offset;
12505           md_number_to_chars (buf, value, 4);
12506         }
12507 #endif
12508       break;
12509
12510 #ifdef OBJ_ELF
12511     case BFD_RELOC_ARM_PLT32:
12512       /* It appears the instruction is fully prepared at this point.  */
12513       break;
12514 #endif
12515
12516     case BFD_RELOC_ARM_CP_OFF_IMM:
12517       sign = value >= 0;
12518       if (value < -1023 || value > 1023 || (value & 3))
12519         as_bad_where (fixP->fx_file, fixP->fx_line,
12520                       _("illegal value for co-processor offset"));
12521       if (value < 0)
12522         value = -value;
12523       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12524       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12525       md_number_to_chars (buf, newval, INSN_SIZE);
12526       break;
12527
12528     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12529       sign = value >= 0;
12530       if (value < -255 || value > 255)
12531         as_bad_where (fixP->fx_file, fixP->fx_line,
12532                       _("Illegal value for co-processor offset"));
12533       if (value < 0)
12534         value = -value;
12535       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12536       newval |= value | (sign ?  INDEX_UP : 0);
12537       md_number_to_chars (buf, newval , INSN_SIZE);
12538       break;
12539
12540     case BFD_RELOC_ARM_THUMB_OFFSET:
12541       newval = md_chars_to_number (buf, THUMB_SIZE);
12542       /* Exactly what ranges, and where the offset is inserted depends
12543          on the type of instruction, we can establish this from the
12544          top 4 bits.  */
12545       switch (newval >> 12)
12546         {
12547         case 4: /* PC load.  */
12548           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12549              forced to zero for these loads, so we will need to round
12550              up the offset if the instruction address is not word
12551              aligned (since the final address produced must be, and
12552              we can only describe word-aligned immediate offsets).  */
12553
12554           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12555             as_bad_where (fixP->fx_file, fixP->fx_line,
12556                           _("invalid offset, target not word aligned (0x%08X)"),
12557                           (unsigned int) (fixP->fx_frag->fr_address
12558                                           + fixP->fx_where + value));
12559
12560           if ((value + 2) & ~0x3fe)
12561             as_bad_where (fixP->fx_file, fixP->fx_line,
12562                           _("invalid offset, value too big (0x%08lX)"),
12563                           (long) value);
12564
12565           /* Round up, since pc will be rounded down.  */
12566           newval |= (value + 2) >> 2;
12567           break;
12568
12569         case 9: /* SP load/store.  */
12570           if (value & ~0x3fc)
12571             as_bad_where (fixP->fx_file, fixP->fx_line,
12572                           _("invalid offset, value too big (0x%08lX)"),
12573                           (long) value);
12574           newval |= value >> 2;
12575           break;
12576
12577         case 6: /* Word load/store.  */
12578           if (value & ~0x7c)
12579             as_bad_where (fixP->fx_file, fixP->fx_line,
12580                           _("invalid offset, value too big (0x%08lX)"),
12581                           (long) value);
12582           newval |= value << 4; /* 6 - 2.  */
12583           break;
12584
12585         case 7: /* Byte load/store.  */
12586           if (value & ~0x1f)
12587             as_bad_where (fixP->fx_file, fixP->fx_line,
12588                           _("invalid offset, value too big (0x%08lX)"),
12589                           (long) value);
12590           newval |= value << 6;
12591           break;
12592
12593         case 8: /* Halfword load/store.  */
12594           if (value & ~0x3e)
12595             as_bad_where (fixP->fx_file, fixP->fx_line,
12596                           _("invalid offset, value too big (0x%08lX)"),
12597                           (long) value);
12598           newval |= value << 5; /* 6 - 1.  */
12599           break;
12600
12601         default:
12602           as_bad_where (fixP->fx_file, fixP->fx_line,
12603                         "Unable to process relocation for thumb opcode: %lx",
12604                         (unsigned long) newval);
12605           break;
12606         }
12607       md_number_to_chars (buf, newval, THUMB_SIZE);
12608       break;
12609
12610     case BFD_RELOC_ARM_THUMB_ADD:
12611       /* This is a complicated relocation, since we use it for all of
12612          the following immediate relocations:
12613
12614             3bit ADD/SUB
12615             8bit ADD/SUB
12616             9bit ADD/SUB SP word-aligned
12617            10bit ADD PC/SP word-aligned
12618
12619          The type of instruction being processed is encoded in the
12620          instruction field:
12621
12622            0x8000  SUB
12623            0x00F0  Rd
12624            0x000F  Rs
12625       */
12626       newval = md_chars_to_number (buf, THUMB_SIZE);
12627       {
12628         int rd = (newval >> 4) & 0xf;
12629         int rs = newval & 0xf;
12630         int subtract = newval & 0x8000;
12631
12632         if (rd == REG_SP)
12633           {
12634             if (value & ~0x1fc)
12635               as_bad_where (fixP->fx_file, fixP->fx_line,
12636                             _("invalid immediate for stack address calculation"));
12637             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12638             newval |= value >> 2;
12639           }
12640         else if (rs == REG_PC || rs == REG_SP)
12641           {
12642             if (subtract ||
12643                 value & ~0x3fc)
12644               as_bad_where (fixP->fx_file, fixP->fx_line,
12645                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12646                             (unsigned long) value);
12647             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12648             newval |= rd << 8;
12649             newval |= value >> 2;
12650           }
12651         else if (rs == rd)
12652           {
12653             if (value & ~0xff)
12654               as_bad_where (fixP->fx_file, fixP->fx_line,
12655                             _("invalid 8bit immediate"));
12656             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12657             newval |= (rd << 8) | value;
12658           }
12659         else
12660           {
12661             if (value & ~0x7)
12662               as_bad_where (fixP->fx_file, fixP->fx_line,
12663                             _("invalid 3bit immediate"));
12664             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12665             newval |= rd | (rs << 3) | (value << 6);
12666           }
12667       }
12668       md_number_to_chars (buf, newval, THUMB_SIZE);
12669       break;
12670
12671     case BFD_RELOC_ARM_THUMB_IMM:
12672       newval = md_chars_to_number (buf, THUMB_SIZE);
12673       switch (newval >> 11)
12674         {
12675         case 0x04: /* 8bit immediate MOV.  */
12676         case 0x05: /* 8bit immediate CMP.  */
12677           if (value < 0 || value > 255)
12678             as_bad_where (fixP->fx_file, fixP->fx_line,
12679                           _("invalid immediate: %ld is too large"),
12680                           (long) value);
12681           newval |= value;
12682           break;
12683
12684         default:
12685           abort ();
12686         }
12687       md_number_to_chars (buf, newval, THUMB_SIZE);
12688       break;
12689
12690     case BFD_RELOC_ARM_THUMB_SHIFT:
12691       /* 5bit shift value (0..31).  */
12692       if (value < 0 || value > 31)
12693         as_bad_where (fixP->fx_file, fixP->fx_line,
12694                       _("illegal Thumb shift value: %ld"), (long) value);
12695       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12696       newval |= value << 6;
12697       md_number_to_chars (buf, newval, THUMB_SIZE);
12698       break;
12699
12700     case BFD_RELOC_VTABLE_INHERIT:
12701     case BFD_RELOC_VTABLE_ENTRY:
12702       fixP->fx_done = 0;
12703       return;
12704
12705     case BFD_RELOC_NONE:
12706     default:
12707       as_bad_where (fixP->fx_file, fixP->fx_line,
12708                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12709     }
12710 }
12711
12712 /* Translate internal representation of relocation info to BFD target
12713    format.  */
12714
12715 arelent *
12716 tc_gen_reloc (section, fixp)
12717      asection * section ATTRIBUTE_UNUSED;
12718      fixS * fixp;
12719 {
12720   arelent * reloc;
12721   bfd_reloc_code_real_type code;
12722
12723   reloc = (arelent *) xmalloc (sizeof (arelent));
12724
12725   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12726   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12727   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12728
12729   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12730 #ifndef OBJ_ELF
12731   if (fixp->fx_pcrel == 0)
12732     reloc->addend = fixp->fx_offset;
12733   else
12734     reloc->addend = fixp->fx_offset = reloc->address;
12735 #else  /* OBJ_ELF */
12736   reloc->addend = fixp->fx_offset;
12737 #endif
12738
12739   switch (fixp->fx_r_type)
12740     {
12741     case BFD_RELOC_8:
12742       if (fixp->fx_pcrel)
12743         {
12744           code = BFD_RELOC_8_PCREL;
12745           break;
12746         }
12747
12748     case BFD_RELOC_16:
12749       if (fixp->fx_pcrel)
12750         {
12751           code = BFD_RELOC_16_PCREL;
12752           break;
12753         }
12754
12755     case BFD_RELOC_32:
12756       if (fixp->fx_pcrel)
12757         {
12758           code = BFD_RELOC_32_PCREL;
12759           break;
12760         }
12761
12762     case BFD_RELOC_ARM_PCREL_BRANCH:
12763     case BFD_RELOC_ARM_PCREL_BLX:
12764     case BFD_RELOC_RVA:
12765     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12766     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12767     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12768     case BFD_RELOC_THUMB_PCREL_BLX:
12769     case BFD_RELOC_VTABLE_ENTRY:
12770     case BFD_RELOC_VTABLE_INHERIT:
12771       code = fixp->fx_r_type;
12772       break;
12773
12774     case BFD_RELOC_ARM_LITERAL:
12775     case BFD_RELOC_ARM_HWLITERAL:
12776       /* If this is called then the a literal has
12777          been referenced across a section boundary.  */
12778       as_bad_where (fixp->fx_file, fixp->fx_line,
12779                     _("literal referenced across section boundary"));
12780       return NULL;
12781
12782 #ifdef OBJ_ELF
12783     case BFD_RELOC_ARM_GOT32:
12784     case BFD_RELOC_ARM_GOTOFF:
12785     case BFD_RELOC_ARM_PLT32:
12786       code = fixp->fx_r_type;
12787       break;
12788 #endif
12789
12790     case BFD_RELOC_ARM_IMMEDIATE:
12791       as_bad_where (fixp->fx_file, fixp->fx_line,
12792                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12793       return NULL;
12794
12795     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12796       as_bad_where (fixp->fx_file, fixp->fx_line,
12797                     _("ADRL used for a symbol not defined in the same file"));
12798       return NULL;
12799
12800     case BFD_RELOC_ARM_OFFSET_IMM:
12801       as_bad_where (fixp->fx_file, fixp->fx_line,
12802                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12803       return NULL;
12804
12805     default:
12806       {
12807         char * type;
12808
12809         switch (fixp->fx_r_type)
12810           {
12811           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12812           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12813           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12814           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12815           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12816           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12817           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12818           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12819           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12820           default:                         type = _("<unknown>"); break;
12821           }
12822         as_bad_where (fixp->fx_file, fixp->fx_line,
12823                       _("cannot represent %s relocation in this object file format"),
12824                       type);
12825         return NULL;
12826       }
12827     }
12828
12829 #ifdef OBJ_ELF
12830   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12831       && GOT_symbol
12832       && fixp->fx_addsy == GOT_symbol)
12833     {
12834       code = BFD_RELOC_ARM_GOTPC;
12835       reloc->addend = fixp->fx_offset = reloc->address;
12836     }
12837 #endif
12838
12839   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12840
12841   if (reloc->howto == NULL)
12842     {
12843       as_bad_where (fixp->fx_file, fixp->fx_line,
12844                     _("cannot represent %s relocation in this object file format"),
12845                     bfd_get_reloc_code_name (code));
12846       return NULL;
12847     }
12848
12849   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12850      vtable entry to be used in the relocation's section offset.  */
12851   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12852     reloc->address = fixp->fx_offset;
12853
12854   return reloc;
12855 }
12856
12857 int
12858 md_estimate_size_before_relax (fragP, segtype)
12859      fragS * fragP ATTRIBUTE_UNUSED;
12860      segT    segtype ATTRIBUTE_UNUSED;
12861 {
12862   as_fatal (_("md_estimate_size_before_relax\n"));
12863   return 1;
12864 }
12865
12866 static void
12867 output_inst (str)
12868      const char *str;
12869 {
12870   char * to = NULL;
12871
12872   if (inst.error)
12873     {
12874       as_bad ("%s -- `%s'", inst.error, str);
12875       return;
12876     }
12877
12878   to = frag_more (inst.size);
12879
12880   if (thumb_mode && (inst.size > THUMB_SIZE))
12881     {
12882       assert (inst.size == (2 * THUMB_SIZE));
12883       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12884       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12885     }
12886   else if (inst.size > INSN_SIZE)
12887     {
12888       assert (inst.size == (2 * INSN_SIZE));
12889       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12890       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12891     }
12892   else
12893     md_number_to_chars (to, inst.instruction, inst.size);
12894
12895   if (inst.reloc.type != BFD_RELOC_NONE)
12896     fix_new_arm (frag_now, to - frag_now->fr_literal,
12897                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12898                  inst.reloc.type);
12899
12900 #ifdef OBJ_ELF
12901   dwarf2_emit_insn (inst.size);
12902 #endif
12903 }
12904
12905 void
12906 md_assemble (str)
12907      char * str;
12908 {
12909   char  c;
12910   char *p;
12911   char *start;
12912
12913   /* Align the instruction.
12914      This may not be the right thing to do but ...  */
12915 #if 0
12916   arm_align (2, 0);
12917 #endif
12918
12919   /* Align the previous label if needed.  */
12920   if (last_label_seen != NULL)
12921     {
12922       symbol_set_frag (last_label_seen, frag_now);
12923       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12924       S_SET_SEGMENT (last_label_seen, now_seg);
12925     }
12926
12927   memset (&inst, '\0', sizeof (inst));
12928   inst.reloc.type = BFD_RELOC_NONE;
12929
12930   skip_whitespace (str);
12931
12932   /* Scan up to the end of the op-code, which must end in white space or
12933      end of string.  */
12934   for (start = p = str; *p != '\0'; p++)
12935     if (*p == ' ')
12936       break;
12937
12938   if (p == str)
12939     {
12940       as_bad (_("no operator -- statement `%s'\n"), str);
12941       return;
12942     }
12943
12944   if (thumb_mode)
12945     {
12946       const struct thumb_opcode * opcode;
12947
12948       c = *p;
12949       *p = '\0';
12950       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12951       *p = c;
12952
12953       if (opcode)
12954         {
12955           /* Check that this instruction is supported for this CPU.  */
12956           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12957             {
12958               as_bad (_("selected processor does not support `%s'"), str);
12959               return;
12960             }
12961
12962           mapping_state (MAP_THUMB);
12963           inst.instruction = opcode->value;
12964           inst.size = opcode->size;
12965           (*opcode->parms) (p);
12966           output_inst (str);
12967           return;
12968         }
12969     }
12970   else
12971     {
12972       const struct asm_opcode * opcode;
12973
12974       c = *p;
12975       *p = '\0';
12976       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12977       *p = c;
12978
12979       if (opcode)
12980         {
12981           /* Check that this instruction is supported for this CPU.  */
12982           if ((opcode->variant & cpu_variant) == 0)
12983             {
12984               as_bad (_("selected processor does not support `%s'"), str);
12985               return;
12986             }
12987
12988           mapping_state (MAP_ARM);
12989           inst.instruction = opcode->value;
12990           inst.size = INSN_SIZE;
12991           (*opcode->parms) (p);
12992           output_inst (str);
12993           return;
12994         }
12995     }
12996
12997   /* It wasn't an instruction, but it might be a register alias of the form
12998      alias .req reg.  */
12999   if (create_register_alias (str, p))
13000     return;
13001
13002   as_bad (_("bad instruction `%s'"), start);
13003 }
13004
13005 /* md_parse_option
13006       Invocation line includes a switch not recognized by the base assembler.
13007       See if it's a processor-specific option.
13008
13009       This routine is somewhat complicated by the need for backwards
13010       compatibility (since older releases of gcc can't be changed).
13011       The new options try to make the interface as compatible as
13012       possible with GCC.
13013
13014       New options (supported) are:
13015
13016               -mcpu=<cpu name>           Assemble for selected processor
13017               -march=<architecture name> Assemble for selected architecture
13018               -mfpu=<fpu architecture>   Assemble for selected FPU.
13019               -EB/-mbig-endian           Big-endian
13020               -EL/-mlittle-endian        Little-endian
13021               -k                         Generate PIC code
13022               -mthumb                    Start in Thumb mode
13023               -mthumb-interwork          Code supports ARM/Thumb interworking
13024
13025       For now we will also provide support for:
13026
13027               -mapcs-32                  32-bit Program counter
13028               -mapcs-26                  26-bit Program counter
13029               -macps-float               Floats passed in FP registers
13030               -mapcs-reentrant           Reentrant code
13031               -matpcs
13032       (sometime these will probably be replaced with -mapcs=<list of options>
13033       and -matpcs=<list of options>)
13034
13035       The remaining options are only supported for back-wards compatibility.
13036       Cpu variants, the arm part is optional:
13037               -m[arm]1                Currently not supported.
13038               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13039               -m[arm]3                Arm 3 processor
13040               -m[arm]6[xx],           Arm 6 processors
13041               -m[arm]7[xx][t][[d]m]   Arm 7 processors
13042               -m[arm]8[10]            Arm 8 processors
13043               -m[arm]9[20][tdmi]      Arm 9 processors
13044               -mstrongarm[110[0]]     StrongARM processors
13045               -mxscale                XScale processors
13046               -m[arm]v[2345[t[e]]]    Arm architectures
13047               -mall                   All (except the ARM1)
13048       FP variants:
13049               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13050               -mfpe-old               (No float load/store multiples)
13051               -mvfpxd                 VFP Single precision
13052               -mvfp                   All VFP
13053               -mno-fpu                Disable all floating point instructions
13054
13055       The following CPU names are recognized:
13056               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13057               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13058               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13059               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13060               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13061               arm10t arm10e, arm1020t, arm1020e, arm10200e,
13062               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13063
13064       */
13065
13066 const char * md_shortopts = "m:k";
13067
13068 #ifdef ARM_BI_ENDIAN
13069 #define OPTION_EB (OPTION_MD_BASE + 0)
13070 #define OPTION_EL (OPTION_MD_BASE + 1)
13071 #else
13072 #if TARGET_BYTES_BIG_ENDIAN
13073 #define OPTION_EB (OPTION_MD_BASE + 0)
13074 #else
13075 #define OPTION_EL (OPTION_MD_BASE + 1)
13076 #endif
13077 #endif
13078
13079 struct option md_longopts[] =
13080 {
13081 #ifdef OPTION_EB
13082   {"EB", no_argument, NULL, OPTION_EB},
13083 #endif
13084 #ifdef OPTION_EL
13085   {"EL", no_argument, NULL, OPTION_EL},
13086 #endif
13087   {NULL, no_argument, NULL, 0}
13088 };
13089
13090 size_t md_longopts_size = sizeof (md_longopts);
13091
13092 struct arm_option_table
13093 {
13094   char *option;         /* Option name to match.  */
13095   char *help;           /* Help information.  */
13096   int  *var;            /* Variable to change.  */
13097   int   value;          /* What to change it to.  */
13098   char *deprecated;     /* If non-null, print this message.  */
13099 };
13100
13101 struct arm_option_table arm_opts[] =
13102 {
13103   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13104   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13105   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13106    &support_interwork, 1, NULL},
13107   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13108   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13109   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13110   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13111    1, NULL},
13112   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13113   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13114   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13115   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13116    NULL},
13117
13118   /* These are recognized by the assembler, but have no affect on code.  */
13119   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13120   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13121
13122   /* DON'T add any new processors to this list -- we want the whole list
13123      to go away...  Add them to the processors table instead.  */
13124   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13125   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13126   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13127   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13128   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13129   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13130   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13131   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13132   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13133   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13134   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13135   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13136   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13137   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13138   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13139   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13140   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13141   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13142   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13143   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13144   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13145   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13146   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13147   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13148   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13149   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13150   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13151   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13152   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13153   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13154   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13155   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13156   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13157   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13158   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13159   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13160   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13161   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13162   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13163   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13164   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13165   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13166   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13167   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13168   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13169   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13170   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13171   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13172   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13173   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13174   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13175   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13176   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13177   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13178   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13179   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13180   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13181   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13182   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13183   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13184   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13185   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13186   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13187   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13188   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13189   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13190   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13191   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13192   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13193   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13194    N_("use -mcpu=strongarm110")},
13195   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13196    N_("use -mcpu=strongarm1100")},
13197   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13198    N_("use -mcpu=strongarm1110")},
13199   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13200   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13201   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13202
13203   /* Architecture variants -- don't add any more to this list either.  */
13204   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13205   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13206   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13207   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13208   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13209   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13210   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13211   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13212   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13213   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13214   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13215   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13216   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13217   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13218   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13219   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13220   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13221   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13222
13223   /* Floating point variants -- don't add any more to this list either.  */
13224   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13225   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13226   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13227   {"mno-fpu",  NULL, &legacy_fpu, 0,
13228    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13229
13230   {NULL, NULL, NULL, 0, NULL}
13231 };
13232
13233 struct arm_cpu_option_table
13234 {
13235   char *name;
13236   int   value;
13237   /* For some CPUs we assume an FPU unless the user explicitly sets
13238      -mfpu=...  */
13239   int   default_fpu;
13240 };
13241
13242 /* This list should, at a minimum, contain all the cpu names
13243    recognized by GCC.  */
13244 static struct arm_cpu_option_table arm_cpus[] =
13245 {
13246   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13247   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13248   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13249   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13250   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13251   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13252   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13253   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13254   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13255   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13256   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13257   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13258   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13259   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13260   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13261   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13262   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13263   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13264   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13265   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13266   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13267   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13268   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13269   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13270   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13271   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13272   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13273   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13274   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13275   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13276   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13277   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13278   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13279   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13280   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13281   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13282   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13283   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13284   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13285   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13286   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13287   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13288   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13289   /* For V5 or later processors we default to using VFP; but the user
13290      should really set the FPU type explicitly.  */
13291   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13292   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13293   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13294   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13295   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13296   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13297   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13298   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13299   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13300   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13301   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13302   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13303   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13304   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13305   /* ??? XSCALE is really an architecture.  */
13306   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13307   /* ??? iwmmxt is not a processor.  */
13308   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13309   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13310   /* Maverick */
13311   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13312   {NULL, 0, 0}
13313 };
13314
13315 struct arm_arch_option_table
13316 {
13317   char *name;
13318   int   value;
13319   int   default_fpu;
13320 };
13321
13322 /* This list should, at a minimum, contain all the architecture names
13323    recognized by GCC.  */
13324 static struct arm_arch_option_table arm_archs[] =
13325 {
13326   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13327   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13328   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13329   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13330   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13331   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13332   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13333   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13334   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13335   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13336   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13337   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13338   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13339   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13340   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13341   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13342   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13343   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13344   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13345   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13346   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13347   {NULL, 0, 0}
13348 };
13349
13350 /* ISA extensions in the co-processor space.  */
13351 struct arm_arch_extension_table
13352 {
13353   char *name;
13354   int value;
13355 };
13356
13357 static struct arm_arch_extension_table arm_extensions[] =
13358 {
13359   {"maverick",          ARM_CEXT_MAVERICK},
13360   {"xscale",            ARM_CEXT_XSCALE},
13361   {"iwmmxt",            ARM_CEXT_IWMMXT},
13362   {NULL,                0}
13363 };
13364
13365 struct arm_fpu_option_table
13366 {
13367   char *name;
13368   int   value;
13369 };
13370
13371 /* This list should, at a minimum, contain all the fpu names
13372    recognized by GCC.  */
13373 static struct arm_fpu_option_table arm_fpus[] =
13374 {
13375   {"softfpa",           FPU_NONE},
13376   {"fpe",               FPU_ARCH_FPE},
13377   {"fpe2",              FPU_ARCH_FPE},
13378   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13379   {"fpa",               FPU_ARCH_FPA},
13380   {"fpa10",             FPU_ARCH_FPA},
13381   {"fpa11",             FPU_ARCH_FPA},
13382   {"arm7500fe",         FPU_ARCH_FPA},
13383   {"softvfp",           FPU_ARCH_VFP},
13384   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13385   {"vfp",               FPU_ARCH_VFP_V2},
13386   {"vfp9",              FPU_ARCH_VFP_V2},
13387   {"vfp10",             FPU_ARCH_VFP_V2},
13388   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13389   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13390   {"arm1020t",          FPU_ARCH_VFP_V1},
13391   {"arm1020e",          FPU_ARCH_VFP_V2},
13392   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13393   {"maverick",          FPU_ARCH_MAVERICK},
13394   {NULL, 0}
13395 };
13396
13397 struct arm_float_abi_option_table
13398 {
13399   char *name;
13400   int value;
13401 };
13402
13403 static struct arm_float_abi_option_table arm_float_abis[] =
13404 {
13405   {"hard",      ARM_FLOAT_ABI_HARD},
13406   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13407   {"soft",      ARM_FLOAT_ABI_SOFT},
13408   {NULL, 0}
13409 };
13410
13411 struct arm_long_option_table
13412 {
13413   char *option;         /* Substring to match.  */
13414   char *help;           /* Help information.  */
13415   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
13416   char *deprecated;     /* If non-null, print this message.  */
13417 };
13418
13419 static int
13420 arm_parse_extension (str, opt_p)
13421      char *str;
13422      int *opt_p;
13423 {
13424   while (str != NULL && *str != 0)
13425     {
13426       struct arm_arch_extension_table *opt;
13427       char *ext;
13428       int optlen;
13429
13430       if (*str != '+')
13431         {
13432           as_bad (_("invalid architectural extension"));
13433           return 0;
13434         }
13435
13436       str++;
13437       ext = strchr (str, '+');
13438
13439       if (ext != NULL)
13440         optlen = ext - str;
13441       else
13442         optlen = strlen (str);
13443
13444       if (optlen == 0)
13445         {
13446           as_bad (_("missing architectural extension"));
13447           return 0;
13448         }
13449
13450       for (opt = arm_extensions; opt->name != NULL; opt++)
13451         if (strncmp (opt->name, str, optlen) == 0)
13452           {
13453             *opt_p |= opt->value;
13454             break;
13455           }
13456
13457       if (opt->name == NULL)
13458         {
13459           as_bad (_("unknown architectural extnsion `%s'"), str);
13460           return 0;
13461         }
13462
13463       str = ext;
13464     };
13465
13466   return 1;
13467 }
13468
13469 static int
13470 arm_parse_cpu (str)
13471      char *str;
13472 {
13473   struct arm_cpu_option_table *opt;
13474   char *ext = strchr (str, '+');
13475   int optlen;
13476
13477   if (ext != NULL)
13478     optlen = ext - str;
13479   else
13480     optlen = strlen (str);
13481
13482   if (optlen == 0)
13483     {
13484       as_bad (_("missing cpu name `%s'"), str);
13485       return 0;
13486     }
13487
13488   for (opt = arm_cpus; opt->name != NULL; opt++)
13489     if (strncmp (opt->name, str, optlen) == 0)
13490       {
13491         mcpu_cpu_opt = opt->value;
13492         mcpu_fpu_opt = opt->default_fpu;
13493
13494         if (ext != NULL)
13495           return arm_parse_extension (ext, &mcpu_cpu_opt);
13496
13497         return 1;
13498       }
13499
13500   as_bad (_("unknown cpu `%s'"), str);
13501   return 0;
13502 }
13503
13504 static int
13505 arm_parse_arch (str)
13506      char *str;
13507 {
13508   struct arm_arch_option_table *opt;
13509   char *ext = strchr (str, '+');
13510   int optlen;
13511
13512   if (ext != NULL)
13513     optlen = ext - str;
13514   else
13515     optlen = strlen (str);
13516
13517   if (optlen == 0)
13518     {
13519       as_bad (_("missing architecture name `%s'"), str);
13520       return 0;
13521     }
13522
13523
13524   for (opt = arm_archs; opt->name != NULL; opt++)
13525     if (strcmp (opt->name, str) == 0)
13526       {
13527         march_cpu_opt = opt->value;
13528         march_fpu_opt = opt->default_fpu;
13529
13530         if (ext != NULL)
13531           return arm_parse_extension (ext, &march_cpu_opt);
13532
13533         return 1;
13534       }
13535
13536   as_bad (_("unknown architecture `%s'\n"), str);
13537   return 0;
13538 }
13539
13540 static int
13541 arm_parse_fpu (str)
13542      char *str;
13543 {
13544   struct arm_fpu_option_table *opt;
13545
13546   for (opt = arm_fpus; opt->name != NULL; opt++)
13547     if (strcmp (opt->name, str) == 0)
13548       {
13549         mfpu_opt = opt->value;
13550         return 1;
13551       }
13552
13553   as_bad (_("unknown floating point format `%s'\n"), str);
13554   return 0;
13555 }
13556
13557 static int
13558 arm_parse_float_abi (str)
13559      char * str;
13560 {
13561   struct arm_float_abi_option_table *opt;
13562
13563   for (opt = arm_float_abis; opt->name != NULL; opt++)
13564     if (strcmp (opt->name, str) == 0)
13565       {
13566         mfloat_abi_opt = opt->value;
13567         return 1;
13568       }
13569
13570   as_bad (_("unknown floating point abi `%s'\n"), str);
13571   return 0;
13572 }
13573
13574 struct arm_long_option_table arm_long_opts[] =
13575 {
13576   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13577    arm_parse_cpu, NULL},
13578   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13579    arm_parse_arch, NULL},
13580   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13581    arm_parse_fpu, NULL},
13582   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13583    arm_parse_float_abi, NULL},
13584   {NULL, NULL, 0, NULL}
13585 };
13586
13587 int
13588 md_parse_option (c, arg)
13589      int    c;
13590      char * arg;
13591 {
13592   struct arm_option_table *opt;
13593   struct arm_long_option_table *lopt;
13594
13595   switch (c)
13596     {
13597 #ifdef OPTION_EB
13598     case OPTION_EB:
13599       target_big_endian = 1;
13600       break;
13601 #endif
13602
13603 #ifdef OPTION_EL
13604     case OPTION_EL:
13605       target_big_endian = 0;
13606       break;
13607 #endif
13608
13609     case 'a':
13610       /* Listing option.  Just ignore these, we don't support additional
13611          ones.  */
13612       return 0;
13613
13614     default:
13615       for (opt = arm_opts; opt->option != NULL; opt++)
13616         {
13617           if (c == opt->option[0]
13618               && ((arg == NULL && opt->option[1] == 0)
13619                   || strcmp (arg, opt->option + 1) == 0))
13620             {
13621 #if WARN_DEPRECATED
13622               /* If the option is deprecated, tell the user.  */
13623               if (opt->deprecated != NULL)
13624                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13625                            arg ? arg : "", _(opt->deprecated));
13626 #endif
13627
13628               if (opt->var != NULL)
13629                 *opt->var = opt->value;
13630
13631               return 1;
13632             }
13633         }
13634
13635       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13636         {
13637           /* These options are expected to have an argument.  */
13638           if (c == lopt->option[0]
13639               && arg != NULL
13640               && strncmp (arg, lopt->option + 1,
13641                           strlen (lopt->option + 1)) == 0)
13642             {
13643 #if WARN_DEPRECATED
13644               /* If the option is deprecated, tell the user.  */
13645               if (lopt->deprecated != NULL)
13646                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13647                            _(lopt->deprecated));
13648 #endif
13649
13650               /* Call the sup-option parser.  */
13651               return (*lopt->func)(arg + strlen (lopt->option) - 1);
13652             }
13653         }
13654
13655       as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13656       return 0;
13657     }
13658
13659   return 1;
13660 }
13661
13662 void
13663 md_show_usage (fp)
13664      FILE * fp;
13665 {
13666   struct arm_option_table *opt;
13667   struct arm_long_option_table *lopt;
13668
13669   fprintf (fp, _(" ARM-specific assembler options:\n"));
13670
13671   for (opt = arm_opts; opt->option != NULL; opt++)
13672     if (opt->help != NULL)
13673       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13674
13675   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13676     if (lopt->help != NULL)
13677       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13678
13679 #ifdef OPTION_EB
13680   fprintf (fp, _("\
13681   -EB                     assemble code for a big-endian cpu\n"));
13682 #endif
13683
13684 #ifdef OPTION_EL
13685   fprintf (fp, _("\
13686   -EL                     assemble code for a little-endian cpu\n"));
13687 #endif
13688 }
13689
13690 /* We need to be able to fix up arbitrary expressions in some statements.
13691    This is so that we can handle symbols that are an arbitrary distance from
13692    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13693    which returns part of an address in a form which will be valid for
13694    a data instruction.  We do this by pushing the expression into a symbol
13695    in the expr_section, and creating a fix for that.  */
13696
13697 static void
13698 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13699      fragS *       frag;
13700      int           where;
13701      short int     size;
13702      expressionS * exp;
13703      int           pc_rel;
13704      int           reloc;
13705 {
13706   fixS *           new_fix;
13707   arm_fix_data *   arm_data;
13708
13709   switch (exp->X_op)
13710     {
13711     case O_constant:
13712     case O_symbol:
13713     case O_add:
13714     case O_subtract:
13715       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13716       break;
13717
13718     default:
13719       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13720                          pc_rel, reloc);
13721       break;
13722     }
13723
13724   /* Mark whether the fix is to a THUMB instruction, or an ARM
13725      instruction.  */
13726   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13727   new_fix->tc_fix_data = (PTR) arm_data;
13728   arm_data->thumb_mode = thumb_mode;
13729 }
13730
13731 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13732
13733 void
13734 cons_fix_new_arm (frag, where, size, exp)
13735      fragS *       frag;
13736      int           where;
13737      int           size;
13738      expressionS * exp;
13739 {
13740   bfd_reloc_code_real_type type;
13741   int pcrel = 0;
13742
13743   /* Pick a reloc.
13744      FIXME: @@ Should look at CPU word size.  */
13745   switch (size)
13746     {
13747     case 1:
13748       type = BFD_RELOC_8;
13749       break;
13750     case 2:
13751       type = BFD_RELOC_16;
13752       break;
13753     case 4:
13754     default:
13755       type = BFD_RELOC_32;
13756       break;
13757     case 8:
13758       type = BFD_RELOC_64;
13759       break;
13760     }
13761
13762   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13763 }
13764
13765 /* A good place to do this, although this was probably not intended
13766    for this kind of use.  We need to dump the literal pool before
13767    references are made to a null symbol pointer.  */
13768
13769 void
13770 arm_cleanup ()
13771 {
13772   literal_pool * pool;
13773
13774   for (pool = list_of_pools; pool; pool = pool->next)
13775     {
13776       /* Put it at the end of the relevent section.  */
13777       subseg_set (pool->section, pool->sub_section);
13778       s_ltorg (0);
13779     }
13780 }
13781
13782 void
13783 arm_start_line_hook ()
13784 {
13785   last_label_seen = NULL;
13786 }
13787
13788 void
13789 arm_frob_label (sym)
13790      symbolS * sym;
13791 {
13792   last_label_seen = sym;
13793
13794   ARM_SET_THUMB (sym, thumb_mode);
13795
13796 #if defined OBJ_COFF || defined OBJ_ELF
13797   ARM_SET_INTERWORK (sym, support_interwork);
13798 #endif
13799
13800   /* Note - do not allow local symbols (.Lxxx) to be labeled
13801      as Thumb functions.  This is because these labels, whilst
13802      they exist inside Thumb code, are not the entry points for
13803      possible ARM->Thumb calls.  Also, these labels can be used
13804      as part of a computed goto or switch statement.  eg gcc
13805      can generate code that looks like this:
13806
13807                 ldr  r2, [pc, .Laaa]
13808                 lsl  r3, r3, #2
13809                 ldr  r2, [r3, r2]
13810                 mov  pc, r2
13811
13812        .Lbbb:  .word .Lxxx
13813        .Lccc:  .word .Lyyy
13814        ..etc...
13815        .Laaa:   .word Lbbb
13816
13817      The first instruction loads the address of the jump table.
13818      The second instruction converts a table index into a byte offset.
13819      The third instruction gets the jump address out of the table.
13820      The fourth instruction performs the jump.
13821
13822      If the address stored at .Laaa is that of a symbol which has the
13823      Thumb_Func bit set, then the linker will arrange for this address
13824      to have the bottom bit set, which in turn would mean that the
13825      address computation performed by the third instruction would end
13826      up with the bottom bit set.  Since the ARM is capable of unaligned
13827      word loads, the instruction would then load the incorrect address
13828      out of the jump table, and chaos would ensue.  */
13829   if (label_is_thumb_function_name
13830       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13831       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13832     {
13833       /* When the address of a Thumb function is taken the bottom
13834          bit of that address should be set.  This will allow
13835          interworking between Arm and Thumb functions to work
13836          correctly.  */
13837
13838       THUMB_SET_FUNC (sym, 1);
13839
13840       label_is_thumb_function_name = FALSE;
13841     }
13842 }
13843
13844 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13845    ARM ones.  */
13846
13847 void
13848 arm_adjust_symtab ()
13849 {
13850 #ifdef OBJ_COFF
13851   symbolS * sym;
13852
13853   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13854     {
13855       if (ARM_IS_THUMB (sym))
13856         {
13857           if (THUMB_IS_FUNC (sym))
13858             {
13859               /* Mark the symbol as a Thumb function.  */
13860               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13861                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13862                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13863
13864               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13865                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13866               else
13867                 as_bad (_("%s: unexpected function type: %d"),
13868                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13869             }
13870           else switch (S_GET_STORAGE_CLASS (sym))
13871             {
13872             case C_EXT:
13873               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13874               break;
13875             case C_STAT:
13876               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13877               break;
13878             case C_LABEL:
13879               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13880               break;
13881             default:
13882               /* Do nothing.  */
13883               break;
13884             }
13885         }
13886
13887       if (ARM_IS_INTERWORK (sym))
13888         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13889     }
13890 #endif
13891 #ifdef OBJ_ELF
13892   symbolS * sym;
13893   char      bind;
13894
13895   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13896     {
13897       if (ARM_IS_THUMB (sym))
13898         {
13899           elf_symbol_type * elf_sym;
13900
13901           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13902           bind = ELF_ST_BIND (elf_sym);
13903
13904           /* If it's a .thumb_func, declare it as so,
13905              otherwise tag label as .code 16.  */
13906           if (THUMB_IS_FUNC (sym))
13907             elf_sym->internal_elf_sym.st_info =
13908               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13909           else
13910             elf_sym->internal_elf_sym.st_info =
13911               ELF_ST_INFO (bind, STT_ARM_16BIT);
13912         }
13913     }
13914 #endif
13915 }
13916
13917 int
13918 arm_data_in_code ()
13919 {
13920   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13921     {
13922       *input_line_pointer = '/';
13923       input_line_pointer += 5;
13924       *input_line_pointer = 0;
13925       return 1;
13926     }
13927
13928   return 0;
13929 }
13930
13931 char *
13932 arm_canonicalize_symbol_name (name)
13933      char * name;
13934 {
13935   int len;
13936
13937   if (thumb_mode && (len = strlen (name)) > 5
13938       && streq (name + len - 5, "/data"))
13939     *(name + len - 5) = 0;
13940
13941   return name;
13942 }
13943
13944 #if defined OBJ_COFF || defined OBJ_ELF
13945 void
13946 arm_validate_fix (fixP)
13947      fixS * fixP;
13948 {
13949   /* If the destination of the branch is a defined symbol which does not have
13950      the THUMB_FUNC attribute, then we must be calling a function which has
13951      the (interfacearm) attribute.  We look for the Thumb entry point to that
13952      function and change the branch to refer to that function instead.  */
13953   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13954       && fixP->fx_addsy != NULL
13955       && S_IS_DEFINED (fixP->fx_addsy)
13956       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13957     {
13958       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13959     }
13960 }
13961 #endif
13962
13963 int
13964 arm_force_relocation (fixp)
13965      struct fix * fixp;
13966 {
13967 #if defined (OBJ_COFF) && defined (TE_PE)
13968   if (fixp->fx_r_type == BFD_RELOC_RVA)
13969     return 1;
13970 #endif
13971 #ifdef OBJ_ELF
13972   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13973       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13974       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13975       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13976     return 1;
13977 #endif
13978
13979   /* Resolve these relocations even if the symbol is extern or weak.  */
13980   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13981       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13982       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13983     return 0;
13984
13985   return generic_force_reloc (fixp);
13986 }
13987
13988 #ifdef OBJ_COFF
13989 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13990    local labels from being added to the output symbol table when they
13991    are used with the ADRL pseudo op.  The ADRL relocation should always
13992    be resolved before the binbary is emitted, so it is safe to say that
13993    it is adjustable.  */
13994
13995 bfd_boolean
13996 arm_fix_adjustable (fixP)
13997    fixS * fixP;
13998 {
13999   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14000     return 1;
14001   return 0;
14002 }
14003 #endif
14004
14005 #ifdef OBJ_ELF
14006 /* Relocations against Thumb function names must be left unadjusted,
14007    so that the linker can use this information to correctly set the
14008    bottom bit of their addresses.  The MIPS version of this function
14009    also prevents relocations that are mips-16 specific, but I do not
14010    know why it does this.
14011
14012    FIXME:
14013    There is one other problem that ought to be addressed here, but
14014    which currently is not:  Taking the address of a label (rather
14015    than a function) and then later jumping to that address.  Such
14016    addresses also ought to have their bottom bit set (assuming that
14017    they reside in Thumb code), but at the moment they will not.  */
14018
14019 bfd_boolean
14020 arm_fix_adjustable (fixP)
14021    fixS * fixP;
14022 {
14023   if (fixP->fx_addsy == NULL)
14024     return 1;
14025
14026   if (THUMB_IS_FUNC (fixP->fx_addsy)
14027       && fixP->fx_subsy == NULL)
14028     return 0;
14029
14030   /* We need the symbol name for the VTABLE entries.  */
14031   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14032       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14033     return 0;
14034
14035   /* Don't allow symbols to be discarded on GOT related relocs.  */
14036   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14037       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14038       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14039     return 0;
14040
14041   return 1;
14042 }
14043
14044 const char *
14045 elf32_arm_target_format ()
14046 {
14047   if (target_big_endian)
14048     {
14049       if (target_oabi)
14050         return "elf32-bigarm-oabi";
14051       else
14052         return "elf32-bigarm";
14053     }
14054   else
14055     {
14056       if (target_oabi)
14057         return "elf32-littlearm-oabi";
14058       else
14059         return "elf32-littlearm";
14060     }
14061 }
14062
14063 void
14064 armelf_frob_symbol (symp, puntp)
14065      symbolS * symp;
14066      int *     puntp;
14067 {
14068   elf_frob_symbol (symp, puntp);
14069 }
14070
14071 static bfd_reloc_code_real_type
14072 arm_parse_reloc ()
14073 {
14074   char         id [16];
14075   char *       ip;
14076   unsigned int i;
14077   static struct
14078   {
14079     char * str;
14080     int    len;
14081     bfd_reloc_code_real_type reloc;
14082   }
14083   reloc_map[] =
14084   {
14085 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14086     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14087     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14088     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14089        branch instructions generated by GCC for PLT relocs.  */
14090     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14091     { NULL, 0,         BFD_RELOC_UNUSED }
14092 #undef MAP
14093   };
14094
14095   for (i = 0, ip = input_line_pointer;
14096        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14097        i++, ip++)
14098     id[i] = TOLOWER (*ip);
14099
14100   for (i = 0; reloc_map[i].str; i++)
14101     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14102       break;
14103
14104   input_line_pointer += reloc_map[i].len;
14105
14106   return reloc_map[i].reloc;
14107 }
14108
14109 static void
14110 s_arm_elf_cons (nbytes)
14111      int nbytes;
14112 {
14113   expressionS exp;
14114
14115 #ifdef md_flush_pending_output
14116   md_flush_pending_output ();
14117 #endif
14118
14119   if (is_it_end_of_statement ())
14120     {
14121       demand_empty_rest_of_line ();
14122       return;
14123     }
14124
14125 #ifdef md_cons_align
14126   md_cons_align (nbytes);
14127 #endif
14128
14129   mapping_state (MAP_DATA);
14130   do
14131     {
14132       bfd_reloc_code_real_type reloc;
14133
14134       expression (& exp);
14135
14136       if (exp.X_op == O_symbol
14137           && * input_line_pointer == '('
14138           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14139         {
14140           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14141           int size = bfd_get_reloc_size (howto);
14142
14143           if (size > nbytes)
14144             as_bad ("%s relocations do not fit in %d bytes",
14145                     howto->name, nbytes);
14146           else
14147             {
14148               register char *p = frag_more ((int) nbytes);
14149               int offset = nbytes - size;
14150
14151               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14152                            &exp, 0, reloc);
14153             }
14154         }
14155       else
14156         emit_expr (&exp, (unsigned int) nbytes);
14157     }
14158   while (*input_line_pointer++ == ',');
14159
14160   /* Put terminator back into stream.  */
14161   input_line_pointer --;
14162   demand_empty_rest_of_line ();
14163 }
14164
14165 #endif /* OBJ_ELF */
14166
14167 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14168    of an rs_align_code fragment.  */
14169
14170 void
14171 arm_handle_align (fragP)
14172      fragS *fragP;
14173 {
14174   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14175   static char const thumb_noop[2] = { 0xc0, 0x46 };
14176   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14177   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14178
14179   int bytes, fix, noop_size;
14180   char * p;
14181   const char * noop;
14182
14183   if (fragP->fr_type != rs_align_code)
14184     return;
14185
14186   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14187   p = fragP->fr_literal + fragP->fr_fix;
14188   fix = 0;
14189
14190   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14191     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14192
14193   if (fragP->tc_frag_data)
14194     {
14195       if (target_big_endian)
14196         noop = thumb_bigend_noop;
14197       else
14198         noop = thumb_noop;
14199       noop_size = sizeof (thumb_noop);
14200     }
14201   else
14202     {
14203       if (target_big_endian)
14204         noop = arm_bigend_noop;
14205       else
14206         noop = arm_noop;
14207       noop_size = sizeof (arm_noop);
14208     }
14209
14210   if (bytes & (noop_size - 1))
14211     {
14212       fix = bytes & (noop_size - 1);
14213       memset (p, 0, fix);
14214       p += fix;
14215       bytes -= fix;
14216     }
14217
14218   while (bytes >= noop_size)
14219     {
14220       memcpy (p, noop, noop_size);
14221       p += noop_size;
14222       bytes -= noop_size;
14223       fix += noop_size;
14224     }
14225
14226   fragP->fr_fix += fix;
14227   fragP->fr_var = noop_size;
14228 }
14229
14230 /* Called from md_do_align.  Used to create an alignment
14231    frag in a code section.  */
14232
14233 void
14234 arm_frag_align_code (n, max)
14235      int n;
14236      int max;
14237 {
14238   char * p;
14239
14240   /* We assume that there will never be a requirement
14241      to support alignments greater than 32 bytes.  */
14242   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14243     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14244
14245   p = frag_var (rs_align_code,
14246                 MAX_MEM_FOR_RS_ALIGN_CODE,
14247                 1,
14248                 (relax_substateT) max,
14249                 (symbolS *) NULL,
14250                 (offsetT) n,
14251                 (char *) NULL);
14252   *p = 0;
14253
14254 }
14255
14256 /* Perform target specific initialisation of a frag.  */
14257
14258 void
14259 arm_init_frag (fragP)
14260      fragS *fragP;
14261 {
14262   /* Record whether this frag is in an ARM or a THUMB area.  */
14263   fragP->tc_frag_data = thumb_mode;
14264 }