2004-10-12 Paul Brook <paul@codesourcery.com>
[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, 2004
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         Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8         Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
9
10    This file is part of GAS, the GNU Assembler.
11
12    GAS is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2, or (at your option)
15    any later version.
16
17    GAS is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with GAS; see the file COPYING.  If not, write to the Free
24    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25    02111-1307, USA.  */
26
27 #include <string.h>
28 #define  NO_RELOC 0
29 #include "as.h"
30 #include "safe-ctype.h"
31
32 /* Need TARGET_CPU.  */
33 #include "config.h"
34 #include "subsegs.h"
35 #include "obstack.h"
36 #include "symbols.h"
37 #include "listing.h"
38
39 #include "opcode/arm.h"
40
41 #ifdef OBJ_ELF
42 #include "elf/arm.h"
43 #include "dwarf2dbg.h"
44 #endif
45
46 /* XXX Set this to 1 after the next binutils release.  */
47 #define WARN_DEPRECATED 0
48
49 #ifdef OBJ_ELF
50 /* Must be at least the size of the largest unwind opcode (currently two).  */
51 #define ARM_OPCODE_CHUNK_SIZE 8
52
53 /* This structure holds the unwinding state.  */
54
55 static struct
56 {
57   symbolS *       proc_start;
58   symbolS *       table_entry;
59   symbolS *       personality_routine;
60   int             personality_index;
61   /* The segment containing the function.  */
62   segT            saved_seg;
63   subsegT         saved_subseg;
64   /* Opcodes generated from this function.  */
65   unsigned char * opcodes;
66   int             opcode_count;
67   int             opcode_alloc;
68   /* The number of bytes pushed to the stack.  */
69   offsetT         frame_size;
70   /* We don't add stack adjustment opcodes immediately so that we can merge
71      multiple adjustments.  We can also omit the final adjustment
72      when using a frame pointer.  */
73   offsetT         pending_offset;
74   /* These two fields are set by both unwind_movsp and unwind_setfp.  They
75      hold the reg+offset to use when restoring sp from a frame pointer.  */
76   offsetT         fp_offset;
77   int             fp_reg;
78   /* Nonzero if an unwind_setfp directive has been seen.  */
79   unsigned        fp_used:1;
80   /* Nonzero if the last opcode restores sp from fp_reg.  */
81   unsigned        sp_restored:1;
82 } unwind;
83
84 #endif /* OBJ_ELF */
85
86 enum arm_float_abi
87 {
88   ARM_FLOAT_ABI_HARD,
89   ARM_FLOAT_ABI_SOFTFP,
90   ARM_FLOAT_ABI_SOFT
91 };
92
93 /* Types of processor to assemble for.  */
94 #define ARM_1           ARM_ARCH_V1
95 #define ARM_2           ARM_ARCH_V2
96 #define ARM_3           ARM_ARCH_V2S
97 #define ARM_250         ARM_ARCH_V2S
98 #define ARM_6           ARM_ARCH_V3
99 #define ARM_7           ARM_ARCH_V3
100 #define ARM_8           ARM_ARCH_V4
101 #define ARM_9           ARM_ARCH_V4T
102 #define ARM_STRONG      ARM_ARCH_V4
103 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
104
105 #ifndef CPU_DEFAULT
106 #if defined __XSCALE__
107 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
108 #else
109 #if defined __thumb__
110 #define CPU_DEFAULT     (ARM_ARCH_V5T)
111 #else
112 #define CPU_DEFAULT     ARM_ANY
113 #endif
114 #endif
115 #endif
116
117 #ifdef TE_LINUX
118 #define FPU_DEFAULT FPU_ARCH_FPA
119 #endif
120
121 #ifdef TE_NetBSD
122 #ifdef OBJ_ELF
123 #define FPU_DEFAULT FPU_ARCH_VFP        /* Soft-float, but VFP order.  */
124 #else
125 /* Legacy a.out format.  */
126 #define FPU_DEFAULT FPU_ARCH_FPA        /* Soft-float, but FPA order.  */
127 #endif
128 #endif
129
130 /* For backwards compatibility we default to the FPA.  */
131 #ifndef FPU_DEFAULT
132 #define FPU_DEFAULT FPU_ARCH_FPA
133 #endif
134
135 #define streq(a, b)           (strcmp (a, b) == 0)
136 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
137
138 static unsigned long cpu_variant;
139 static int target_oabi = 0;
140
141 /* Flags stored in private area of BFD structure.  */
142 static int uses_apcs_26      = FALSE;
143 static int atpcs             = FALSE;
144 static int support_interwork = FALSE;
145 static int uses_apcs_float   = FALSE;
146 static int pic_code          = FALSE;
147
148 /* Variables that we set while parsing command-line options.  Once all
149    options have been read we re-process these values to set the real
150    assembly flags.  */
151 static int legacy_cpu = -1;
152 static int legacy_fpu = -1;
153
154 static int mcpu_cpu_opt = -1;
155 static int mcpu_fpu_opt = -1;
156 static int march_cpu_opt = -1;
157 static int march_fpu_opt = -1;
158 static int mfpu_opt = -1;
159 static int mfloat_abi_opt = -1;
160 #ifdef OBJ_ELF
161 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
162 #endif
163
164 /* This array holds the chars that always start a comment.  If the
165    pre-processor is disabled, these aren't very useful.  */
166 const char comment_chars[] = "@";
167
168 /* This array holds the chars that only start a comment at the beginning of
169    a line.  If the line seems to have the form '# 123 filename'
170    .line and .file directives will appear in the pre-processed output.  */
171 /* Note that input_file.c hand checks for '#' at the beginning of the
172    first line of the input file.  This is because the compiler outputs
173    #NO_APP at the beginning of its output.  */
174 /* Also note that comments like this one will always work.  */
175 const char line_comment_chars[] = "#";
176
177 const char line_separator_chars[] = ";";
178
179 /* Chars that can be used to separate mant
180    from exp in floating point numbers.  */
181 const char EXP_CHARS[] = "eE";
182
183 /* Chars that mean this number is a floating point constant.  */
184 /* As in 0f12.456  */
185 /* or    0d1.2345e12  */
186
187 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
188
189 /* Prefix characters that indicate the start of an immediate
190    value.  */
191 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
192
193 #ifdef OBJ_ELF
194 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
195 symbolS * GOT_symbol;
196 #endif
197
198 /* Size of relocation record.  */
199 const int md_reloc_size = 8;
200
201 /* 0: assemble for ARM,
202    1: assemble for Thumb,
203    2: assemble for Thumb even though target CPU does not support thumb
204       instructions.  */
205 static int thumb_mode = 0;
206
207 typedef struct arm_fix
208 {
209   int thumb_mode;
210 } arm_fix_data;
211
212 struct arm_it
213 {
214   const char *  error;
215   unsigned long instruction;
216   int           size;
217   struct
218   {
219     bfd_reloc_code_real_type type;
220     expressionS              exp;
221     int                      pc_rel;
222   } reloc;
223 };
224
225 struct arm_it inst;
226
227 enum asm_shift_index
228 {
229   SHIFT_LSL = 0,
230   SHIFT_LSR,
231   SHIFT_ASR,
232   SHIFT_ROR,
233   SHIFT_RRX
234 };
235
236 struct asm_shift_properties
237 {
238   enum asm_shift_index index;
239   unsigned long        bit_field;
240   unsigned int         allows_0  : 1;
241   unsigned int         allows_32 : 1;
242 };
243
244 static const struct asm_shift_properties shift_properties [] =
245 {
246   { SHIFT_LSL, 0,    1, 0},
247   { SHIFT_LSR, 0x20, 0, 1},
248   { SHIFT_ASR, 0x40, 0, 1},
249   { SHIFT_ROR, 0x60, 0, 0},
250   { SHIFT_RRX, 0x60, 0, 0}
251 };
252
253 struct asm_shift_name
254 {
255   const char *                        name;
256   const struct asm_shift_properties * properties;
257 };
258
259 static const struct asm_shift_name shift_names [] =
260 {
261   { "asl", shift_properties + SHIFT_LSL },
262   { "lsl", shift_properties + SHIFT_LSL },
263   { "lsr", shift_properties + SHIFT_LSR },
264   { "asr", shift_properties + SHIFT_ASR },
265   { "ror", shift_properties + SHIFT_ROR },
266   { "rrx", shift_properties + SHIFT_RRX },
267   { "ASL", shift_properties + SHIFT_LSL },
268   { "LSL", shift_properties + SHIFT_LSL },
269   { "LSR", shift_properties + SHIFT_LSR },
270   { "ASR", shift_properties + SHIFT_ASR },
271   { "ROR", shift_properties + SHIFT_ROR },
272   { "RRX", shift_properties + SHIFT_RRX }
273 };
274
275 /* Any kind of shift is accepted.  */
276 #define NO_SHIFT_RESTRICT 1
277 /* The shift operand must be an immediate value, not a register.  */
278 #define SHIFT_IMMEDIATE   0
279 /* The shift must be LSL or ASR and the operand must be an immediate.  */
280 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
281 /* The shift must be ASR and the operand must be an immediate.  */
282 #define SHIFT_ASR_IMMEDIATE 3
283 /* The shift must be LSL and the operand must be an immediate.  */
284 #define SHIFT_LSL_IMMEDIATE 4
285
286 #define NUM_FLOAT_VALS 8
287
288 const char * fp_const[] =
289 {
290   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
291 };
292
293 /* Number of littlenums required to hold an extended precision number.  */
294 #define MAX_LITTLENUMS 6
295
296 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
297
298 #define FAIL    (-1)
299 #define SUCCESS (0)
300
301 /* Whether a Co-processor load/store operation accepts write-back forms.  */
302 #define CP_WB_OK 1
303 #define CP_NO_WB 0
304
305 #define SUFF_S 1
306 #define SUFF_D 2
307 #define SUFF_E 3
308 #define SUFF_P 4
309
310 #define CP_T_X   0x00008000
311 #define CP_T_Y   0x00400000
312 #define CP_T_Pre 0x01000000
313 #define CP_T_UD  0x00800000
314 #define CP_T_WB  0x00200000
315
316 #define CONDS_BIT        0x00100000
317 #define LOAD_BIT         0x00100000
318
319 #define DOUBLE_LOAD_FLAG 0x00000001
320
321 struct asm_cond
322 {
323   const char *  template;
324   unsigned long value;
325 };
326
327 #define COND_ALWAYS 0xe0000000
328 #define COND_MASK   0xf0000000
329
330 static const struct asm_cond conds[] =
331 {
332   {"eq", 0x00000000},
333   {"ne", 0x10000000},
334   {"cs", 0x20000000}, {"hs", 0x20000000},
335   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
336   {"mi", 0x40000000},
337   {"pl", 0x50000000},
338   {"vs", 0x60000000},
339   {"vc", 0x70000000},
340   {"hi", 0x80000000},
341   {"ls", 0x90000000},
342   {"ge", 0xa0000000},
343   {"lt", 0xb0000000},
344   {"gt", 0xc0000000},
345   {"le", 0xd0000000},
346   {"al", 0xe0000000},
347   {"nv", 0xf0000000}
348 };
349
350 struct asm_psr
351 {
352   const char *template;
353   bfd_boolean cpsr;
354   unsigned long field;
355 };
356
357 /* The bit that distinguishes CPSR and SPSR.  */
358 #define SPSR_BIT   (1 << 22)
359
360 /* How many bits to shift the PSR_xxx bits up by.  */
361 #define PSR_SHIFT  16
362
363 #define PSR_c   (1 << 0)
364 #define PSR_x   (1 << 1)
365 #define PSR_s   (1 << 2)
366 #define PSR_f   (1 << 3)
367
368 static const struct asm_psr psrs[] =
369 {
370   {"CPSR",      TRUE,  PSR_c | PSR_f},
371   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
372   {"SPSR",      FALSE, PSR_c | PSR_f},
373   {"SPSR_all",  FALSE, PSR_c | PSR_f},
374   {"CPSR_flg",  TRUE,  PSR_f},
375   {"CPSR_f",    TRUE,  PSR_f},
376   {"SPSR_flg",  FALSE, PSR_f},
377   {"SPSR_f",    FALSE, PSR_f},
378   {"CPSR_c",    TRUE,  PSR_c},
379   {"CPSR_ctl",  TRUE,  PSR_c},
380   {"SPSR_c",    FALSE, PSR_c},
381   {"SPSR_ctl",  FALSE, PSR_c},
382   {"CPSR_x",    TRUE,  PSR_x},
383   {"CPSR_s",    TRUE,  PSR_s},
384   {"SPSR_x",    FALSE, PSR_x},
385   {"SPSR_s",    FALSE, PSR_s},
386   /* Combinations of flags.  */
387   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
388   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
389   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
390   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
391   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
392   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
393   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
394   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
395   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
396   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
397   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
398   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
399   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
400   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
401   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
402   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
403   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
404   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
405   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
406   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
407   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
408   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
409   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
410   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
411   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
412   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
413   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
414   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
415   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
416   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
417   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
418   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
419   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
420   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
421   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
422   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
423   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
424   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
425   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
426   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
427   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
428   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
429   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
430   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
431   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
432   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
433   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
434   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
435   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
436   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
437   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
438   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
439   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
440   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
441   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
442   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
443   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
444   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
445   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
446   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
447   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
448   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
449   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
450   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
451   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
452   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
453   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
454   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
455   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
456   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
457   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
458   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
459   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
460   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
461   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
462   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
463   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
464   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
465   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
466   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
467   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
468   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
469   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
470   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
471   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
472   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
473   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
474   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
475   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
476   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
477   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
478   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
479   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
480   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
481   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
482   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
483   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
484   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
485   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
486   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
487   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
488   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
489   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
490   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
491   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
492   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
493   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
494   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
495   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
496   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
497   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
498   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
499   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
500   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
501   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
502   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
503   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
504   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
505   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
506   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
507 };
508
509 enum wreg_type
510   {
511     IWMMXT_REG_WR = 0,
512     IWMMXT_REG_WC = 1,
513     IWMMXT_REG_WR_OR_WC = 2,
514     IWMMXT_REG_WCG
515   };
516
517 enum iwmmxt_insn_type
518 {
519   check_rd,
520   check_wr,
521   check_wrwr,
522   check_wrwrwr,
523   check_wrwrwcg,
524   check_tbcst,
525   check_tmovmsk,
526   check_tmia,
527   check_tmcrr,
528   check_tmrrc,
529   check_tmcr,
530   check_tmrc,
531   check_tinsr,
532   check_textrc,
533   check_waligni,
534   check_textrm,
535   check_wshufh
536 };
537
538 enum vfp_dp_reg_pos
539 {
540   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
541 };
542
543 enum vfp_sp_reg_pos
544 {
545   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
546 };
547
548 enum vfp_ldstm_type
549 {
550   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
551 };
552
553 /* VFP system registers.  */
554 struct vfp_reg
555 {
556   const char *name;
557   unsigned long regno;
558 };
559
560 static const struct vfp_reg vfp_regs[] =
561 {
562   {"fpsid", 0x00000000},
563   {"FPSID", 0x00000000},
564   {"fpscr", 0x00010000},
565   {"FPSCR", 0x00010000},
566   {"fpexc", 0x00080000},
567   {"FPEXC", 0x00080000}
568 };
569
570 /* Structure for a hash table entry for a register.  */
571 struct reg_entry
572 {
573   const char * name;
574   int          number;
575   bfd_boolean  builtin;
576 };
577
578 /* Some well known registers that we refer to directly elsewhere.  */
579 #define REG_SP  13
580 #define REG_LR  14
581 #define REG_PC  15
582
583 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
584 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
585 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
586
587 /* These are the standard names.  Users can add aliases with .req.
588    and delete them with .unreq.  */
589
590 /* Integer Register Numbers.  */
591 static const struct reg_entry rn_table[] =
592 {
593   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
594   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
595   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
596   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
597   /* ATPCS Synonyms.  */
598   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
599   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
600   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
601   /* Well-known aliases.  */
602   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
603   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
604   {NULL, 0, TRUE}
605 };
606
607 #define WR_PREFIX 0x200
608 #define WC_PREFIX 0x400
609
610 static const struct reg_entry iwmmxt_table[] =
611 {
612   /* Intel Wireless MMX technology register names.  */
613   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
614   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
615   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
616   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
617   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
618   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
619   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
620   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
621   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
622   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
623   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
624   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
625
626   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
627   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
628   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
629   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
630   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
631   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
632   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
633   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
634   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
635   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
636   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
637   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
638   {NULL, 0, TRUE}
639 };
640
641 /* Co-processor Numbers.  */
642 static const struct reg_entry cp_table[] =
643 {
644   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
645   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
646   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
647   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
648   {NULL, 0, TRUE}
649 };
650
651 /* Co-processor Register Numbers.  */
652 static const struct reg_entry cn_table[] =
653 {
654   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
655   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
656   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
657   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
658   /* Not really valid, but kept for back-wards compatibility.  */
659   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
660   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
661   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
662   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
663   {NULL, 0, TRUE}
664 };
665
666 /* FPA Registers.  */
667 static const struct reg_entry fn_table[] =
668 {
669   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
670   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
671   {NULL, 0, TRUE}
672 };
673
674 /* VFP SP Registers.  */
675 static const struct reg_entry sn_table[] =
676 {
677   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
678   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
679   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
680   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
681   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
682   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
683   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
684   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
685   {NULL, 0, TRUE}
686 };
687
688 /* VFP DP Registers.  */
689 static const struct reg_entry dn_table[] =
690 {
691   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
692   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
693   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
694   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
695   {NULL, 0, TRUE}
696 };
697
698 /* Maverick DSP coprocessor registers.  */
699 static const struct reg_entry mav_mvf_table[] =
700 {
701   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
702   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
703   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
704   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
705   {NULL, 0, TRUE}
706 };
707
708 static const struct reg_entry mav_mvd_table[] =
709 {
710   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
711   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
712   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
713   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
714   {NULL, 0, TRUE}
715 };
716
717 static const struct reg_entry mav_mvfx_table[] =
718 {
719   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
720   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
721   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
722   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
723   {NULL, 0, TRUE}
724 };
725
726 static const struct reg_entry mav_mvdx_table[] =
727 {
728   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
729   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
730   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
731   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
732   {NULL, 0, TRUE}
733 };
734
735 static const struct reg_entry mav_mvax_table[] =
736 {
737   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
738   {NULL, 0, TRUE}
739 };
740
741 static const struct reg_entry mav_dspsc_table[] =
742 {
743   {"dspsc", 0, TRUE},
744   {NULL, 0, TRUE}
745 };
746
747 struct reg_map
748 {
749   const struct reg_entry * names;
750   int                      max_regno;
751   struct hash_control *    htab;
752   const char *             expected;
753 };
754
755 struct reg_map all_reg_maps[] =
756 {
757   {rn_table,        15, NULL, N_("ARM register expected")},
758   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
759   {cn_table,        15, NULL, N_("co-processor register expected")},
760   {fn_table,         7, NULL, N_("FPA register expected")},
761   {sn_table,        31, NULL, N_("VFP single precision register expected")},
762   {dn_table,        15, NULL, N_("VFP double precision register expected")},
763   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
764   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
765   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
766   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
767   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
768   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
769   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
770 };
771
772 /* Enumeration matching entries in table above.  */
773 enum arm_reg_type
774 {
775   REG_TYPE_RN = 0,
776 #define REG_TYPE_FIRST REG_TYPE_RN
777   REG_TYPE_CP = 1,
778   REG_TYPE_CN = 2,
779   REG_TYPE_FN = 3,
780   REG_TYPE_SN = 4,
781   REG_TYPE_DN = 5,
782   REG_TYPE_MVF = 6,
783   REG_TYPE_MVD = 7,
784   REG_TYPE_MVFX = 8,
785   REG_TYPE_MVDX = 9,
786   REG_TYPE_MVAX = 10,
787   REG_TYPE_DSPSC = 11,
788   REG_TYPE_IWMMXT = 12,
789
790   REG_TYPE_MAX = 13
791 };
792
793 /* ARM instructions take 4bytes in the object file, Thumb instructions
794    take 2:  */
795 #define INSN_SIZE       4
796
797 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
798 #define MAV_MODE1       0x100c
799
800 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
801 #define MAV_MODE2       0x0c10
802
803 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
804 #define MAV_MODE3       0x100c
805
806 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
807 #define MAV_MODE4       0x0c0010
808
809 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
810 #define MAV_MODE5       0x00100c
811
812 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
813 #define MAV_MODE6       0x00100c05
814
815 struct asm_opcode
816 {
817   /* Basic string to match.  */
818   const char * template;
819
820   /* Basic instruction code.  */
821   unsigned long value;
822
823   /* Offset into the template where the condition code (if any) will be.
824      If zero, then the instruction is never conditional.  */
825   unsigned cond_offset;
826
827   /* Which architecture variant provides this instruction.  */
828   unsigned long variant;
829
830   /* Function to call to parse args.  */
831   void (* parms) (char *);
832 };
833
834 /* Defines for various bits that we will want to toggle.  */
835 #define INST_IMMEDIATE  0x02000000
836 #define OFFSET_REG      0x02000000
837 #define HWOFFSET_IMM    0x00400000
838 #define SHIFT_BY_REG    0x00000010
839 #define PRE_INDEX       0x01000000
840 #define INDEX_UP        0x00800000
841 #define WRITE_BACK      0x00200000
842 #define LDM_TYPE_2_OR_3 0x00400000
843
844 #define LITERAL_MASK    0xf000f000
845 #define OPCODE_MASK     0xfe1fffff
846 #define V4_STR_BIT      0x00000020
847
848 #define DATA_OP_SHIFT   21
849
850 /* Codes to distinguish the arithmetic instructions.  */
851 #define OPCODE_AND      0
852 #define OPCODE_EOR      1
853 #define OPCODE_SUB      2
854 #define OPCODE_RSB      3
855 #define OPCODE_ADD      4
856 #define OPCODE_ADC      5
857 #define OPCODE_SBC      6
858 #define OPCODE_RSC      7
859 #define OPCODE_TST      8
860 #define OPCODE_TEQ      9
861 #define OPCODE_CMP      10
862 #define OPCODE_CMN      11
863 #define OPCODE_ORR      12
864 #define OPCODE_MOV      13
865 #define OPCODE_BIC      14
866 #define OPCODE_MVN      15
867
868 #define T_OPCODE_MUL 0x4340
869 #define T_OPCODE_TST 0x4200
870 #define T_OPCODE_CMN 0x42c0
871 #define T_OPCODE_NEG 0x4240
872 #define T_OPCODE_MVN 0x43c0
873
874 #define T_OPCODE_ADD_R3 0x1800
875 #define T_OPCODE_SUB_R3 0x1a00
876 #define T_OPCODE_ADD_HI 0x4400
877 #define T_OPCODE_ADD_ST 0xb000
878 #define T_OPCODE_SUB_ST 0xb080
879 #define T_OPCODE_ADD_SP 0xa800
880 #define T_OPCODE_ADD_PC 0xa000
881 #define T_OPCODE_ADD_I8 0x3000
882 #define T_OPCODE_SUB_I8 0x3800
883 #define T_OPCODE_ADD_I3 0x1c00
884 #define T_OPCODE_SUB_I3 0x1e00
885
886 #define T_OPCODE_ASR_R  0x4100
887 #define T_OPCODE_LSL_R  0x4080
888 #define T_OPCODE_LSR_R  0x40c0
889 #define T_OPCODE_ASR_I  0x1000
890 #define T_OPCODE_LSL_I  0x0000
891 #define T_OPCODE_LSR_I  0x0800
892
893 #define T_OPCODE_MOV_I8 0x2000
894 #define T_OPCODE_CMP_I8 0x2800
895 #define T_OPCODE_CMP_LR 0x4280
896 #define T_OPCODE_MOV_HR 0x4600
897 #define T_OPCODE_CMP_HR 0x4500
898
899 #define T_OPCODE_LDR_PC 0x4800
900 #define T_OPCODE_LDR_SP 0x9800
901 #define T_OPCODE_STR_SP 0x9000
902 #define T_OPCODE_LDR_IW 0x6800
903 #define T_OPCODE_STR_IW 0x6000
904 #define T_OPCODE_LDR_IH 0x8800
905 #define T_OPCODE_STR_IH 0x8000
906 #define T_OPCODE_LDR_IB 0x7800
907 #define T_OPCODE_STR_IB 0x7000
908 #define T_OPCODE_LDR_RW 0x5800
909 #define T_OPCODE_STR_RW 0x5000
910 #define T_OPCODE_LDR_RH 0x5a00
911 #define T_OPCODE_STR_RH 0x5200
912 #define T_OPCODE_LDR_RB 0x5c00
913 #define T_OPCODE_STR_RB 0x5400
914
915 #define T_OPCODE_PUSH   0xb400
916 #define T_OPCODE_POP    0xbc00
917
918 #define T_OPCODE_BRANCH 0xe7fe
919
920 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
921 #define THUMB_REG_LO    0x1
922 #define THUMB_REG_HI    0x2
923 #define THUMB_REG_ANY   0x3
924
925 #define THUMB_H1        0x0080
926 #define THUMB_H2        0x0040
927
928 #define THUMB_ASR 0
929 #define THUMB_LSL 1
930 #define THUMB_LSR 2
931
932 #define THUMB_MOVE 0
933 #define THUMB_COMPARE 1
934 #define THUMB_CPY 2
935
936 #define THUMB_LOAD 0
937 #define THUMB_STORE 1
938
939 #define THUMB_PP_PC_LR 0x0100
940
941 /* These three are used for immediate shifts, do not alter.  */
942 #define THUMB_WORD 2
943 #define THUMB_HALFWORD 1
944 #define THUMB_BYTE 0
945
946 struct thumb_opcode
947 {
948   /* Basic string to match.  */
949   const char * template;
950
951   /* Basic instruction code.  */
952   unsigned long value;
953
954   int size;
955
956   /* Which CPU variants this exists for.  */
957   unsigned long variant;
958
959   /* Function to call to parse args.  */
960   void (* parms) (char *);
961 };
962
963 #define BAD_ARGS        _("bad arguments to instruction")
964 #define BAD_PC          _("r15 not allowed here")
965 #define BAD_COND        _("instruction is not conditional")
966 #define ERR_NO_ACCUM    _("acc0 expected")
967
968 static struct hash_control * arm_ops_hsh   = NULL;
969 static struct hash_control * arm_tops_hsh  = NULL;
970 static struct hash_control * arm_cond_hsh  = NULL;
971 static struct hash_control * arm_shift_hsh = NULL;
972 static struct hash_control * arm_psr_hsh   = NULL;
973
974 /* Stuff needed to resolve the label ambiguity
975    As:
976      ...
977      label:   <insn>
978    may differ from:
979      ...
980      label:
981               <insn>
982 */
983
984 symbolS *  last_label_seen;
985 static int label_is_thumb_function_name = FALSE;
986 \f
987 /* Literal Pool stuff.  */
988
989 #define MAX_LITERAL_POOL_SIZE 1024
990
991 /* Literal pool structure.  Held on a per-section
992    and per-sub-section basis.  */
993
994 typedef struct literal_pool
995 {
996   expressionS    literals [MAX_LITERAL_POOL_SIZE];
997   unsigned int   next_free_entry;
998   unsigned int   id;
999   symbolS *      symbol;
1000   segT           section;
1001   subsegT        sub_section;
1002   struct literal_pool * next;
1003 } literal_pool;
1004
1005 /* Pointer to a linked list of literal pools.  */
1006 literal_pool * list_of_pools = NULL;
1007
1008 static literal_pool *
1009 find_literal_pool (void)
1010 {
1011   literal_pool * pool;
1012
1013   for (pool = list_of_pools; pool != NULL; pool = pool->next)
1014     {
1015       if (pool->section == now_seg
1016           && pool->sub_section == now_subseg)
1017         break;
1018     }
1019
1020   return pool;
1021 }
1022
1023 static literal_pool *
1024 find_or_make_literal_pool (void)
1025 {
1026   /* Next literal pool ID number.  */
1027   static unsigned int latest_pool_num = 1;
1028   literal_pool *      pool;
1029
1030   pool = find_literal_pool ();
1031
1032   if (pool == NULL)
1033     {
1034       /* Create a new pool.  */
1035       pool = xmalloc (sizeof (* pool));
1036       if (! pool)
1037         return NULL;
1038
1039       pool->next_free_entry = 0;
1040       pool->section         = now_seg;
1041       pool->sub_section     = now_subseg;
1042       pool->next            = list_of_pools;
1043       pool->symbol          = NULL;
1044
1045       /* Add it to the list.  */
1046       list_of_pools = pool;
1047     }
1048
1049   /* New pools, and emptied pools, will have a NULL symbol.  */
1050   if (pool->symbol == NULL)
1051     {
1052       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
1053                                     (valueT) 0, &zero_address_frag);
1054       pool->id = latest_pool_num ++;
1055     }
1056
1057   /* Done.  */
1058   return pool;
1059 }
1060
1061 /* Add the literal in the global 'inst'
1062    structure to the relevent literal pool.  */
1063
1064 static int
1065 add_to_lit_pool (void)
1066 {
1067   literal_pool * pool;
1068   unsigned int entry;
1069
1070   pool = find_or_make_literal_pool ();
1071
1072   /* Check if this literal value is already in the pool.  */
1073   for (entry = 0; entry < pool->next_free_entry; entry ++)
1074     {
1075       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1076           && (inst.reloc.exp.X_op == O_constant)
1077           && (pool->literals[entry].X_add_number
1078               == inst.reloc.exp.X_add_number)
1079           && (pool->literals[entry].X_unsigned
1080               == inst.reloc.exp.X_unsigned))
1081         break;
1082
1083       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1084           && (inst.reloc.exp.X_op == O_symbol)
1085           && (pool->literals[entry].X_add_number
1086               == inst.reloc.exp.X_add_number)
1087           && (pool->literals[entry].X_add_symbol
1088               == inst.reloc.exp.X_add_symbol)
1089           && (pool->literals[entry].X_op_symbol
1090               == inst.reloc.exp.X_op_symbol))
1091         break;
1092     }
1093
1094   /* Do we need to create a new entry?  */
1095   if (entry == pool->next_free_entry)
1096     {
1097       if (entry >= MAX_LITERAL_POOL_SIZE)
1098         {
1099           inst.error = _("literal pool overflow");
1100           return FAIL;
1101         }
1102
1103       pool->literals[entry] = inst.reloc.exp;
1104       pool->next_free_entry += 1;
1105     }
1106
1107   inst.reloc.exp.X_op         = O_symbol;
1108   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
1109   inst.reloc.exp.X_add_symbol = pool->symbol;
1110
1111   return SUCCESS;
1112 }
1113
1114 /* Can't use symbol_new here, so have to create a symbol and then at
1115    a later date assign it a value. Thats what these functions do.  */
1116
1117 static void
1118 symbol_locate (symbolS *    symbolP,
1119                const char * name,       /* It is copied, the caller can modify.  */
1120                segT         segment,    /* Segment identifier (SEG_<something>).  */
1121                valueT       valu,       /* Symbol value.  */
1122                fragS *      frag)       /* Associated fragment.  */
1123 {
1124   unsigned int name_length;
1125   char * preserved_copy_of_name;
1126
1127   name_length = strlen (name) + 1;   /* +1 for \0.  */
1128   obstack_grow (&notes, name, name_length);
1129   preserved_copy_of_name = obstack_finish (&notes);
1130 #ifdef STRIP_UNDERSCORE
1131   if (preserved_copy_of_name[0] == '_')
1132     preserved_copy_of_name++;
1133 #endif
1134
1135 #ifdef tc_canonicalize_symbol_name
1136   preserved_copy_of_name =
1137     tc_canonicalize_symbol_name (preserved_copy_of_name);
1138 #endif
1139
1140   S_SET_NAME (symbolP, preserved_copy_of_name);
1141
1142   S_SET_SEGMENT (symbolP, segment);
1143   S_SET_VALUE (symbolP, valu);
1144   symbol_clear_list_pointers (symbolP);
1145
1146   symbol_set_frag (symbolP, frag);
1147
1148   /* Link to end of symbol chain.  */
1149   {
1150     extern int symbol_table_frozen;
1151
1152     if (symbol_table_frozen)
1153       abort ();
1154   }
1155
1156   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1157
1158   obj_symbol_new_hook (symbolP);
1159
1160 #ifdef tc_symbol_new_hook
1161   tc_symbol_new_hook (symbolP);
1162 #endif
1163
1164 #ifdef DEBUG_SYMS
1165   verify_symbol_chain (symbol_rootP, symbol_lastP);
1166 #endif /* DEBUG_SYMS  */
1167 }
1168
1169 /* Check that an immediate is valid.
1170    If so, convert it to the right format.  */
1171
1172 static unsigned int
1173 validate_immediate (unsigned int val)
1174 {
1175   unsigned int a;
1176   unsigned int i;
1177
1178 #define rotate_left(v, n) (v << n | v >> (32 - n))
1179
1180   for (i = 0; i < 32; i += 2)
1181     if ((a = rotate_left (val, i)) <= 0xff)
1182       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
1183
1184   return FAIL;
1185 }
1186
1187 /* Check to see if an immediate can be computed as two separate immediate
1188    values, added together.  We already know that this value cannot be
1189    computed by just one ARM instruction.  */
1190
1191 static unsigned int
1192 validate_immediate_twopart (unsigned int   val,
1193                             unsigned int * highpart)
1194 {
1195   unsigned int a;
1196   unsigned int i;
1197
1198   for (i = 0; i < 32; i += 2)
1199     if (((a = rotate_left (val, i)) & 0xff) != 0)
1200       {
1201         if (a & 0xff00)
1202           {
1203             if (a & ~ 0xffff)
1204               continue;
1205             * highpart = (a  >> 8) | ((i + 24) << 7);
1206           }
1207         else if (a & 0xff0000)
1208           {
1209             if (a & 0xff000000)
1210               continue;
1211             * highpart = (a >> 16) | ((i + 16) << 7);
1212           }
1213         else
1214           {
1215             assert (a & 0xff000000);
1216             * highpart = (a >> 24) | ((i + 8) << 7);
1217           }
1218
1219         return (a & 0xff) | (i << 7);
1220       }
1221
1222   return FAIL;
1223 }
1224
1225 static int
1226 validate_offset_imm (unsigned int val, int hwse)
1227 {
1228   if ((hwse && val > 255) || val > 4095)
1229     return FAIL;
1230   return val;
1231 }
1232
1233 \f
1234 #ifdef OBJ_ELF
1235 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
1236    (This text is taken from version B-02 of the spec):
1237
1238       4.4.7 Mapping and tagging symbols
1239
1240       A section of an ARM ELF file can contain a mixture of ARM code,
1241       Thumb code, and data.  There are inline transitions between code
1242       and data at literal pool boundaries. There can also be inline
1243       transitions between ARM code and Thumb code, for example in
1244       ARM-Thumb inter-working veneers.  Linkers, machine-level
1245       debuggers, profiling tools, and disassembly tools need to map
1246       images accurately. For example, setting an ARM breakpoint on a
1247       Thumb location, or in a literal pool, can crash the program
1248       being debugged, ruining the debugging session.
1249
1250       ARM ELF entities are mapped (see section 4.4.7.1 below) and
1251       tagged (see section 4.4.7.2 below) using local symbols (with
1252       binding STB_LOCAL).  To assist consumers, mapping and tagging
1253       symbols should be collated first in the symbol table, before
1254       other symbols with binding STB_LOCAL.
1255
1256       To allow properly collated mapping and tagging symbols to be
1257       skipped by consumers that have no interest in them, the first
1258       such symbol should have the name $m and its st_value field equal
1259       to the total number of mapping and tagging symbols (including
1260       the $m) in the symbol table.
1261
1262       4.4.7.1 Mapping symbols
1263
1264       $a    Labels the first byte of a sequence of ARM instructions.
1265             Its type is STT_FUNC.
1266
1267       $d    Labels the first byte of a sequence of data items.
1268             Its type is STT_OBJECT.
1269
1270       $t    Labels the first byte of a sequence of Thumb instructions.
1271             Its type is STT_FUNC.
1272
1273       This list of mapping symbols may be extended in the future.
1274
1275       Section-relative mapping symbols
1276
1277       Mapping symbols defined in a section define a sequence of
1278       half-open address intervals that cover the address range of the
1279       section. Each interval starts at the address defined by a
1280       mapping symbol, and continues up to, but not including, the
1281       address defined by the next (in address order) mapping symbol or
1282       the end of the section. A corollary is that there must be a
1283       mapping symbol defined at the beginning of each section.
1284       Consumers can ignore the size of a section-relative mapping
1285       symbol. Producers can set it to 0.
1286
1287       Absolute mapping symbols
1288
1289       Because of the need to crystallize a Thumb address with the
1290       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
1291       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
1292       or $t.
1293
1294       The extent of a mapping symbol defined in SHN_ABS is [st_value,
1295       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
1296       where [x, y) denotes the half-open address range from x,
1297       inclusive, to y, exclusive.
1298
1299       In the absence of a mapping symbol, a consumer can interpret a
1300       function symbol with an odd value as the Thumb code address
1301       obtained by clearing the least significant bit of the
1302       value. This interpretation is deprecated, and it may not work in
1303       the future.
1304
1305    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
1306    the EABI (which is still under development), so they are not
1307    implemented here.  */
1308
1309 static enum mstate mapstate = MAP_UNDEFINED;
1310
1311 static void
1312 mapping_state (enum mstate state)
1313 {
1314   symbolS * symbolP;
1315   const char * symname;
1316   int type;
1317
1318   if (mapstate == state)
1319     /* The mapping symbol has already been emitted.
1320        There is nothing else to do.  */
1321     return;
1322
1323   mapstate = state;
1324
1325   switch (state)
1326     {
1327     case MAP_DATA:
1328       symname = "$d";
1329       type = BSF_OBJECT;
1330       break;
1331     case MAP_ARM:
1332       symname = "$a";
1333       type = BSF_FUNCTION;
1334       break;
1335     case MAP_THUMB:
1336       symname = "$t";
1337       type = BSF_FUNCTION;
1338       break;
1339     case MAP_UNDEFINED:
1340       return;
1341     default:
1342       abort ();
1343     }
1344
1345   seg_info (now_seg)->tc_segment_info_data = state;
1346
1347   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
1348   symbol_table_insert (symbolP);
1349   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1350
1351   switch (state)
1352     {
1353     case MAP_ARM:
1354       THUMB_SET_FUNC (symbolP, 0);
1355       ARM_SET_THUMB (symbolP, 0);
1356       ARM_SET_INTERWORK (symbolP, support_interwork);
1357       break;
1358
1359     case MAP_THUMB:
1360       THUMB_SET_FUNC (symbolP, 1);
1361       ARM_SET_THUMB (symbolP, 1);
1362       ARM_SET_INTERWORK (symbolP, support_interwork);
1363       break;
1364
1365     case MAP_DATA:
1366     default:
1367       return;
1368     }
1369 }
1370
1371 /* When we change sections we need to issue a new mapping symbol.  */
1372
1373 void
1374 arm_elf_change_section (void)
1375 {
1376   flagword flags;
1377
1378   /* Link an unlinked unwind index table section to the .text section.  */
1379   if (elf_section_type (now_seg) == SHT_ARM_EXIDX
1380       && elf_linked_to_section (now_seg) == NULL)
1381     elf_linked_to_section (now_seg) = text_section;
1382
1383   if (!SEG_NORMAL (now_seg))
1384     return;
1385
1386   flags = bfd_get_section_flags (stdoutput, now_seg);
1387
1388   /* We can ignore sections that only contain debug info.  */
1389   if ((flags & SEC_ALLOC) == 0)
1390     return;
1391
1392   mapstate = seg_info (now_seg)->tc_segment_info_data;
1393 }
1394
1395 int
1396 arm_elf_section_type (const char * str, size_t len)
1397 {
1398   if (len == 5 && strncmp (str, "exidx", 5) == 0)
1399     return SHT_ARM_EXIDX;
1400
1401   return -1;
1402 }
1403 #else
1404 #define mapping_state(a)
1405 #endif /* OBJ_ELF */
1406 \f
1407 /* arm_reg_parse () := if it looks like a register, return its token and
1408    advance the pointer.  */
1409
1410 static int
1411 arm_reg_parse (char ** ccp, struct hash_control * htab)
1412 {
1413   char * start = * ccp;
1414   char   c;
1415   char * p;
1416   struct reg_entry * reg;
1417
1418 #ifdef REGISTER_PREFIX
1419   if (*start != REGISTER_PREFIX)
1420     return FAIL;
1421   p = start + 1;
1422 #else
1423   p = start;
1424 #ifdef OPTIONAL_REGISTER_PREFIX
1425   if (*p == OPTIONAL_REGISTER_PREFIX)
1426     p++, start++;
1427 #endif
1428 #endif
1429   if (!ISALPHA (*p) || !is_name_beginner (*p))
1430     return FAIL;
1431
1432   c = *p++;
1433   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
1434     c = *p++;
1435
1436   *--p = 0;
1437   reg = (struct reg_entry *) hash_find (htab, start);
1438   *p = c;
1439
1440   if (reg)
1441     {
1442       *ccp = p;
1443       return reg->number;
1444     }
1445
1446   return FAIL;
1447 }
1448
1449 /* Search for the following register name in each of the possible reg name
1450    tables.  Return the classification if found, or REG_TYPE_MAX if not
1451    present.  */
1452
1453 static enum arm_reg_type
1454 arm_reg_parse_any (char *cp)
1455 {
1456   int i;
1457
1458   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
1459     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
1460       return (enum arm_reg_type) i;
1461
1462   return REG_TYPE_MAX;
1463 }
1464
1465 static void
1466 opcode_select (int width)
1467 {
1468   switch (width)
1469     {
1470     case 16:
1471       if (! thumb_mode)
1472         {
1473           if (! (cpu_variant & ARM_EXT_V4T))
1474             as_bad (_("selected processor does not support THUMB opcodes"));
1475
1476           thumb_mode = 1;
1477           /* No need to force the alignment, since we will have been
1478              coming from ARM mode, which is word-aligned.  */
1479           record_alignment (now_seg, 1);
1480         }
1481       mapping_state (MAP_THUMB);
1482       break;
1483
1484     case 32:
1485       if (thumb_mode)
1486         {
1487           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
1488             as_bad (_("selected processor does not support ARM opcodes"));
1489
1490           thumb_mode = 0;
1491
1492           if (!need_pass_2)
1493             frag_align (2, 0, 0);
1494
1495           record_alignment (now_seg, 1);
1496         }
1497       mapping_state (MAP_ARM);
1498       break;
1499
1500     default:
1501       as_bad (_("invalid instruction size selected (%d)"), width);
1502     }
1503 }
1504
1505 static void
1506 s_req (int a ATTRIBUTE_UNUSED)
1507 {
1508   as_bad (_("invalid syntax for .req directive"));
1509 }
1510
1511 /* The .unreq directive deletes an alias which was previously defined
1512    by .req.  For example:
1513
1514        my_alias .req r11
1515        .unreq my_alias    */
1516
1517 static void
1518 s_unreq (int a ATTRIBUTE_UNUSED)
1519 {
1520   char * name;
1521   char saved_char;
1522
1523   skip_whitespace (input_line_pointer);
1524   name = input_line_pointer;
1525
1526   while (*input_line_pointer != 0
1527          && *input_line_pointer != ' '
1528          && *input_line_pointer != '\n')
1529     ++input_line_pointer;
1530
1531   saved_char = *input_line_pointer;
1532   *input_line_pointer = 0;
1533
1534   if (*name)
1535     {
1536       enum arm_reg_type req_type = arm_reg_parse_any (name);
1537
1538       if (req_type != REG_TYPE_MAX)
1539         {
1540           char *temp_name = name;
1541           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
1542
1543           if (req_no != FAIL)
1544             {
1545               struct reg_entry *req_entry;
1546
1547               /* Check to see if this alias is a builtin one.  */
1548               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
1549
1550               if (!req_entry)
1551                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
1552               else if (req_entry->builtin)
1553                 /* FIXME: We are deleting a built in register alias which
1554                    points to a const data structure, so we only need to
1555                    free up the memory used by the key in the hash table.
1556                    Unfortunately we have not recorded this value, so this
1557                    is a memory leak.  */
1558                   /* FIXME: Should we issue a warning message ?  */
1559                 ;
1560               else
1561                 {
1562                   /* Deleting a user defined alias.  We need to free the
1563                      key and the value, but fortunately the key is the same
1564                      as the value->name field.  */
1565                   free ((char *) req_entry->name);
1566                   free (req_entry);
1567                 }
1568             }
1569           else
1570             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1571         }
1572       else
1573         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
1574     }
1575   else
1576     as_bad (_("invalid syntax for .unreq directive"));
1577
1578   *input_line_pointer = saved_char;
1579   demand_empty_rest_of_line ();
1580 }
1581
1582 static void
1583 s_bss (int ignore ATTRIBUTE_UNUSED)
1584 {
1585   /* We don't support putting frags in the BSS segment, we fake it by
1586      marking in_bss, then looking at s_skip for clues.  */
1587   subseg_set (bss_section, 0);
1588   demand_empty_rest_of_line ();
1589   mapping_state (MAP_DATA);
1590 }
1591
1592 static void
1593 s_even (int ignore ATTRIBUTE_UNUSED)
1594 {
1595   /* Never make frag if expect extra pass.  */
1596   if (!need_pass_2)
1597     frag_align (1, 0, 0);
1598
1599   record_alignment (now_seg, 1);
1600
1601   demand_empty_rest_of_line ();
1602 }
1603
1604 static void
1605 s_ltorg (int ignored ATTRIBUTE_UNUSED)
1606 {
1607   unsigned int entry;
1608   literal_pool * pool;
1609   char sym_name[20];
1610
1611   pool = find_literal_pool ();
1612   if (pool == NULL
1613       || pool->symbol == NULL
1614       || pool->next_free_entry == 0)
1615     return;
1616
1617   mapping_state (MAP_DATA);
1618
1619   /* Align pool as you have word accesses.
1620      Only make a frag if we have to.  */
1621   if (!need_pass_2)
1622     frag_align (2, 0, 0);
1623
1624   record_alignment (now_seg, 2);
1625
1626   sprintf (sym_name, "$$lit_\002%x", pool->id);
1627
1628   symbol_locate (pool->symbol, sym_name, now_seg,
1629                  (valueT) frag_now_fix (), frag_now);
1630   symbol_table_insert (pool->symbol);
1631
1632   ARM_SET_THUMB (pool->symbol, thumb_mode);
1633
1634 #if defined OBJ_COFF || defined OBJ_ELF
1635   ARM_SET_INTERWORK (pool->symbol, support_interwork);
1636 #endif
1637
1638   for (entry = 0; entry < pool->next_free_entry; entry ++)
1639     /* First output the expression in the instruction to the pool.  */
1640     emit_expr (&(pool->literals[entry]), 4); /* .word  */
1641
1642   /* Mark the pool as empty.  */
1643   pool->next_free_entry = 0;
1644   pool->symbol = NULL;
1645 }
1646
1647 /* Same as s_align_ptwo but align 0 => align 2.  */
1648
1649 static void
1650 s_align (int unused ATTRIBUTE_UNUSED)
1651 {
1652   int temp;
1653   long temp_fill;
1654   long max_alignment = 15;
1655
1656   temp = get_absolute_expression ();
1657   if (temp > max_alignment)
1658     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
1659   else if (temp < 0)
1660     {
1661       as_bad (_("alignment negative. 0 assumed."));
1662       temp = 0;
1663     }
1664
1665   if (*input_line_pointer == ',')
1666     {
1667       input_line_pointer++;
1668       temp_fill = get_absolute_expression ();
1669     }
1670   else
1671     temp_fill = 0;
1672
1673   if (!temp)
1674     temp = 2;
1675
1676   /* Only make a frag if we HAVE to.  */
1677   if (temp && !need_pass_2)
1678     frag_align (temp, (int) temp_fill, 0);
1679   demand_empty_rest_of_line ();
1680
1681   record_alignment (now_seg, temp);
1682 }
1683
1684 static void
1685 s_force_thumb (int ignore ATTRIBUTE_UNUSED)
1686 {
1687   /* If we are not already in thumb mode go into it, EVEN if
1688      the target processor does not support thumb instructions.
1689      This is used by gcc/config/arm/lib1funcs.asm for example
1690      to compile interworking support functions even if the
1691      target processor should not support interworking.  */
1692   if (! thumb_mode)
1693     {
1694       thumb_mode = 2;
1695
1696       record_alignment (now_seg, 1);
1697     }
1698
1699   demand_empty_rest_of_line ();
1700 }
1701
1702 static void
1703 s_thumb_func (int ignore ATTRIBUTE_UNUSED)
1704 {
1705   if (! thumb_mode)
1706     opcode_select (16);
1707
1708   /* The following label is the name/address of the start of a Thumb function.
1709      We need to know this for the interworking support.  */
1710   label_is_thumb_function_name = TRUE;
1711
1712   demand_empty_rest_of_line ();
1713 }
1714
1715 /* Perform a .set directive, but also mark the alias as
1716    being a thumb function.  */
1717
1718 static void
1719 s_thumb_set (int equiv)
1720 {
1721   /* XXX the following is a duplicate of the code for s_set() in read.c
1722      We cannot just call that code as we need to get at the symbol that
1723      is created.  */
1724   char *    name;
1725   char      delim;
1726   char *    end_name;
1727   symbolS * symbolP;
1728
1729   /* Especial apologies for the random logic:
1730      This just grew, and could be parsed much more simply!
1731      Dean - in haste.  */
1732   name      = input_line_pointer;
1733   delim     = get_symbol_end ();
1734   end_name  = input_line_pointer;
1735   *end_name = delim;
1736
1737   SKIP_WHITESPACE ();
1738
1739   if (*input_line_pointer != ',')
1740     {
1741       *end_name = 0;
1742       as_bad (_("expected comma after name \"%s\""), name);
1743       *end_name = delim;
1744       ignore_rest_of_line ();
1745       return;
1746     }
1747
1748   input_line_pointer++;
1749   *end_name = 0;
1750
1751   if (name[0] == '.' && name[1] == '\0')
1752     {
1753       /* XXX - this should not happen to .thumb_set.  */
1754       abort ();
1755     }
1756
1757   if ((symbolP = symbol_find (name)) == NULL
1758       && (symbolP = md_undefined_symbol (name)) == NULL)
1759     {
1760 #ifndef NO_LISTING
1761       /* When doing symbol listings, play games with dummy fragments living
1762          outside the normal fragment chain to record the file and line info
1763          for this symbol.  */
1764       if (listing & LISTING_SYMBOLS)
1765         {
1766           extern struct list_info_struct * listing_tail;
1767           fragS * dummy_frag = xmalloc (sizeof (fragS));
1768
1769           memset (dummy_frag, 0, sizeof (fragS));
1770           dummy_frag->fr_type = rs_fill;
1771           dummy_frag->line = listing_tail;
1772           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1773           dummy_frag->fr_symbol = symbolP;
1774         }
1775       else
1776 #endif
1777         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1778
1779 #ifdef OBJ_COFF
1780       /* "set" symbols are local unless otherwise specified.  */
1781       SF_SET_LOCAL (symbolP);
1782 #endif /* OBJ_COFF  */
1783     }                           /* Make a new symbol.  */
1784
1785   symbol_table_insert (symbolP);
1786
1787   * end_name = delim;
1788
1789   if (equiv
1790       && S_IS_DEFINED (symbolP)
1791       && S_GET_SEGMENT (symbolP) != reg_section)
1792     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1793
1794   pseudo_set (symbolP);
1795
1796   demand_empty_rest_of_line ();
1797
1798   /* XXX Now we come to the Thumb specific bit of code.  */
1799
1800   THUMB_SET_FUNC (symbolP, 1);
1801   ARM_SET_THUMB (symbolP, 1);
1802 #if defined OBJ_ELF || defined OBJ_COFF
1803   ARM_SET_INTERWORK (symbolP, support_interwork);
1804 #endif
1805 }
1806
1807 static void
1808 s_arm (int ignore ATTRIBUTE_UNUSED)
1809 {
1810   opcode_select (32);
1811   demand_empty_rest_of_line ();
1812 }
1813
1814 static void
1815 s_thumb (int ignore ATTRIBUTE_UNUSED)
1816 {
1817   opcode_select (16);
1818   demand_empty_rest_of_line ();
1819 }
1820
1821 static void
1822 s_code (int unused ATTRIBUTE_UNUSED)
1823 {
1824   int temp;
1825
1826   temp = get_absolute_expression ();
1827   switch (temp)
1828     {
1829     case 16:
1830     case 32:
1831       opcode_select (temp);
1832       break;
1833
1834     default:
1835       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1836     }
1837 }
1838
1839 static void
1840 end_of_line (char * str)
1841 {
1842   skip_whitespace (str);
1843
1844   if (*str != '\0' && !inst.error)
1845     inst.error = _("garbage following instruction");
1846 }
1847
1848 static int
1849 skip_past_comma (char ** str)
1850 {
1851   char * p = * str, c;
1852   int comma = 0;
1853
1854   while ((c = *p) == ' ' || c == ',')
1855     {
1856       p++;
1857       if (c == ',' && comma++)
1858         return FAIL;
1859     }
1860
1861   if (c == '\0')
1862     return FAIL;
1863
1864   *str = p;
1865   return comma ? SUCCESS : FAIL;
1866 }
1867
1868 /* Return TRUE if anything in the expression is a bignum.  */
1869
1870 static int
1871 walk_no_bignums (symbolS * sp)
1872 {
1873   if (symbol_get_value_expression (sp)->X_op == O_big)
1874     return 1;
1875
1876   if (symbol_get_value_expression (sp)->X_add_symbol)
1877     {
1878       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1879               || (symbol_get_value_expression (sp)->X_op_symbol
1880                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
1881     }
1882
1883   return 0;
1884 }
1885
1886 static int in_my_get_expression = 0;
1887
1888 static int
1889 my_get_expression (expressionS * ep, char ** str)
1890 {
1891   char * save_in;
1892   segT   seg;
1893
1894   save_in = input_line_pointer;
1895   input_line_pointer = *str;
1896   in_my_get_expression = 1;
1897   seg = expression (ep);
1898   in_my_get_expression = 0;
1899
1900   if (ep->X_op == O_illegal)
1901     {
1902       /* We found a bad expression in md_operand().  */
1903       *str = input_line_pointer;
1904       input_line_pointer = save_in;
1905       return 1;
1906     }
1907
1908 #ifdef OBJ_AOUT
1909   if (seg != absolute_section
1910       && seg != text_section
1911       && seg != data_section
1912       && seg != bss_section
1913       && seg != undefined_section)
1914     {
1915       inst.error = _("bad_segment");
1916       *str = input_line_pointer;
1917       input_line_pointer = save_in;
1918       return 1;
1919     }
1920 #endif
1921
1922   /* Get rid of any bignums now, so that we don't generate an error for which
1923      we can't establish a line number later on.  Big numbers are never valid
1924      in instructions, which is where this routine is always called.  */
1925   if (ep->X_op == O_big
1926       || (ep->X_add_symbol
1927           && (walk_no_bignums (ep->X_add_symbol)
1928               || (ep->X_op_symbol
1929                   && walk_no_bignums (ep->X_op_symbol)))))
1930     {
1931       inst.error = _("invalid constant");
1932       *str = input_line_pointer;
1933       input_line_pointer = save_in;
1934       return 1;
1935     }
1936
1937   *str = input_line_pointer;
1938   input_line_pointer = save_in;
1939   return 0;
1940 }
1941
1942 /* A standard register must be given at this point.
1943    SHIFT is the place to put it in inst.instruction.
1944    Restores input start point on error.
1945    Returns the reg#, or FAIL.  */
1946
1947 static int
1948 reg_required_here (char ** str, int shift)
1949 {
1950   static char buff [128]; /* XXX  */
1951   int         reg;
1952   char *      start = * str;
1953
1954   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
1955     {
1956       if (shift >= 0)
1957         inst.instruction |= reg << shift;
1958       return reg;
1959     }
1960
1961   /* Restore the start point, we may have got a reg of the wrong class.  */
1962   *str = start;
1963
1964   /* In the few cases where we might be able to accept something else
1965      this error can be overridden.  */
1966   sprintf (buff, _("register expected, not '%.100s'"), start);
1967   inst.error = buff;
1968
1969   return FAIL;
1970 }
1971
1972 /* A Intel Wireless MMX technology register
1973    must be given at this point.
1974    Shift is the place to put it in inst.instruction.
1975    Restores input start point on err.
1976    Returns the reg#, or FAIL.  */
1977
1978 static int
1979 wreg_required_here (char ** str,
1980                     int shift,
1981                     enum wreg_type reg_type)
1982 {
1983   static char buff [128];
1984   int    reg;
1985   char * start = *str;
1986
1987   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
1988     {
1989       if (wr_register (reg)
1990           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
1991         {
1992           if (shift >= 0)
1993             inst.instruction |= (reg ^ WR_PREFIX) << shift;
1994           return reg;
1995         }
1996       else if (wc_register (reg)
1997                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
1998         {
1999           if (shift >= 0)
2000             inst.instruction |= (reg ^ WC_PREFIX) << shift;
2001           return reg;
2002         }
2003       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
2004         {
2005           if (shift >= 0)
2006             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
2007           return reg;
2008         }
2009     }
2010
2011   /* Restore the start point, we may have got a reg of the wrong class.  */
2012   *str = start;
2013
2014   /* In the few cases where we might be able to accept
2015      something else this error can be overridden.  */
2016   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
2017   inst.error = buff;
2018
2019   return FAIL;
2020 }
2021
2022 static const struct asm_psr *
2023 arm_psr_parse (char ** ccp)
2024 {
2025   char * start = * ccp;
2026   char   c;
2027   char * p;
2028   const struct asm_psr * psr;
2029
2030   p = start;
2031
2032   /* Skip to the end of the next word in the input stream.  */
2033   do
2034     {
2035       c = *p++;
2036     }
2037   while (ISALPHA (c) || c == '_');
2038
2039   /* Terminate the word.  */
2040   *--p = 0;
2041
2042   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
2043      feature for ease of use and backwards compatibility.  */
2044   if (!strncmp (start, "cpsr", 4))
2045     strncpy (start, "CPSR", 4);
2046   else if (!strncmp (start, "spsr", 4))
2047     strncpy (start, "SPSR", 4);
2048
2049   /* Now locate the word in the psr hash table.  */
2050   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2051
2052   /* Restore the input stream.  */
2053   *p = c;
2054
2055   /* If we found a valid match, advance the
2056      stream pointer past the end of the word.  */
2057   *ccp = p;
2058
2059   return psr;
2060 }
2061
2062 /* Parse the input looking for a PSR flag.  */
2063
2064 static int
2065 psr_required_here (char ** str)
2066 {
2067   char * start = * str;
2068   const struct asm_psr * psr;
2069
2070   psr = arm_psr_parse (str);
2071
2072   if (psr)
2073     {
2074       /* If this is the SPSR that is being modified, set the R bit.  */
2075       if (! psr->cpsr)
2076         inst.instruction |= SPSR_BIT;
2077
2078       /* Set the psr flags in the MSR instruction.  */
2079       inst.instruction |= psr->field << PSR_SHIFT;
2080
2081       return SUCCESS;
2082     }
2083
2084   /* In the few cases where we might be able to accept
2085      something else this error can be overridden.  */
2086   inst.error = _("flag for {c}psr instruction expected");
2087
2088   /* Restore the start point.  */
2089   *str = start;
2090   return FAIL;
2091 }
2092
2093 static int
2094 co_proc_number (char ** str)
2095 {
2096   int processor, pchar;
2097   char *start;
2098
2099   skip_whitespace (*str);
2100   start = *str;
2101
2102   /* The data sheet seems to imply that just a number on its own is valid
2103      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
2104      accept either.  */
2105   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2106       == FAIL)
2107     {
2108       *str = start;
2109
2110       pchar = *(*str)++;
2111       if (pchar >= '0' && pchar <= '9')
2112         {
2113           processor = pchar - '0';
2114           if (**str >= '0' && **str <= '9')
2115             {
2116               processor = processor * 10 + *(*str)++ - '0';
2117               if (processor > 15)
2118                 {
2119                   inst.error = _("illegal co-processor number");
2120                   return FAIL;
2121                 }
2122             }
2123         }
2124       else
2125         {
2126           inst.error = all_reg_maps[REG_TYPE_CP].expected;
2127           return FAIL;
2128         }
2129     }
2130
2131   inst.instruction |= processor << 8;
2132   return SUCCESS;
2133 }
2134
2135 static int
2136 cp_opc_expr (char ** str, int where, int length)
2137 {
2138   expressionS expr;
2139
2140   skip_whitespace (* str);
2141
2142   memset (&expr, '\0', sizeof (expr));
2143
2144   if (my_get_expression (&expr, str))
2145     return FAIL;
2146   if (expr.X_op != O_constant)
2147     {
2148       inst.error = _("bad or missing expression");
2149       return FAIL;
2150     }
2151
2152   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2153     {
2154       inst.error = _("immediate co-processor expression too large");
2155       return FAIL;
2156     }
2157
2158   inst.instruction |= expr.X_add_number << where;
2159   return SUCCESS;
2160 }
2161
2162 static int
2163 cp_reg_required_here (char ** str, int where)
2164 {
2165   int    reg;
2166   char * start = *str;
2167
2168   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2169     {
2170       inst.instruction |= reg << where;
2171       return reg;
2172     }
2173
2174   /* In the few cases where we might be able to accept something else
2175      this error can be overridden.  */
2176   inst.error = all_reg_maps[REG_TYPE_CN].expected;
2177
2178   /* Restore the start point.  */
2179   *str = start;
2180   return FAIL;
2181 }
2182
2183 static int
2184 fp_reg_required_here (char ** str, int where)
2185 {
2186   int    reg;
2187   char * start = * str;
2188
2189   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2190     {
2191       inst.instruction |= reg << where;
2192       return reg;
2193     }
2194
2195   /* In the few cases where we might be able to accept something else
2196      this error can be overridden.  */
2197   inst.error = all_reg_maps[REG_TYPE_FN].expected;
2198
2199   /* Restore the start point.  */
2200   *str = start;
2201   return FAIL;
2202 }
2203
2204 static int
2205 cp_address_offset (char ** str)
2206 {
2207   int offset;
2208
2209   skip_whitespace (* str);
2210
2211   if (! is_immediate_prefix (**str))
2212     {
2213       inst.error = _("immediate expression expected");
2214       return FAIL;
2215     }
2216
2217   (*str)++;
2218
2219   if (my_get_expression (& inst.reloc.exp, str))
2220     return FAIL;
2221
2222   if (inst.reloc.exp.X_op == O_constant)
2223     {
2224       offset = inst.reloc.exp.X_add_number;
2225
2226       if (offset & 3)
2227         {
2228           inst.error = _("co-processor address must be word aligned");
2229           return FAIL;
2230         }
2231
2232       if (offset > 1023 || offset < -1023)
2233         {
2234           inst.error = _("offset too large");
2235           return FAIL;
2236         }
2237
2238       if (offset >= 0)
2239         inst.instruction |= INDEX_UP;
2240       else
2241         offset = -offset;
2242
2243       inst.instruction |= offset >> 2;
2244     }
2245   else
2246     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2247
2248   return SUCCESS;
2249 }
2250
2251 static int
2252 cp_address_required_here (char ** str, int wb_ok)
2253 {
2254   char * p = * str;
2255   int    pre_inc = 0;
2256   int    write_back = 0;
2257
2258   if (*p == '[')
2259     {
2260       int reg;
2261
2262       p++;
2263       skip_whitespace (p);
2264
2265       if ((reg = reg_required_here (& p, 16)) == FAIL)
2266         return FAIL;
2267
2268       skip_whitespace (p);
2269
2270       if (*p == ']')
2271         {
2272           p++;
2273
2274           skip_whitespace (p);
2275
2276           if (*p == '\0')
2277             {
2278               /* As an extension to the official ARM syntax we allow:
2279                    [Rn]
2280                  as a short hand for:
2281                    [Rn,#0]  */
2282               inst.instruction |= PRE_INDEX | INDEX_UP;
2283               *str = p;
2284               return SUCCESS;
2285             }
2286
2287           if (skip_past_comma (& p) == FAIL)
2288             {
2289               inst.error = _("comma expected after closing square bracket");
2290               return FAIL;
2291             }
2292
2293           skip_whitespace (p);
2294
2295           if (*p == '#')
2296             {
2297               if (wb_ok)
2298                 {
2299                   /* [Rn], #expr  */
2300                   write_back = WRITE_BACK;
2301
2302                   if (reg == REG_PC)
2303                     {
2304                       inst.error = _("pc may not be used in post-increment");
2305                       return FAIL;
2306                     }
2307
2308                   if (cp_address_offset (& p) == FAIL)
2309                     return FAIL;
2310                 }
2311               else
2312                 pre_inc = PRE_INDEX | INDEX_UP;
2313             }
2314           else if (*p == '{')
2315             {
2316               int option;
2317
2318               /* [Rn], {<expr>}  */
2319               p++;
2320
2321               skip_whitespace (p);
2322
2323               if (my_get_expression (& inst.reloc.exp, & p))
2324                 return FAIL;
2325
2326               if (inst.reloc.exp.X_op == O_constant)
2327                 {
2328                   option = inst.reloc.exp.X_add_number;
2329
2330                   if (option > 255 || option < 0)
2331                     {
2332                       inst.error = _("'option' field too large");
2333                       return FAIL;
2334                     }
2335
2336                   skip_whitespace (p);
2337
2338                   if (*p != '}')
2339                     {
2340                       inst.error = _("'}' expected at end of 'option' field");
2341                       return FAIL;
2342                     }
2343                   else
2344                     {
2345                       p++;
2346                       inst.instruction |= option;
2347                       inst.instruction |= INDEX_UP;
2348                     }
2349                 }
2350               else
2351                 {
2352                   inst.error = _("non-constant expressions for 'option' field not supported");
2353                   return FAIL;
2354                 }
2355             }
2356           else
2357             {
2358               inst.error = _("# or { expected after comma");
2359               return FAIL;
2360             }
2361         }
2362       else
2363         {
2364           /* '['Rn, #expr']'[!]  */
2365
2366           if (skip_past_comma (& p) == FAIL)
2367             {
2368               inst.error = _("pre-indexed expression expected");
2369               return FAIL;
2370             }
2371
2372           pre_inc = PRE_INDEX;
2373
2374           if (cp_address_offset (& p) == FAIL)
2375             return FAIL;
2376
2377           skip_whitespace (p);
2378
2379           if (*p++ != ']')
2380             {
2381               inst.error = _("missing ]");
2382               return FAIL;
2383             }
2384
2385           skip_whitespace (p);
2386
2387           if (wb_ok && *p == '!')
2388             {
2389               if (reg == REG_PC)
2390                 {
2391                   inst.error = _("pc may not be used with write-back");
2392                   return FAIL;
2393                 }
2394
2395               p++;
2396               write_back = WRITE_BACK;
2397             }
2398         }
2399     }
2400   else
2401     {
2402       if (my_get_expression (&inst.reloc.exp, &p))
2403         return FAIL;
2404
2405       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2406       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2407       inst.reloc.pc_rel = 1;
2408       inst.instruction |= (REG_PC << 16);
2409       pre_inc = PRE_INDEX;
2410     }
2411
2412   inst.instruction |= write_back | pre_inc;
2413   *str = p;
2414   return SUCCESS;
2415 }
2416
2417 static int
2418 cp_byte_address_offset (char ** str)
2419 {
2420   int offset;
2421
2422   skip_whitespace (* str);
2423
2424   if (! is_immediate_prefix (**str))
2425     {
2426       inst.error = _("immediate expression expected");
2427       return FAIL;
2428     }
2429
2430   (*str)++;
2431
2432   if (my_get_expression (& inst.reloc.exp, str))
2433     return FAIL;
2434
2435   if (inst.reloc.exp.X_op == O_constant)
2436     {
2437       offset = inst.reloc.exp.X_add_number;
2438
2439       if (offset > 255 || offset < -255)
2440         {
2441           inst.error = _("offset too large");
2442           return FAIL;
2443         }
2444
2445       if (offset >= 0)
2446         inst.instruction |= INDEX_UP;
2447       else
2448         offset = -offset;
2449
2450       inst.instruction |= offset;
2451     }
2452   else
2453     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2454
2455   return SUCCESS;
2456 }
2457
2458 static int
2459 cp_byte_address_required_here (char ** str)
2460 {
2461   char * p = * str;
2462   int    pre_inc = 0;
2463   int    write_back = 0;
2464
2465   if (*p == '[')
2466     {
2467       int reg;
2468
2469       p++;
2470       skip_whitespace (p);
2471
2472       if ((reg = reg_required_here (& p, 16)) == FAIL)
2473         return FAIL;
2474
2475       skip_whitespace (p);
2476
2477       if (*p == ']')
2478         {
2479           p++;
2480
2481           if (skip_past_comma (& p) == SUCCESS)
2482             {
2483               /* [Rn], #expr */
2484               write_back = WRITE_BACK;
2485
2486               if (reg == REG_PC)
2487                 {
2488                   inst.error = _("pc may not be used in post-increment");
2489                   return FAIL;
2490                 }
2491
2492               if (cp_byte_address_offset (& p) == FAIL)
2493                 return FAIL;
2494             }
2495           else
2496             pre_inc = PRE_INDEX | INDEX_UP;
2497         }
2498       else
2499         {
2500           /* '['Rn, #expr']'[!] */
2501
2502           if (skip_past_comma (& p) == FAIL)
2503             {
2504               inst.error = _("pre-indexed expression expected");
2505               return FAIL;
2506             }
2507
2508           pre_inc = PRE_INDEX;
2509
2510           if (cp_byte_address_offset (& p) == FAIL)
2511             return FAIL;
2512
2513           skip_whitespace (p);
2514
2515           if (*p++ != ']')
2516             {
2517               inst.error = _("missing ]");
2518               return FAIL;
2519             }
2520
2521           skip_whitespace (p);
2522
2523           if (*p == '!')
2524             {
2525               if (reg == REG_PC)
2526                 {
2527                   inst.error = _("pc may not be used with write-back");
2528                   return FAIL;
2529                 }
2530
2531               p++;
2532               write_back = WRITE_BACK;
2533             }
2534         }
2535     }
2536   else
2537     {
2538       if (my_get_expression (&inst.reloc.exp, &p))
2539         return FAIL;
2540
2541       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
2542       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
2543       inst.reloc.pc_rel = 1;
2544       inst.instruction |= (REG_PC << 16);
2545       pre_inc = PRE_INDEX;
2546     }
2547
2548   inst.instruction |= write_back | pre_inc;
2549   *str = p;
2550   return SUCCESS;
2551 }
2552
2553 static void
2554 do_nop (char * str)
2555 {
2556   skip_whitespace (str);
2557   if (*str == '{')
2558     {
2559       str++;
2560
2561       if (my_get_expression (&inst.reloc.exp, &str))
2562         inst.reloc.exp.X_op = O_illegal;
2563       else
2564         {
2565           skip_whitespace (str);
2566           if (*str == '}')
2567             str++;
2568           else
2569             inst.reloc.exp.X_op = O_illegal;
2570         }
2571
2572       if (inst.reloc.exp.X_op != O_constant
2573           || inst.reloc.exp.X_add_number > 255
2574           || inst.reloc.exp.X_add_number < 0)
2575         {
2576           inst.error = _("Invalid NOP hint");
2577           return;
2578         }
2579
2580       /* Arcitectural NOP hints are CPSR sets with no bits selected.  */
2581       inst.instruction &= 0xf0000000;
2582       inst.instruction |= 0x0320f000 + inst.reloc.exp.X_add_number;
2583     }
2584
2585   end_of_line (str);
2586 }
2587
2588 static void
2589 do_empty (char * str)
2590 {
2591   /* Do nothing really.  */
2592   end_of_line (str);
2593 }
2594
2595 static void
2596 do_mrs (char * str)
2597 {
2598   int skip = 0;
2599
2600   /* Only one syntax.  */
2601   skip_whitespace (str);
2602
2603   if (reg_required_here (&str, 12) == FAIL)
2604     {
2605       inst.error = BAD_ARGS;
2606       return;
2607     }
2608
2609   if (skip_past_comma (&str) == FAIL)
2610     {
2611       inst.error = _("comma expected after register name");
2612       return;
2613     }
2614
2615   skip_whitespace (str);
2616
2617   if (   streq (str, "CPSR")
2618       || streq (str, "SPSR")
2619          /* Lower case versions for backwards compatibility.  */
2620       || streq (str, "cpsr")
2621       || streq (str, "spsr"))
2622     skip = 4;
2623
2624   /* This is for backwards compatibility with older toolchains.  */
2625   else if (   streq (str, "cpsr_all")
2626            || streq (str, "spsr_all"))
2627     skip = 8;
2628   else
2629     {
2630       inst.error = _("CPSR or SPSR expected");
2631       return;
2632     }
2633
2634   if (* str == 's' || * str == 'S')
2635     inst.instruction |= SPSR_BIT;
2636   str += skip;
2637
2638   end_of_line (str);
2639 }
2640
2641 /* Two possible forms:
2642       "{C|S}PSR_<field>, Rm",
2643       "{C|S}PSR_f, #expression".  */
2644
2645 static void
2646 do_msr (char * str)
2647 {
2648   skip_whitespace (str);
2649
2650   if (psr_required_here (& str) == FAIL)
2651     return;
2652
2653   if (skip_past_comma (& str) == FAIL)
2654     {
2655       inst.error = _("comma missing after psr flags");
2656       return;
2657     }
2658
2659   skip_whitespace (str);
2660
2661   if (reg_required_here (& str, 0) != FAIL)
2662     {
2663       inst.error = NULL;
2664       end_of_line (str);
2665       return;
2666     }
2667
2668   if (! is_immediate_prefix (* str))
2669     {
2670       inst.error =
2671         _("only a register or immediate value can follow a psr flag");
2672       return;
2673     }
2674
2675   str ++;
2676   inst.error = NULL;
2677
2678   if (my_get_expression (& inst.reloc.exp, & str))
2679     {
2680       inst.error =
2681         _("only a register or immediate value can follow a psr flag");
2682       return;
2683     }
2684
2685 #if 0  /* The first edition of the ARM architecture manual stated that
2686           writing anything other than the flags with an immediate operation
2687           had UNPREDICTABLE effects.  This constraint was removed in the
2688           second edition of the specification.  */
2689   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
2690       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2691     {
2692       inst.error = _("immediate value cannot be used to set this field");
2693       return;
2694     }
2695 #endif
2696
2697   inst.instruction |= INST_IMMEDIATE;
2698
2699   if (inst.reloc.exp.X_add_symbol)
2700     {
2701       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2702       inst.reloc.pc_rel = 0;
2703     }
2704   else
2705     {
2706       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2707
2708       if (value == (unsigned) FAIL)
2709         {
2710           inst.error = _("invalid constant");
2711           return;
2712         }
2713
2714       inst.instruction |= value;
2715     }
2716
2717   inst.error = NULL;
2718   end_of_line (str);
2719 }
2720
2721 /* Long Multiply Parser
2722    UMULL RdLo, RdHi, Rm, Rs
2723    SMULL RdLo, RdHi, Rm, Rs
2724    UMLAL RdLo, RdHi, Rm, Rs
2725    SMLAL RdLo, RdHi, Rm, Rs.  */
2726
2727 static void
2728 do_mull (char * str)
2729 {
2730   int rdlo, rdhi, rm, rs;
2731
2732   /* Only one format "rdlo, rdhi, rm, rs".  */
2733   skip_whitespace (str);
2734
2735   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2736     {
2737       inst.error = BAD_ARGS;
2738       return;
2739     }
2740
2741   if (skip_past_comma (&str) == FAIL
2742       || (rdhi = reg_required_here (&str, 16)) == FAIL)
2743     {
2744       inst.error = BAD_ARGS;
2745       return;
2746     }
2747
2748   if (skip_past_comma (&str) == FAIL
2749       || (rm = reg_required_here (&str, 0)) == FAIL)
2750     {
2751       inst.error = BAD_ARGS;
2752       return;
2753     }
2754
2755   /* rdhi, rdlo and rm must all be different.  */
2756   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2757     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2758
2759   if (skip_past_comma (&str) == FAIL
2760       || (rs = reg_required_here (&str, 8)) == FAIL)
2761     {
2762       inst.error = BAD_ARGS;
2763       return;
2764     }
2765
2766   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2767     {
2768       inst.error = BAD_PC;
2769       return;
2770     }
2771
2772   end_of_line (str);
2773 }
2774
2775 static void
2776 do_mul (char * str)
2777 {
2778   int rd, rm;
2779
2780   /* Only one format "rd, rm, rs".  */
2781   skip_whitespace (str);
2782
2783   if ((rd = reg_required_here (&str, 16)) == FAIL)
2784     {
2785       inst.error = BAD_ARGS;
2786       return;
2787     }
2788
2789   if (rd == REG_PC)
2790     {
2791       inst.error = BAD_PC;
2792       return;
2793     }
2794
2795   if (skip_past_comma (&str) == FAIL
2796       || (rm = reg_required_here (&str, 0)) == FAIL)
2797     {
2798       inst.error = BAD_ARGS;
2799       return;
2800     }
2801
2802   if (rm == REG_PC)
2803     {
2804       inst.error = BAD_PC;
2805       return;
2806     }
2807
2808   if (rm == rd)
2809     as_tsktsk (_("rd and rm should be different in mul"));
2810
2811   if (skip_past_comma (&str) == FAIL
2812       || (rm = reg_required_here (&str, 8)) == FAIL)
2813     {
2814       inst.error = BAD_ARGS;
2815       return;
2816     }
2817
2818   if (rm == REG_PC)
2819     {
2820       inst.error = BAD_PC;
2821       return;
2822     }
2823
2824   end_of_line (str);
2825 }
2826
2827 static void
2828 do_mla (char * str)
2829 {
2830   int rd, rm;
2831
2832   /* Only one format "rd, rm, rs, rn".  */
2833   skip_whitespace (str);
2834
2835   if ((rd = reg_required_here (&str, 16)) == FAIL)
2836     {
2837       inst.error = BAD_ARGS;
2838       return;
2839     }
2840
2841   if (rd == REG_PC)
2842     {
2843       inst.error = BAD_PC;
2844       return;
2845     }
2846
2847   if (skip_past_comma (&str) == FAIL
2848       || (rm = reg_required_here (&str, 0)) == FAIL)
2849     {
2850       inst.error = BAD_ARGS;
2851       return;
2852     }
2853
2854   if (rm == REG_PC)
2855     {
2856       inst.error = BAD_PC;
2857       return;
2858     }
2859
2860   if (rm == rd)
2861     as_tsktsk (_("rd and rm should be different in mla"));
2862
2863   if (skip_past_comma (&str) == FAIL
2864       || (rd = reg_required_here (&str, 8)) == FAIL
2865       || skip_past_comma (&str) == FAIL
2866       || (rm = reg_required_here (&str, 12)) == FAIL)
2867     {
2868       inst.error = BAD_ARGS;
2869       return;
2870     }
2871
2872   if (rd == REG_PC || rm == REG_PC)
2873     {
2874       inst.error = BAD_PC;
2875       return;
2876     }
2877
2878   end_of_line (str);
2879 }
2880
2881 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2882    Advances *str to the next non-alphanumeric.
2883    Returns 0, or else FAIL (in which case sets inst.error).
2884
2885   (In a future XScale, there may be accumulators other than zero.
2886   At that time this routine and its callers can be upgraded to suit.)  */
2887
2888 static int
2889 accum0_required_here (char ** str)
2890 {
2891   static char buff [128];       /* Note the address is taken.  Hence, static.  */
2892   char * p = * str;
2893   char   c;
2894   int result = 0;               /* The accum number.  */
2895
2896   skip_whitespace (p);
2897
2898   *str = p;                     /* Advance caller's string pointer too.  */
2899   c = *p++;
2900   while (ISALNUM (c))
2901     c = *p++;
2902
2903   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
2904
2905   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2906     {
2907       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2908       inst.error = buff;
2909       result = FAIL;
2910     }
2911
2912   *p = c;                       /* Unzap.  */
2913   *str = p;                     /* Caller's string pointer to after match.  */
2914   return result;
2915 }
2916
2917 static int
2918 ldst_extend_v4 (char ** str)
2919 {
2920   int add = INDEX_UP;
2921
2922   switch (**str)
2923     {
2924     case '#':
2925     case '$':
2926       (*str)++;
2927       if (my_get_expression (& inst.reloc.exp, str))
2928         return FAIL;
2929
2930       if (inst.reloc.exp.X_op == O_constant)
2931         {
2932           int value = inst.reloc.exp.X_add_number;
2933
2934           if (value < -255 || value > 255)
2935             {
2936               inst.error = _("address offset too large");
2937               return FAIL;
2938             }
2939
2940           if (value < 0)
2941             {
2942               value = -value;
2943               add = 0;
2944             }
2945
2946           /* Halfword and signextension instructions have the
2947              immediate value split across bits 11..8 and bits 3..0.  */
2948           inst.instruction |= (add | HWOFFSET_IMM
2949                                | ((value >> 4) << 8) | (value & 0xF));
2950         }
2951       else
2952         {
2953           inst.instruction |= HWOFFSET_IMM;
2954           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2955           inst.reloc.pc_rel = 0;
2956         }
2957       return SUCCESS;
2958
2959     case '-':
2960       add = 0;
2961       /* Fall through.  */
2962
2963     case '+':
2964       (*str)++;
2965       /* Fall through.  */
2966
2967     default:
2968       if (reg_required_here (str, 0) == FAIL)
2969         return FAIL;
2970
2971       inst.instruction |= add;
2972       return SUCCESS;
2973     }
2974 }
2975
2976 /* Expects **str -> after a comma. May be leading blanks.
2977    Advances *str, recognizing a load  mode, and setting inst.instruction.
2978    Returns rn, or else FAIL (in which case may set inst.error
2979    and not advance str)
2980
2981    Note: doesn't know Rd, so no err checks that require such knowledge.  */
2982
2983 static int
2984 ld_mode_required_here (char ** string)
2985 {
2986   char * str = * string;
2987   int    rn;
2988   int    pre_inc = 0;
2989
2990   skip_whitespace (str);
2991
2992   if (* str == '[')
2993     {
2994       str++;
2995
2996       skip_whitespace (str);
2997
2998       if ((rn = reg_required_here (& str, 16)) == FAIL)
2999         return FAIL;
3000
3001       skip_whitespace (str);
3002
3003       if (* str == ']')
3004         {
3005           str ++;
3006
3007           if (skip_past_comma (& str) == SUCCESS)
3008             {
3009               /* [Rn],... (post inc) */
3010               if (ldst_extend_v4 (&str) == FAIL)
3011                 return FAIL;
3012             }
3013           else        /* [Rn] */
3014             {
3015               skip_whitespace (str);
3016
3017               if (* str == '!')
3018                 {
3019                   str ++;
3020                   inst.instruction |= WRITE_BACK;
3021                 }
3022
3023               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3024               pre_inc = 1;
3025             }
3026         }
3027       else        /* [Rn,...] */
3028         {
3029           if (skip_past_comma (& str) == FAIL)
3030             {
3031               inst.error = _("pre-indexed expression expected");
3032               return FAIL;
3033             }
3034
3035           pre_inc = 1;
3036
3037           if (ldst_extend_v4 (&str) == FAIL)
3038             return FAIL;
3039
3040           skip_whitespace (str);
3041
3042           if (* str ++ != ']')
3043             {
3044               inst.error = _("missing ]");
3045               return FAIL;
3046             }
3047
3048           skip_whitespace (str);
3049
3050           if (* str == '!')
3051             {
3052               str ++;
3053               inst.instruction |= WRITE_BACK;
3054             }
3055         }
3056     }
3057   else if (* str == '=')        /* ldr's "r,=label" syntax */
3058     /* We should never reach here, because <text> = <expression> is
3059        caught gas/read.c read_a_source_file() as a .set operation.  */
3060     return FAIL;
3061   else                          /* PC +- 8 bit immediate offset.  */
3062     {
3063       if (my_get_expression (& inst.reloc.exp, & str))
3064         return FAIL;
3065
3066       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
3067       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
3068       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
3069       inst.reloc.pc_rel            = 1;
3070       inst.instruction            |= (REG_PC << 16);
3071
3072       rn = REG_PC;
3073       pre_inc = 1;
3074     }
3075
3076   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3077   * string = str;
3078
3079   return rn;
3080 }
3081
3082 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3083    SMLAxy{cond} Rd,Rm,Rs,Rn
3084    SMLAWy{cond} Rd,Rm,Rs,Rn
3085    Error if any register is R15.  */
3086
3087 static void
3088 do_smla (char * str)
3089 {
3090   int rd, rm, rs, rn;
3091
3092   skip_whitespace (str);
3093
3094   if ((rd = reg_required_here (& str, 16)) == FAIL
3095       || skip_past_comma (& str) == FAIL
3096       || (rm = reg_required_here (& str, 0)) == FAIL
3097       || skip_past_comma (& str) == FAIL
3098       || (rs = reg_required_here (& str, 8)) == FAIL
3099       || skip_past_comma (& str) == FAIL
3100       || (rn = reg_required_here (& str, 12)) == FAIL)
3101     inst.error = BAD_ARGS;
3102
3103   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3104     inst.error = BAD_PC;
3105
3106   else
3107     end_of_line (str);
3108 }
3109
3110 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3111    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3112    Error if any register is R15.
3113    Warning if Rdlo == Rdhi.  */
3114
3115 static void
3116 do_smlal (char * str)
3117 {
3118   int rdlo, rdhi, rm, rs;
3119
3120   skip_whitespace (str);
3121
3122   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3123       || skip_past_comma (& str) == FAIL
3124       || (rdhi = reg_required_here (& str, 16)) == FAIL
3125       || skip_past_comma (& str) == FAIL
3126       || (rm = reg_required_here (& str, 0)) == FAIL
3127       || skip_past_comma (& str) == FAIL
3128       || (rs = reg_required_here (& str, 8)) == FAIL)
3129     {
3130       inst.error = BAD_ARGS;
3131       return;
3132     }
3133
3134   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3135     {
3136       inst.error = BAD_PC;
3137       return;
3138     }
3139
3140   if (rdlo == rdhi)
3141     as_tsktsk (_("rdhi and rdlo must be different"));
3142
3143   end_of_line (str);
3144 }
3145
3146 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3147    SMULxy{cond} Rd,Rm,Rs
3148    Error if any register is R15.  */
3149
3150 static void
3151 do_smul (char * str)
3152 {
3153   int rd, rm, rs;
3154
3155   skip_whitespace (str);
3156
3157   if ((rd = reg_required_here (& str, 16)) == FAIL
3158       || skip_past_comma (& str) == FAIL
3159       || (rm = reg_required_here (& str, 0)) == FAIL
3160       || skip_past_comma (& str) == FAIL
3161       || (rs = reg_required_here (& str, 8)) == FAIL)
3162     inst.error = BAD_ARGS;
3163
3164   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3165     inst.error = BAD_PC;
3166
3167   else
3168     end_of_line (str);
3169 }
3170
3171 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3172    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3173    Error if any register is R15.  */
3174
3175 static void
3176 do_qadd (char * str)
3177 {
3178   int rd, rm, rn;
3179
3180   skip_whitespace (str);
3181
3182   if ((rd = reg_required_here (& str, 12)) == FAIL
3183       || skip_past_comma (& str) == FAIL
3184       || (rm = reg_required_here (& str, 0)) == FAIL
3185       || skip_past_comma (& str) == FAIL
3186       || (rn = reg_required_here (& str, 16)) == FAIL)
3187     inst.error = BAD_ARGS;
3188
3189   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3190     inst.error = BAD_PC;
3191
3192   else
3193     end_of_line (str);
3194 }
3195
3196 /* ARM V5E (el Segundo)
3197    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3198    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3199
3200    These are equivalent to the XScale instructions MAR and MRA,
3201    respectively, when coproc == 0, opcode == 0, and CRm == 0.
3202
3203    Result unpredicatable if Rd or Rn is R15.  */
3204
3205 static void
3206 do_co_reg2c (char * str)
3207 {
3208   int rd, rn;
3209
3210   skip_whitespace (str);
3211
3212   if (co_proc_number (& str) == FAIL)
3213     {
3214       if (!inst.error)
3215         inst.error = BAD_ARGS;
3216       return;
3217     }
3218
3219   if (skip_past_comma (& str) == FAIL
3220       || cp_opc_expr (& str, 4, 4) == FAIL)
3221     {
3222       if (!inst.error)
3223         inst.error = BAD_ARGS;
3224       return;
3225     }
3226
3227   if (skip_past_comma (& str) == FAIL
3228       || (rd = reg_required_here (& str, 12)) == FAIL)
3229     {
3230       if (!inst.error)
3231         inst.error = BAD_ARGS;
3232       return;
3233     }
3234
3235   if (skip_past_comma (& str) == FAIL
3236       || (rn = reg_required_here (& str, 16)) == FAIL)
3237     {
3238       if (!inst.error)
3239         inst.error = BAD_ARGS;
3240       return;
3241     }
3242
3243   /* Unpredictable result if rd or rn is R15.  */
3244   if (rd == REG_PC || rn == REG_PC)
3245     as_tsktsk
3246       (_("Warning: instruction unpredictable when using r15"));
3247
3248   if (skip_past_comma (& str) == FAIL
3249       || cp_reg_required_here (& str, 0) == FAIL)
3250     {
3251       if (!inst.error)
3252         inst.error = BAD_ARGS;
3253       return;
3254     }
3255
3256   end_of_line (str);
3257 }
3258
3259 /* ARM V5 count-leading-zeroes instruction (argument parse)
3260      CLZ{<cond>} <Rd>, <Rm>
3261      Condition defaults to COND_ALWAYS.
3262      Error if Rd or Rm are R15.  */
3263
3264 static void
3265 do_clz (char * str)
3266 {
3267   int rd, rm;
3268
3269   skip_whitespace (str);
3270
3271   if (((rd = reg_required_here (& str, 12)) == FAIL)
3272       || (skip_past_comma (& str) == FAIL)
3273       || ((rm = reg_required_here (& str, 0)) == FAIL))
3274     inst.error = BAD_ARGS;
3275
3276   else if (rd == REG_PC || rm == REG_PC )
3277     inst.error = BAD_PC;
3278
3279   else
3280     end_of_line (str);
3281 }
3282
3283 /* ARM V5 (argument parse)
3284      LDC2{L} <coproc>, <CRd>, <addressing mode>
3285      STC2{L} <coproc>, <CRd>, <addressing mode>
3286      Instruction is not conditional, and has 0xf in the condition field.
3287      Otherwise, it's the same as LDC/STC.  */
3288
3289 static void
3290 do_lstc2 (char * str)
3291 {
3292   skip_whitespace (str);
3293
3294   if (co_proc_number (& str) == FAIL)
3295     {
3296       if (!inst.error)
3297         inst.error = BAD_ARGS;
3298     }
3299   else if (skip_past_comma (& str) == FAIL
3300            || cp_reg_required_here (& str, 12) == FAIL)
3301     {
3302       if (!inst.error)
3303         inst.error = BAD_ARGS;
3304     }
3305   else if (skip_past_comma (& str) == FAIL
3306            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3307     {
3308       if (! inst.error)
3309         inst.error = BAD_ARGS;
3310     }
3311   else
3312     end_of_line (str);
3313 }
3314
3315 /* ARM V5 (argument parse)
3316      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3317      Instruction is not conditional, and has 0xf in the condition field.
3318      Otherwise, it's the same as CDP.  */
3319
3320 static void
3321 do_cdp2 (char * str)
3322 {
3323   skip_whitespace (str);
3324
3325   if (co_proc_number (& str) == FAIL)
3326     {
3327       if (!inst.error)
3328         inst.error = BAD_ARGS;
3329       return;
3330     }
3331
3332   if (skip_past_comma (& str) == FAIL
3333       || cp_opc_expr (& str, 20,4) == FAIL)
3334     {
3335       if (!inst.error)
3336         inst.error = BAD_ARGS;
3337       return;
3338     }
3339
3340   if (skip_past_comma (& str) == FAIL
3341       || cp_reg_required_here (& str, 12) == FAIL)
3342     {
3343       if (!inst.error)
3344         inst.error = BAD_ARGS;
3345       return;
3346     }
3347
3348   if (skip_past_comma (& str) == FAIL
3349       || cp_reg_required_here (& str, 16) == FAIL)
3350     {
3351       if (!inst.error)
3352         inst.error = BAD_ARGS;
3353       return;
3354     }
3355
3356   if (skip_past_comma (& str) == FAIL
3357       || cp_reg_required_here (& str, 0) == FAIL)
3358     {
3359       if (!inst.error)
3360         inst.error = BAD_ARGS;
3361       return;
3362     }
3363
3364   if (skip_past_comma (& str) == SUCCESS)
3365     {
3366       if (cp_opc_expr (& str, 5, 3) == FAIL)
3367         {
3368           if (!inst.error)
3369             inst.error = BAD_ARGS;
3370           return;
3371         }
3372     }
3373
3374   end_of_line (str);
3375 }
3376
3377 /* ARM V5 (argument parse)
3378      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3379      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3380      Instruction is not conditional, and has 0xf in the condition field.
3381      Otherwise, it's the same as MCR/MRC.  */
3382
3383 static void
3384 do_co_reg2 (char * str)
3385 {
3386   skip_whitespace (str);
3387
3388   if (co_proc_number (& str) == FAIL)
3389     {
3390       if (!inst.error)
3391         inst.error = BAD_ARGS;
3392       return;
3393     }
3394
3395   if (skip_past_comma (& str) == FAIL
3396       || cp_opc_expr (& str, 21, 3) == FAIL)
3397     {
3398       if (!inst.error)
3399         inst.error = BAD_ARGS;
3400       return;
3401     }
3402
3403   if (skip_past_comma (& str) == FAIL
3404       || reg_required_here (& str, 12) == FAIL)
3405     {
3406       if (!inst.error)
3407         inst.error = BAD_ARGS;
3408       return;
3409     }
3410
3411   if (skip_past_comma (& str) == FAIL
3412       || cp_reg_required_here (& str, 16) == FAIL)
3413     {
3414       if (!inst.error)
3415         inst.error = BAD_ARGS;
3416       return;
3417     }
3418
3419   if (skip_past_comma (& str) == FAIL
3420       || cp_reg_required_here (& str, 0) == FAIL)
3421     {
3422       if (!inst.error)
3423         inst.error = BAD_ARGS;
3424       return;
3425     }
3426
3427   if (skip_past_comma (& str) == SUCCESS)
3428     {
3429       if (cp_opc_expr (& str, 5, 3) == FAIL)
3430         {
3431           if (!inst.error)
3432             inst.error = BAD_ARGS;
3433           return;
3434         }
3435     }
3436
3437   end_of_line (str);
3438 }
3439
3440 static void
3441 do_bx (char * str)
3442 {
3443   int reg;
3444
3445   skip_whitespace (str);
3446
3447   if ((reg = reg_required_here (&str, 0)) == FAIL)
3448     {
3449       inst.error = BAD_ARGS;
3450       return;
3451     }
3452
3453   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
3454   if (reg == REG_PC)
3455     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
3456
3457   end_of_line (str);
3458 }
3459
3460 /* ARM v5TEJ.  Jump to Jazelle code.  */
3461
3462 static void
3463 do_bxj (char * str)
3464 {
3465   int reg;
3466
3467   skip_whitespace (str);
3468
3469   if ((reg = reg_required_here (&str, 0)) == FAIL)
3470     {
3471       inst.error = BAD_ARGS;
3472       return;
3473     }
3474
3475   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
3476   if (reg == REG_PC)
3477     as_tsktsk (_("use of r15 in bxj is not really useful"));
3478
3479   end_of_line (str);
3480 }
3481
3482 /* ARM V6 umaal (argument parse).  */
3483
3484 static void
3485 do_umaal (char * str)
3486 {
3487   int rdlo, rdhi, rm, rs;
3488
3489   skip_whitespace (str);
3490   if ((rdlo = reg_required_here (& str, 12)) == FAIL
3491       || skip_past_comma (& str) == FAIL
3492       || (rdhi = reg_required_here (& str, 16)) == FAIL
3493       || skip_past_comma (& str) == FAIL
3494       || (rm = reg_required_here (& str, 0)) == FAIL
3495       || skip_past_comma (& str) == FAIL
3496       || (rs = reg_required_here (& str, 8)) == FAIL)
3497     {
3498       inst.error = BAD_ARGS;
3499       return;
3500     }
3501
3502   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3503     {
3504       inst.error = BAD_PC;
3505       return;
3506     }
3507
3508   end_of_line (str);
3509 }
3510
3511 /* ARM V6 strex (argument parse).  */
3512
3513 static void
3514 do_strex (char * str)
3515 {
3516   int rd, rm, rn;
3517
3518   /* Parse Rd, Rm,.  */
3519   skip_whitespace (str);
3520   if ((rd = reg_required_here (& str, 12)) == FAIL
3521       || skip_past_comma (& str) == FAIL
3522       || (rm = reg_required_here (& str, 0)) == FAIL
3523       || skip_past_comma (& str) == FAIL)
3524     {
3525       inst.error = BAD_ARGS;
3526       return;
3527     }
3528   if (rd == REG_PC || rm == REG_PC)
3529     {
3530       inst.error = BAD_PC;
3531       return;
3532     }
3533   if (rd == rm)
3534     {
3535       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3536       return;
3537     }
3538
3539   /* Skip past '['.  */
3540   if ((strlen (str) >= 1)
3541       && strncmp (str, "[", 1) == 0)
3542     str += 1;
3543
3544   skip_whitespace (str);
3545
3546   /* Parse Rn.  */
3547   if ((rn = reg_required_here (& str, 16)) == FAIL)
3548     {
3549       inst.error = BAD_ARGS;
3550       return;
3551     }
3552   else if (rn == REG_PC)
3553     {
3554       inst.error = BAD_PC;
3555       return;
3556     }
3557   if (rd == rn)
3558     {
3559       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
3560       return;
3561     }
3562   skip_whitespace (str);
3563
3564   /* Skip past ']'.  */
3565   if ((strlen (str) >= 1)
3566       && strncmp (str, "]", 1) == 0)
3567     str += 1;
3568
3569   end_of_line (str);
3570 }
3571
3572 /* KIND indicates what kind of shifts are accepted.  */
3573
3574 static int
3575 decode_shift (char ** str, int kind)
3576 {
3577   const struct asm_shift_name * shift;
3578   char * p;
3579   char   c;
3580
3581   skip_whitespace (* str);
3582
3583   for (p = * str; ISALPHA (* p); p ++)
3584     ;
3585
3586   if (p == * str)
3587     {
3588       inst.error = _("shift expression expected");
3589       return FAIL;
3590     }
3591
3592   c = * p;
3593   * p = '\0';
3594   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3595   * p = c;
3596
3597   if (shift == NULL)
3598     {
3599       inst.error = _("shift expression expected");
3600       return FAIL;
3601     }
3602
3603   assert (shift->properties->index == shift_properties[shift->properties->index].index);
3604
3605   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
3606       && shift->properties->index != SHIFT_LSL
3607       && shift->properties->index != SHIFT_ASR)
3608     {
3609       inst.error = _("'LSL' or 'ASR' required");
3610       return FAIL;
3611     }
3612   else if (kind == SHIFT_LSL_IMMEDIATE
3613            && shift->properties->index != SHIFT_LSL)
3614     {
3615       inst.error = _("'LSL' required");
3616       return FAIL;
3617     }
3618   else if (kind == SHIFT_ASR_IMMEDIATE
3619            && shift->properties->index != SHIFT_ASR)
3620     {
3621       inst.error = _("'ASR' required");
3622       return FAIL;
3623     }
3624
3625   if (shift->properties->index == SHIFT_RRX)
3626     {
3627       * str = p;
3628       inst.instruction |= shift->properties->bit_field;
3629       return SUCCESS;
3630     }
3631
3632   skip_whitespace (p);
3633
3634   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
3635     {
3636       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3637       * str = p;
3638       return SUCCESS;
3639     }
3640   else if (! is_immediate_prefix (* p))
3641     {
3642       inst.error = (NO_SHIFT_RESTRICT
3643                     ? _("shift requires register or #expression")
3644                     : _("shift requires #expression"));
3645       * str = p;
3646       return FAIL;
3647     }
3648
3649   inst.error = NULL;
3650   p ++;
3651
3652   if (my_get_expression (& inst.reloc.exp, & p))
3653     return FAIL;
3654
3655   /* Validate some simple #expressions.  */
3656   if (inst.reloc.exp.X_op == O_constant)
3657     {
3658       unsigned num = inst.reloc.exp.X_add_number;
3659
3660       /* Reject operations greater than 32.  */
3661       if (num > 32
3662           /* Reject a shift of 0 unless the mode allows it.  */
3663           || (num == 0 && shift->properties->allows_0 == 0)
3664           /* Reject a shift of 32 unless the mode allows it.  */
3665           || (num == 32 && shift->properties->allows_32 == 0)
3666           )
3667         {
3668           /* As a special case we allow a shift of zero for
3669              modes that do not support it to be recoded as an
3670              logical shift left of zero (ie nothing).  We warn
3671              about this though.  */
3672           if (num == 0)
3673             {
3674               as_warn (_("shift of 0 ignored."));
3675               shift = & shift_names[0];
3676               assert (shift->properties->index == SHIFT_LSL);
3677             }
3678           else
3679             {
3680               inst.error = _("invalid immediate shift");
3681               return FAIL;
3682             }
3683         }
3684
3685       /* Shifts of 32 are encoded as 0, for those shifts that
3686          support it.  */
3687       if (num == 32)
3688         num = 0;
3689
3690       inst.instruction |= (num << 7) | shift->properties->bit_field;
3691     }
3692   else
3693     {
3694       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
3695       inst.reloc.pc_rel = 0;
3696       inst.instruction |= shift->properties->bit_field;
3697     }
3698
3699   * str = p;
3700   return SUCCESS;
3701 }
3702
3703 static void
3704 do_sat (char ** str, int bias)
3705 {
3706   int rd, rm;
3707   expressionS expr;
3708
3709   skip_whitespace (*str);
3710
3711   /* Parse <Rd>, field.  */
3712   if ((rd = reg_required_here (str, 12)) == FAIL
3713       || skip_past_comma (str) == FAIL)
3714     {
3715       inst.error = BAD_ARGS;
3716       return;
3717     }
3718   if (rd == REG_PC)
3719     {
3720       inst.error = BAD_PC;
3721       return;
3722     }
3723
3724   /* Parse #<immed>,  field.  */
3725   if (is_immediate_prefix (**str))
3726     (*str)++;
3727   else
3728     {
3729       inst.error = _("immediate expression expected");
3730       return;
3731     }
3732   if (my_get_expression (&expr, str))
3733     {
3734       inst.error = _("bad expression");
3735       return;
3736     }
3737   if (expr.X_op != O_constant)
3738     {
3739       inst.error = _("constant expression expected");
3740       return;
3741     }
3742   if (expr.X_add_number + bias < 0
3743       || expr.X_add_number + bias > 31)
3744     {
3745       inst.error = _("immediate value out of range");
3746       return;
3747     }
3748   inst.instruction |= (expr.X_add_number + bias) << 16;
3749   if (skip_past_comma (str) == FAIL)
3750     {
3751       inst.error = BAD_ARGS;
3752       return;
3753     }
3754
3755   /* Parse <Rm> field.  */
3756   if ((rm = reg_required_here (str, 0)) == FAIL)
3757     {
3758       inst.error = BAD_ARGS;
3759       return;
3760     }
3761   if (rm == REG_PC)
3762     {
3763       inst.error = BAD_PC;
3764       return;
3765     }
3766
3767   if (skip_past_comma (str) == SUCCESS)
3768     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
3769 }
3770
3771 /* ARM V6 ssat (argument parse).  */
3772
3773 static void
3774 do_ssat (char * str)
3775 {
3776   do_sat (&str, /*bias=*/-1);
3777   end_of_line (str);
3778 }
3779
3780 /* ARM V6 usat (argument parse).  */
3781
3782 static void
3783 do_usat (char * str)
3784 {
3785   do_sat (&str, /*bias=*/0);
3786   end_of_line (str);
3787 }
3788
3789 static void
3790 do_sat16 (char ** str, int bias)
3791 {
3792   int rd, rm;
3793   expressionS expr;
3794
3795   skip_whitespace (*str);
3796
3797   /* Parse the <Rd> field.  */
3798   if ((rd = reg_required_here (str, 12)) == FAIL
3799       || skip_past_comma (str) == FAIL)
3800     {
3801       inst.error = BAD_ARGS;
3802       return;
3803     }
3804   if (rd == REG_PC)
3805     {
3806       inst.error = BAD_PC;
3807       return;
3808     }
3809
3810   /* Parse #<immed>, field.  */
3811   if (is_immediate_prefix (**str))
3812     (*str)++;
3813   else
3814     {
3815       inst.error = _("immediate expression expected");
3816       return;
3817     }
3818   if (my_get_expression (&expr, str))
3819     {
3820       inst.error = _("bad expression");
3821       return;
3822     }
3823   if (expr.X_op != O_constant)
3824     {
3825       inst.error = _("constant expression expected");
3826       return;
3827     }
3828   if (expr.X_add_number + bias < 0
3829       || expr.X_add_number + bias > 15)
3830     {
3831       inst.error = _("immediate value out of range");
3832       return;
3833     }
3834   inst.instruction |= (expr.X_add_number + bias) << 16;
3835   if (skip_past_comma (str) == FAIL)
3836     {
3837       inst.error = BAD_ARGS;
3838       return;
3839     }
3840
3841   /* Parse <Rm> field.  */
3842   if ((rm = reg_required_here (str, 0)) == FAIL)
3843     {
3844       inst.error = BAD_ARGS;
3845       return;
3846     }
3847   if (rm == REG_PC)
3848     {
3849       inst.error = BAD_PC;
3850       return;
3851     }
3852 }
3853
3854 /* ARM V6 ssat16 (argument parse).  */
3855
3856 static void
3857 do_ssat16 (char * str)
3858 {
3859   do_sat16 (&str, /*bias=*/-1);
3860   end_of_line (str);
3861 }
3862
3863 static void
3864 do_usat16 (char * str)
3865 {
3866   do_sat16 (&str, /*bias=*/0);
3867   end_of_line (str);
3868 }
3869
3870 static void
3871 do_cps_mode (char ** str)
3872 {
3873   expressionS expr;
3874
3875   skip_whitespace (*str);
3876
3877   if (! is_immediate_prefix (**str))
3878     {
3879       inst.error = _("immediate expression expected");
3880       return;
3881     }
3882
3883   (*str)++; /* Strip off the immediate signifier.  */
3884   if (my_get_expression (&expr, str))
3885     {
3886       inst.error = _("bad expression");
3887       return;
3888     }
3889
3890   if (expr.X_op != O_constant)
3891     {
3892       inst.error = _("constant expression expected");
3893       return;
3894     }
3895
3896   /* The mode is a 5 bit field.  Valid values are 0-31.  */
3897   if (((unsigned) expr.X_add_number) > 31
3898       || (inst.reloc.exp.X_add_number) < 0)
3899     {
3900       inst.error = _("invalid constant");
3901       return;
3902     }
3903
3904   inst.instruction |= expr.X_add_number;
3905 }
3906
3907 /* ARM V6 srs (argument parse).  */
3908
3909 static void
3910 do_srs (char * str)
3911 {
3912   char *exclam;
3913   skip_whitespace (str);
3914   exclam = strchr (str, '!');
3915   if (exclam)
3916     *exclam = '\0';
3917   do_cps_mode (&str);
3918   if (exclam)
3919     *exclam = '!';
3920   if (*str == '!')
3921     {
3922       inst.instruction |= WRITE_BACK;
3923       str++;
3924     }
3925   end_of_line (str);
3926 }
3927
3928 /* ARM V6 SMMUL (argument parse).  */
3929
3930 static void
3931 do_smmul (char * str)
3932 {
3933   int rd, rm, rs;
3934
3935   skip_whitespace (str);
3936   if ((rd = reg_required_here (&str, 16)) == FAIL
3937       || skip_past_comma (&str) == FAIL
3938       || (rm = reg_required_here (&str, 0)) == FAIL
3939       || skip_past_comma (&str) == FAIL
3940       || (rs = reg_required_here (&str, 8)) == FAIL)
3941     {
3942       inst.error = BAD_ARGS;
3943       return;
3944     }
3945
3946   if (   rd == REG_PC
3947       || rm == REG_PC
3948       || rs == REG_PC)
3949     {
3950       inst.error = BAD_PC;
3951       return;
3952     }
3953
3954   end_of_line (str);
3955 }
3956
3957 /* ARM V6 SMLALD (argument parse).  */
3958
3959 static void
3960 do_smlald (char * str)
3961 {
3962   int rdlo, rdhi, rm, rs;
3963
3964   skip_whitespace (str);
3965   if ((rdlo = reg_required_here (&str, 12)) == FAIL
3966       || skip_past_comma (&str) == FAIL
3967       || (rdhi = reg_required_here (&str, 16)) == FAIL
3968       || skip_past_comma (&str) == FAIL
3969       || (rm = reg_required_here (&str, 0)) == FAIL
3970       || skip_past_comma (&str) == FAIL
3971       || (rs = reg_required_here (&str, 8)) == FAIL)
3972     {
3973       inst.error = BAD_ARGS;
3974       return;
3975     }
3976
3977   if (   rdlo == REG_PC
3978       || rdhi == REG_PC
3979       || rm == REG_PC
3980       || rs == REG_PC)
3981     {
3982       inst.error = BAD_PC;
3983       return;
3984     }
3985
3986   end_of_line (str);
3987 }
3988
3989 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
3990    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
3991
3992 static void
3993 do_smlad (char * str)
3994 {
3995   int rd, rm, rs, rn;
3996
3997   skip_whitespace (str);
3998   if ((rd = reg_required_here (&str, 16)) == FAIL
3999       || skip_past_comma (&str) == FAIL
4000       || (rm = reg_required_here (&str, 0)) == FAIL
4001       || skip_past_comma (&str) == FAIL
4002       || (rs = reg_required_here (&str, 8)) == FAIL
4003       || skip_past_comma (&str) == FAIL
4004       || (rn = reg_required_here (&str, 12)) == FAIL)
4005     {
4006       inst.error = BAD_ARGS;
4007       return;
4008     }
4009
4010   if (   rd == REG_PC
4011       || rn == REG_PC
4012       || rs == REG_PC
4013       || rm == REG_PC)
4014     {
4015       inst.error = BAD_PC;
4016       return;
4017     }
4018
4019   end_of_line (str);
4020 }
4021
4022 /* Returns true if the endian-specifier indicates big-endianness.  */
4023
4024 static int
4025 do_endian_specifier (char * str)
4026 {
4027   int big_endian = 0;
4028
4029   skip_whitespace (str);
4030   if (strlen (str) < 2)
4031     inst.error = _("missing endian specifier");
4032   else if (strncasecmp (str, "BE", 2) == 0)
4033     {
4034       str += 2;
4035       big_endian = 1;
4036     }
4037   else if (strncasecmp (str, "LE", 2) == 0)
4038     str += 2;
4039   else
4040     inst.error = _("valid endian specifiers are be or le");
4041
4042   end_of_line (str);
4043
4044   return big_endian;
4045 }
4046
4047 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
4048    preserving the other bits.
4049
4050    setend <endian_specifier>, where <endian_specifier> is either
4051    BE or LE.  */
4052
4053 static void
4054 do_setend (char * str)
4055 {
4056   if (do_endian_specifier (str))
4057     inst.instruction |= 0x200;
4058 }
4059
4060 /* ARM V6 SXTH.
4061
4062    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
4063    Condition defaults to COND_ALWAYS.
4064    Error if any register uses R15.  */
4065
4066 static void
4067 do_sxth (char * str)
4068 {
4069   int rd, rm;
4070   expressionS expr;
4071   int rotation_clear_mask = 0xfffff3ff;
4072   int rotation_eight_mask = 0x00000400;
4073   int rotation_sixteen_mask = 0x00000800;
4074   int rotation_twenty_four_mask = 0x00000c00;
4075
4076   skip_whitespace (str);
4077   if ((rd = reg_required_here (&str, 12)) == FAIL
4078       || skip_past_comma (&str) == FAIL
4079       || (rm = reg_required_here (&str, 0)) == FAIL)
4080     {
4081       inst.error = BAD_ARGS;
4082       return;
4083     }
4084
4085   else if (rd == REG_PC || rm == REG_PC)
4086     {
4087       inst.error = BAD_PC;
4088       return;
4089     }
4090
4091   /* Zero out the rotation field.  */
4092   inst.instruction &= rotation_clear_mask;
4093
4094   /* Check for lack of optional rotation field.  */
4095   if (skip_past_comma (&str) == FAIL)
4096     {
4097       end_of_line (str);
4098       return;
4099     }
4100
4101   /* Move past 'ROR'.  */
4102   skip_whitespace (str);
4103   if (strncasecmp (str, "ROR", 3) == 0)
4104     str += 3;
4105   else
4106     {
4107       inst.error = _("missing rotation field after comma");
4108       return;
4109     }
4110
4111   /* Get the immediate constant.  */
4112   skip_whitespace (str);
4113   if (is_immediate_prefix (* str))
4114     str++;
4115   else
4116     {
4117       inst.error = _("immediate expression expected");
4118       return;
4119     }
4120
4121   if (my_get_expression (&expr, &str))
4122     {
4123       inst.error = _("bad expression");
4124       return;
4125     }
4126
4127   if (expr.X_op != O_constant)
4128     {
4129       inst.error = _("constant expression expected");
4130       return;
4131     }
4132
4133   switch (expr.X_add_number)
4134     {
4135     case 0:
4136       /* Rotation field has already been zeroed.  */
4137       break;
4138     case 8:
4139       inst.instruction |= rotation_eight_mask;
4140       break;
4141
4142     case 16:
4143       inst.instruction |= rotation_sixteen_mask;
4144       break;
4145
4146     case 24:
4147       inst.instruction |= rotation_twenty_four_mask;
4148       break;
4149
4150     default:
4151       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4152       break;
4153     }
4154
4155   end_of_line (str);
4156 }
4157
4158 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
4159    extends it to 32-bits, and adds the result to a value in another
4160    register.  You can specify a rotation by 0, 8, 16, or 24 bits
4161    before extracting the 16-bit value.
4162    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
4163    Condition defaults to COND_ALWAYS.
4164    Error if any register uses R15.  */
4165
4166 static void
4167 do_sxtah (char * str)
4168 {
4169   int rd, rn, rm;
4170   expressionS expr;
4171   int rotation_clear_mask = 0xfffff3ff;
4172   int rotation_eight_mask = 0x00000400;
4173   int rotation_sixteen_mask = 0x00000800;
4174   int rotation_twenty_four_mask = 0x00000c00;
4175
4176   skip_whitespace (str);
4177   if ((rd = reg_required_here (&str, 12)) == FAIL
4178       || skip_past_comma (&str) == FAIL
4179       || (rn = reg_required_here (&str, 16)) == FAIL
4180       || skip_past_comma (&str) == FAIL
4181       || (rm = reg_required_here (&str, 0)) == FAIL)
4182     {
4183       inst.error = BAD_ARGS;
4184       return;
4185     }
4186
4187   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4188     {
4189       inst.error = BAD_PC;
4190       return;
4191     }
4192
4193   /* Zero out the rotation field.  */
4194   inst.instruction &= rotation_clear_mask;
4195
4196   /* Check for lack of optional rotation field.  */
4197   if (skip_past_comma (&str) == FAIL)
4198     {
4199       end_of_line (str);
4200       return;
4201     }
4202
4203   /* Move past 'ROR'.  */
4204   skip_whitespace (str);
4205   if (strncasecmp (str, "ROR", 3) == 0)
4206     str += 3;
4207   else
4208     {
4209       inst.error = _("missing rotation field after comma");
4210       return;
4211     }
4212
4213   /* Get the immediate constant.  */
4214   skip_whitespace (str);
4215   if (is_immediate_prefix (* str))
4216     str++;
4217   else
4218     {
4219       inst.error = _("immediate expression expected");
4220       return;
4221     }
4222
4223   if (my_get_expression (&expr, &str))
4224     {
4225       inst.error = _("bad expression");
4226       return;
4227     }
4228
4229   if (expr.X_op != O_constant)
4230     {
4231       inst.error = _("constant expression expected");
4232       return;
4233     }
4234
4235   switch (expr.X_add_number)
4236     {
4237     case 0:
4238       /* Rotation field has already been zeroed.  */
4239       break;
4240
4241     case 8:
4242       inst.instruction |= rotation_eight_mask;
4243       break;
4244
4245     case 16:
4246       inst.instruction |= rotation_sixteen_mask;
4247       break;
4248
4249     case 24:
4250       inst.instruction |= rotation_twenty_four_mask;
4251       break;
4252
4253     default:
4254       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
4255       break;
4256     }
4257
4258   end_of_line (str);
4259 }
4260
4261
4262 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
4263    word at the specified address and the following word
4264    respectively.
4265    Unconditionally executed.
4266    Error if Rn is R15.  */
4267
4268 static void
4269 do_rfe (char * str)
4270 {
4271   int rn;
4272
4273   skip_whitespace (str);
4274
4275   if ((rn = reg_required_here (&str, 16)) == FAIL)
4276     return;
4277
4278   if (rn == REG_PC)
4279     {
4280       inst.error = BAD_PC;
4281       return;
4282     }
4283
4284   skip_whitespace (str);
4285
4286   if (*str == '!')
4287     {
4288       inst.instruction |= WRITE_BACK;
4289       str++;
4290     }
4291   end_of_line (str);
4292 }
4293
4294 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
4295    register (argument parse).
4296    REV{<cond>} Rd, Rm.
4297    Condition defaults to COND_ALWAYS.
4298    Error if Rd or Rm are R15.  */
4299
4300 static void
4301 do_rev (char * str)
4302 {
4303   int rd, rm;
4304
4305   skip_whitespace (str);
4306
4307   if ((rd = reg_required_here (&str, 12)) == FAIL
4308       || skip_past_comma (&str) == FAIL
4309       || (rm = reg_required_here (&str, 0)) == FAIL)
4310     inst.error = BAD_ARGS;
4311
4312   else if (rd == REG_PC || rm == REG_PC)
4313     inst.error = BAD_PC;
4314
4315   else
4316     end_of_line (str);
4317 }
4318
4319 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
4320    QADD16{<cond>} <Rd>, <Rn>, <Rm>
4321    Condition defaults to COND_ALWAYS.
4322    Error if Rd, Rn or Rm are R15.  */
4323
4324 static void
4325 do_qadd16 (char * str)
4326 {
4327   int rd, rm, rn;
4328
4329   skip_whitespace (str);
4330
4331   if ((rd = reg_required_here (&str, 12)) == FAIL
4332       || skip_past_comma (&str) == FAIL
4333       || (rn = reg_required_here (&str, 16)) == FAIL
4334       || skip_past_comma (&str) == FAIL
4335       || (rm = reg_required_here (&str, 0)) == FAIL)
4336     inst.error = BAD_ARGS;
4337
4338   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4339     inst.error = BAD_PC;
4340
4341   else
4342     end_of_line (str);
4343 }
4344
4345 static void
4346 do_pkh_core (char * str, int shift)
4347 {
4348   int rd, rn, rm;
4349
4350   skip_whitespace (str);
4351   if (((rd = reg_required_here (&str, 12)) == FAIL)
4352       || (skip_past_comma (&str) == FAIL)
4353       || ((rn = reg_required_here (&str, 16)) == FAIL)
4354       || (skip_past_comma (&str) == FAIL)
4355       || ((rm = reg_required_here (&str, 0)) == FAIL))
4356     {
4357       inst.error = BAD_ARGS;
4358       return;
4359     }
4360
4361   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
4362     {
4363       inst.error = BAD_PC;
4364       return;
4365     }
4366
4367   /* Check for optional shift immediate constant.  */
4368   if (skip_past_comma (&str) == FAIL)
4369     {
4370       if (shift == SHIFT_ASR_IMMEDIATE)
4371         {
4372           /* If the shift specifier is ommited, turn the instruction
4373              into pkhbt rd, rm, rn.  First, switch the instruction
4374              code, and clear the rn and rm fields.  */
4375           inst.instruction &= 0xfff0f010;
4376           /* Now, re-encode the registers.  */
4377           inst.instruction |= (rm << 16) | rn;
4378         }
4379       return;
4380     }
4381
4382   decode_shift (&str, shift);
4383 }
4384
4385 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
4386    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
4387    Condition defaults to COND_ALWAYS.
4388    Error if Rd, Rn or Rm are R15.  */
4389
4390 static void
4391 do_pkhbt (char * str)
4392 {
4393   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
4394 }
4395
4396 /* ARM V6 PKHTB (Argument Parse).  */
4397
4398 static void
4399 do_pkhtb (char * str)
4400 {
4401   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
4402 }
4403
4404 /* ARM V6 Load Register Exclusive instruction (argument parse).
4405    LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
4406    Condition defaults to COND_ALWAYS.
4407    Error if Rd or Rn are R15.
4408    See ARMARMv6 A4.1.27: LDREX.  */
4409
4410 static void
4411 do_ldrex (char * str)
4412 {
4413   int rd, rn;
4414
4415   skip_whitespace (str);
4416
4417   /* Parse Rd.  */
4418   if (((rd = reg_required_here (&str, 12)) == FAIL)
4419       || (skip_past_comma (&str) == FAIL))
4420     {
4421       inst.error = BAD_ARGS;
4422       return;
4423     }
4424   else if (rd == REG_PC)
4425     {
4426       inst.error = BAD_PC;
4427       return;
4428     }
4429   skip_whitespace (str);
4430
4431   /* Skip past '['.  */
4432   if ((strlen (str) >= 1)
4433       &&strncmp (str, "[", 1) == 0)
4434     str += 1;
4435   skip_whitespace (str);
4436
4437   /* Parse Rn.  */
4438   if ((rn = reg_required_here (&str, 16)) == FAIL)
4439     {
4440       inst.error = BAD_ARGS;
4441       return;
4442     }
4443   else if (rn == REG_PC)
4444     {
4445       inst.error = BAD_PC;
4446       return;
4447     }
4448   skip_whitespace (str);
4449
4450   /* Skip past ']'.  */
4451   if ((strlen (str) >= 1)
4452       && strncmp (str, "]", 1) == 0)
4453     str += 1;
4454
4455   end_of_line (str);
4456 }
4457
4458 /* ARM V6 change processor state instruction (argument parse)
4459       CPS, CPSIE, CSPID .  */
4460
4461 static void
4462 do_cps (char * str)
4463 {
4464   do_cps_mode (&str);
4465   end_of_line (str);
4466 }
4467
4468 static void
4469 do_cps_flags (char ** str, int thumb_p)
4470 {
4471   struct cps_flag
4472   {
4473     char character;
4474     unsigned long arm_value;
4475     unsigned long thumb_value;
4476   };
4477   static struct cps_flag flag_table[] =
4478   {
4479     {'a', 0x100, 0x4 },
4480     {'i', 0x080, 0x2 },
4481     {'f', 0x040, 0x1 }
4482   };
4483
4484   int saw_a_flag = 0;
4485
4486   skip_whitespace (*str);
4487
4488   /* Get the a, f and i flags.  */
4489   while (**str && **str != ',')
4490     {
4491       struct cps_flag *p;
4492       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
4493
4494       for (p = flag_table; p < q; ++p)
4495         if (strncasecmp (*str, &p->character, 1) == 0)
4496           {
4497             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
4498             saw_a_flag = 1;
4499             break;
4500           }
4501       if (p == q)
4502         {
4503           inst.error = _("unrecognized flag");
4504           return;
4505         }
4506       (*str)++;
4507     }
4508
4509   if (!saw_a_flag)
4510     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
4511 }
4512
4513 static void
4514 do_cpsi (char * str)
4515 {
4516   do_cps_flags (&str, /*thumb_p=*/0);
4517
4518   if (skip_past_comma (&str) == SUCCESS)
4519     {
4520       skip_whitespace (str);
4521       do_cps_mode (&str);
4522     }
4523   end_of_line (str);
4524 }
4525
4526 /* THUMB V5 breakpoint instruction (argument parse)
4527         BKPT <immed_8>.  */
4528
4529 static void
4530 do_t_bkpt (char * str)
4531 {
4532   expressionS expr;
4533   unsigned long number;
4534
4535   skip_whitespace (str);
4536
4537   /* Allow optional leading '#'.  */
4538   if (is_immediate_prefix (*str))
4539     str ++;
4540
4541   memset (& expr, '\0', sizeof (expr));
4542   if (my_get_expression (& expr, & str)
4543       || (expr.X_op != O_constant
4544           /* As a convenience we allow 'bkpt' without an operand.  */
4545           && expr.X_op != O_absent))
4546     {
4547       inst.error = _("bad expression");
4548       return;
4549     }
4550
4551   number = expr.X_add_number;
4552
4553   /* Check it fits an 8 bit unsigned.  */
4554   if (number != (number & 0xff))
4555     {
4556       inst.error = _("immediate value out of range");
4557       return;
4558     }
4559
4560   inst.instruction |= number;
4561
4562   end_of_line (str);
4563 }
4564
4565 static bfd_reloc_code_real_type
4566 arm_parse_reloc (void)
4567 {
4568   char         id [16];
4569   char *       ip;
4570   unsigned int i;
4571   static struct
4572   {
4573     char * str;
4574     int    len;
4575     bfd_reloc_code_real_type reloc;
4576   }
4577   reloc_map[] =
4578   {
4579 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
4580     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
4581     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
4582     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
4583        branch instructions generated by GCC for PLT relocs.  */
4584     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
4585     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
4586     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
4587     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
4588     { NULL, 0,         BFD_RELOC_UNUSED }
4589 #undef MAP
4590   };
4591
4592   for (i = 0, ip = input_line_pointer;
4593        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
4594        i++, ip++)
4595     id[i] = TOLOWER (*ip);
4596
4597   for (i = 0; reloc_map[i].str; i++)
4598     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
4599       break;
4600
4601   input_line_pointer += reloc_map[i].len;
4602
4603   return reloc_map[i].reloc;
4604 }
4605
4606 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4607    Expects inst.instruction is set for BLX(1).
4608    Note: this is cloned from do_branch, and the reloc changed to be a
4609         new one that can cope with setting one extra bit (the H bit).  */
4610
4611 static void
4612 do_branch25 (char * str)
4613 {
4614   if (my_get_expression (& inst.reloc.exp, & str))
4615     return;
4616
4617 #ifdef OBJ_ELF
4618   {
4619     char * save_in;
4620
4621     /* ScottB: February 5, 1998 */
4622     /* Check to see of PLT32 reloc required for the instruction.  */
4623
4624     /* arm_parse_reloc() works on input_line_pointer.
4625        We actually want to parse the operands to the branch instruction
4626        passed in 'str'.  Save the input pointer and restore it later.  */
4627     save_in = input_line_pointer;
4628     input_line_pointer = str;
4629
4630     if (inst.reloc.exp.X_op == O_symbol
4631         && *str == '('
4632         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4633       {
4634         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
4635         inst.reloc.pc_rel = 0;
4636         /* Modify str to point to after parsed operands, otherwise
4637            end_of_line() will complain about the (PLT) left in str.  */
4638         str = input_line_pointer;
4639       }
4640     else
4641       {
4642         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4643         inst.reloc.pc_rel = 1;
4644       }
4645
4646     input_line_pointer = save_in;
4647   }
4648 #else
4649   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
4650   inst.reloc.pc_rel = 1;
4651 #endif /* OBJ_ELF */
4652
4653   end_of_line (str);
4654 }
4655
4656 /* ARM V5 branch-link-exchange instruction (argument parse)
4657      BLX <target_addr>          ie BLX(1)
4658      BLX{<condition>} <Rm>      ie BLX(2)
4659    Unfortunately, there are two different opcodes for this mnemonic.
4660    So, the insns[].value is not used, and the code here zaps values
4661         into inst.instruction.
4662    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
4663
4664 static void
4665 do_blx (char * str)
4666 {
4667   char * mystr = str;
4668   int rm;
4669
4670   skip_whitespace (mystr);
4671   rm = reg_required_here (& mystr, 0);
4672
4673   /* The above may set inst.error.  Ignore his opinion.  */
4674   inst.error = 0;
4675
4676   if (rm != FAIL)
4677     {
4678       /* Arg is a register.
4679          Use the condition code our caller put in inst.instruction.
4680          Pass ourselves off as a BX with a funny opcode.  */
4681       inst.instruction |= 0x012fff30;
4682       do_bx (str);
4683     }
4684   else
4685     {
4686       /* This must be is BLX <target address>, no condition allowed.  */
4687       if (inst.instruction != COND_ALWAYS)
4688         {
4689           inst.error = BAD_COND;
4690           return;
4691         }
4692
4693       inst.instruction = 0xfafffffe;
4694
4695       /* Process like a B/BL, but with a different reloc.
4696          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
4697       do_branch25 (str);
4698     }
4699 }
4700
4701 /* ARM V5 Thumb BLX (argument parse)
4702         BLX <target_addr>       which is BLX(1)
4703         BLX <Rm>                which is BLX(2)
4704    Unfortunately, there are two different opcodes for this mnemonic.
4705    So, the tinsns[].value is not used, and the code here zaps values
4706         into inst.instruction.  */
4707
4708 static void
4709 do_t_blx (char * str)
4710 {
4711   char * mystr = str;
4712   int rm;
4713
4714   skip_whitespace (mystr);
4715   inst.instruction = 0x4780;
4716
4717   /* Note that this call is to the ARM register recognizer.  BLX(2)
4718      uses the ARM register space, not the Thumb one, so a call to
4719      thumb_reg() would be wrong.  */
4720   rm = reg_required_here (& mystr, 3);
4721   inst.error = 0;
4722
4723   if (rm != FAIL)
4724     {
4725       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
4726       inst.size = 2;
4727     }
4728   else
4729     {
4730       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
4731       inst.instruction = 0xf7ffeffe;
4732       inst.size = 4;
4733
4734       if (my_get_expression (& inst.reloc.exp, & mystr))
4735         return;
4736
4737       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
4738       inst.reloc.pc_rel = 1;
4739     }
4740
4741   end_of_line (mystr);
4742 }
4743
4744 /* ARM V5 breakpoint instruction (argument parse)
4745      BKPT <16 bit unsigned immediate>
4746      Instruction is not conditional.
4747         The bit pattern given in insns[] has the COND_ALWAYS condition,
4748         and it is an error if the caller tried to override that.  */
4749
4750 static void
4751 do_bkpt (char * str)
4752 {
4753   expressionS expr;
4754   unsigned long number;
4755
4756   skip_whitespace (str);
4757
4758   /* Allow optional leading '#'.  */
4759   if (is_immediate_prefix (* str))
4760     str++;
4761
4762   memset (& expr, '\0', sizeof (expr));
4763
4764   if (my_get_expression (& expr, & str)
4765       || (expr.X_op != O_constant
4766           /* As a convenience we allow 'bkpt' without an operand.  */
4767           && expr.X_op != O_absent))
4768     {
4769       inst.error = _("bad expression");
4770       return;
4771     }
4772
4773   number = expr.X_add_number;
4774
4775   /* Check it fits a 16 bit unsigned.  */
4776   if (number != (number & 0xffff))
4777     {
4778       inst.error = _("immediate value out of range");
4779       return;
4780     }
4781
4782   /* Top 12 of 16 bits to bits 19:8.  */
4783   inst.instruction |= (number & 0xfff0) << 4;
4784
4785   /* Bottom 4 of 16 bits to bits 3:0.  */
4786   inst.instruction |= number & 0xf;
4787
4788   end_of_line (str);
4789 }
4790
4791 /* THUMB CPS instruction (argument parse).  */
4792
4793 static void
4794 do_t_cps (char * str)
4795 {
4796   do_cps_flags (&str, /*thumb_p=*/1);
4797   end_of_line (str);
4798 }
4799
4800 /* Parse and validate that a register is of the right form, this saves
4801    repeated checking of this information in many similar cases.
4802    Unlike the 32-bit case we do not insert the register into the opcode
4803    here, since the position is often unknown until the full instruction
4804    has been parsed.  */
4805
4806 static int
4807 thumb_reg (char ** strp, int hi_lo)
4808 {
4809   int reg;
4810
4811   if ((reg = reg_required_here (strp, -1)) == FAIL)
4812     return FAIL;
4813
4814   switch (hi_lo)
4815     {
4816     case THUMB_REG_LO:
4817       if (reg > 7)
4818         {
4819           inst.error = _("lo register required");
4820           return FAIL;
4821         }
4822       break;
4823
4824     case THUMB_REG_HI:
4825       if (reg < 8)
4826         {
4827           inst.error = _("hi register required");
4828           return FAIL;
4829         }
4830       break;
4831
4832     default:
4833       break;
4834     }
4835
4836   return reg;
4837 }
4838
4839 static void
4840 thumb_mov_compare (char * str, int move)
4841 {
4842   int Rd, Rs = FAIL;
4843
4844   skip_whitespace (str);
4845
4846   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4847       || skip_past_comma (&str) == FAIL)
4848     {
4849       if (! inst.error)
4850         inst.error = BAD_ARGS;
4851       return;
4852     }
4853
4854   if (move != THUMB_CPY && is_immediate_prefix (*str))
4855     {
4856       str++;
4857       if (my_get_expression (&inst.reloc.exp, &str))
4858         return;
4859     }
4860   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4861     return;
4862
4863   if (Rs != FAIL)
4864     {
4865       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
4866         {
4867           if (move == THUMB_MOVE)
4868             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4869                since a MOV instruction produces unpredictable results.  */
4870             inst.instruction = T_OPCODE_ADD_I3;
4871           else
4872             inst.instruction = T_OPCODE_CMP_LR;
4873           inst.instruction |= Rd | (Rs << 3);
4874         }
4875       else
4876         {
4877           if (move == THUMB_MOVE)
4878             inst.instruction = T_OPCODE_MOV_HR;
4879           else if (move != THUMB_CPY)
4880             inst.instruction = T_OPCODE_CMP_HR;
4881
4882           if (Rd > 7)
4883             inst.instruction |= THUMB_H1;
4884
4885           if (Rs > 7)
4886             inst.instruction |= THUMB_H2;
4887
4888           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4889         }
4890     }
4891   else
4892     {
4893       if (Rd > 7)
4894         {
4895           inst.error = _("only lo regs allowed with immediate");
4896           return;
4897         }
4898
4899       if (move == THUMB_MOVE)
4900         inst.instruction = T_OPCODE_MOV_I8;
4901       else
4902         inst.instruction = T_OPCODE_CMP_I8;
4903
4904       inst.instruction |= Rd << 8;
4905
4906       if (inst.reloc.exp.X_op != O_constant)
4907         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4908       else
4909         {
4910           unsigned value = inst.reloc.exp.X_add_number;
4911
4912           if (value > 255)
4913             {
4914               inst.error = _("invalid immediate");
4915               return;
4916             }
4917
4918           inst.instruction |= value;
4919         }
4920     }
4921
4922   end_of_line (str);
4923 }
4924
4925 /* THUMB CPY instruction (argument parse).  */
4926
4927 static void
4928 do_t_cpy (char * str)
4929 {
4930   thumb_mov_compare (str, THUMB_CPY);
4931 }
4932
4933 /* THUMB SETEND instruction (argument parse).  */
4934
4935 static void
4936 do_t_setend (char * str)
4937 {
4938   if (do_endian_specifier (str))
4939     inst.instruction |= 0x8;
4940 }
4941
4942 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
4943
4944 static unsigned long
4945 check_iwmmxt_insn (char * str,
4946                    enum iwmmxt_insn_type insn_type,
4947                    int immediate_size)
4948 {
4949   int reg = 0;
4950   const char *  inst_error;
4951   expressionS expr;
4952   unsigned long number;
4953
4954   inst_error = inst.error;
4955   if (!inst.error)
4956     inst.error = BAD_ARGS;
4957   skip_whitespace (str);
4958
4959   switch (insn_type)
4960     {
4961     case check_rd:
4962       if ((reg = reg_required_here (&str, 12)) == FAIL)
4963         return FAIL;
4964       break;
4965
4966     case check_wr:
4967        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4968          return FAIL;
4969        break;
4970
4971     case check_wrwr:
4972       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4973            || skip_past_comma (&str) == FAIL
4974            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4975         return FAIL;
4976       break;
4977
4978     case check_wrwrwr:
4979       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4980            || skip_past_comma (&str) == FAIL
4981            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4982            || skip_past_comma (&str) == FAIL
4983            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4984         return FAIL;
4985       break;
4986
4987     case check_wrwrwcg:
4988       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4989            || skip_past_comma (&str) == FAIL
4990            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4991            || skip_past_comma (&str) == FAIL
4992            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4993         return FAIL;
4994       break;
4995
4996     case check_tbcst:
4997       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4998            || skip_past_comma (&str) == FAIL
4999            || reg_required_here (&str, 12) == FAIL))
5000         return FAIL;
5001       break;
5002
5003     case check_tmovmsk:
5004       if ((reg_required_here (&str, 12) == FAIL
5005            || skip_past_comma (&str) == FAIL
5006            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
5007         return FAIL;
5008       break;
5009
5010     case check_tmia:
5011       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
5012            || skip_past_comma (&str) == FAIL
5013            || reg_required_here (&str, 0) == FAIL
5014            || skip_past_comma (&str) == FAIL
5015            || reg_required_here (&str, 12) == FAIL))
5016         return FAIL;
5017       break;
5018
5019     case check_tmcrr:
5020       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5021            || skip_past_comma (&str) == FAIL
5022            || reg_required_here (&str, 12) == FAIL
5023            || skip_past_comma (&str) == FAIL
5024            || reg_required_here (&str, 16) == FAIL))
5025         return FAIL;
5026       break;
5027
5028     case check_tmrrc:
5029       if ((reg_required_here (&str, 12) == FAIL
5030            || skip_past_comma (&str) == FAIL
5031            || reg_required_here (&str, 16) == FAIL
5032            || skip_past_comma (&str) == FAIL
5033            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
5034         return FAIL;
5035       break;
5036
5037     case check_tmcr:
5038       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
5039            || skip_past_comma (&str) == FAIL
5040            || reg_required_here (&str, 12) == FAIL))
5041         return FAIL;
5042       break;
5043
5044     case check_tmrc:
5045       if ((reg_required_here (&str, 12) == FAIL
5046            || skip_past_comma (&str) == FAIL
5047            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
5048         return FAIL;
5049       break;
5050
5051     case check_tinsr:
5052       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5053            || skip_past_comma (&str) == FAIL
5054            || reg_required_here (&str, 12) == FAIL
5055            || skip_past_comma (&str) == FAIL))
5056         return FAIL;
5057       break;
5058
5059     case check_textrc:
5060       if ((reg_required_here (&str, 12) == FAIL
5061            || skip_past_comma (&str) == FAIL))
5062         return FAIL;
5063       break;
5064
5065     case check_waligni:
5066       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5067            || skip_past_comma (&str) == FAIL
5068            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5069            || skip_past_comma (&str) == FAIL
5070            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
5071            || skip_past_comma (&str) == FAIL))
5072         return FAIL;
5073       break;
5074
5075     case check_textrm:
5076       if ((reg_required_here (&str, 12) == FAIL
5077            || skip_past_comma (&str) == FAIL
5078            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5079            || skip_past_comma (&str) == FAIL))
5080         return FAIL;
5081       break;
5082
5083     case check_wshufh:
5084       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
5085            || skip_past_comma (&str) == FAIL
5086            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
5087            || skip_past_comma (&str) == FAIL))
5088         return FAIL;
5089       break;
5090     }
5091
5092   if (immediate_size == 0)
5093     {
5094       end_of_line (str);
5095       inst.error = inst_error;
5096       return reg;
5097     }
5098   else
5099     {
5100       skip_whitespace (str);
5101
5102       /* Allow optional leading '#'.  */
5103       if (is_immediate_prefix (* str))
5104         str++;
5105
5106       memset (& expr, '\0', sizeof (expr));
5107
5108       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
5109         {
5110           inst.error = _("bad or missing expression");
5111           return FAIL;
5112         }
5113
5114       number = expr.X_add_number;
5115
5116       if (number != (number & immediate_size))
5117         {
5118           inst.error = _("immediate value out of range");
5119           return FAIL;
5120         }
5121       end_of_line (str);
5122       inst.error = inst_error;
5123       return number;
5124     }
5125 }
5126
5127 static void
5128 do_iwmmxt_byte_addr (char * str)
5129 {
5130   int op = (inst.instruction & 0x300) >> 8;
5131   int reg;
5132
5133   inst.instruction &= ~0x300;
5134   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5135
5136   skip_whitespace (str);
5137
5138   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5139       || skip_past_comma (& str) == FAIL
5140       || cp_byte_address_required_here (&str) == FAIL)
5141     {
5142       if (! inst.error)
5143         inst.error = BAD_ARGS;
5144     }
5145   else
5146     end_of_line (str);
5147
5148   if (wc_register (reg))
5149     {
5150       as_bad (_("non-word size not supported with control register"));
5151       inst.instruction |=  0xf0000100;
5152       inst.instruction &= ~0x00400000;
5153     }
5154 }
5155
5156 static void
5157 do_iwmmxt_tandc (char * str)
5158 {
5159   int reg;
5160
5161   reg = check_iwmmxt_insn (str, check_rd, 0);
5162
5163   if (reg != REG_PC && !inst.error)
5164     inst.error = _("only r15 allowed here");
5165 }
5166
5167 static void
5168 do_iwmmxt_tbcst (char * str)
5169 {
5170   check_iwmmxt_insn (str, check_tbcst, 0);
5171 }
5172
5173 static void
5174 do_iwmmxt_textrc (char * str)
5175 {
5176   unsigned long number;
5177
5178   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
5179     return;
5180
5181   inst.instruction |= number & 0x7;
5182 }
5183
5184 static void
5185 do_iwmmxt_textrm (char * str)
5186 {
5187   unsigned long number;
5188
5189   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
5190     return;
5191
5192   inst.instruction |= number & 0x7;
5193 }
5194
5195 static void
5196 do_iwmmxt_tinsr (char * str)
5197 {
5198   unsigned long number;
5199
5200   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
5201     return;
5202
5203   inst.instruction |= number & 0x7;
5204 }
5205
5206 static void
5207 do_iwmmxt_tmcr (char * str)
5208 {
5209   check_iwmmxt_insn (str, check_tmcr, 0);
5210 }
5211
5212 static void
5213 do_iwmmxt_tmcrr (char * str)
5214 {
5215   check_iwmmxt_insn (str, check_tmcrr, 0);
5216 }
5217
5218 static void
5219 do_iwmmxt_tmia (char * str)
5220 {
5221   check_iwmmxt_insn (str, check_tmia, 0);
5222 }
5223
5224 static void
5225 do_iwmmxt_tmovmsk (char * str)
5226 {
5227   check_iwmmxt_insn (str, check_tmovmsk, 0);
5228 }
5229
5230 static void
5231 do_iwmmxt_tmrc (char * str)
5232 {
5233   check_iwmmxt_insn (str, check_tmrc, 0);
5234 }
5235
5236 static void
5237 do_iwmmxt_tmrrc (char * str)
5238 {
5239   check_iwmmxt_insn (str, check_tmrrc, 0);
5240 }
5241
5242 static void
5243 do_iwmmxt_torc (char * str)
5244 {
5245   check_iwmmxt_insn (str, check_rd, 0);
5246 }
5247
5248 static void
5249 do_iwmmxt_waligni (char * str)
5250 {
5251   unsigned long number;
5252
5253   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
5254     return;
5255
5256   inst.instruction |= ((number & 0x7) << 20);
5257 }
5258
5259 static void
5260 do_iwmmxt_wmov (char * str)
5261 {
5262   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
5263     return;
5264
5265   inst.instruction |= ((inst.instruction >> 16) & 0xf);
5266 }
5267
5268 static void
5269 do_iwmmxt_word_addr (char * str)
5270 {
5271   int op = (inst.instruction & 0x300) >> 8;
5272   int reg;
5273
5274   inst.instruction &= ~0x300;
5275   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
5276
5277   skip_whitespace (str);
5278
5279   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
5280       || skip_past_comma (& str) == FAIL
5281       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
5282     {
5283       if (! inst.error)
5284         inst.error = BAD_ARGS;
5285     }
5286   else
5287     end_of_line (str);
5288
5289   if (wc_register (reg))
5290     {
5291       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
5292         as_bad (_("conditional execution not supported with control register"));
5293       if (op != 2)
5294         as_bad (_("non-word size not supported with control register"));
5295       inst.instruction |=  0xf0000100;
5296       inst.instruction &= ~0x00400000;
5297     }
5298 }
5299
5300 static void
5301 do_iwmmxt_wrwr (char * str)
5302 {
5303   check_iwmmxt_insn (str, check_wrwr, 0);
5304 }
5305
5306 static void
5307 do_iwmmxt_wrwrwcg (char * str)
5308 {
5309   check_iwmmxt_insn (str, check_wrwrwcg, 0);
5310 }
5311
5312 static void
5313 do_iwmmxt_wrwrwr (char * str)
5314 {
5315   check_iwmmxt_insn (str, check_wrwrwr, 0);
5316 }
5317
5318 static void
5319 do_iwmmxt_wshufh (char * str)
5320 {
5321   unsigned long number;
5322
5323   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5324     return;
5325
5326   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5327 }
5328
5329 static void
5330 do_iwmmxt_wzero (char * str)
5331 {
5332   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5333     return;
5334
5335   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5336 }
5337
5338 /* Xscale multiply-accumulate (argument parse)
5339      MIAcc   acc0,Rm,Rs
5340      MIAPHcc acc0,Rm,Rs
5341      MIAxycc acc0,Rm,Rs.  */
5342
5343 static void
5344 do_xsc_mia (char * str)
5345 {
5346   int rs;
5347   int rm;
5348
5349   if (accum0_required_here (& str) == FAIL)
5350     inst.error = ERR_NO_ACCUM;
5351
5352   else if (skip_past_comma (& str) == FAIL
5353            || (rm = reg_required_here (& str, 0)) == FAIL)
5354     inst.error = BAD_ARGS;
5355
5356   else if (skip_past_comma (& str) == FAIL
5357            || (rs = reg_required_here (& str, 12)) == FAIL)
5358     inst.error = BAD_ARGS;
5359
5360   /* inst.instruction has now been zapped with both rm and rs.  */
5361   else if (rm == REG_PC || rs == REG_PC)
5362     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
5363
5364   else
5365     end_of_line (str);
5366 }
5367
5368 /* Xscale move-accumulator-register (argument parse)
5369
5370      MARcc   acc0,RdLo,RdHi.  */
5371
5372 static void
5373 do_xsc_mar (char * str)
5374 {
5375   int rdlo, rdhi;
5376
5377   if (accum0_required_here (& str) == FAIL)
5378     inst.error = ERR_NO_ACCUM;
5379
5380   else if (skip_past_comma (& str) == FAIL
5381            || (rdlo = reg_required_here (& str, 12)) == FAIL)
5382     inst.error = BAD_ARGS;
5383
5384   else if (skip_past_comma (& str) == FAIL
5385            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5386     inst.error = BAD_ARGS;
5387
5388   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5389   else if (rdlo == REG_PC || rdhi == REG_PC)
5390     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5391
5392   else
5393     end_of_line (str);
5394 }
5395
5396 /* Xscale move-register-accumulator (argument parse)
5397
5398      MRAcc   RdLo,RdHi,acc0.  */
5399
5400 static void
5401 do_xsc_mra (char * str)
5402 {
5403   int rdlo;
5404   int rdhi;
5405
5406   skip_whitespace (str);
5407
5408   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5409     inst.error = BAD_ARGS;
5410
5411   else if (skip_past_comma (& str) == FAIL
5412            || (rdhi = reg_required_here (& str, 16)) == FAIL)
5413     inst.error = BAD_ARGS;
5414
5415   else if  (skip_past_comma (& str) == FAIL
5416             || accum0_required_here (& str) == FAIL)
5417     inst.error = ERR_NO_ACCUM;
5418
5419   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
5420   else if (rdlo == rdhi)
5421     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
5422
5423   else if (rdlo == REG_PC || rdhi == REG_PC)
5424     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
5425   else
5426     end_of_line (str);
5427 }
5428
5429 static int
5430 ldst_extend (char ** str)
5431 {
5432   int add = INDEX_UP;
5433
5434   switch (**str)
5435     {
5436     case '#':
5437     case '$':
5438       (*str)++;
5439       if (my_get_expression (& inst.reloc.exp, str))
5440         return FAIL;
5441
5442       if (inst.reloc.exp.X_op == O_constant)
5443         {
5444           int value = inst.reloc.exp.X_add_number;
5445
5446           if (value < -4095 || value > 4095)
5447             {
5448               inst.error = _("address offset too large");
5449               return FAIL;
5450             }
5451
5452           if (value < 0)
5453             {
5454               value = -value;
5455               add = 0;
5456             }
5457
5458           inst.instruction |= add | value;
5459         }
5460       else
5461         {
5462           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5463           inst.reloc.pc_rel = 0;
5464         }
5465       return SUCCESS;
5466
5467     case '-':
5468       add = 0;
5469       /* Fall through.  */
5470
5471     case '+':
5472       (*str)++;
5473       /* Fall through.  */
5474
5475     default:
5476       if (reg_required_here (str, 0) == FAIL)
5477         return FAIL;
5478
5479       inst.instruction |= add | OFFSET_REG;
5480       if (skip_past_comma (str) == SUCCESS)
5481         return decode_shift (str, SHIFT_IMMEDIATE);
5482
5483       return SUCCESS;
5484     }
5485 }
5486
5487 /* ARMv5TE: Preload-Cache
5488
5489     PLD <addr_mode>
5490
5491   Syntactically, like LDR with B=1, W=0, L=1.  */
5492
5493 static void
5494 do_pld (char * str)
5495 {
5496   int rd;
5497
5498   skip_whitespace (str);
5499
5500   if (* str != '[')
5501     {
5502       inst.error = _("'[' expected after PLD mnemonic");
5503       return;
5504     }
5505
5506   ++str;
5507   skip_whitespace (str);
5508
5509   if ((rd = reg_required_here (& str, 16)) == FAIL)
5510     return;
5511
5512   skip_whitespace (str);
5513
5514   if (*str == ']')
5515     {
5516       /* [Rn], ... ?  */
5517       ++str;
5518       skip_whitespace (str);
5519
5520       /* Post-indexed addressing is not allowed with PLD.  */
5521       if (skip_past_comma (&str) == SUCCESS)
5522         {
5523           inst.error
5524             = _("post-indexed expression used in preload instruction");
5525           return;
5526         }
5527       else if (*str == '!') /* [Rn]! */
5528         {
5529           inst.error = _("writeback used in preload instruction");
5530           ++str;
5531         }
5532       else /* [Rn] */
5533         inst.instruction |= INDEX_UP | PRE_INDEX;
5534     }
5535   else /* [Rn, ...] */
5536     {
5537       if (skip_past_comma (& str) == FAIL)
5538         {
5539           inst.error = _("pre-indexed expression expected");
5540           return;
5541         }
5542
5543       if (ldst_extend (&str) == FAIL)
5544         return;
5545
5546       skip_whitespace (str);
5547
5548       if (* str != ']')
5549         {
5550           inst.error = _("missing ]");
5551           return;
5552         }
5553
5554       ++ str;
5555       skip_whitespace (str);
5556
5557       if (* str == '!') /* [Rn]! */
5558         {
5559           inst.error = _("writeback used in preload instruction");
5560           ++ str;
5561         }
5562
5563       inst.instruction |= PRE_INDEX;
5564     }
5565
5566   end_of_line (str);
5567 }
5568
5569 /* ARMv5TE load-consecutive (argument parse)
5570    Mode is like LDRH.
5571
5572      LDRccD R, mode
5573      STRccD R, mode.  */
5574
5575 static void
5576 do_ldrd (char * str)
5577 {
5578   int rd;
5579   int rn;
5580
5581   skip_whitespace (str);
5582
5583   if ((rd = reg_required_here (& str, 12)) == FAIL)
5584     {
5585       inst.error = BAD_ARGS;
5586       return;
5587     }
5588
5589   if (skip_past_comma (& str) == FAIL
5590       || (rn = ld_mode_required_here (& str)) == FAIL)
5591     {
5592       if (!inst.error)
5593         inst.error = BAD_ARGS;
5594       return;
5595     }
5596
5597   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
5598   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
5599     {
5600       inst.error = _("destination register must be even");
5601       return;
5602     }
5603
5604   if (rd == REG_LR)
5605     {
5606       inst.error = _("r14 not allowed here");
5607       return;
5608     }
5609
5610   if (((rd == rn) || (rd + 1 == rn))
5611       && ((inst.instruction & WRITE_BACK)
5612           || (!(inst.instruction & PRE_INDEX))))
5613     as_warn (_("pre/post-indexing used when modified address register is destination"));
5614
5615   /* For an index-register load, the index register must not overlap the
5616      destination (even if not write-back).  */
5617   if ((inst.instruction & V4_STR_BIT) == 0
5618       && (inst.instruction & HWOFFSET_IMM) == 0)
5619     {
5620       int rm = inst.instruction & 0x0000000f;
5621
5622       if (rm == rd || (rm == rd + 1))
5623         as_warn (_("ldrd destination registers must not overlap index register"));
5624     }
5625
5626   end_of_line (str);
5627 }
5628
5629 /* Returns the index into fp_values of a floating point number,
5630    or -1 if not in the table.  */
5631
5632 static int
5633 my_get_float_expression (char ** str)
5634 {
5635   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5636   char *         save_in;
5637   expressionS    exp;
5638   int            i;
5639   int            j;
5640
5641   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5642
5643   /* Look for a raw floating point number.  */
5644   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5645       && is_end_of_line[(unsigned char) *save_in])
5646     {
5647       for (i = 0; i < NUM_FLOAT_VALS; i++)
5648         {
5649           for (j = 0; j < MAX_LITTLENUMS; j++)
5650             {
5651               if (words[j] != fp_values[i][j])
5652                 break;
5653             }
5654
5655           if (j == MAX_LITTLENUMS)
5656             {
5657               *str = save_in;
5658               return i;
5659             }
5660         }
5661     }
5662
5663   /* Try and parse a more complex expression, this will probably fail
5664      unless the code uses a floating point prefix (eg "0f").  */
5665   save_in = input_line_pointer;
5666   input_line_pointer = *str;
5667   if (expression (&exp) == absolute_section
5668       && exp.X_op == O_big
5669       && exp.X_add_number < 0)
5670     {
5671       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5672          Ditto for 15.  */
5673       if (gen_to_words (words, 5, (long) 15) == 0)
5674         {
5675           for (i = 0; i < NUM_FLOAT_VALS; i++)
5676             {
5677               for (j = 0; j < MAX_LITTLENUMS; j++)
5678                 {
5679                   if (words[j] != fp_values[i][j])
5680                     break;
5681                 }
5682
5683               if (j == MAX_LITTLENUMS)
5684                 {
5685                   *str = input_line_pointer;
5686                   input_line_pointer = save_in;
5687                   return i;
5688                 }
5689             }
5690         }
5691     }
5692
5693   *str = input_line_pointer;
5694   input_line_pointer = save_in;
5695   return -1;
5696 }
5697
5698 /* We handle all bad expressions here, so that we can report the faulty
5699    instruction in the error message.  */
5700 void
5701 md_operand (expressionS * expr)
5702 {
5703   if (in_my_get_expression)
5704     {
5705       expr->X_op = O_illegal;
5706       if (inst.error == NULL)
5707         inst.error = _("bad expression");
5708     }
5709 }
5710
5711 /* Do those data_ops which can take a negative immediate constant
5712    by altering the instruction.  A bit of a hack really.
5713         MOV <-> MVN
5714         AND <-> BIC
5715         ADC <-> SBC
5716         by inverting the second operand, and
5717         ADD <-> SUB
5718         CMP <-> CMN
5719         by negating the second operand.  */
5720
5721 static int
5722 negate_data_op (unsigned long * instruction,
5723                 unsigned long   value)
5724 {
5725   int op, new_inst;
5726   unsigned long negated, inverted;
5727
5728   negated = validate_immediate (-value);
5729   inverted = validate_immediate (~value);
5730
5731   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5732   switch (op)
5733     {
5734       /* First negates.  */
5735     case OPCODE_SUB:             /* ADD <-> SUB  */
5736       new_inst = OPCODE_ADD;
5737       value = negated;
5738       break;
5739
5740     case OPCODE_ADD:
5741       new_inst = OPCODE_SUB;
5742       value = negated;
5743       break;
5744
5745     case OPCODE_CMP:             /* CMP <-> CMN  */
5746       new_inst = OPCODE_CMN;
5747       value = negated;
5748       break;
5749
5750     case OPCODE_CMN:
5751       new_inst = OPCODE_CMP;
5752       value = negated;
5753       break;
5754
5755       /* Now Inverted ops.  */
5756     case OPCODE_MOV:             /* MOV <-> MVN  */
5757       new_inst = OPCODE_MVN;
5758       value = inverted;
5759       break;
5760
5761     case OPCODE_MVN:
5762       new_inst = OPCODE_MOV;
5763       value = inverted;
5764       break;
5765
5766     case OPCODE_AND:             /* AND <-> BIC  */
5767       new_inst = OPCODE_BIC;
5768       value = inverted;
5769       break;
5770
5771     case OPCODE_BIC:
5772       new_inst = OPCODE_AND;
5773       value = inverted;
5774       break;
5775
5776     case OPCODE_ADC:              /* ADC <-> SBC  */
5777       new_inst = OPCODE_SBC;
5778       value = inverted;
5779       break;
5780
5781     case OPCODE_SBC:
5782       new_inst = OPCODE_ADC;
5783       value = inverted;
5784       break;
5785
5786       /* We cannot do anything.  */
5787     default:
5788       return FAIL;
5789     }
5790
5791   if (value == (unsigned) FAIL)
5792     return FAIL;
5793
5794   *instruction &= OPCODE_MASK;
5795   *instruction |= new_inst << DATA_OP_SHIFT;
5796   return value;
5797 }
5798
5799 static int
5800 data_op2 (char ** str)
5801 {
5802   int value;
5803   expressionS expr;
5804
5805   skip_whitespace (* str);
5806
5807   if (reg_required_here (str, 0) != FAIL)
5808     {
5809       if (skip_past_comma (str) == SUCCESS)
5810         /* Shift operation on register.  */
5811         return decode_shift (str, NO_SHIFT_RESTRICT);
5812
5813       return SUCCESS;
5814     }
5815   else
5816     {
5817       /* Immediate expression.  */
5818       if (is_immediate_prefix (**str))
5819         {
5820           (*str)++;
5821           inst.error = NULL;
5822
5823           if (my_get_expression (&inst.reloc.exp, str))
5824             return FAIL;
5825
5826           if (inst.reloc.exp.X_add_symbol)
5827             {
5828               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5829               inst.reloc.pc_rel = 0;
5830             }
5831           else
5832             {
5833               if (skip_past_comma (str) == SUCCESS)
5834                 {
5835                   /* #x, y -- ie explicit rotation by Y.  */
5836                   if (my_get_expression (&expr, str))
5837                     return FAIL;
5838
5839                   if (expr.X_op != O_constant)
5840                     {
5841                       inst.error = _("constant expression expected");
5842                       return FAIL;
5843                     }
5844
5845                   /* Rotate must be a multiple of 2.  */
5846                   if (((unsigned) expr.X_add_number) > 30
5847                       || (expr.X_add_number & 1) != 0
5848                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
5849                     {
5850                       inst.error = _("invalid constant");
5851                       return FAIL;
5852                     }
5853                   inst.instruction |= INST_IMMEDIATE;
5854                   inst.instruction |= inst.reloc.exp.X_add_number;
5855                   inst.instruction |= expr.X_add_number << 7;
5856                   return SUCCESS;
5857                 }
5858
5859               /* Implicit rotation, select a suitable one.  */
5860               value = validate_immediate (inst.reloc.exp.X_add_number);
5861
5862               if (value == FAIL)
5863                 {
5864                   /* Can't be done.  Perhaps the code reads something like
5865                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
5866                   if ((value = negate_data_op (&inst.instruction,
5867                                                inst.reloc.exp.X_add_number))
5868                       == FAIL)
5869                     {
5870                       inst.error = _("invalid constant");
5871                       return FAIL;
5872                     }
5873                 }
5874
5875               inst.instruction |= value;
5876             }
5877
5878           inst.instruction |= INST_IMMEDIATE;
5879           return SUCCESS;
5880         }
5881
5882       (*str)++;
5883       inst.error = _("register or shift expression expected");
5884       return FAIL;
5885     }
5886 }
5887
5888 static int
5889 fp_op2 (char ** str)
5890 {
5891   skip_whitespace (* str);
5892
5893   if (fp_reg_required_here (str, 0) != FAIL)
5894     return SUCCESS;
5895   else
5896     {
5897       /* Immediate expression.  */
5898       if (*((*str)++) == '#')
5899         {
5900           int i;
5901
5902           inst.error = NULL;
5903
5904           skip_whitespace (* str);
5905
5906           /* First try and match exact strings, this is to guarantee
5907              that some formats will work even for cross assembly.  */
5908
5909           for (i = 0; fp_const[i]; i++)
5910             {
5911               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
5912                 {
5913                   char *start = *str;
5914
5915                   *str += strlen (fp_const[i]);
5916                   if (is_end_of_line[(unsigned char) **str])
5917                     {
5918                       inst.instruction |= i + 8;
5919                       return SUCCESS;
5920                     }
5921                   *str = start;
5922                 }
5923             }
5924
5925           /* Just because we didn't get a match doesn't mean that the
5926              constant isn't valid, just that it is in a format that we
5927              don't automatically recognize.  Try parsing it with
5928              the standard expression routines.  */
5929           if ((i = my_get_float_expression (str)) >= 0)
5930             {
5931               inst.instruction |= i + 8;
5932               return SUCCESS;
5933             }
5934
5935           inst.error = _("invalid floating point immediate expression");
5936           return FAIL;
5937         }
5938       inst.error =
5939         _("floating point register or immediate expression expected");
5940       return FAIL;
5941     }
5942 }
5943
5944 static void
5945 do_arit (char * str)
5946 {
5947   skip_whitespace (str);
5948
5949   if (reg_required_here (&str, 12) == FAIL
5950       || skip_past_comma (&str) == FAIL
5951       || reg_required_here (&str, 16) == FAIL
5952       || skip_past_comma (&str) == FAIL
5953       || data_op2 (&str) == FAIL)
5954     {
5955       if (!inst.error)
5956         inst.error = BAD_ARGS;
5957       return;
5958     }
5959
5960   end_of_line (str);
5961 }
5962
5963 static void
5964 do_adr (char * str)
5965 {
5966   /* This is a pseudo-op of the form "adr rd, label" to be converted
5967      into a relative address of the form "add rd, pc, #label-.-8".  */
5968   skip_whitespace (str);
5969
5970   if (reg_required_here (&str, 12) == FAIL
5971       || skip_past_comma (&str) == FAIL
5972       || my_get_expression (&inst.reloc.exp, &str))
5973     {
5974       if (!inst.error)
5975         inst.error = BAD_ARGS;
5976       return;
5977     }
5978
5979   /* Frag hacking will turn this into a sub instruction if the offset turns
5980      out to be negative.  */
5981   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5982 #ifndef TE_WINCE
5983   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
5984 #endif
5985   inst.reloc.pc_rel = 1;
5986
5987   end_of_line (str);
5988 }
5989
5990 static void
5991 do_adrl (char * str)
5992 {
5993   /* This is a pseudo-op of the form "adrl rd, label" to be converted
5994      into a relative address of the form:
5995      add rd, pc, #low(label-.-8)"
5996      add rd, rd, #high(label-.-8)"  */
5997
5998   skip_whitespace (str);
5999
6000   if (reg_required_here (&str, 12) == FAIL
6001       || skip_past_comma (&str) == FAIL
6002       || my_get_expression (&inst.reloc.exp, &str))
6003     {
6004       if (!inst.error)
6005         inst.error = BAD_ARGS;
6006
6007       return;
6008     }
6009
6010   end_of_line (str);
6011   /* Frag hacking will turn this into a sub instruction if the offset turns
6012      out to be negative.  */
6013   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
6014 #ifndef TE_WINCE
6015   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
6016 #endif
6017   inst.reloc.pc_rel            = 1;
6018   inst.size                    = INSN_SIZE * 2;
6019 }
6020
6021 static void
6022 do_cmp (char * str)
6023 {
6024   skip_whitespace (str);
6025
6026   if (reg_required_here (&str, 16) == FAIL)
6027     {
6028       if (!inst.error)
6029         inst.error = BAD_ARGS;
6030       return;
6031     }
6032
6033   if (skip_past_comma (&str) == FAIL
6034       || data_op2 (&str) == FAIL)
6035     {
6036       if (!inst.error)
6037         inst.error = BAD_ARGS;
6038       return;
6039     }
6040
6041   end_of_line (str);
6042 }
6043
6044 static void
6045 do_mov (char * str)
6046 {
6047   skip_whitespace (str);
6048
6049   if (reg_required_here (&str, 12) == FAIL)
6050     {
6051       if (!inst.error)
6052         inst.error = BAD_ARGS;
6053       return;
6054     }
6055
6056   if (skip_past_comma (&str) == FAIL
6057       || data_op2 (&str) == FAIL)
6058     {
6059       if (!inst.error)
6060         inst.error = BAD_ARGS;
6061       return;
6062     }
6063
6064   end_of_line (str);
6065 }
6066
6067 static void
6068 do_ldst (char * str)
6069 {
6070   int pre_inc = 0;
6071   int conflict_reg;
6072   int value;
6073
6074   skip_whitespace (str);
6075
6076   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
6077     {
6078       if (!inst.error)
6079         inst.error = BAD_ARGS;
6080       return;
6081     }
6082
6083   if (skip_past_comma (&str) == FAIL)
6084     {
6085       inst.error = _("address expected");
6086       return;
6087     }
6088
6089   if (*str == '[')
6090     {
6091       int reg;
6092
6093       str++;
6094
6095       skip_whitespace (str);
6096
6097       if ((reg = reg_required_here (&str, 16)) == FAIL)
6098         return;
6099
6100       /* Conflicts can occur on stores as well as loads.  */
6101       conflict_reg = (conflict_reg == reg);
6102
6103       skip_whitespace (str);
6104
6105       if (*str == ']')
6106         {
6107           str ++;
6108
6109           if (skip_past_comma (&str) == SUCCESS)
6110             {
6111               /* [Rn],... (post inc)  */
6112               if (ldst_extend (&str) == FAIL)
6113                 return;
6114               if (conflict_reg)
6115                 as_warn (_("%s register same as write-back base"),
6116                          ((inst.instruction & LOAD_BIT)
6117                           ? _("destination") : _("source")));
6118             }
6119           else
6120             {
6121               /* [Rn]  */
6122               skip_whitespace (str);
6123
6124               if (*str == '!')
6125                 {
6126                   if (conflict_reg)
6127                     as_warn (_("%s register same as write-back base"),
6128                              ((inst.instruction & LOAD_BIT)
6129                               ? _("destination") : _("source")));
6130                   str++;
6131                   inst.instruction |= WRITE_BACK;
6132                 }
6133
6134               inst.instruction |= INDEX_UP;
6135               pre_inc = 1;
6136             }
6137         }
6138       else
6139         {
6140           /* [Rn,...]  */
6141           if (skip_past_comma (&str) == FAIL)
6142             {
6143               inst.error = _("pre-indexed expression expected");
6144               return;
6145             }
6146
6147           pre_inc = 1;
6148           if (ldst_extend (&str) == FAIL)
6149             return;
6150
6151           skip_whitespace (str);
6152
6153           if (*str++ != ']')
6154             {
6155               inst.error = _("missing ]");
6156               return;
6157             }
6158
6159           skip_whitespace (str);
6160
6161           if (*str == '!')
6162             {
6163               if (conflict_reg)
6164                 as_warn (_("%s register same as write-back base"),
6165                          ((inst.instruction & LOAD_BIT)
6166                           ? _("destination") : _("source")));
6167               str++;
6168               inst.instruction |= WRITE_BACK;
6169             }
6170         }
6171     }
6172   else if (*str == '=')
6173     {
6174       if ((inst.instruction & LOAD_BIT) == 0)
6175         {
6176           inst.error = _("invalid pseudo operation");
6177           return;
6178         }
6179
6180       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6181       str++;
6182
6183       skip_whitespace (str);
6184
6185       if (my_get_expression (&inst.reloc.exp, &str))
6186         return;
6187
6188       if (inst.reloc.exp.X_op != O_constant
6189           && inst.reloc.exp.X_op != O_symbol)
6190         {
6191           inst.error = _("constant expression expected");
6192           return;
6193         }
6194
6195       if (inst.reloc.exp.X_op == O_constant)
6196         {
6197           value = validate_immediate (inst.reloc.exp.X_add_number);
6198
6199           if (value != FAIL)
6200             {
6201               /* This can be done with a mov instruction.  */
6202               inst.instruction &= LITERAL_MASK;
6203               inst.instruction |= (INST_IMMEDIATE
6204                                    | (OPCODE_MOV << DATA_OP_SHIFT));
6205               inst.instruction |= value & 0xfff;
6206               end_of_line (str);
6207               return;
6208             }
6209
6210           value = validate_immediate (~inst.reloc.exp.X_add_number);
6211
6212           if (value != FAIL)
6213             {
6214               /* This can be done with a mvn instruction.  */
6215               inst.instruction &= LITERAL_MASK;
6216               inst.instruction |= (INST_IMMEDIATE
6217                                    | (OPCODE_MVN << DATA_OP_SHIFT));
6218               inst.instruction |= value & 0xfff;
6219               end_of_line (str);
6220               return;
6221             }
6222         }
6223
6224       /* Insert into literal pool.  */
6225       if (add_to_lit_pool () == FAIL)
6226         {
6227           if (!inst.error)
6228             inst.error = _("literal pool insertion failed");
6229           return;
6230         }
6231
6232       /* Change the instruction exp to point to the pool.  */
6233       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6234       inst.reloc.pc_rel = 1;
6235       inst.instruction |= (REG_PC << 16);
6236       pre_inc = 1;
6237     }
6238   else
6239     {
6240       if (my_get_expression (&inst.reloc.exp, &str))
6241         return;
6242
6243       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6244 #ifndef TE_WINCE
6245       /* PC rel adjust.  */
6246       inst.reloc.exp.X_add_number -= 8;
6247 #endif
6248       inst.reloc.pc_rel = 1;
6249       inst.instruction |= (REG_PC << 16);
6250       pre_inc = 1;
6251     }
6252
6253   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6254   end_of_line (str);
6255 }
6256
6257 static void
6258 do_ldstt (char * str)
6259 {
6260   int conflict_reg;
6261
6262   skip_whitespace (str);
6263
6264   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6265     {
6266       if (!inst.error)
6267         inst.error = BAD_ARGS;
6268       return;
6269     }
6270
6271   if (skip_past_comma (& str) == FAIL)
6272     {
6273       inst.error = _("address expected");
6274       return;
6275     }
6276
6277   if (*str == '[')
6278     {
6279       int reg;
6280
6281       str++;
6282
6283       skip_whitespace (str);
6284
6285       if ((reg = reg_required_here (&str, 16)) == FAIL)
6286         return;
6287
6288       /* ldrt/strt always use post-indexed addressing, so if the base is
6289          the same as Rd, we warn.  */
6290       if (conflict_reg == reg)
6291         as_warn (_("%s register same as write-back base"),
6292                  ((inst.instruction & LOAD_BIT)
6293                   ? _("destination") : _("source")));
6294
6295       skip_whitespace (str);
6296
6297       if (*str == ']')
6298         {
6299           str ++;
6300
6301           if (skip_past_comma (&str) == SUCCESS)
6302             {
6303               /* [Rn],... (post inc)  */
6304               if (ldst_extend (&str) == FAIL)
6305                 return;
6306             }
6307           else
6308             {
6309               /* [Rn]  */
6310               skip_whitespace (str);
6311
6312               /* Skip a write-back '!'.  */
6313               if (*str == '!')
6314                 str++;
6315
6316               inst.instruction |= INDEX_UP;
6317             }
6318         }
6319       else
6320         {
6321           inst.error = _("post-indexed expression expected");
6322           return;
6323         }
6324     }
6325   else
6326     {
6327       inst.error = _("post-indexed expression expected");
6328       return;
6329     }
6330
6331   end_of_line (str);
6332 }
6333
6334 /* Halfword and signed-byte load/store operations.  */
6335
6336 static void
6337 do_ldstv4 (char * str)
6338 {
6339   int pre_inc = 0;
6340   int conflict_reg;
6341   int value;
6342
6343   skip_whitespace (str);
6344
6345   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6346     {
6347       if (!inst.error)
6348         inst.error = BAD_ARGS;
6349       return;
6350     }
6351
6352   if (skip_past_comma (& str) == FAIL)
6353     {
6354       inst.error = _("address expected");
6355       return;
6356     }
6357
6358   if (*str == '[')
6359     {
6360       int reg;
6361
6362       str++;
6363
6364       skip_whitespace (str);
6365
6366       if ((reg = reg_required_here (&str, 16)) == FAIL)
6367         return;
6368
6369       /* Conflicts can occur on stores as well as loads.  */
6370       conflict_reg = (conflict_reg == reg);
6371
6372       skip_whitespace (str);
6373
6374       if (*str == ']')
6375         {
6376           str ++;
6377
6378           if (skip_past_comma (&str) == SUCCESS)
6379             {
6380               /* [Rn],... (post inc)  */
6381               if (ldst_extend_v4 (&str) == FAIL)
6382                 return;
6383               if (conflict_reg)
6384                 as_warn (_("%s register same as write-back base"),
6385                          ((inst.instruction & LOAD_BIT)
6386                           ? _("destination") : _("source")));
6387             }
6388           else
6389             {
6390               /* [Rn]  */
6391               inst.instruction |= HWOFFSET_IMM;
6392
6393               skip_whitespace (str);
6394
6395               if (*str == '!')
6396                 {
6397                   if (conflict_reg)
6398                     as_warn (_("%s register same as write-back base"),
6399                              ((inst.instruction & LOAD_BIT)
6400                               ? _("destination") : _("source")));
6401                   str++;
6402                   inst.instruction |= WRITE_BACK;
6403                 }
6404
6405               inst.instruction |= INDEX_UP;
6406               pre_inc = 1;
6407             }
6408         }
6409       else
6410         {
6411           /* [Rn,...]  */
6412           if (skip_past_comma (&str) == FAIL)
6413             {
6414               inst.error = _("pre-indexed expression expected");
6415               return;
6416             }
6417
6418           pre_inc = 1;
6419           if (ldst_extend_v4 (&str) == FAIL)
6420             return;
6421
6422           skip_whitespace (str);
6423
6424           if (*str++ != ']')
6425             {
6426               inst.error = _("missing ]");
6427               return;
6428             }
6429
6430           skip_whitespace (str);
6431
6432           if (*str == '!')
6433             {
6434               if (conflict_reg)
6435                 as_warn (_("%s register same as write-back base"),
6436                          ((inst.instruction & LOAD_BIT)
6437                           ? _("destination") : _("source")));
6438               str++;
6439               inst.instruction |= WRITE_BACK;
6440             }
6441         }
6442     }
6443   else if (*str == '=')
6444     {
6445       if ((inst.instruction & LOAD_BIT) == 0)
6446         {
6447           inst.error = _("invalid pseudo operation");
6448           return;
6449         }
6450
6451       /* XXX Does this work correctly for half-word/byte ops?  */
6452       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
6453       str++;
6454
6455       skip_whitespace (str);
6456
6457       if (my_get_expression (&inst.reloc.exp, &str))
6458         return;
6459
6460       if (inst.reloc.exp.X_op != O_constant
6461           && inst.reloc.exp.X_op != O_symbol)
6462         {
6463           inst.error = _("constant expression expected");
6464           return;
6465         }
6466
6467       if (inst.reloc.exp.X_op == O_constant)
6468         {
6469           value = validate_immediate (inst.reloc.exp.X_add_number);
6470
6471           if (value != FAIL)
6472             {
6473               /* This can be done with a mov instruction.  */
6474               inst.instruction &= LITERAL_MASK;
6475               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6476               inst.instruction |= value & 0xfff;
6477               end_of_line (str);
6478               return;
6479             }
6480
6481           value = validate_immediate (~ inst.reloc.exp.X_add_number);
6482
6483           if (value != FAIL)
6484             {
6485               /* This can be done with a mvn instruction.  */
6486               inst.instruction &= LITERAL_MASK;
6487               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6488               inst.instruction |= value & 0xfff;
6489               end_of_line (str);
6490               return;
6491             }
6492         }
6493
6494       /* Insert into literal pool.  */
6495       if (add_to_lit_pool () == FAIL)
6496         {
6497           if (!inst.error)
6498             inst.error = _("literal pool insertion failed");
6499           return;
6500         }
6501
6502       /* Change the instruction exp to point to the pool.  */
6503       inst.instruction |= HWOFFSET_IMM;
6504       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6505       inst.reloc.pc_rel = 1;
6506       inst.instruction |= (REG_PC << 16);
6507       pre_inc = 1;
6508     }
6509   else
6510     {
6511       if (my_get_expression (&inst.reloc.exp, &str))
6512         return;
6513
6514       inst.instruction |= HWOFFSET_IMM;
6515       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6516 #ifndef TE_WINCE
6517       /* PC rel adjust.  */
6518       inst.reloc.exp.X_add_number -= 8;
6519 #endif
6520       inst.reloc.pc_rel = 1;
6521       inst.instruction |= (REG_PC << 16);
6522       pre_inc = 1;
6523     }
6524
6525   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6526   end_of_line (str);
6527 }
6528
6529 static long
6530 reg_list (char ** strp)
6531 {
6532   char * str = * strp;
6533   long   range = 0;
6534   int    another_range;
6535
6536   /* We come back here if we get ranges concatenated by '+' or '|'.  */
6537   do
6538     {
6539       another_range = 0;
6540
6541       if (*str == '{')
6542         {
6543           int in_range = 0;
6544           int cur_reg = -1;
6545
6546           str++;
6547           do
6548             {
6549               int reg;
6550
6551               skip_whitespace (str);
6552
6553               if ((reg = reg_required_here (& str, -1)) == FAIL)
6554                 return FAIL;
6555
6556               if (in_range)
6557                 {
6558                   int i;
6559
6560                   if (reg <= cur_reg)
6561                     {
6562                       inst.error = _("bad range in register list");
6563                       return FAIL;
6564                     }
6565
6566                   for (i = cur_reg + 1; i < reg; i++)
6567                     {
6568                       if (range & (1 << i))
6569                         as_tsktsk
6570                           (_("Warning: duplicated register (r%d) in register list"),
6571                            i);
6572                       else
6573                         range |= 1 << i;
6574                     }
6575                   in_range = 0;
6576                 }
6577
6578               if (range & (1 << reg))
6579                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6580                            reg);
6581               else if (reg <= cur_reg)
6582                 as_tsktsk (_("Warning: register range not in ascending order"));
6583
6584               range |= 1 << reg;
6585               cur_reg = reg;
6586             }
6587           while (skip_past_comma (&str) != FAIL
6588                  || (in_range = 1, *str++ == '-'));
6589           str--;
6590           skip_whitespace (str);
6591
6592           if (*str++ != '}')
6593             {
6594               inst.error = _("missing `}'");
6595               return FAIL;
6596             }
6597         }
6598       else
6599         {
6600           expressionS expr;
6601
6602           if (my_get_expression (&expr, &str))
6603             return FAIL;
6604
6605           if (expr.X_op == O_constant)
6606             {
6607               if (expr.X_add_number
6608                   != (expr.X_add_number & 0x0000ffff))
6609                 {
6610                   inst.error = _("invalid register mask");
6611                   return FAIL;
6612                 }
6613
6614               if ((range & expr.X_add_number) != 0)
6615                 {
6616                   int regno = range & expr.X_add_number;
6617
6618                   regno &= -regno;
6619                   regno = (1 << regno) - 1;
6620                   as_tsktsk
6621                     (_("Warning: duplicated register (r%d) in register list"),
6622                      regno);
6623                 }
6624
6625               range |= expr.X_add_number;
6626             }
6627           else
6628             {
6629               if (inst.reloc.type != 0)
6630                 {
6631                   inst.error = _("expression too complex");
6632                   return FAIL;
6633                 }
6634
6635               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6636               inst.reloc.type = BFD_RELOC_ARM_MULTI;
6637               inst.reloc.pc_rel = 0;
6638             }
6639         }
6640
6641       skip_whitespace (str);
6642
6643       if (*str == '|' || *str == '+')
6644         {
6645           str++;
6646           another_range = 1;
6647         }
6648     }
6649   while (another_range);
6650
6651   *strp = str;
6652   return range;
6653 }
6654
6655 static void
6656 do_ldmstm (char * str)
6657 {
6658   int base_reg;
6659   long range;
6660
6661   skip_whitespace (str);
6662
6663   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6664     return;
6665
6666   if (base_reg == REG_PC)
6667     {
6668       inst.error = _("r15 not allowed as base register");
6669       return;
6670     }
6671
6672   skip_whitespace (str);
6673
6674   if (*str == '!')
6675     {
6676       inst.instruction |= WRITE_BACK;
6677       str++;
6678     }
6679
6680   if (skip_past_comma (&str) == FAIL
6681       || (range = reg_list (&str)) == FAIL)
6682     {
6683       if (! inst.error)
6684         inst.error = BAD_ARGS;
6685       return;
6686     }
6687
6688   if (*str == '^')
6689     {
6690       str++;
6691       inst.instruction |= LDM_TYPE_2_OR_3;
6692     }
6693
6694   if (inst.instruction & WRITE_BACK)
6695     {
6696       /* Check for unpredictable uses of writeback.  */
6697       if (inst.instruction & LOAD_BIT)
6698         {
6699           /* Not allowed in LDM type 2.  */
6700           if ((inst.instruction & LDM_TYPE_2_OR_3)
6701               && ((range & (1 << REG_PC)) == 0))
6702             as_warn (_("writeback of base register is UNPREDICTABLE"));
6703           /* Only allowed if base reg not in list for other types.  */
6704           else if (range & (1 << base_reg))
6705             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
6706         }
6707       else /* STM.  */
6708         {
6709           /* Not allowed for type 2.  */
6710           if (inst.instruction & LDM_TYPE_2_OR_3)
6711             as_warn (_("writeback of base register is UNPREDICTABLE"));
6712           /* Only allowed if base reg not in list, or first in list.  */
6713           else if ((range & (1 << base_reg))
6714                    && (range & ((1 << base_reg) - 1)))
6715             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
6716         }
6717     }
6718
6719   inst.instruction |= range;
6720   end_of_line (str);
6721 }
6722
6723 static void
6724 do_smi (char * str)
6725 {
6726   skip_whitespace (str);
6727
6728   /* Allow optional leading '#'.  */
6729   if (is_immediate_prefix (*str))
6730     str++;
6731
6732   if (my_get_expression (& inst.reloc.exp, & str))
6733     return;
6734
6735   inst.reloc.type = BFD_RELOC_ARM_SMI;
6736   inst.reloc.pc_rel = 0;
6737   end_of_line (str);
6738 }
6739
6740 static void
6741 do_swi (char * str)
6742 {
6743   skip_whitespace (str);
6744
6745   /* Allow optional leading '#'.  */
6746   if (is_immediate_prefix (*str))
6747     str++;
6748
6749   if (my_get_expression (& inst.reloc.exp, & str))
6750     return;
6751
6752   inst.reloc.type = BFD_RELOC_ARM_SWI;
6753   inst.reloc.pc_rel = 0;
6754   end_of_line (str);
6755 }
6756
6757 static void
6758 do_swap (char * str)
6759 {
6760   int reg;
6761
6762   skip_whitespace (str);
6763
6764   if ((reg = reg_required_here (&str, 12)) == FAIL)
6765     return;
6766
6767   if (reg == REG_PC)
6768     {
6769       inst.error = _("r15 not allowed in swap");
6770       return;
6771     }
6772
6773   if (skip_past_comma (&str) == FAIL
6774       || (reg = reg_required_here (&str, 0)) == FAIL)
6775     {
6776       if (!inst.error)
6777         inst.error = BAD_ARGS;
6778       return;
6779     }
6780
6781   if (reg == REG_PC)
6782     {
6783       inst.error = _("r15 not allowed in swap");
6784       return;
6785     }
6786
6787   if (skip_past_comma (&str) == FAIL
6788       || *str++ != '[')
6789     {
6790       inst.error = BAD_ARGS;
6791       return;
6792     }
6793
6794   skip_whitespace (str);
6795
6796   if ((reg = reg_required_here (&str, 16)) == FAIL)
6797     return;
6798
6799   if (reg == REG_PC)
6800     {
6801       inst.error = BAD_PC;
6802       return;
6803     }
6804
6805   skip_whitespace (str);
6806
6807   if (*str++ != ']')
6808     {
6809       inst.error = _("missing ]");
6810       return;
6811     }
6812
6813   end_of_line (str);
6814 }
6815
6816 static void
6817 do_branch (char * str)
6818 {
6819   if (my_get_expression (&inst.reloc.exp, &str))
6820     return;
6821
6822 #ifdef OBJ_ELF
6823   {
6824     char * save_in;
6825
6826     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
6827        required for the instruction.  */
6828
6829     /* arm_parse_reloc () works on input_line_pointer.
6830        We actually want to parse the operands to the branch instruction
6831        passed in 'str'.  Save the input pointer and restore it later.  */
6832     save_in = input_line_pointer;
6833     input_line_pointer = str;
6834     if (inst.reloc.exp.X_op == O_symbol
6835         && *str == '('
6836         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
6837       {
6838         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
6839         inst.reloc.pc_rel = 0;
6840         /* Modify str to point to after parsed operands, otherwise
6841            end_of_line() will complain about the (PLT) left in str.  */
6842         str = input_line_pointer;
6843       }
6844     else
6845       {
6846         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6847         inst.reloc.pc_rel = 1;
6848       }
6849     input_line_pointer = save_in;
6850   }
6851 #else
6852   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
6853   inst.reloc.pc_rel = 1;
6854 #endif /* OBJ_ELF  */
6855
6856   end_of_line (str);
6857 }
6858
6859 static void
6860 do_cdp (char * str)
6861 {
6862   /* Co-processor data operation.
6863      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
6864   skip_whitespace (str);
6865
6866   if (co_proc_number (&str) == FAIL)
6867     {
6868       if (!inst.error)
6869         inst.error = BAD_ARGS;
6870       return;
6871     }
6872
6873   if (skip_past_comma (&str) == FAIL
6874       || cp_opc_expr (&str, 20,4) == FAIL)
6875     {
6876       if (!inst.error)
6877         inst.error = BAD_ARGS;
6878       return;
6879     }
6880
6881   if (skip_past_comma (&str) == FAIL
6882       || cp_reg_required_here (&str, 12) == FAIL)
6883     {
6884       if (!inst.error)
6885         inst.error = BAD_ARGS;
6886       return;
6887     }
6888
6889   if (skip_past_comma (&str) == FAIL
6890       || cp_reg_required_here (&str, 16) == FAIL)
6891     {
6892       if (!inst.error)
6893         inst.error = BAD_ARGS;
6894       return;
6895     }
6896
6897   if (skip_past_comma (&str) == FAIL
6898       || cp_reg_required_here (&str, 0) == FAIL)
6899     {
6900       if (!inst.error)
6901         inst.error = BAD_ARGS;
6902       return;
6903     }
6904
6905   if (skip_past_comma (&str) == SUCCESS)
6906     {
6907       if (cp_opc_expr (&str, 5, 3) == FAIL)
6908         {
6909           if (!inst.error)
6910             inst.error = BAD_ARGS;
6911           return;
6912         }
6913     }
6914
6915   end_of_line (str);
6916 }
6917
6918 static void
6919 do_lstc (char * str)
6920 {
6921   /* Co-processor register load/store.
6922      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
6923
6924   skip_whitespace (str);
6925
6926   if (co_proc_number (&str) == FAIL)
6927     {
6928       if (!inst.error)
6929         inst.error = BAD_ARGS;
6930       return;
6931     }
6932
6933   if (skip_past_comma (&str) == FAIL
6934       || cp_reg_required_here (&str, 12) == FAIL)
6935     {
6936       if (!inst.error)
6937         inst.error = BAD_ARGS;
6938       return;
6939     }
6940
6941   if (skip_past_comma (&str) == FAIL
6942       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6943     {
6944       if (! inst.error)
6945         inst.error = BAD_ARGS;
6946       return;
6947     }
6948
6949   end_of_line (str);
6950 }
6951
6952 static void
6953 do_co_reg (char * str)
6954 {
6955   /* Co-processor register transfer.
6956      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
6957
6958   skip_whitespace (str);
6959
6960   if (co_proc_number (&str) == FAIL)
6961     {
6962       if (!inst.error)
6963         inst.error = BAD_ARGS;
6964       return;
6965     }
6966
6967   if (skip_past_comma (&str) == FAIL
6968       || cp_opc_expr (&str, 21, 3) == FAIL)
6969     {
6970       if (!inst.error)
6971         inst.error = BAD_ARGS;
6972       return;
6973     }
6974
6975   if (skip_past_comma (&str) == FAIL
6976       || reg_required_here (&str, 12) == FAIL)
6977     {
6978       if (!inst.error)
6979         inst.error = BAD_ARGS;
6980       return;
6981     }
6982
6983   if (skip_past_comma (&str) == FAIL
6984       || cp_reg_required_here (&str, 16) == FAIL)
6985     {
6986       if (!inst.error)
6987         inst.error = BAD_ARGS;
6988       return;
6989     }
6990
6991   if (skip_past_comma (&str) == FAIL
6992       || cp_reg_required_here (&str, 0) == FAIL)
6993     {
6994       if (!inst.error)
6995         inst.error = BAD_ARGS;
6996       return;
6997     }
6998
6999   if (skip_past_comma (&str) == SUCCESS)
7000     {
7001       if (cp_opc_expr (&str, 5, 3) == FAIL)
7002         {
7003           if (!inst.error)
7004             inst.error = BAD_ARGS;
7005           return;
7006         }
7007     }
7008
7009   end_of_line (str);
7010 }
7011
7012 static void
7013 do_fpa_ctrl (char * str)
7014 {
7015   /* FP control registers.
7016      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
7017
7018   skip_whitespace (str);
7019
7020   if (reg_required_here (&str, 12) == FAIL)
7021     {
7022       if (!inst.error)
7023         inst.error = BAD_ARGS;
7024       return;
7025     }
7026
7027   end_of_line (str);
7028 }
7029
7030 static void
7031 do_fpa_ldst (char * str)
7032 {
7033   skip_whitespace (str);
7034
7035   if (fp_reg_required_here (&str, 12) == FAIL)
7036     {
7037       if (!inst.error)
7038         inst.error = BAD_ARGS;
7039       return;
7040     }
7041
7042   if (skip_past_comma (&str) == FAIL
7043       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7044     {
7045       if (!inst.error)
7046         inst.error = BAD_ARGS;
7047       return;
7048     }
7049
7050   end_of_line (str);
7051 }
7052
7053 static void
7054 do_fpa_ldmstm (char * str)
7055 {
7056   int num_regs;
7057
7058   skip_whitespace (str);
7059
7060   if (fp_reg_required_here (&str, 12) == FAIL)
7061     {
7062       if (! inst.error)
7063         inst.error = BAD_ARGS;
7064       return;
7065     }
7066
7067   /* Get Number of registers to transfer.  */
7068   if (skip_past_comma (&str) == FAIL
7069       || my_get_expression (&inst.reloc.exp, &str))
7070     {
7071       if (! inst.error)
7072         inst.error = _("constant expression expected");
7073       return;
7074     }
7075
7076   if (inst.reloc.exp.X_op != O_constant)
7077     {
7078       inst.error = _("constant value required for number of registers");
7079       return;
7080     }
7081
7082   num_regs = inst.reloc.exp.X_add_number;
7083
7084   if (num_regs < 1 || num_regs > 4)
7085     {
7086       inst.error = _("number of registers must be in the range [1:4]");
7087       return;
7088     }
7089
7090   switch (num_regs)
7091     {
7092     case 1:
7093       inst.instruction |= CP_T_X;
7094       break;
7095     case 2:
7096       inst.instruction |= CP_T_Y;
7097       break;
7098     case 3:
7099       inst.instruction |= CP_T_Y | CP_T_X;
7100       break;
7101     case 4:
7102       break;
7103     default:
7104       abort ();
7105     }
7106
7107   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
7108     {
7109       int reg;
7110       int write_back;
7111       int offset;
7112
7113       /* The instruction specified "ea" or "fd", so we can only accept
7114          [Rn]{!}.  The instruction does not really support stacking or
7115          unstacking, so we have to emulate these by setting appropriate
7116          bits and offsets.  */
7117       if (skip_past_comma (&str) == FAIL
7118           || *str != '[')
7119         {
7120           if (! inst.error)
7121             inst.error = BAD_ARGS;
7122           return;
7123         }
7124
7125       str++;
7126       skip_whitespace (str);
7127
7128       if ((reg = reg_required_here (&str, 16)) == FAIL)
7129         return;
7130
7131       skip_whitespace (str);
7132
7133       if (*str != ']')
7134         {
7135           inst.error = BAD_ARGS;
7136           return;
7137         }
7138
7139       str++;
7140       if (*str == '!')
7141         {
7142           write_back = 1;
7143           str++;
7144           if (reg == REG_PC)
7145             {
7146               inst.error =
7147                 _("r15 not allowed as base register with write-back");
7148               return;
7149             }
7150         }
7151       else
7152         write_back = 0;
7153
7154       if (inst.instruction & CP_T_Pre)
7155         {
7156           /* Pre-decrement.  */
7157           offset = 3 * num_regs;
7158           if (write_back)
7159             inst.instruction |= CP_T_WB;
7160         }
7161       else
7162         {
7163           /* Post-increment.  */
7164           if (write_back)
7165             {
7166               inst.instruction |= CP_T_WB;
7167               offset = 3 * num_regs;
7168             }
7169           else
7170             {
7171               /* No write-back, so convert this into a standard pre-increment
7172                  instruction -- aesthetically more pleasing.  */
7173               inst.instruction |= CP_T_Pre | CP_T_UD;
7174               offset = 0;
7175             }
7176         }
7177
7178       inst.instruction |= offset;
7179     }
7180   else if (skip_past_comma (&str) == FAIL
7181            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7182     {
7183       if (! inst.error)
7184         inst.error = BAD_ARGS;
7185       return;
7186     }
7187
7188   end_of_line (str);
7189 }
7190
7191 static void
7192 do_fpa_dyadic (char * str)
7193 {
7194   skip_whitespace (str);
7195
7196   if (fp_reg_required_here (&str, 12) == FAIL)
7197     {
7198       if (! inst.error)
7199         inst.error = BAD_ARGS;
7200       return;
7201     }
7202
7203   if (skip_past_comma (&str) == FAIL
7204       || fp_reg_required_here (&str, 16) == FAIL)
7205     {
7206       if (! inst.error)
7207         inst.error = BAD_ARGS;
7208       return;
7209     }
7210
7211   if (skip_past_comma (&str) == FAIL
7212       || fp_op2 (&str) == FAIL)
7213     {
7214       if (! inst.error)
7215         inst.error = BAD_ARGS;
7216       return;
7217     }
7218
7219   end_of_line (str);
7220 }
7221
7222 static void
7223 do_fpa_monadic (char * str)
7224 {
7225   skip_whitespace (str);
7226
7227   if (fp_reg_required_here (&str, 12) == FAIL)
7228     {
7229       if (! inst.error)
7230         inst.error = BAD_ARGS;
7231       return;
7232     }
7233
7234   if (skip_past_comma (&str) == FAIL
7235       || fp_op2 (&str) == FAIL)
7236     {
7237       if (! inst.error)
7238         inst.error = BAD_ARGS;
7239       return;
7240     }
7241
7242   end_of_line (str);
7243 }
7244
7245 static void
7246 do_fpa_cmp (char * str)
7247 {
7248   skip_whitespace (str);
7249
7250   if (fp_reg_required_here (&str, 16) == FAIL)
7251     {
7252       if (! inst.error)
7253         inst.error = BAD_ARGS;
7254       return;
7255     }
7256
7257   if (skip_past_comma (&str) == FAIL
7258       || fp_op2 (&str) == FAIL)
7259     {
7260       if (! inst.error)
7261         inst.error = BAD_ARGS;
7262       return;
7263     }
7264
7265   end_of_line (str);
7266 }
7267
7268 static void
7269 do_fpa_from_reg (char * str)
7270 {
7271   skip_whitespace (str);
7272
7273   if (fp_reg_required_here (&str, 16) == FAIL)
7274     {
7275       if (! inst.error)
7276         inst.error = BAD_ARGS;
7277       return;
7278     }
7279
7280   if (skip_past_comma (&str) == FAIL
7281       || reg_required_here (&str, 12) == FAIL)
7282     {
7283       if (! inst.error)
7284         inst.error = BAD_ARGS;
7285       return;
7286     }
7287
7288   end_of_line (str);
7289 }
7290
7291 static void
7292 do_fpa_to_reg (char * str)
7293 {
7294   skip_whitespace (str);
7295
7296   if (reg_required_here (&str, 12) == FAIL)
7297     return;
7298
7299   if (skip_past_comma (&str) == FAIL
7300       || fp_reg_required_here (&str, 0) == FAIL)
7301     {
7302       if (! inst.error)
7303         inst.error = BAD_ARGS;
7304       return;
7305     }
7306
7307   end_of_line (str);
7308 }
7309
7310 /* Encode a VFP SP register number.  */
7311
7312 static void
7313 vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
7314 {
7315   switch (pos)
7316     {
7317     case VFP_REG_Sd:
7318       inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7319       break;
7320
7321     case VFP_REG_Sn:
7322       inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7323       break;
7324
7325     case VFP_REG_Sm:
7326       inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7327       break;
7328
7329     default:
7330       abort ();
7331     }
7332 }
7333
7334 static int
7335 vfp_sp_reg_required_here (char ** str,
7336                           enum vfp_sp_reg_pos pos)
7337 {
7338   int    reg;
7339   char * start = *str;
7340
7341   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7342     {
7343       vfp_sp_encode_reg (reg, pos);
7344       return reg;
7345     }
7346
7347   /* In the few cases where we might be able to accept something else
7348      this error can be overridden.  */
7349   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7350
7351   /* Restore the start point.  */
7352   *str = start;
7353   return FAIL;
7354 }
7355
7356 static int
7357 vfp_dp_reg_required_here (char ** str,
7358                           enum vfp_dp_reg_pos pos)
7359 {
7360   int    reg;
7361   char * start = *str;
7362
7363   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7364     {
7365       switch (pos)
7366         {
7367         case VFP_REG_Dd:
7368           inst.instruction |= reg << 12;
7369           break;
7370
7371         case VFP_REG_Dn:
7372           inst.instruction |= reg << 16;
7373           break;
7374
7375         case VFP_REG_Dm:
7376           inst.instruction |= reg << 0;
7377           break;
7378
7379         default:
7380           abort ();
7381         }
7382       return reg;
7383     }
7384
7385   /* In the few cases where we might be able to accept something else
7386      this error can be overridden.  */
7387   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7388
7389   /* Restore the start point.  */
7390   *str = start;
7391   return FAIL;
7392 }
7393
7394 static void
7395 do_vfp_sp_monadic (char * str)
7396 {
7397   skip_whitespace (str);
7398
7399   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7400     return;
7401
7402   if (skip_past_comma (&str) == FAIL
7403       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7404     {
7405       if (! inst.error)
7406         inst.error = BAD_ARGS;
7407       return;
7408     }
7409
7410   end_of_line (str);
7411 }
7412
7413 static void
7414 do_vfp_dp_monadic (char * str)
7415 {
7416   skip_whitespace (str);
7417
7418   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7419     return;
7420
7421   if (skip_past_comma (&str) == FAIL
7422       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7423     {
7424       if (! inst.error)
7425         inst.error = BAD_ARGS;
7426       return;
7427     }
7428
7429   end_of_line (str);
7430 }
7431
7432 static void
7433 do_vfp_sp_dyadic (char * str)
7434 {
7435   skip_whitespace (str);
7436
7437   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7438     return;
7439
7440   if (skip_past_comma (&str) == FAIL
7441       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7442       || skip_past_comma (&str) == FAIL
7443       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7444     {
7445       if (! inst.error)
7446         inst.error = BAD_ARGS;
7447       return;
7448     }
7449
7450   end_of_line (str);
7451 }
7452
7453 static void
7454 do_vfp_dp_dyadic (char * str)
7455 {
7456   skip_whitespace (str);
7457
7458   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7459     return;
7460
7461   if (skip_past_comma (&str) == FAIL
7462       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7463       || skip_past_comma (&str) == FAIL
7464       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7465     {
7466       if (! inst.error)
7467         inst.error = BAD_ARGS;
7468       return;
7469     }
7470
7471   end_of_line (str);
7472 }
7473
7474 static void
7475 do_vfp_reg_from_sp (char * str)
7476 {
7477   skip_whitespace (str);
7478
7479   if (reg_required_here (&str, 12) == FAIL)
7480     return;
7481
7482   if (skip_past_comma (&str) == FAIL
7483       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7484     {
7485       if (! inst.error)
7486         inst.error = BAD_ARGS;
7487       return;
7488     }
7489
7490   end_of_line (str);
7491 }
7492
7493 /* Parse a VFP register list.  If the string is invalid return FAIL.
7494    Otherwise return the number of registers, and set PBASE to the first
7495    register.  Double precision registers are matched if DP is nonzero.  */
7496
7497 static int
7498 vfp_parse_reg_list (char **str, int *pbase, int dp)
7499 {
7500   int base_reg;
7501   int new_base;
7502   int regtype;
7503   int max_regs;
7504   int count = 0;
7505   int warned = 0;
7506   unsigned long mask = 0;
7507   int i;
7508
7509   if (**str != '{')
7510     return FAIL;
7511
7512   (*str)++;
7513   skip_whitespace (*str);
7514
7515   if (dp)
7516     {
7517       regtype = REG_TYPE_DN;
7518       max_regs = 16;
7519     }
7520   else
7521     {
7522       regtype = REG_TYPE_SN;
7523       max_regs = 32;
7524     }
7525
7526   base_reg = max_regs;
7527
7528   do
7529     {
7530       new_base = arm_reg_parse (str, all_reg_maps[regtype].htab);
7531       if (new_base == FAIL)
7532         {
7533           inst.error = _(all_reg_maps[regtype].expected);
7534           return FAIL;
7535         }
7536
7537       if (new_base < base_reg)
7538         base_reg = new_base;
7539
7540       if (mask & (1 << new_base))
7541         {
7542           inst.error = _("invalid register list");
7543           return FAIL;
7544         }
7545
7546       if ((mask >> new_base) != 0 && ! warned)
7547         {
7548           as_tsktsk (_("register list not in ascending order"));
7549           warned = 1;
7550         }
7551
7552       mask |= 1 << new_base;
7553       count++;
7554
7555       skip_whitespace (*str);
7556
7557       if (**str == '-') /* We have the start of a range expression */
7558         {
7559           int high_range;
7560
7561           (*str)++;
7562
7563           if ((high_range
7564                = arm_reg_parse (str, all_reg_maps[regtype].htab))
7565               == FAIL)
7566             {
7567               inst.error = _(all_reg_maps[regtype].expected);
7568               return FAIL;
7569             }
7570
7571           if (high_range <= new_base)
7572             {
7573               inst.error = _("register range not in ascending order");
7574               return FAIL;
7575             }
7576
7577           for (new_base++; new_base <= high_range; new_base++)
7578             {
7579               if (mask & (1 << new_base))
7580                 {
7581                   inst.error = _("invalid register list");
7582                   return FAIL;
7583                 }
7584
7585               mask |= 1 << new_base;
7586               count++;
7587             }
7588         }
7589     }
7590   while (skip_past_comma (str) != FAIL);
7591
7592   (*str)++;
7593
7594   /* Sanity check -- should have raised a parse error above.  */
7595   if (count == 0 || count > max_regs)
7596     abort ();
7597
7598   *pbase = base_reg;
7599
7600   /* Final test -- the registers must be consecutive.  */
7601   mask >>= base_reg;
7602   for (i = 0; i < count; i++)
7603     {
7604       if ((mask & (1u << i)) == 0)
7605         {
7606           inst.error = _("non-contiguous register range");
7607           return FAIL;
7608         }
7609     }
7610
7611   return count;
7612 }
7613
7614 static void
7615 do_vfp_reg2_from_sp2 (char * str)
7616 {
7617   int reg;
7618
7619   skip_whitespace (str);
7620
7621   if (reg_required_here (&str, 12) == FAIL
7622       || skip_past_comma (&str) == FAIL
7623       || reg_required_here (&str, 16) == FAIL
7624       || skip_past_comma (&str) == FAIL)
7625     {
7626       if (! inst.error)
7627         inst.error = BAD_ARGS;
7628       return;
7629     }
7630
7631   /* We require exactly two consecutive SP registers.  */
7632   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7633     {
7634       if (! inst.error)
7635         inst.error = _("only two consecutive VFP SP registers allowed here");
7636     }
7637   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7638
7639   end_of_line (str);
7640 }
7641
7642 static void
7643 do_vfp_sp_from_reg (char * str)
7644 {
7645   skip_whitespace (str);
7646
7647   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7648     return;
7649
7650   if (skip_past_comma (&str) == FAIL
7651       || reg_required_here (&str, 12) == FAIL)
7652     {
7653       if (! inst.error)
7654         inst.error = BAD_ARGS;
7655       return;
7656     }
7657
7658   end_of_line (str);
7659 }
7660
7661 static void
7662 do_vfp_sp2_from_reg2 (char * str)
7663 {
7664   int reg;
7665
7666   skip_whitespace (str);
7667
7668   /* We require exactly two consecutive SP registers.  */
7669   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
7670     {
7671       if (! inst.error)
7672         inst.error = _("only two consecutive VFP SP registers allowed here");
7673     }
7674   vfp_sp_encode_reg (reg, VFP_REG_Sm);
7675
7676   if (skip_past_comma (&str) == FAIL
7677       || reg_required_here (&str, 12) == FAIL
7678       || skip_past_comma (&str) == FAIL
7679       || reg_required_here (&str, 16) == FAIL)
7680     {
7681       if (! inst.error)
7682         inst.error = BAD_ARGS;
7683       return;
7684     }
7685
7686   end_of_line (str);
7687 }
7688
7689 static void
7690 do_vfp_reg_from_dp (char * str)
7691 {
7692   skip_whitespace (str);
7693
7694   if (reg_required_here (&str, 12) == FAIL)
7695     return;
7696
7697   if (skip_past_comma (&str) == FAIL
7698       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7699     {
7700       if (! inst.error)
7701         inst.error = BAD_ARGS;
7702       return;
7703     }
7704
7705   end_of_line (str);
7706 }
7707
7708 static void
7709 do_vfp_reg2_from_dp (char * str)
7710 {
7711   skip_whitespace (str);
7712
7713   if (reg_required_here (&str, 12) == FAIL)
7714     return;
7715
7716   if (skip_past_comma (&str) == FAIL
7717       || reg_required_here (&str, 16) == FAIL
7718       || skip_past_comma (&str) == FAIL
7719       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7720     {
7721       if (! inst.error)
7722         inst.error = BAD_ARGS;
7723       return;
7724     }
7725
7726   end_of_line (str);
7727 }
7728
7729 static void
7730 do_vfp_dp_from_reg (char * str)
7731 {
7732   skip_whitespace (str);
7733
7734   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7735     return;
7736
7737   if (skip_past_comma (&str) == FAIL
7738       || reg_required_here (&str, 12) == FAIL)
7739     {
7740       if (! inst.error)
7741         inst.error = BAD_ARGS;
7742       return;
7743     }
7744
7745   end_of_line (str);
7746 }
7747
7748 static void
7749 do_vfp_dp_from_reg2 (char * str)
7750 {
7751   skip_whitespace (str);
7752
7753   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7754     return;
7755
7756   if (skip_past_comma (&str) == FAIL
7757       || reg_required_here (&str, 12) == FAIL
7758       || skip_past_comma (&str) == FAIL
7759       || reg_required_here (&str, 16) == FAIL)
7760     {
7761       if (! inst.error)
7762         inst.error = BAD_ARGS;
7763       return;
7764     }
7765
7766   end_of_line (str);
7767 }
7768
7769 static const struct vfp_reg *
7770 vfp_psr_parse (char ** str)
7771 {
7772   char *start = *str;
7773   char  c;
7774   char *p;
7775   const struct vfp_reg *vreg;
7776
7777   p = start;
7778
7779   /* Find the end of the current token.  */
7780   do
7781     {
7782       c = *p++;
7783     }
7784   while (ISALPHA (c));
7785
7786   /* Mark it.  */
7787   *--p = 0;
7788
7789   for (vreg = vfp_regs + 0;
7790        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
7791        vreg++)
7792     {
7793       if (streq (start, vreg->name))
7794         {
7795           *p = c;
7796           *str = p;
7797           return vreg;
7798         }
7799     }
7800
7801   *p = c;
7802   return NULL;
7803 }
7804
7805 static int
7806 vfp_psr_required_here (char ** str)
7807 {
7808   char *start = *str;
7809   const struct vfp_reg *vreg;
7810
7811   vreg = vfp_psr_parse (str);
7812
7813   if (vreg)
7814     {
7815       inst.instruction |= vreg->regno;
7816       return SUCCESS;
7817     }
7818
7819   inst.error = _("VFP system register expected");
7820
7821   *str = start;
7822   return FAIL;
7823 }
7824
7825 static void
7826 do_vfp_reg_from_ctrl (char * str)
7827 {
7828   skip_whitespace (str);
7829
7830   if (reg_required_here (&str, 12) == FAIL)
7831     return;
7832
7833   if (skip_past_comma (&str) == FAIL
7834       || vfp_psr_required_here (&str) == FAIL)
7835     {
7836       if (! inst.error)
7837         inst.error = BAD_ARGS;
7838       return;
7839     }
7840
7841   end_of_line (str);
7842 }
7843
7844 static void
7845 do_vfp_ctrl_from_reg (char * str)
7846 {
7847   skip_whitespace (str);
7848
7849   if (vfp_psr_required_here (&str) == FAIL)
7850     return;
7851
7852   if (skip_past_comma (&str) == FAIL
7853       || reg_required_here (&str, 12) == FAIL)
7854     {
7855       if (! inst.error)
7856         inst.error = BAD_ARGS;
7857       return;
7858     }
7859
7860   end_of_line (str);
7861 }
7862
7863 static void
7864 do_vfp_sp_ldst (char * str)
7865 {
7866   skip_whitespace (str);
7867
7868   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7869     {
7870       if (!inst.error)
7871         inst.error = BAD_ARGS;
7872       return;
7873     }
7874
7875   if (skip_past_comma (&str) == FAIL
7876       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7877     {
7878       if (!inst.error)
7879         inst.error = BAD_ARGS;
7880       return;
7881     }
7882
7883   end_of_line (str);
7884 }
7885
7886 static void
7887 do_vfp_dp_ldst (char * str)
7888 {
7889   skip_whitespace (str);
7890
7891   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7892     {
7893       if (!inst.error)
7894         inst.error = BAD_ARGS;
7895       return;
7896     }
7897
7898   if (skip_past_comma (&str) == FAIL
7899       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7900     {
7901       if (!inst.error)
7902         inst.error = BAD_ARGS;
7903       return;
7904     }
7905
7906   end_of_line (str);
7907 }
7908
7909
7910 static void
7911 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7912 {
7913   int count;
7914   int reg;
7915
7916   skip_whitespace (str);
7917
7918   if (reg_required_here (&str, 16) == FAIL)
7919     return;
7920
7921   skip_whitespace (str);
7922
7923   if (*str == '!')
7924     {
7925       inst.instruction |= WRITE_BACK;
7926       str++;
7927     }
7928   else if (ldstm_type != VFP_LDSTMIA)
7929     {
7930       inst.error = _("this addressing mode requires base-register writeback");
7931       return;
7932     }
7933
7934   if (skip_past_comma (&str) == FAIL
7935       || (count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
7936     {
7937       if (!inst.error)
7938         inst.error = BAD_ARGS;
7939       return;
7940     }
7941   vfp_sp_encode_reg (reg, VFP_REG_Sd);
7942
7943   inst.instruction |= count;
7944   end_of_line (str);
7945 }
7946
7947 static void
7948 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
7949 {
7950   int count;
7951   int reg;
7952
7953   skip_whitespace (str);
7954
7955   if (reg_required_here (&str, 16) == FAIL)
7956     return;
7957
7958   skip_whitespace (str);
7959
7960   if (*str == '!')
7961     {
7962       inst.instruction |= WRITE_BACK;
7963       str++;
7964     }
7965   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7966     {
7967       inst.error = _("this addressing mode requires base-register writeback");
7968       return;
7969     }
7970
7971   if (skip_past_comma (&str) == FAIL
7972       || (count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
7973     {
7974       if (!inst.error)
7975         inst.error = BAD_ARGS;
7976       return;
7977     }
7978
7979   count <<= 1;
7980   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7981     count += 1;
7982
7983   inst.instruction |= (reg << 12) | count;
7984   end_of_line (str);
7985 }
7986
7987 static void
7988 do_vfp_sp_ldstmia (char * str)
7989 {
7990   vfp_sp_ldstm (str, VFP_LDSTMIA);
7991 }
7992
7993 static void
7994 do_vfp_sp_ldstmdb (char * str)
7995 {
7996   vfp_sp_ldstm (str, VFP_LDSTMDB);
7997 }
7998
7999 static void
8000 do_vfp_dp_ldstmia (char * str)
8001 {
8002   vfp_dp_ldstm (str, VFP_LDSTMIA);
8003 }
8004
8005 static void
8006 do_vfp_dp_ldstmdb (char * str)
8007 {
8008   vfp_dp_ldstm (str, VFP_LDSTMDB);
8009 }
8010
8011 static void
8012 do_vfp_xp_ldstmia (char *str)
8013 {
8014   vfp_dp_ldstm (str, VFP_LDSTMIAX);
8015 }
8016
8017 static void
8018 do_vfp_xp_ldstmdb (char * str)
8019 {
8020   vfp_dp_ldstm (str, VFP_LDSTMDBX);
8021 }
8022
8023 static void
8024 do_vfp_sp_compare_z (char * str)
8025 {
8026   skip_whitespace (str);
8027
8028   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8029     {
8030       if (!inst.error)
8031         inst.error = BAD_ARGS;
8032       return;
8033     }
8034
8035   end_of_line (str);
8036 }
8037
8038 static void
8039 do_vfp_dp_compare_z (char * str)
8040 {
8041   skip_whitespace (str);
8042
8043   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8044     {
8045       if (!inst.error)
8046         inst.error = BAD_ARGS;
8047       return;
8048     }
8049
8050   end_of_line (str);
8051 }
8052
8053 static void
8054 do_vfp_dp_sp_cvt (char * str)
8055 {
8056   skip_whitespace (str);
8057
8058   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8059     return;
8060
8061   if (skip_past_comma (&str) == FAIL
8062       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8063     {
8064       if (! inst.error)
8065         inst.error = BAD_ARGS;
8066       return;
8067     }
8068
8069   end_of_line (str);
8070 }
8071
8072 static void
8073 do_vfp_sp_dp_cvt (char * str)
8074 {
8075   skip_whitespace (str);
8076
8077   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8078     return;
8079
8080   if (skip_past_comma (&str) == FAIL
8081       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8082     {
8083       if (! inst.error)
8084         inst.error = BAD_ARGS;
8085       return;
8086     }
8087
8088   end_of_line (str);
8089 }
8090
8091 /* Thumb specific routines.  */
8092
8093 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8094    was SUB.  */
8095
8096 static void
8097 thumb_add_sub (char * str, int subtract)
8098 {
8099   int Rd, Rs, Rn = FAIL;
8100
8101   skip_whitespace (str);
8102
8103   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8104       || skip_past_comma (&str) == FAIL)
8105     {
8106       if (! inst.error)
8107         inst.error = BAD_ARGS;
8108       return;
8109     }
8110
8111   if (is_immediate_prefix (*str))
8112     {
8113       Rs = Rd;
8114       str++;
8115       if (my_get_expression (&inst.reloc.exp, &str))
8116         return;
8117     }
8118   else
8119     {
8120       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8121         return;
8122
8123       if (skip_past_comma (&str) == FAIL)
8124         {
8125           /* Two operand format, shuffle the registers
8126              and pretend there are 3.  */
8127           Rn = Rs;
8128           Rs = Rd;
8129         }
8130       else if (is_immediate_prefix (*str))
8131         {
8132           str++;
8133           if (my_get_expression (&inst.reloc.exp, &str))
8134             return;
8135         }
8136       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8137         return;
8138     }
8139
8140   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8141      for the latter case, EXPR contains the immediate that was found.  */
8142   if (Rn != FAIL)
8143     {
8144       /* All register format.  */
8145       if (Rd > 7 || Rs > 7 || Rn > 7)
8146         {
8147           if (Rs != Rd)
8148             {
8149               inst.error = _("dest and source1 must be the same register");
8150               return;
8151             }
8152
8153           /* Can't do this for SUB.  */
8154           if (subtract)
8155             {
8156               inst.error = _("subtract valid only on lo regs");
8157               return;
8158             }
8159
8160           inst.instruction = (T_OPCODE_ADD_HI
8161                               | (Rd > 7 ? THUMB_H1 : 0)
8162                               | (Rn > 7 ? THUMB_H2 : 0));
8163           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8164         }
8165       else
8166         {
8167           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8168           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8169         }
8170     }
8171   else
8172     {
8173       /* Immediate expression, now things start to get nasty.  */
8174
8175       /* First deal with HI regs, only very restricted cases allowed:
8176          Adjusting SP, and using PC or SP to get an address.  */
8177       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8178           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8179         {
8180           inst.error = _("invalid Hi register with immediate");
8181           return;
8182         }
8183
8184       if (inst.reloc.exp.X_op != O_constant)
8185         {
8186           /* Value isn't known yet, all we can do is store all the fragments
8187              we know about in the instruction and let the reloc hacking
8188              work it all out.  */
8189           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8190           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8191         }
8192       else
8193         {
8194           int offset = inst.reloc.exp.X_add_number;
8195
8196           if (subtract)
8197             offset = - offset;
8198
8199           if (offset < 0)
8200             {
8201               offset = - offset;
8202               subtract = 1;
8203
8204               /* Quick check, in case offset is MIN_INT.  */
8205               if (offset < 0)
8206                 {
8207                   inst.error = _("immediate value out of range");
8208                   return;
8209                 }
8210             }
8211           /* Note - you cannot convert a subtract of 0 into an
8212              add of 0 because the carry flag is set differently.  */
8213           else if (offset > 0)
8214             subtract = 0;
8215
8216           if (Rd == REG_SP)
8217             {
8218               if (offset & ~0x1fc)
8219                 {
8220                   inst.error = _("invalid immediate value for stack adjust");
8221                   return;
8222                 }
8223               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8224               inst.instruction |= offset >> 2;
8225             }
8226           else if (Rs == REG_PC || Rs == REG_SP)
8227             {
8228               if (subtract
8229                   || (offset & ~0x3fc))
8230                 {
8231                   inst.error = _("invalid immediate for address calculation");
8232                   return;
8233                 }
8234               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8235                                   : T_OPCODE_ADD_SP);
8236               inst.instruction |= (Rd << 8) | (offset >> 2);
8237             }
8238           else if (Rs == Rd)
8239             {
8240               if (offset & ~0xff)
8241                 {
8242                   inst.error = _("immediate value out of range");
8243                   return;
8244                 }
8245               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8246               inst.instruction |= (Rd << 8) | offset;
8247             }
8248           else
8249             {
8250               if (offset & ~0x7)
8251                 {
8252                   inst.error = _("immediate value out of range");
8253                   return;
8254                 }
8255               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8256               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8257             }
8258         }
8259     }
8260
8261   end_of_line (str);
8262 }
8263
8264 static void
8265 thumb_shift (char * str, int shift)
8266 {
8267   int Rd, Rs, Rn = FAIL;
8268
8269   skip_whitespace (str);
8270
8271   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8272       || skip_past_comma (&str) == FAIL)
8273     {
8274       if (! inst.error)
8275         inst.error = BAD_ARGS;
8276       return;
8277     }
8278
8279   if (is_immediate_prefix (*str))
8280     {
8281       /* Two operand immediate format, set Rs to Rd.  */
8282       Rs = Rd;
8283       str ++;
8284       if (my_get_expression (&inst.reloc.exp, &str))
8285         return;
8286     }
8287   else
8288     {
8289       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8290         return;
8291
8292       if (skip_past_comma (&str) == FAIL)
8293         {
8294           /* Two operand format, shuffle the registers
8295              and pretend there are 3.  */
8296           Rn = Rs;
8297           Rs = Rd;
8298         }
8299       else if (is_immediate_prefix (*str))
8300         {
8301           str++;
8302           if (my_get_expression (&inst.reloc.exp, &str))
8303             return;
8304         }
8305       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8306         return;
8307     }
8308
8309   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8310      for the latter case, EXPR contains the immediate that was found.  */
8311
8312   if (Rn != FAIL)
8313     {
8314       if (Rs != Rd)
8315         {
8316           inst.error = _("source1 and dest must be same register");
8317           return;
8318         }
8319
8320       switch (shift)
8321         {
8322         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8323         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8324         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8325         }
8326
8327       inst.instruction |= Rd | (Rn << 3);
8328     }
8329   else
8330     {
8331       switch (shift)
8332         {
8333         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8334         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8335         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8336         }
8337
8338       if (inst.reloc.exp.X_op != O_constant)
8339         {
8340           /* Value isn't known yet, create a dummy reloc and let reloc
8341              hacking fix it up.  */
8342           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8343         }
8344       else
8345         {
8346           unsigned shift_value = inst.reloc.exp.X_add_number;
8347
8348           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8349             {
8350               inst.error = _("invalid immediate for shift");
8351               return;
8352             }
8353
8354           /* Shifts of zero are handled by converting to LSL.  */
8355           if (shift_value == 0)
8356             inst.instruction = T_OPCODE_LSL_I;
8357
8358           /* Shifts of 32 are encoded as a shift of zero.  */
8359           if (shift_value == 32)
8360             shift_value = 0;
8361
8362           inst.instruction |= shift_value << 6;
8363         }
8364
8365       inst.instruction |= Rd | (Rs << 3);
8366     }
8367
8368   end_of_line (str);
8369 }
8370
8371 static void
8372 thumb_load_store (char * str, int load_store, int size)
8373 {
8374   int Rd, Rb, Ro = FAIL;
8375
8376   skip_whitespace (str);
8377
8378   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8379       || skip_past_comma (&str) == FAIL)
8380     {
8381       if (! inst.error)
8382         inst.error = BAD_ARGS;
8383       return;
8384     }
8385
8386   if (*str == '[')
8387     {
8388       str++;
8389       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8390         return;
8391
8392       if (skip_past_comma (&str) != FAIL)
8393         {
8394           if (is_immediate_prefix (*str))
8395             {
8396               str++;
8397               if (my_get_expression (&inst.reloc.exp, &str))
8398                 return;
8399             }
8400           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8401             return;
8402         }
8403       else
8404         {
8405           inst.reloc.exp.X_op = O_constant;
8406           inst.reloc.exp.X_add_number = 0;
8407         }
8408
8409       if (*str != ']')
8410         {
8411           inst.error = _("expected ']'");
8412           return;
8413         }
8414       str++;
8415     }
8416   else if (*str == '=')
8417     {
8418       if (load_store != THUMB_LOAD)
8419         {
8420           inst.error = _("invalid pseudo operation");
8421           return;
8422         }
8423
8424       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
8425       str++;
8426
8427       skip_whitespace (str);
8428
8429       if (my_get_expression (& inst.reloc.exp, & str))
8430         return;
8431
8432       end_of_line (str);
8433
8434       if (   inst.reloc.exp.X_op != O_constant
8435           && inst.reloc.exp.X_op != O_symbol)
8436         {
8437           inst.error = "Constant expression expected";
8438           return;
8439         }
8440
8441       if (inst.reloc.exp.X_op == O_constant
8442           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8443         {
8444           /* This can be done with a mov instruction.  */
8445
8446           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
8447           inst.instruction |= inst.reloc.exp.X_add_number;
8448           return;
8449         }
8450
8451       /* Insert into literal pool.  */
8452       if (add_to_lit_pool () == FAIL)
8453         {
8454           if (!inst.error)
8455             inst.error = "literal pool insertion failed";
8456           return;
8457         }
8458
8459       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
8460       inst.reloc.pc_rel = 1;
8461       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
8462       /* Adjust ARM pipeline offset to Thumb.  */
8463       inst.reloc.exp.X_add_number += 4;
8464
8465       return;
8466     }
8467   else
8468     {
8469       if (my_get_expression (&inst.reloc.exp, &str))
8470         return;
8471
8472       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8473       inst.reloc.pc_rel = 1;
8474       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
8475       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8476       end_of_line (str);
8477       return;
8478     }
8479
8480   if (Rb == REG_PC || Rb == REG_SP)
8481     {
8482       if (size != THUMB_WORD)
8483         {
8484           inst.error = _("byte or halfword not valid for base register");
8485           return;
8486         }
8487       else if (Rb == REG_PC && load_store != THUMB_LOAD)
8488         {
8489           inst.error = _("r15 based store not allowed");
8490           return;
8491         }
8492       else if (Ro != FAIL)
8493         {
8494           inst.error = _("invalid base register for register offset");
8495           return;
8496         }
8497
8498       if (Rb == REG_PC)
8499         inst.instruction = T_OPCODE_LDR_PC;
8500       else if (load_store == THUMB_LOAD)
8501         inst.instruction = T_OPCODE_LDR_SP;
8502       else
8503         inst.instruction = T_OPCODE_STR_SP;
8504
8505       inst.instruction |= Rd << 8;
8506       if (inst.reloc.exp.X_op == O_constant)
8507         {
8508           unsigned offset = inst.reloc.exp.X_add_number;
8509
8510           if (offset & ~0x3fc)
8511             {
8512               inst.error = _("invalid offset");
8513               return;
8514             }
8515
8516           inst.instruction |= offset >> 2;
8517         }
8518       else
8519         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8520     }
8521   else if (Rb > 7)
8522     {
8523       inst.error = _("invalid base register in load/store");
8524       return;
8525     }
8526   else if (Ro == FAIL)
8527     {
8528       /* Immediate offset.  */
8529       if (size == THUMB_WORD)
8530         inst.instruction = (load_store == THUMB_LOAD
8531                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8532       else if (size == THUMB_HALFWORD)
8533         inst.instruction = (load_store == THUMB_LOAD
8534                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8535       else
8536         inst.instruction = (load_store == THUMB_LOAD
8537                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8538
8539       inst.instruction |= Rd | (Rb << 3);
8540
8541       if (inst.reloc.exp.X_op == O_constant)
8542         {
8543           unsigned offset = inst.reloc.exp.X_add_number;
8544
8545           if (offset & ~(0x1f << size))
8546             {
8547               inst.error = _("invalid offset");
8548               return;
8549             }
8550           inst.instruction |= (offset >> size) << 6;
8551         }
8552       else
8553         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8554     }
8555   else
8556     {
8557       /* Register offset.  */
8558       if (size == THUMB_WORD)
8559         inst.instruction = (load_store == THUMB_LOAD
8560                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8561       else if (size == THUMB_HALFWORD)
8562         inst.instruction = (load_store == THUMB_LOAD
8563                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8564       else
8565         inst.instruction = (load_store == THUMB_LOAD
8566                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8567
8568       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8569     }
8570
8571   end_of_line (str);
8572 }
8573
8574 /* A register must be given at this point.
8575
8576    Shift is the place to put it in inst.instruction.
8577
8578    Restores input start point on err.
8579    Returns the reg#, or FAIL.  */
8580
8581 static int
8582 mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
8583 {
8584   int   reg;
8585   char *start = *str;
8586
8587   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8588     {
8589       if (shift >= 0)
8590         inst.instruction |= reg << shift;
8591
8592       return reg;
8593     }
8594
8595   /* Restore the start point.  */
8596   *str = start;
8597
8598   /* Try generic coprocessor name if applicable.  */
8599   if (regtype == REG_TYPE_MVF ||
8600       regtype == REG_TYPE_MVD ||
8601       regtype == REG_TYPE_MVFX ||
8602       regtype == REG_TYPE_MVDX)
8603     {
8604       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
8605         {
8606           if (shift >= 0)
8607             inst.instruction |= reg << shift;
8608
8609           return reg;
8610         }
8611
8612       /* Restore the start point.  */
8613       *str = start;
8614     }
8615
8616   /* In the few cases where we might be able to accept something else
8617      this error can be overridden.  */
8618   inst.error = _(all_reg_maps[regtype].expected);
8619
8620   return FAIL;
8621 }
8622
8623 /* Cirrus Maverick Instructions.  */
8624
8625 /* Isnsn like "foo X,Y".  */
8626
8627 static void
8628 do_mav_binops (char * str,
8629                int mode,
8630                enum arm_reg_type reg0,
8631                enum arm_reg_type reg1)
8632 {
8633   int shift0, shift1;
8634
8635   shift0 = mode & 0xff;
8636   shift1 = (mode >> 8) & 0xff;
8637
8638   skip_whitespace (str);
8639
8640   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8641       || skip_past_comma (&str) == FAIL
8642       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8643     {
8644       if (!inst.error)
8645         inst.error = BAD_ARGS;
8646     }
8647   else
8648     end_of_line (str);
8649 }
8650
8651 /* Isnsn like "foo X,Y,Z".  */
8652
8653 static void
8654 do_mav_triple (char * str,
8655                int mode,
8656                enum arm_reg_type reg0,
8657                enum arm_reg_type reg1,
8658                enum arm_reg_type reg2)
8659 {
8660   int shift0, shift1, shift2;
8661
8662   shift0 = mode & 0xff;
8663   shift1 = (mode >> 8) & 0xff;
8664   shift2 = (mode >> 16) & 0xff;
8665
8666   skip_whitespace (str);
8667
8668   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8669       || skip_past_comma (&str) == FAIL
8670       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8671       || skip_past_comma (&str) == FAIL
8672       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8673     {
8674       if (!inst.error)
8675         inst.error = BAD_ARGS;
8676     }
8677   else
8678     end_of_line (str);
8679 }
8680
8681 /* Wrapper functions.  */
8682
8683 static void
8684 do_mav_binops_1a (char * str)
8685 {
8686   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8687 }
8688
8689 static void
8690 do_mav_binops_1b (char * str)
8691 {
8692   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
8693 }
8694
8695 static void
8696 do_mav_binops_1c (char * str)
8697 {
8698   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8699 }
8700
8701 static void
8702 do_mav_binops_1d (char * str)
8703 {
8704   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8705 }
8706
8707 static void
8708 do_mav_binops_1e (char * str)
8709 {
8710   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8711 }
8712
8713 static void
8714 do_mav_binops_1f (char * str)
8715 {
8716   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8717 }
8718
8719 static void
8720 do_mav_binops_1g (char * str)
8721 {
8722   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8723 }
8724
8725 static void
8726 do_mav_binops_1h (char * str)
8727 {
8728   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8729 }
8730
8731 static void
8732 do_mav_binops_1i (char * str)
8733 {
8734   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8735 }
8736
8737 static void
8738 do_mav_binops_1j (char * str)
8739 {
8740   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8741 }
8742
8743 static void
8744 do_mav_binops_1k (char * str)
8745 {
8746   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8747 }
8748
8749 static void
8750 do_mav_binops_1l (char * str)
8751 {
8752   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8753 }
8754
8755 static void
8756 do_mav_binops_1m (char * str)
8757 {
8758   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8759 }
8760
8761 static void
8762 do_mav_binops_1n (char * str)
8763 {
8764   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8765 }
8766
8767 static void
8768 do_mav_binops_1o (char * str)
8769 {
8770   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8771 }
8772
8773 static void
8774 do_mav_binops_2a (char * str)
8775 {
8776   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8777 }
8778
8779 static void
8780 do_mav_binops_2b (char * str)
8781 {
8782   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8783 }
8784
8785 static void
8786 do_mav_binops_2c (char * str)
8787 {
8788   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8789 }
8790
8791 static void
8792 do_mav_binops_3a (char * str)
8793 {
8794   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8795 }
8796
8797 static void
8798 do_mav_binops_3b (char * str)
8799 {
8800   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8801 }
8802
8803 static void
8804 do_mav_binops_3c (char * str)
8805 {
8806   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8807 }
8808
8809 static void
8810 do_mav_binops_3d (char * str)
8811 {
8812   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8813 }
8814
8815 static void
8816 do_mav_triple_4a (char * str)
8817 {
8818   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8819 }
8820
8821 static void
8822 do_mav_triple_4b (char * str)
8823 {
8824   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8825 }
8826
8827 static void
8828 do_mav_triple_5a (char * str)
8829 {
8830   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8831 }
8832
8833 static void
8834 do_mav_triple_5b (char * str)
8835 {
8836   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8837 }
8838
8839 static void
8840 do_mav_triple_5c (char * str)
8841 {
8842   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8843 }
8844
8845 static void
8846 do_mav_triple_5d (char * str)
8847 {
8848   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8849 }
8850
8851 static void
8852 do_mav_triple_5e (char * str)
8853 {
8854   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8855 }
8856
8857 static void
8858 do_mav_triple_5f (char * str)
8859 {
8860   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8861 }
8862
8863 static void
8864 do_mav_triple_5g (char * str)
8865 {
8866   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8867 }
8868
8869 static void
8870 do_mav_triple_5h (char * str)
8871 {
8872   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8873 }
8874
8875 /* Isnsn like "foo W,X,Y,Z".
8876     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
8877
8878 static void
8879 do_mav_quad (char * str,
8880              int mode,
8881              enum arm_reg_type reg0,
8882              enum arm_reg_type reg1,
8883              enum arm_reg_type reg2,
8884              enum arm_reg_type reg3)
8885 {
8886   int shift0, shift1, shift2, shift3;
8887
8888   shift0= mode & 0xff;
8889   shift1 = (mode >> 8) & 0xff;
8890   shift2 = (mode >> 16) & 0xff;
8891   shift3 = (mode >> 24) & 0xff;
8892
8893   skip_whitespace (str);
8894
8895   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8896       || skip_past_comma (&str) == FAIL
8897       || mav_reg_required_here (&str, shift1, reg1) == FAIL
8898       || skip_past_comma (&str) == FAIL
8899       || mav_reg_required_here (&str, shift2, reg2) == FAIL
8900       || skip_past_comma (&str) == FAIL
8901       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
8902     {
8903       if (!inst.error)
8904         inst.error = BAD_ARGS;
8905     }
8906   else
8907     end_of_line (str);
8908 }
8909
8910 static void
8911 do_mav_quad_6a (char * str)
8912 {
8913   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8914                REG_TYPE_MVFX);
8915 }
8916
8917 static void
8918 do_mav_quad_6b (char * str)
8919 {
8920   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8921                REG_TYPE_MVFX);
8922 }
8923
8924 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
8925 static void
8926 do_mav_dspsc_1 (char * str)
8927 {
8928   skip_whitespace (str);
8929
8930   /* cfmvsc32.  */
8931   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8932       || skip_past_comma (&str) == FAIL
8933       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
8934     {
8935       if (!inst.error)
8936         inst.error = BAD_ARGS;
8937
8938       return;
8939     }
8940
8941   end_of_line (str);
8942 }
8943
8944 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
8945 static void
8946 do_mav_dspsc_2 (char * str)
8947 {
8948   skip_whitespace (str);
8949
8950   /* cfmv32sc.  */
8951   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
8952       || skip_past_comma (&str) == FAIL
8953       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8954     {
8955       if (!inst.error)
8956         inst.error = BAD_ARGS;
8957
8958       return;
8959     }
8960
8961   end_of_line (str);
8962 }
8963
8964 /* Maverick shift immediate instructions.
8965    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8966    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
8967
8968 static void
8969 do_mav_shift (char * str,
8970               enum arm_reg_type reg0,
8971               enum arm_reg_type reg1)
8972 {
8973   int error;
8974   int imm, neg = 0;
8975
8976   skip_whitespace (str);
8977
8978   error = 0;
8979
8980   if (mav_reg_required_here (&str, 12, reg0) == FAIL
8981       || skip_past_comma (&str) == FAIL
8982       || mav_reg_required_here (&str, 16, reg1) == FAIL
8983       || skip_past_comma  (&str) == FAIL)
8984     {
8985       if (!inst.error)
8986         inst.error = BAD_ARGS;
8987       return;
8988     }
8989
8990   /* Calculate the immediate operand.
8991      The operand is a 7bit signed number.  */
8992   skip_whitespace (str);
8993
8994   if (*str == '#')
8995     ++str;
8996
8997   if (!ISDIGIT (*str) && *str != '-')
8998     {
8999       inst.error = _("expecting immediate, 7bit operand");
9000       return;
9001     }
9002
9003   if (*str == '-')
9004     {
9005       neg = 1;
9006       ++str;
9007     }
9008
9009   for (imm = 0; *str && ISDIGIT (*str); ++str)
9010     imm = imm * 10 + *str - '0';
9011
9012   if (imm > 64)
9013     {
9014       inst.error = _("immediate out of range");
9015       return;
9016     }
9017
9018   /* Make negative imm's into 7bit signed numbers.  */
9019   if (neg)
9020     {
9021       imm = -imm;
9022       imm &= 0x0000007f;
9023     }
9024
9025   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9026      Bits 5-7 of the insn should have bits 4-6 of the immediate.
9027      Bit 4 should be 0.  */
9028   imm = (imm & 0xf) | ((imm & 0x70) << 1);
9029
9030   inst.instruction |= imm;
9031   end_of_line (str);
9032 }
9033
9034 static void
9035 do_mav_shift_1 (char * str)
9036 {
9037   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9038 }
9039
9040 static void
9041 do_mav_shift_2 (char * str)
9042 {
9043   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9044 }
9045
9046 static int
9047 mav_parse_offset (char ** str, int * negative)
9048 {
9049   char * p = *str;
9050   int offset;
9051
9052   *negative = 0;
9053
9054   skip_whitespace (p);
9055
9056   if (*p == '#')
9057     ++p;
9058
9059   if (*p == '-')
9060     {
9061       *negative = 1;
9062       ++p;
9063     }
9064
9065   if (!ISDIGIT (*p))
9066     {
9067       inst.error = _("offset expected");
9068       return 0;
9069     }
9070
9071   for (offset = 0; *p && ISDIGIT (*p); ++p)
9072     offset = offset * 10 + *p - '0';
9073
9074   if (offset > 0x3fc)
9075     {
9076       inst.error = _("offset out of range");
9077       return 0;
9078     }
9079   if (offset & 0x3)
9080     {
9081       inst.error = _("offset not a multiple of 4");
9082       return 0;
9083     }
9084
9085   *str = p;
9086
9087   return *negative ? -offset : offset;
9088 }
9089
9090 /* Maverick load/store instructions.
9091   <insn><cond> CRd,[Rn,<offset>]{!}.
9092   <insn><cond> CRd,[Rn],<offset>.  */
9093
9094 static void
9095 do_mav_ldst (char * str, enum arm_reg_type reg0)
9096 {
9097   int offset, negative;
9098
9099   skip_whitespace (str);
9100
9101   if (mav_reg_required_here (&str, 12, reg0) == FAIL
9102       || skip_past_comma (&str) == FAIL
9103       || *str++ != '['
9104       || reg_required_here (&str, 16) == FAIL)
9105     goto fail_ldst;
9106
9107   if (skip_past_comma (&str) == SUCCESS)
9108     {
9109       /* You are here: "<offset>]{!}".  */
9110       inst.instruction |= PRE_INDEX;
9111
9112       offset = mav_parse_offset (&str, &negative);
9113
9114       if (inst.error)
9115         return;
9116
9117       if (*str++ != ']')
9118         {
9119           inst.error = _("missing ]");
9120           return;
9121         }
9122
9123       if (*str == '!')
9124         {
9125           inst.instruction |= WRITE_BACK;
9126           ++str;
9127         }
9128     }
9129   else
9130     {
9131       /* You are here: "], <offset>".  */
9132       if (*str++ != ']')
9133         {
9134           inst.error = _("missing ]");
9135           return;
9136         }
9137
9138       if (skip_past_comma (&str) == FAIL
9139           || (offset = mav_parse_offset (&str, &negative), inst.error))
9140         goto fail_ldst;
9141
9142       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
9143     }
9144
9145   if (negative)
9146     offset = -offset;
9147   else
9148     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
9149
9150   inst.instruction |= offset >> 2;
9151   end_of_line (str);
9152   return;
9153
9154 fail_ldst:
9155   if (!inst.error)
9156      inst.error = BAD_ARGS;
9157 }
9158
9159 static void
9160 do_mav_ldst_1 (char * str)
9161 {
9162   do_mav_ldst (str, REG_TYPE_MVF);
9163 }
9164
9165 static void
9166 do_mav_ldst_2 (char * str)
9167 {
9168   do_mav_ldst (str, REG_TYPE_MVD);
9169 }
9170
9171 static void
9172 do_mav_ldst_3 (char * str)
9173 {
9174   do_mav_ldst (str, REG_TYPE_MVFX);
9175 }
9176
9177 static void
9178 do_mav_ldst_4 (char * str)
9179 {
9180   do_mav_ldst (str, REG_TYPE_MVDX);
9181 }
9182
9183 static void
9184 do_t_nop (char * str)
9185 {
9186   /* Do nothing.  */
9187   end_of_line (str);
9188 }
9189
9190 /* Handle the Format 4 instructions that do not have equivalents in other
9191    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9192    BIC and MVN.  */
9193
9194 static void
9195 do_t_arit (char * str)
9196 {
9197   int Rd, Rs, Rn;
9198
9199   skip_whitespace (str);
9200
9201   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9202       || skip_past_comma (&str) == FAIL
9203       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9204     {
9205       inst.error = BAD_ARGS;
9206       return;
9207     }
9208
9209   if (skip_past_comma (&str) != FAIL)
9210     {
9211       /* Three operand format not allowed for TST, CMN, NEG and MVN.
9212          (It isn't allowed for CMP either, but that isn't handled by this
9213          function.)  */
9214       if (inst.instruction == T_OPCODE_TST
9215           || inst.instruction == T_OPCODE_CMN
9216           || inst.instruction == T_OPCODE_NEG
9217           || inst.instruction == T_OPCODE_MVN)
9218         {
9219           inst.error = BAD_ARGS;
9220           return;
9221         }
9222
9223       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9224         return;
9225
9226       if (Rs != Rd)
9227         {
9228           inst.error = _("dest and source1 must be the same register");
9229           return;
9230         }
9231       Rs = Rn;
9232     }
9233
9234   if (inst.instruction == T_OPCODE_MUL
9235       && Rs == Rd)
9236     as_tsktsk (_("Rs and Rd must be different in MUL"));
9237
9238   inst.instruction |= Rd | (Rs << 3);
9239   end_of_line (str);
9240 }
9241
9242 static void
9243 do_t_add (char * str)
9244 {
9245   thumb_add_sub (str, 0);
9246 }
9247
9248 static void
9249 do_t_asr (char * str)
9250 {
9251   thumb_shift (str, THUMB_ASR);
9252 }
9253
9254 static void
9255 do_t_branch9 (char * str)
9256 {
9257   if (my_get_expression (&inst.reloc.exp, &str))
9258     return;
9259   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9260   inst.reloc.pc_rel = 1;
9261   end_of_line (str);
9262 }
9263
9264 static void
9265 do_t_branch12 (char * str)
9266 {
9267   if (my_get_expression (&inst.reloc.exp, &str))
9268     return;
9269   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9270   inst.reloc.pc_rel = 1;
9271   end_of_line (str);
9272 }
9273
9274 /* Find the real, Thumb encoded start of a Thumb function.  */
9275
9276 static symbolS *
9277 find_real_start (symbolS * symbolP)
9278 {
9279   char *       real_start;
9280   const char * name = S_GET_NAME (symbolP);
9281   symbolS *    new_target;
9282
9283   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
9284 #define STUB_NAME ".real_start_of"
9285
9286   if (name == NULL)
9287     abort ();
9288
9289   /* Names that start with '.' are local labels, not function entry points.
9290      The compiler may generate BL instructions to these labels because it
9291      needs to perform a branch to a far away location.  */
9292   if (name[0] == '.')
9293     return symbolP;
9294
9295   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9296   sprintf (real_start, "%s%s", STUB_NAME, name);
9297
9298   new_target = symbol_find (real_start);
9299
9300   if (new_target == NULL)
9301     {
9302       as_warn ("Failed to find real start of function: %s\n", name);
9303       new_target = symbolP;
9304     }
9305
9306   free (real_start);
9307
9308   return new_target;
9309 }
9310
9311 static void
9312 do_t_branch23 (char * str)
9313 {
9314   if (my_get_expression (& inst.reloc.exp, & str))
9315     return;
9316
9317   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
9318   inst.reloc.pc_rel = 1;
9319   end_of_line (str);
9320
9321   /* If the destination of the branch is a defined symbol which does not have
9322      the THUMB_FUNC attribute, then we must be calling a function which has
9323      the (interfacearm) attribute.  We look for the Thumb entry point to that
9324      function and change the branch to refer to that function instead.  */
9325   if (   inst.reloc.exp.X_op == O_symbol
9326       && inst.reloc.exp.X_add_symbol != NULL
9327       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9328       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9329     inst.reloc.exp.X_add_symbol =
9330       find_real_start (inst.reloc.exp.X_add_symbol);
9331 }
9332
9333 static void
9334 do_t_bx (char * str)
9335 {
9336   int reg;
9337
9338   skip_whitespace (str);
9339
9340   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9341     return;
9342
9343   /* This sets THUMB_H2 from the top bit of reg.  */
9344   inst.instruction |= reg << 3;
9345
9346   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
9347      should cause the alignment to be checked once it is known.  This is
9348      because BX PC only works if the instruction is word aligned.  */
9349
9350   end_of_line (str);
9351 }
9352
9353 static void
9354 do_t_compare (char * str)
9355 {
9356   thumb_mov_compare (str, THUMB_COMPARE);
9357 }
9358
9359 static void
9360 do_t_ldmstm (char * str)
9361 {
9362   int Rb;
9363   long range;
9364
9365   skip_whitespace (str);
9366
9367   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9368     return;
9369
9370   if (*str != '!')
9371     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9372   else
9373     str++;
9374
9375   if (skip_past_comma (&str) == FAIL
9376       || (range = reg_list (&str)) == FAIL)
9377     {
9378       if (! inst.error)
9379         inst.error = BAD_ARGS;
9380       return;
9381     }
9382
9383   if (inst.reloc.type != BFD_RELOC_NONE)
9384     {
9385       /* This really doesn't seem worth it.  */
9386       inst.reloc.type = BFD_RELOC_NONE;
9387       inst.error = _("expression too complex");
9388       return;
9389     }
9390
9391   if (range & ~0xff)
9392     {
9393       inst.error = _("only lo-regs valid in load/store multiple");
9394       return;
9395     }
9396
9397   inst.instruction |= (Rb << 8) | range;
9398   end_of_line (str);
9399 }
9400
9401 static void
9402 do_t_ldr (char * str)
9403 {
9404   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9405 }
9406
9407 static void
9408 do_t_ldrb (char * str)
9409 {
9410   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9411 }
9412
9413 static void
9414 do_t_ldrh (char * str)
9415 {
9416   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9417 }
9418
9419 static void
9420 do_t_lds (char * str)
9421 {
9422   int Rd, Rb, Ro;
9423
9424   skip_whitespace (str);
9425
9426   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9427       || skip_past_comma (&str) == FAIL
9428       || *str++ != '['
9429       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9430       || skip_past_comma (&str) == FAIL
9431       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9432       || *str++ != ']')
9433     {
9434       if (! inst.error)
9435         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9436       return;
9437     }
9438
9439   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9440   end_of_line (str);
9441 }
9442
9443 static void
9444 do_t_lsl (char * str)
9445 {
9446   thumb_shift (str, THUMB_LSL);
9447 }
9448
9449 static void
9450 do_t_lsr (char * str)
9451 {
9452   thumb_shift (str, THUMB_LSR);
9453 }
9454
9455 static void
9456 do_t_mov (char * str)
9457 {
9458   thumb_mov_compare (str, THUMB_MOVE);
9459 }
9460
9461 static void
9462 do_t_push_pop (char * str)
9463 {
9464   long range;
9465
9466   skip_whitespace (str);
9467
9468   if ((range = reg_list (&str)) == FAIL)
9469     {
9470       if (! inst.error)
9471         inst.error = BAD_ARGS;
9472       return;
9473     }
9474
9475   if (inst.reloc.type != BFD_RELOC_NONE)
9476     {
9477       /* This really doesn't seem worth it.  */
9478       inst.reloc.type = BFD_RELOC_NONE;
9479       inst.error = _("expression too complex");
9480       return;
9481     }
9482
9483   if (range & ~0xff)
9484     {
9485       if ((inst.instruction == T_OPCODE_PUSH
9486            && (range & ~0xff) == 1 << REG_LR)
9487           || (inst.instruction == T_OPCODE_POP
9488               && (range & ~0xff) == 1 << REG_PC))
9489         {
9490           inst.instruction |= THUMB_PP_PC_LR;
9491           range &= 0xff;
9492         }
9493       else
9494         {
9495           inst.error = _("invalid register list to push/pop instruction");
9496           return;
9497         }
9498     }
9499
9500   inst.instruction |= range;
9501   end_of_line (str);
9502 }
9503
9504 static void
9505 do_t_str (char * str)
9506 {
9507   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9508 }
9509
9510 static void
9511 do_t_strb (char * str)
9512 {
9513   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9514 }
9515
9516 static void
9517 do_t_strh (char * str)
9518 {
9519   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9520 }
9521
9522 static void
9523 do_t_sub (char * str)
9524 {
9525   thumb_add_sub (str, 1);
9526 }
9527
9528 static void
9529 do_t_swi (char * str)
9530 {
9531   skip_whitespace (str);
9532
9533   if (my_get_expression (&inst.reloc.exp, &str))
9534     return;
9535
9536   inst.reloc.type = BFD_RELOC_ARM_SWI;
9537   end_of_line (str);
9538 }
9539
9540 static void
9541 do_t_adr (char * str)
9542 {
9543   int reg;
9544
9545   /* This is a pseudo-op of the form "adr rd, label" to be converted
9546      into a relative address of the form "add rd, pc, #label-.-4".  */
9547   skip_whitespace (str);
9548
9549   /* Store Rd in temporary location inside instruction.  */
9550   if ((reg = reg_required_here (&str, 4)) == FAIL
9551       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
9552       || skip_past_comma (&str) == FAIL
9553       || my_get_expression (&inst.reloc.exp, &str))
9554     {
9555       if (!inst.error)
9556         inst.error = BAD_ARGS;
9557       return;
9558     }
9559
9560   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9561   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
9562   inst.reloc.pc_rel = 1;
9563   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
9564
9565   end_of_line (str);
9566 }
9567
9568 static void
9569 insert_reg (const struct reg_entry * r,
9570             struct hash_control * htab)
9571 {
9572   int    len  = strlen (r->name) + 2;
9573   char * buf  = xmalloc (len);
9574   char * buf2 = xmalloc (len);
9575   int    i    = 0;
9576
9577 #ifdef REGISTER_PREFIX
9578   buf[i++] = REGISTER_PREFIX;
9579 #endif
9580
9581   strcpy (buf + i, r->name);
9582
9583   for (i = 0; buf[i]; i++)
9584     buf2[i] = TOUPPER (buf[i]);
9585
9586   buf2[i] = '\0';
9587
9588   hash_insert (htab, buf,  (PTR) r);
9589   hash_insert (htab, buf2, (PTR) r);
9590 }
9591
9592 static void
9593 build_reg_hsh (struct reg_map * map)
9594 {
9595   const struct reg_entry *r;
9596
9597   if ((map->htab = hash_new ()) == NULL)
9598     as_fatal (_("virtual memory exhausted"));
9599
9600   for (r = map->names; r->name != NULL; r++)
9601     insert_reg (r, map->htab);
9602 }
9603
9604 static void
9605 insert_reg_alias (char * str,
9606                   int regnum,
9607                   struct hash_control *htab)
9608 {
9609   const char * error;
9610   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
9611   const char * name = xmalloc (strlen (str) + 1);
9612
9613   strcpy ((char *) name, str);
9614
9615   new->name = name;
9616   new->number = regnum;
9617   new->builtin = FALSE;
9618
9619   error = hash_insert (htab, name, (PTR) new);
9620   if (error)
9621     {
9622       as_bad (_("failed to create an alias for %s, reason: %s"),
9623             str, error);
9624       free ((char *) name);
9625       free (new);
9626     }
9627 }
9628
9629 /* Look for the .req directive.  This is of the form:
9630
9631         new_register_name .req existing_register_name
9632
9633    If we find one, or if it looks sufficiently like one that we want to
9634    handle any error here, return non-zero.  Otherwise return zero.  */
9635
9636 static int
9637 create_register_alias (char * newname, char * p)
9638 {
9639   char * q;
9640   char c;
9641
9642   q = p;
9643   skip_whitespace (q);
9644
9645   c = *p;
9646   *p = '\0';
9647
9648   if (*q && !strncmp (q, ".req ", 5))
9649     {
9650       char *copy_of_str;
9651       char *r;
9652
9653 #ifndef IGNORE_OPCODE_CASE
9654       newname = original_case_string;
9655 #endif
9656       copy_of_str = newname;
9657
9658       q += 4;
9659       skip_whitespace (q);
9660
9661       for (r = q; *r != '\0'; r++)
9662         if (*r == ' ')
9663           break;
9664
9665       if (r != q)
9666         {
9667           enum arm_reg_type new_type, old_type;
9668           int old_regno;
9669           char d = *r;
9670
9671           *r = '\0';
9672           old_type = arm_reg_parse_any (q);
9673           *r = d;
9674
9675           new_type = arm_reg_parse_any (newname);
9676
9677           if (new_type == REG_TYPE_MAX)
9678             {
9679               if (old_type != REG_TYPE_MAX)
9680                 {
9681                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9682                   insert_reg_alias (newname, old_regno,
9683                                     all_reg_maps[old_type].htab);
9684                 }
9685               else
9686                 as_warn (_("register '%s' does not exist\n"), q);
9687             }
9688           else if (old_type == REG_TYPE_MAX)
9689             {
9690               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9691                        copy_of_str, q);
9692             }
9693           else
9694             {
9695               /* Do not warn about redefinitions to the same alias.  */
9696               if (new_type != old_type
9697                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9698                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9699                 as_warn (_("ignoring redefinition of register alias '%s'"),
9700                          copy_of_str);
9701
9702             }
9703         }
9704       else
9705         as_warn (_("ignoring incomplete .req pseuso op"));
9706
9707       *p = c;
9708       return 1;
9709     }
9710
9711   *p = c;
9712   return 0;
9713 }
9714
9715 static void
9716 set_constant_flonums (void)
9717 {
9718   int i;
9719
9720   for (i = 0; i < NUM_FLOAT_VALS; i++)
9721     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9722       abort ();
9723 }
9724
9725 \f
9726 static const struct asm_opcode insns[] =
9727 {
9728   /* Core ARM Instructions.  */
9729   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
9730   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
9731   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
9732   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
9733   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
9734   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
9735   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
9736   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
9737   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
9738   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
9739   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
9740   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
9741   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
9742   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
9743   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
9744   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
9745   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
9746   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
9747   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
9748   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
9749
9750   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9751   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
9752   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
9753   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9754   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
9755   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
9756   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9757   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
9758   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
9759   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9760   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
9761   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
9762
9763   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
9764   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
9765   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
9766   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
9767
9768   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
9769   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
9770   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
9771   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
9772   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
9773   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
9774   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
9775   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
9776
9777   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9778   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9779   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9780   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9781   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
9782   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
9783   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
9784   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
9785
9786   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9787   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9788   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9789   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9790   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
9791   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
9792   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
9793   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
9794
9795   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
9796 #ifdef TE_WINCE
9797   /* XXX This is the wrong place to do this.  Think multi-arch.  */
9798   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
9799   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
9800 #else
9801   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
9802   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
9803 #endif
9804
9805   /* Pseudo ops.  */
9806   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
9807   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
9808   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_nop},
9809
9810   /* ARM 2 multiplies.  */
9811   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
9812   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
9813   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
9814   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
9815
9816   /* Generic coprocessor instructions.  */
9817   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
9818   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
9819   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
9820   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
9821   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
9822   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
9823   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
9824
9825   /* ARM 3 - swp instructions.  */
9826   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
9827   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
9828
9829   /* ARM 6 Status register instructions.  */
9830   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
9831   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
9832   /* ScottB: our code uses     0xe128f000 for msr.
9833      NickC:  but this is wrong because the bits 16 through 19 are
9834              handled by the PSR_xxx defines above.  */
9835
9836   /* ARM 7M long multiplies.  */
9837   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
9838   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
9839   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
9840   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
9841   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
9842   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
9843   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
9844   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
9845
9846   /* ARM Architecture 4.  */
9847   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9848   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
9849   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
9850   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
9851
9852   /* ARM Architecture 4T.  */
9853   /* Note: bx (and blx) are required on V5, even if the processor does
9854      not support Thumb.  */
9855   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
9856
9857   /*  ARM Architecture 5T.  */
9858   /* Note: blx has 2 variants, so the .value is set dynamically.
9859      Only one of the variants has conditional execution.  */
9860   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
9861   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
9862   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
9863   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
9864   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
9865   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
9866   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
9867   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
9868   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
9869   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
9870
9871   /*  ARM Architecture 5TExP.  */
9872   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
9873   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
9874   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9875   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
9876
9877   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
9878   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
9879
9880   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
9881   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
9882   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
9883   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
9884
9885   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
9886   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9887   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
9888   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9889
9890   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
9891   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
9892
9893   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
9894   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
9895   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
9896   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
9897
9898   /*  ARM Architecture 5TE.  */
9899   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
9900   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
9901   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
9902
9903   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9904   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
9905
9906   /*  ARM Architecture 5TEJ.  */
9907   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
9908
9909   /*  ARM V6.  */
9910   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
9911   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
9912   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
9913   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
9914   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
9915   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
9916   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
9917   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
9918   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
9919   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
9920   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
9921   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
9922   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
9923   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
9924   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
9925   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
9926   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
9927   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
9928   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
9929   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
9930   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
9931   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
9932   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
9933   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
9934   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
9935   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
9936   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
9937   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
9938   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
9939   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
9940   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
9941   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
9942   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
9943   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
9944   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
9945   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
9946   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
9947   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
9948   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
9949   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
9950   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
9951   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
9952   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
9953   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
9954   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
9955   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
9956   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
9957   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9958   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9959   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9960   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9961   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
9962   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
9963   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
9964   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
9965   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
9966   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
9967   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
9968   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
9969   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
9970   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
9971   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
9972   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
9973   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
9974   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
9975   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
9976   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
9977   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
9978   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
9979   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
9980   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
9981   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
9982   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
9983   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
9984   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
9985   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
9986   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
9987   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
9988   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
9989   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
9990   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
9991   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
9992   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
9993   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
9994   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
9995   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
9996   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
9997   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
9998   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
9999   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
10000   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
10001   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
10002   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
10003   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
10004   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
10005   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
10006   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
10007   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
10008   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
10009
10010   /*  ARM V6K.  */
10011   { "clrex",     0xf57ff01f, 0,  ARM_EXT_V6K,      do_empty},
10012   { "ldrexb",    0xe1d00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10013   { "ldrexd",    0xe1b00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10014   { "ldrexh",    0xe1f00f9f, 6,  ARM_EXT_V6K,      do_ldrex},
10015   { "sev",       0xe320f004, 3,  ARM_EXT_V6K,      do_empty},
10016   { "strexb",    0xe1c00f90, 6,  ARM_EXT_V6K,      do_strex},
10017   { "strexd",    0xe1a00f90, 6,  ARM_EXT_V6K,      do_strex},
10018   { "strexh",    0xe1e00f90, 6,  ARM_EXT_V6K,      do_strex},
10019   { "wfe",       0xe320f002, 3,  ARM_EXT_V6K,      do_empty},
10020   { "wfi",       0xe320f003, 3,  ARM_EXT_V6K,      do_empty},
10021   { "yield",     0xe320f001, 5,  ARM_EXT_V6K,      do_empty},
10022
10023   /*  ARM V6Z.  */
10024   { "smi",       0xe1600070, 3,  ARM_EXT_V6Z,      do_smi},
10025
10026   /* Core FPA instruction set (V1).  */
10027   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10028   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10029   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10030   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
10031
10032   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10033   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10034   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10035   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10036
10037   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10038   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10039   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10040   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
10041
10042   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10043   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10044   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10045   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10046   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10047   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10048   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10049   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10050   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10051   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10052   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10053   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10054
10055   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10056   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10057   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10058   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10059   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10060   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10061   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10062   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10063   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10064   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10065   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10066   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10067
10068   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10069   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10070   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10071   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10072   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10073   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10074   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10075   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10076   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10077   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10078   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10079   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10080
10081   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10082   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10083   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10084   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10085   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10086   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10087   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10088   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10089   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10090   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10091   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10092   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10093
10094   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10095   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10096   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10097   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10098   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10099   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10100   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10101   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10102   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10103   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10104   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10105   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10106
10107   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10108   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10109   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10110   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10111   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10112   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10113   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10114   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10115   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10116   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10117   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10118   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10119
10120   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10121   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10122   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10123   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10124   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10125   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10126   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10127   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10128   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10129   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10130   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10131   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10132
10133   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10134   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10135   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10136   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10137   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10138   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10139   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10140   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10141   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10142   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10143   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10144   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10145
10146   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10147   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10148   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10149   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10150   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10151   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10152   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10153   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10154   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10155   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10156   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10157   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10158
10159   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10160   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10161   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10162   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10163   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10164   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10165   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10166   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10167   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10168   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10169   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10170   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10171
10172   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10173   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10174   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10175   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10176   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10177   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10178   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10179   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10180   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10181   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10182   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10183   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10184
10185   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10186   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10187   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10188   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10189   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10190   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10191   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10192   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10193   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10194   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10195   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10196   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10197
10198   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10199   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10200   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10201   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10202   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10203   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10204   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10205   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10206   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10207   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10208   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10209   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10210
10211   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10212   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10213   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10214   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10215   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10216   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10217   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10218   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10219   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10220   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10221   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10222   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10223
10224   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10225   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10226   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10227   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10228   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10229   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10230   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10231   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10232   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10233   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10234   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10235   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10236
10237   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10238   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10239   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10240   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10241   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10242   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10243   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10244   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10245   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10246   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10247   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10248   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
10249
10250   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10251   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10252   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10253   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10254   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10255   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10256   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10257   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10258   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10259   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10260   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10261   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10262
10263   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10264   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10265   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10266   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10267   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10268   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10269   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10270   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10271   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10272   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10273   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10274   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10275
10276   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10277   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10278   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10279   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10280   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10281   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10282   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10283   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10284   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10285   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10286   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10287   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10288
10289   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10290   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10291   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10292   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10293   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10294   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10295   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10296   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10297   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10298   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10299   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10300   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10301
10302   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10303   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10304   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10305   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10306   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10307   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10308   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10309   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10310   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10311   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10312   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10313   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10314
10315   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10316   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10317   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10318   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10319   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10320   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10321   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10322   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10323   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10324   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10325   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10326   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10327
10328   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10329   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10330   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10331   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10332   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10333   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10334   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10335   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10336   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10337   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10338   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10339   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10340
10341   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10342   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10343   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10344   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10345   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10346   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10347   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10348   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10349   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10350   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10351   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10352   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10353
10354   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10355   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10356   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10357   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10358   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10359   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10360   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10361   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10362   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10363   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10364   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10365   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10366
10367   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10368   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10369   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10370   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10371   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10372   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10373   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10374   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10375   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10376   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10377   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10378   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10379
10380   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10381   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10382   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10383   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10384   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10385   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10386   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10387   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10388   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10389   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10390   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10391   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10392
10393   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10394   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10395   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10396   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10397   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10398   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10399   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10400   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10401   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10402   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10403   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10404   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10405
10406   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10407   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10408   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10409   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10410   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10411   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10412   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10413   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10414   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10415   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10416   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10417   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
10418
10419   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10420   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10421   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10422   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10423   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
10424      not be an optional suffix, but part of the instruction.  To be
10425      compatible, we accept either.  */
10426   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10427   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
10428
10429   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10430   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10431   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10432   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10433   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10434   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10435   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10436   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10437   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10438   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10439   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10440   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
10441
10442   /* The implementation of the FIX instruction is broken on some
10443      assemblers, in that it accepts a precision specifier as well as a
10444      rounding specifier, despite the fact that this is meaningless.
10445      To be more compatible, we accept it as well, though of course it
10446      does not set any bits.  */
10447   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10448   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10449   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10450   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10451   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10452   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10453   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10454   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10455   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10456   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10457   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10458   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10459   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
10460
10461   /* Instructions that were new with the real FPA, call them V2.  */
10462   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10463   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10464   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10465   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10466   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10467   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
10468
10469   /* VFP V1xD (single precision).  */
10470   /* Moves and type conversions.  */
10471   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10472   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
10473   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
10474   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
10475   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10476   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10477   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10478   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10479   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10480   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10481   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
10482   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
10483
10484   /* Memory operations.  */
10485   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10486   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
10487   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10488   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10489   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10490   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10491   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10492   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10493   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10494   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10495   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10496   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
10497   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10498   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
10499   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10500   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
10501   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10502   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
10503
10504   /* Monadic operations.  */
10505   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10506   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10507   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10508
10509   /* Dyadic operations.  */
10510   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10511   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10512   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10513   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10514   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10515   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10516   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10517   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10518   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
10519
10520   /* Comparisons.  */
10521   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10522   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10523   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
10524   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
10525
10526   /* VFP V1 (Double precision).  */
10527   /* Moves and type conversions.  */
10528   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10529   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10530   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10531   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10532   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
10533   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10534   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
10535   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10536   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
10537   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10538   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10539   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10540   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
10541
10542   /* Memory operations.  */
10543   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10544   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
10545   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10546   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10547   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10548   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10549   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10550   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
10551   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10552   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
10553
10554   /* Monadic operations.  */
10555   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10556   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10557   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10558
10559   /* Dyadic operations.  */
10560   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10561   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10562   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10563   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10564   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10565   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10566   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10567   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10568   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
10569
10570   /* Comparisons.  */
10571   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10572   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10573   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
10574   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
10575
10576   /* VFP V2.  */
10577   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
10578   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
10579   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
10580   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
10581
10582   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
10583   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
10584   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10585   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10586   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10587   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10588   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
10589   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
10590   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
10591
10592   /* Intel Wireless MMX technology instructions.  */
10593   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10594   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10595   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
10596   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10597   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10598   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
10599   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10600   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10601   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
10602   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10603   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10604   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10605   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10606   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10607   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
10608   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10609   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10610   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
10611   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
10612   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
10613   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10614   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10615   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10616   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10617   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10618   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
10619   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10620   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10621   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
10622   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
10623   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
10624   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10625   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10626   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
10627   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10628   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10629   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10630   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10631   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10632   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10633   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10634   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10635   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10636   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10637   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10638   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10639   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
10640   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10641   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10642   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10643   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10644   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10645   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10646   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10647   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10648   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10649   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10650   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10651   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10652   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10653   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10654   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10655   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10656   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10657   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10658   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10659   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10660   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10661   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10662   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10663   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10664   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10665   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10666   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10667   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10668   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10669   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10670   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10671   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10672   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10673   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10674   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10675   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10676   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10677   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10678   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10679   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10680   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10681   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
10682   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10683   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10684   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10685   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10686   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10687   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10688   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10689   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10690   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10691   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10692   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10693   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10694   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10695   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10696   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10697   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10698   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10699   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10700   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10701   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10702   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10703   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
10704   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10705   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10706   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10707   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10708   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10709   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10710   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10711   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10712   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10713   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10714   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10715   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10716   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10717   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10718   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10719   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10720   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10721   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
10722   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10723   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
10724   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10725   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
10726   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10727   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10728   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10729   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10730   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10731   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10732   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10733   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10734   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10735   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10736   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10737   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10738   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10739   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10740   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10741   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10742   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10743   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10744   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10745   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10746   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10747   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10748   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10749   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
10750   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10751   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10752   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10753   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
10754   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
10755
10756   /* Cirrus Maverick instructions.  */
10757   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10758   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10759   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10760   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10761   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
10762   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
10763   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
10764   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
10765   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
10766   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
10767   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10768   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10769   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
10770   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
10771   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10772   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10773   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
10774   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
10775   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10776   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10777   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10778   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10779   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10780   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10781   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
10782   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
10783   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
10784   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
10785   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
10786   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
10787   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10788   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10789   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
10790   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
10791   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
10792   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
10793   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
10794   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
10795   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
10796   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
10797   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
10798   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
10799   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
10800   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
10801   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
10802   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
10803   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
10804   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
10805   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
10806   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
10807   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10808   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10809   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
10810   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
10811   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10812   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10813   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10814   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10815   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
10816   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
10817   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10818   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10819   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
10820   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
10821   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10822   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10823   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10824   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10825   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10826   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
10827   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10828   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
10829   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10830   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
10831   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10832   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
10833 };
10834
10835 /* Iterate over the base tables to create the instruction patterns.  */
10836
10837 static void
10838 build_arm_ops_hsh (void)
10839 {
10840   unsigned int i;
10841   unsigned int j;
10842   static struct obstack insn_obstack;
10843
10844   obstack_begin (&insn_obstack, 4000);
10845
10846   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10847     {
10848       const struct asm_opcode *insn = insns + i;
10849
10850       if (insn->cond_offset != 0)
10851         {
10852           /* Insn supports conditional execution.  Build the varaints
10853              and insert them in the hash table.  */
10854           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10855             {
10856               unsigned len = strlen (insn->template);
10857               struct asm_opcode *new;
10858               char *template;
10859
10860               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10861               /* All condition codes are two characters.  */
10862               template = obstack_alloc (&insn_obstack, len + 3);
10863
10864               strncpy (template, insn->template, insn->cond_offset);
10865               strcpy (template + insn->cond_offset, conds[j].template);
10866               if (len > insn->cond_offset)
10867                 strcpy (template + insn->cond_offset + 2,
10868                         insn->template + insn->cond_offset);
10869               new->template = template;
10870               new->cond_offset = 0;
10871               new->variant = insn->variant;
10872               new->parms = insn->parms;
10873               new->value = (insn->value & ~COND_MASK) | conds[j].value;
10874
10875               hash_insert (arm_ops_hsh, new->template, (PTR) new);
10876             }
10877         }
10878       /* Finally, insert the unconditional insn in the table directly;
10879          no need to build a copy.  */
10880       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10881     }
10882 }
10883
10884 #if 0 /* Suppressed - for now.  */
10885 #if defined OBJ_ELF || defined OBJ_COFF
10886
10887 #ifdef OBJ_ELF
10888 #define arm_Note Elf_External_Note
10889 #else
10890 typedef struct
10891 {
10892   unsigned char namesz[4];      /* Size of entry's owner string.  */
10893   unsigned char descsz[4];      /* Size of the note descriptor.  */
10894   unsigned char type[4];        /* Interpretation of the descriptor.  */
10895   char          name[1];        /* Start of the name+desc data.  */
10896 } arm_Note;
10897 #endif
10898
10899 /* The description is kept to a fix sized in order to make updating
10900    it and merging it easier.  */
10901 #define ARM_NOTE_DESCRIPTION_LENGTH     8
10902
10903 static void
10904 arm_add_note (const char * name,
10905               const char * description,
10906               unsigned int type)
10907 {
10908   arm_Note     note ATTRIBUTE_UNUSED;
10909   char *       p;
10910   unsigned int name_len;
10911
10912   name_len = (strlen (name) + 1 + 3) & ~3;
10913
10914   p = frag_more (sizeof (note.namesz));
10915   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
10916
10917   p = frag_more (sizeof (note.descsz));
10918   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
10919
10920   p = frag_more (sizeof (note.type));
10921   md_number_to_chars (p, (valueT) type, sizeof (note.type));
10922
10923   p = frag_more (name_len);
10924   strcpy (p, name);
10925
10926   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
10927   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
10928   frag_align (2, 0, 0);
10929 }
10930 #endif
10931 #endif
10932
10933 \f
10934 static const struct thumb_opcode tinsns[] =
10935 {
10936   /* Thumb v1 (ARMv4T).  */
10937   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
10938   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
10939   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
10940   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
10941   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
10942   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
10943   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
10944   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10945   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
10946   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10947   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10948   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
10949   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
10950   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
10951   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
10952   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
10953   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
10954   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
10955   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
10956   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
10957   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
10958   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
10959   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
10960   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
10961   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
10962   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
10963   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
10964   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
10965   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
10966   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
10967   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
10968   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
10969   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
10970   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10971   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10972   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
10973   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
10974   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
10975   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
10976   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
10977   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
10978   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
10979   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
10980   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
10981   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
10982   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
10983   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
10984   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
10985   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
10986   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
10987   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
10988   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
10989   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
10990   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
10991   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
10992   /* Pseudo ops:  */
10993   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
10994   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
10995   /* Thumb v2 (ARMv5T).  */
10996   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
10997   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
10998
10999   /* ARM V6.  */
11000   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
11001   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
11002   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
11003   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
11004   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
11005   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
11006   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
11007   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
11008   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
11009   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
11010   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
11011 };
11012
11013 void
11014 md_begin (void)
11015 {
11016   unsigned mach;
11017   unsigned int i;
11018
11019   if (   (arm_ops_hsh = hash_new ()) == NULL
11020       || (arm_tops_hsh = hash_new ()) == NULL
11021       || (arm_cond_hsh = hash_new ()) == NULL
11022       || (arm_shift_hsh = hash_new ()) == NULL
11023       || (arm_psr_hsh = hash_new ()) == NULL)
11024     as_fatal (_("virtual memory exhausted"));
11025
11026   build_arm_ops_hsh ();
11027   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11028     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11029   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11030     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11031   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11032     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11033   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11034     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11035
11036   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11037     build_reg_hsh (all_reg_maps + i);
11038
11039   set_constant_flonums ();
11040
11041   /* Set the cpu variant based on the command-line options.  We prefer
11042      -mcpu= over -march= if both are set (as for GCC); and we prefer
11043      -mfpu= over any other way of setting the floating point unit.
11044      Use of legacy options with new options are faulted.  */
11045   if (legacy_cpu != -1)
11046     {
11047       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11048         as_bad (_("use of old and new-style options to set CPU type"));
11049
11050       mcpu_cpu_opt = legacy_cpu;
11051     }
11052   else if (mcpu_cpu_opt == -1)
11053     mcpu_cpu_opt = march_cpu_opt;
11054
11055   if (legacy_fpu != -1)
11056     {
11057       if (mfpu_opt != -1)
11058         as_bad (_("use of old and new-style options to set FPU type"));
11059
11060       mfpu_opt = legacy_fpu;
11061     }
11062   else if (mfpu_opt == -1)
11063     {
11064 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11065       /* Some environments specify a default FPU.  If they don't, infer it
11066          from the processor.  */
11067       if (mcpu_fpu_opt != -1)
11068         mfpu_opt = mcpu_fpu_opt;
11069       else
11070         mfpu_opt = march_fpu_opt;
11071 #else
11072       mfpu_opt = FPU_DEFAULT;
11073 #endif
11074     }
11075
11076   if (mfpu_opt == -1)
11077     {
11078       if (mcpu_cpu_opt == -1)
11079         mfpu_opt = FPU_DEFAULT;
11080       else if (mcpu_cpu_opt & ARM_EXT_V5)
11081         mfpu_opt = FPU_ARCH_VFP_V2;
11082       else
11083         mfpu_opt = FPU_ARCH_FPA;
11084     }
11085
11086   if (mcpu_cpu_opt == -1)
11087     mcpu_cpu_opt = CPU_DEFAULT;
11088
11089   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11090
11091   {
11092     unsigned int flags = 0;
11093
11094 #if defined OBJ_ELF
11095     flags = meabi_flags;
11096
11097     switch (meabi_flags)
11098       {
11099       case EF_ARM_EABI_UNKNOWN:
11100 #endif
11101 #if defined OBJ_COFF || defined OBJ_ELF
11102         /* Set the flags in the private structure.  */
11103         if (uses_apcs_26)      flags |= F_APCS26;
11104         if (support_interwork) flags |= F_INTERWORK;
11105         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11106         if (pic_code)          flags |= F_PIC;
11107         if ((cpu_variant & FPU_ANY) == FPU_NONE
11108              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11109           flags |= F_SOFT_FLOAT;
11110
11111         switch (mfloat_abi_opt)
11112           {
11113           case ARM_FLOAT_ABI_SOFT:
11114           case ARM_FLOAT_ABI_SOFTFP:
11115             flags |= F_SOFT_FLOAT;
11116             break;
11117
11118           case ARM_FLOAT_ABI_HARD:
11119             if (flags & F_SOFT_FLOAT)
11120               as_bad (_("hard-float conflicts with specified fpu"));
11121             break;
11122           }
11123
11124         /* Using VFP conventions (even if soft-float).  */
11125         if (cpu_variant & FPU_VFP_EXT_NONE)
11126           flags |= F_VFP_FLOAT;
11127 #endif
11128 #if defined OBJ_ELF
11129         if (cpu_variant & FPU_ARCH_MAVERICK)
11130             flags |= EF_ARM_MAVERICK_FLOAT;
11131         break;
11132
11133       case EF_ARM_EABI_VER4:
11134         /* No additional flags to set.  */
11135         break;
11136
11137       default:
11138         abort ();
11139       }
11140 #endif
11141 #if defined OBJ_COFF || defined OBJ_ELF
11142     bfd_set_private_flags (stdoutput, flags);
11143
11144     /* We have run out flags in the COFF header to encode the
11145        status of ATPCS support, so instead we create a dummy,
11146        empty, debug section called .arm.atpcs.  */
11147     if (atpcs)
11148       {
11149         asection * sec;
11150
11151         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11152
11153         if (sec != NULL)
11154           {
11155             bfd_set_section_flags
11156               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11157             bfd_set_section_size (stdoutput, sec, 0);
11158             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11159           }
11160       }
11161 #endif
11162   }
11163
11164   /* Record the CPU type as well.  */
11165   switch (cpu_variant & ARM_CPU_MASK)
11166     {
11167     case ARM_2:
11168       mach = bfd_mach_arm_2;
11169       break;
11170
11171     case ARM_3:                 /* Also ARM_250.  */
11172       mach = bfd_mach_arm_2a;
11173       break;
11174
11175     case ARM_6:                 /* Also ARM_7.  */
11176       mach = bfd_mach_arm_3;
11177       break;
11178
11179     default:
11180       mach = bfd_mach_arm_unknown;
11181       break;
11182     }
11183
11184   /* Catch special cases.  */
11185   if (cpu_variant & ARM_CEXT_IWMMXT)
11186     mach = bfd_mach_arm_iWMMXt;
11187   else if (cpu_variant & ARM_CEXT_XSCALE)
11188     mach = bfd_mach_arm_XScale;
11189   else if (cpu_variant & ARM_CEXT_MAVERICK)
11190     mach = bfd_mach_arm_ep9312;
11191   else if (cpu_variant & ARM_EXT_V5E)
11192     mach = bfd_mach_arm_5TE;
11193   else if (cpu_variant & ARM_EXT_V5)
11194     {
11195       if (cpu_variant & ARM_EXT_V4T)
11196         mach = bfd_mach_arm_5T;
11197       else
11198         mach = bfd_mach_arm_5;
11199     }
11200   else if (cpu_variant & ARM_EXT_V4)
11201     {
11202       if (cpu_variant & ARM_EXT_V4T)
11203         mach = bfd_mach_arm_4T;
11204       else
11205         mach = bfd_mach_arm_4;
11206     }
11207   else if (cpu_variant & ARM_EXT_V3M)
11208     mach = bfd_mach_arm_3M;
11209
11210 #if 0 /* Suppressed - for now.  */
11211 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11212
11213   /* Create a .note section to fully identify this arm binary.  */
11214
11215 #define NOTE_ARCH_STRING        "arch: "
11216
11217 #if defined OBJ_COFF && ! defined NT_VERSION
11218 #define NT_VERSION  1
11219 #define NT_ARCH     2
11220 #endif
11221
11222   {
11223     segT current_seg = now_seg;
11224     subsegT current_subseg = now_subseg;
11225     asection * arm_arch;
11226     const char * arch_string;
11227
11228     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11229
11230 #ifdef OBJ_COFF
11231     bfd_set_section_flags (stdoutput, arm_arch,
11232                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11233                            | SEC_HAS_CONTENTS);
11234 #else
11235     bfd_set_section_flags (stdoutput, arm_arch,
11236                            SEC_READONLY | SEC_HAS_CONTENTS);
11237 #endif
11238     arm_arch->output_section = arm_arch;
11239     subseg_set (arm_arch, 0);
11240
11241     switch (mach)
11242       {
11243       default:
11244       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11245       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11246       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11247       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11248       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11249       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11250       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11251       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11252       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11253       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11254       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11255       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11256       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break;
11257       }
11258
11259     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11260
11261     subseg_set (current_seg, current_subseg);
11262   }
11263 #endif
11264 #endif /* Suppressed code.  */
11265
11266   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11267 }
11268
11269 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11270    for use in the a.out file, and stores them in the array pointed to by buf.
11271    This knows about the endian-ness of the target machine and does
11272    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11273    2 (short) and 4 (long)  Floating numbers are put out as a series of
11274    LITTLENUMS (shorts, here at least).  */
11275
11276 void
11277 md_number_to_chars (char * buf, valueT val, int n)
11278 {
11279   if (target_big_endian)
11280     number_to_chars_bigendian (buf, val, n);
11281   else
11282     number_to_chars_littleendian (buf, val, n);
11283 }
11284
11285 static valueT
11286 md_chars_to_number (char * buf, int n)
11287 {
11288   valueT result = 0;
11289   unsigned char * where = (unsigned char *) buf;
11290
11291   if (target_big_endian)
11292     {
11293       while (n--)
11294         {
11295           result <<= 8;
11296           result |= (*where++ & 255);
11297         }
11298     }
11299   else
11300     {
11301       while (n--)
11302         {
11303           result <<= 8;
11304           result |= (where[n] & 255);
11305         }
11306     }
11307
11308   return result;
11309 }
11310
11311 /* Turn a string in input_line_pointer into a floating point constant
11312    of type TYPE, and store the appropriate bytes in *LITP.  The number
11313    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11314    returned, or NULL on OK.
11315
11316    Note that fp constants aren't represent in the normal way on the ARM.
11317    In big endian mode, things are as expected.  However, in little endian
11318    mode fp constants are big-endian word-wise, and little-endian byte-wise
11319    within the words.  For example, (double) 1.1 in big endian mode is
11320    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11321    the byte sequence 99 99 f1 3f 9a 99 99 99.
11322
11323    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11324
11325 char *
11326 md_atof (int type, char * litP, int * sizeP)
11327 {
11328   int prec;
11329   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11330   char *t;
11331   int i;
11332
11333   switch (type)
11334     {
11335     case 'f':
11336     case 'F':
11337     case 's':
11338     case 'S':
11339       prec = 2;
11340       break;
11341
11342     case 'd':
11343     case 'D':
11344     case 'r':
11345     case 'R':
11346       prec = 4;
11347       break;
11348
11349     case 'x':
11350     case 'X':
11351       prec = 6;
11352       break;
11353
11354     case 'p':
11355     case 'P':
11356       prec = 6;
11357       break;
11358
11359     default:
11360       *sizeP = 0;
11361       return _("bad call to MD_ATOF()");
11362     }
11363
11364   t = atof_ieee (input_line_pointer, type, words);
11365   if (t)
11366     input_line_pointer = t;
11367   *sizeP = prec * 2;
11368
11369   if (target_big_endian)
11370     {
11371       for (i = 0; i < prec; i++)
11372         {
11373           md_number_to_chars (litP, (valueT) words[i], 2);
11374           litP += 2;
11375         }
11376     }
11377   else
11378     {
11379       if (cpu_variant & FPU_ARCH_VFP)
11380         for (i = prec - 1; i >= 0; i--)
11381           {
11382             md_number_to_chars (litP, (valueT) words[i], 2);
11383             litP += 2;
11384           }
11385       else
11386         /* For a 4 byte float the order of elements in `words' is 1 0.
11387            For an 8 byte float the order is 1 0 3 2.  */
11388         for (i = 0; i < prec; i += 2)
11389           {
11390             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11391             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11392             litP += 4;
11393           }
11394     }
11395
11396   return 0;
11397 }
11398
11399 /* The knowledge of the PC's pipeline offset is built into the insns
11400    themselves.  */
11401
11402 long
11403 md_pcrel_from (fixS * fixP)
11404 {
11405   if (fixP->fx_addsy
11406       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11407       && fixP->fx_subsy == NULL)
11408     return 0;
11409
11410   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11411     {
11412       /* PC relative addressing on the Thumb is slightly odd
11413          as the bottom two bits of the PC are forced to zero
11414          for the calculation.  */
11415       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11416     }
11417
11418 #ifdef TE_WINCE
11419   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11420      so we un-adjust here to compensate for the accommodation.  */
11421   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11422 #else
11423   return fixP->fx_where + fixP->fx_frag->fr_address;
11424 #endif
11425 }
11426
11427 /* Round up a section size to the appropriate boundary.  */
11428
11429 valueT
11430 md_section_align (segT   segment ATTRIBUTE_UNUSED,
11431                   valueT size)
11432 {
11433 #ifdef OBJ_ELF
11434   return size;
11435 #else
11436   /* Round all sects to multiple of 4.  */
11437   return (size + 3) & ~3;
11438 #endif
11439 }
11440
11441 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
11442    Otherwise we have no need to default values of symbols.  */
11443
11444 symbolS *
11445 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
11446 {
11447 #ifdef OBJ_ELF
11448   if (name[0] == '_' && name[1] == 'G'
11449       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
11450     {
11451       if (!GOT_symbol)
11452         {
11453           if (symbol_find (name))
11454             as_bad ("GOT already in the symbol table");
11455
11456           GOT_symbol = symbol_new (name, undefined_section,
11457                                    (valueT) 0, & zero_address_frag);
11458         }
11459
11460       return GOT_symbol;
11461     }
11462 #endif
11463
11464   return 0;
11465 }
11466
11467 void
11468 md_apply_fix3 (fixS *   fixP,
11469                valueT * valP,
11470                segT     seg)
11471 {
11472   offsetT        value = * valP;
11473   offsetT        newval;
11474   unsigned int   newimm;
11475   unsigned long  temp;
11476   int            sign;
11477   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
11478   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
11479
11480   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
11481
11482   /* Note whether this will delete the relocation.  */
11483 #if 0
11484   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
11485      doesn't work fully.)  */
11486   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
11487       && !fixP->fx_pcrel)
11488 #else
11489   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11490 #endif
11491     fixP->fx_done = 1;
11492
11493   /* If this symbol is in a different section then we need to leave it for
11494      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
11495      so we have to undo it's effects here.  */
11496   if (fixP->fx_pcrel)
11497     {
11498       if (fixP->fx_addsy != NULL
11499           && S_IS_DEFINED (fixP->fx_addsy)
11500           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
11501         {
11502           if (target_oabi
11503               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
11504                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
11505                   ))
11506             value = 0;
11507           else
11508             value += md_pcrel_from (fixP);
11509         }
11510     }
11511
11512   /* Remember value for emit_reloc.  */
11513   fixP->fx_addnumber = value;
11514
11515   switch (fixP->fx_r_type)
11516     {
11517     case BFD_RELOC_ARM_IMMEDIATE:
11518       /* We claim that this fixup has been processed here,
11519          even if in fact we generate an error because we do
11520          not have a reloc for it, so tc_gen_reloc will reject it.  */
11521       fixP->fx_done = 1;
11522
11523       if (fixP->fx_addsy
11524           && ! S_IS_DEFINED (fixP->fx_addsy))
11525         {
11526           as_bad_where (fixP->fx_file, fixP->fx_line,
11527                         _("undefined symbol %s used as an immediate value"),
11528                         S_GET_NAME (fixP->fx_addsy));
11529           break;
11530         }
11531
11532       newimm = validate_immediate (value);
11533       temp = md_chars_to_number (buf, INSN_SIZE);
11534
11535       /* If the instruction will fail, see if we can fix things up by
11536          changing the opcode.  */
11537       if (newimm == (unsigned int) FAIL
11538           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
11539         {
11540           as_bad_where (fixP->fx_file, fixP->fx_line,
11541                         _("invalid constant (%lx) after fixup"),
11542                         (unsigned long) value);
11543           break;
11544         }
11545
11546       newimm |= (temp & 0xfffff000);
11547       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11548       break;
11549
11550     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11551       {
11552         unsigned int highpart = 0;
11553         unsigned int newinsn  = 0xe1a00000; /* nop.  */
11554
11555         newimm = validate_immediate (value);
11556         temp = md_chars_to_number (buf, INSN_SIZE);
11557
11558         /* If the instruction will fail, see if we can fix things up by
11559            changing the opcode.  */
11560         if (newimm == (unsigned int) FAIL
11561             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11562           {
11563             /* No ?  OK - try using two ADD instructions to generate
11564                the value.  */
11565             newimm = validate_immediate_twopart (value, & highpart);
11566
11567             /* Yes - then make sure that the second instruction is
11568                also an add.  */
11569             if (newimm != (unsigned int) FAIL)
11570               newinsn = temp;
11571             /* Still No ?  Try using a negated value.  */
11572             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11573               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11574             /* Otherwise - give up.  */
11575             else
11576               {
11577                 as_bad_where (fixP->fx_file, fixP->fx_line,
11578                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11579                               (long) value);
11580                 break;
11581               }
11582
11583             /* Replace the first operand in the 2nd instruction (which
11584                is the PC) with the destination register.  We have
11585                already added in the PC in the first instruction and we
11586                do not want to do it again.  */
11587             newinsn &= ~ 0xf0000;
11588             newinsn |= ((newinsn & 0x0f000) << 4);
11589           }
11590
11591         newimm |= (temp & 0xfffff000);
11592         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11593
11594         highpart |= (newinsn & 0xfffff000);
11595         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11596       }
11597       break;
11598
11599     case BFD_RELOC_ARM_OFFSET_IMM:
11600       sign = value >= 0;
11601
11602       if (value < 0)
11603         value = - value;
11604
11605       if (validate_offset_imm (value, 0) == FAIL)
11606         {
11607           as_bad_where (fixP->fx_file, fixP->fx_line,
11608                         _("bad immediate value for offset (%ld)"),
11609                         (long) value);
11610           break;
11611         }
11612
11613       newval = md_chars_to_number (buf, INSN_SIZE);
11614       newval &= 0xff7ff000;
11615       newval |= value | (sign ? INDEX_UP : 0);
11616       md_number_to_chars (buf, newval, INSN_SIZE);
11617       break;
11618
11619     case BFD_RELOC_ARM_OFFSET_IMM8:
11620     case BFD_RELOC_ARM_HWLITERAL:
11621       sign = value >= 0;
11622
11623       if (value < 0)
11624         value = - value;
11625
11626       if (validate_offset_imm (value, 1) == FAIL)
11627         {
11628           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11629             as_bad_where (fixP->fx_file, fixP->fx_line,
11630                           _("invalid literal constant: pool needs to be closer"));
11631           else
11632             as_bad (_("bad immediate value for half-word offset (%ld)"),
11633                     (long) value);
11634           break;
11635         }
11636
11637       newval = md_chars_to_number (buf, INSN_SIZE);
11638       newval &= 0xff7ff0f0;
11639       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11640       md_number_to_chars (buf, newval, INSN_SIZE);
11641       break;
11642
11643     case BFD_RELOC_ARM_LITERAL:
11644       sign = value >= 0;
11645
11646       if (value < 0)
11647         value = - value;
11648
11649       if (validate_offset_imm (value, 0) == FAIL)
11650         {
11651           as_bad_where (fixP->fx_file, fixP->fx_line,
11652                         _("invalid literal constant: pool needs to be closer"));
11653           break;
11654         }
11655
11656       newval = md_chars_to_number (buf, INSN_SIZE);
11657       newval &= 0xff7ff000;
11658       newval |= value | (sign ? INDEX_UP : 0);
11659       md_number_to_chars (buf, newval, INSN_SIZE);
11660       break;
11661
11662     case BFD_RELOC_ARM_SHIFT_IMM:
11663       newval = md_chars_to_number (buf, INSN_SIZE);
11664       if (((unsigned long) value) > 32
11665           || (value == 32
11666               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11667         {
11668           as_bad_where (fixP->fx_file, fixP->fx_line,
11669                         _("shift expression is too large"));
11670           break;
11671         }
11672
11673       if (value == 0)
11674         /* Shifts of zero must be done as lsl.  */
11675         newval &= ~0x60;
11676       else if (value == 32)
11677         value = 0;
11678       newval &= 0xfffff07f;
11679       newval |= (value & 0x1f) << 7;
11680       md_number_to_chars (buf, newval, INSN_SIZE);
11681       break;
11682
11683     case BFD_RELOC_ARM_SMI:
11684       if (((unsigned long) value) > 0xffff)
11685         as_bad_where (fixP->fx_file, fixP->fx_line,
11686                       _("invalid smi expression"));
11687       newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0;
11688       newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11689       md_number_to_chars (buf, newval, INSN_SIZE);
11690       break;
11691
11692     case BFD_RELOC_ARM_SWI:
11693       if (arm_data->thumb_mode)
11694         {
11695           if (((unsigned long) value) > 0xff)
11696             as_bad_where (fixP->fx_file, fixP->fx_line,
11697                           _("invalid swi expression"));
11698           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
11699           newval |= value;
11700           md_number_to_chars (buf, newval, THUMB_SIZE);
11701         }
11702       else
11703         {
11704           if (((unsigned long) value) > 0x00ffffff)
11705             as_bad_where (fixP->fx_file, fixP->fx_line,
11706                           _("invalid swi expression"));
11707           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
11708           newval |= value;
11709           md_number_to_chars (buf, newval, INSN_SIZE);
11710         }
11711       break;
11712
11713     case BFD_RELOC_ARM_MULTI:
11714       if (((unsigned long) value) > 0xffff)
11715         as_bad_where (fixP->fx_file, fixP->fx_line,
11716                       _("invalid expression in load/store multiple"));
11717       newval = value | md_chars_to_number (buf, INSN_SIZE);
11718       md_number_to_chars (buf, newval, INSN_SIZE);
11719       break;
11720
11721     case BFD_RELOC_ARM_PCREL_BRANCH:
11722       newval = md_chars_to_number (buf, INSN_SIZE);
11723
11724       /* Sign-extend a 24-bit number.  */
11725 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
11726
11727 #ifdef OBJ_ELF
11728       if (! target_oabi)
11729         value = fixP->fx_offset;
11730 #endif
11731
11732       /* We are going to store value (shifted right by two) in the
11733          instruction, in a 24 bit, signed field.  Thus we need to check
11734          that none of the top 8 bits of the shifted value (top 7 bits of
11735          the unshifted, unsigned value) are set, or that they are all set.  */
11736       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
11737           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
11738         {
11739 #ifdef OBJ_ELF
11740           /* Normally we would be stuck at this point, since we cannot store
11741              the absolute address that is the destination of the branch in the
11742              24 bits of the branch instruction.  If however, we happen to know
11743              that the destination of the branch is in the same section as the
11744              branch instruction itself, then we can compute the relocation for
11745              ourselves and not have to bother the linker with it.
11746
11747              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
11748              because I have not worked out how to do this for OBJ_COFF or
11749              target_oabi.  */
11750           if (! target_oabi
11751               && fixP->fx_addsy != NULL
11752               && S_IS_DEFINED (fixP->fx_addsy)
11753               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
11754             {
11755               /* Get pc relative value to go into the branch.  */
11756               value = * valP;
11757
11758               /* Permit a backward branch provided that enough bits
11759                  are set.  Allow a forwards branch, provided that
11760                  enough bits are clear.  */
11761               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
11762                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
11763                 fixP->fx_done = 1;
11764             }
11765
11766           if (! fixP->fx_done)
11767 #endif
11768             as_bad_where (fixP->fx_file, fixP->fx_line,
11769                           _("GAS can't handle same-section branch dest >= 0x04000000"));
11770         }
11771
11772       value >>= 2;
11773       value += SEXT24 (newval);
11774
11775       if (    (value & ~ ((offsetT) 0xffffff)) != 0
11776           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
11777         as_bad_where (fixP->fx_file, fixP->fx_line,
11778                       _("out of range branch"));
11779
11780       newval = (value & 0x00ffffff) | (newval & 0xff000000);
11781       md_number_to_chars (buf, newval, INSN_SIZE);
11782       break;
11783
11784     case BFD_RELOC_ARM_PCREL_BLX:
11785       {
11786         offsetT hbit;
11787         newval = md_chars_to_number (buf, INSN_SIZE);
11788
11789 #ifdef OBJ_ELF
11790         if (! target_oabi)
11791           value = fixP->fx_offset;
11792 #endif
11793         hbit   = (value >> 1) & 1;
11794         value  = (value >> 2) & 0x00ffffff;
11795         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
11796         newval = value | (newval & 0xfe000000) | (hbit << 24);
11797         md_number_to_chars (buf, newval, INSN_SIZE);
11798       }
11799       break;
11800
11801     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
11802       newval = md_chars_to_number (buf, THUMB_SIZE);
11803       {
11804         addressT diff = (newval & 0xff) << 1;
11805         if (diff & 0x100)
11806           diff |= ~0xff;
11807
11808         value += diff;
11809         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
11810           as_bad_where (fixP->fx_file, fixP->fx_line,
11811                         _("branch out of range"));
11812         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
11813       }
11814       md_number_to_chars (buf, newval, THUMB_SIZE);
11815       break;
11816
11817     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
11818       newval = md_chars_to_number (buf, THUMB_SIZE);
11819       {
11820         addressT diff = (newval & 0x7ff) << 1;
11821         if (diff & 0x800)
11822           diff |= ~0x7ff;
11823
11824         value += diff;
11825         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
11826           as_bad_where (fixP->fx_file, fixP->fx_line,
11827                         _("branch out of range"));
11828         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
11829       }
11830       md_number_to_chars (buf, newval, THUMB_SIZE);
11831       break;
11832
11833     case BFD_RELOC_THUMB_PCREL_BLX:
11834     case BFD_RELOC_THUMB_PCREL_BRANCH23:
11835       {
11836         offsetT newval2;
11837         addressT diff;
11838
11839         newval  = md_chars_to_number (buf, THUMB_SIZE);
11840         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11841         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
11842         if (diff & 0x400000)
11843           diff |= ~0x3fffff;
11844 #ifdef OBJ_ELF
11845         value = fixP->fx_offset;
11846 #endif
11847         value += diff;
11848
11849         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
11850           as_bad_where (fixP->fx_file, fixP->fx_line,
11851                         _("branch with link out of range"));
11852
11853         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
11854         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
11855         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
11856           /* For a BLX instruction, make sure that the relocation is rounded up
11857              to a word boundary.  This follows the semantics of the instruction
11858              which specifies that bit 1 of the target address will come from bit
11859              1 of the base address.  */
11860           newval2 = (newval2 + 1) & ~ 1;
11861         md_number_to_chars (buf, newval, THUMB_SIZE);
11862         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11863       }
11864       break;
11865
11866     case BFD_RELOC_8:
11867       if (fixP->fx_done || fixP->fx_pcrel)
11868         md_number_to_chars (buf, value, 1);
11869 #ifdef OBJ_ELF
11870       else if (!target_oabi)
11871         {
11872           value = fixP->fx_offset;
11873           md_number_to_chars (buf, value, 1);
11874         }
11875 #endif
11876       break;
11877
11878     case BFD_RELOC_16:
11879       if (fixP->fx_done || fixP->fx_pcrel)
11880         md_number_to_chars (buf, value, 2);
11881 #ifdef OBJ_ELF
11882       else if (!target_oabi)
11883         {
11884           value = fixP->fx_offset;
11885           md_number_to_chars (buf, value, 2);
11886         }
11887 #endif
11888       break;
11889
11890 #ifdef OBJ_ELF
11891     case BFD_RELOC_ARM_GOT32:
11892     case BFD_RELOC_ARM_GOTOFF:
11893     case BFD_RELOC_ARM_TARGET2:
11894       md_number_to_chars (buf, 0, 4);
11895       break;
11896 #endif
11897
11898     case BFD_RELOC_RVA:
11899     case BFD_RELOC_32:
11900     case BFD_RELOC_ARM_TARGET1:
11901     case BFD_RELOC_ARM_ROSEGREL32:
11902     case BFD_RELOC_ARM_SBREL32:
11903     case BFD_RELOC_32_PCREL:
11904       if (fixP->fx_done || fixP->fx_pcrel)
11905         md_number_to_chars (buf, value, 4);
11906 #ifdef OBJ_ELF
11907       else if (!target_oabi)
11908         {
11909           value = fixP->fx_offset;
11910           md_number_to_chars (buf, value, 4);
11911         }
11912 #endif
11913       break;
11914
11915 #ifdef OBJ_ELF
11916     case BFD_RELOC_ARM_PREL31:
11917       if (fixP->fx_done || fixP->fx_pcrel)
11918         {
11919           newval = md_chars_to_number (buf, 4) & 0x80000000;
11920           if ((value ^ (value >> 1)) & 0x40000000)
11921             {
11922               as_bad_where (fixP->fx_file, fixP->fx_line,
11923                             _("rel31 relocation overflow"));
11924             }
11925           newval |= value & 0x7fffffff;
11926           md_number_to_chars (buf, newval, 4);
11927         }
11928       break;
11929
11930     case BFD_RELOC_ARM_PLT32:
11931       /* It appears the instruction is fully prepared at this point.  */
11932       break;
11933 #endif
11934
11935     case BFD_RELOC_ARM_CP_OFF_IMM:
11936       sign = value >= 0;
11937       if (value < -1023 || value > 1023 || (value & 3))
11938         as_bad_where (fixP->fx_file, fixP->fx_line,
11939                       _("illegal value for co-processor offset"));
11940       if (value < 0)
11941         value = -value;
11942       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11943       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11944       md_number_to_chars (buf, newval, INSN_SIZE);
11945       break;
11946
11947     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11948       sign = value >= 0;
11949       if (value < -255 || value > 255)
11950         as_bad_where (fixP->fx_file, fixP->fx_line,
11951                       _("Illegal value for co-processor offset"));
11952       if (value < 0)
11953         value = -value;
11954       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11955       newval |= value | (sign ?  INDEX_UP : 0);
11956       md_number_to_chars (buf, newval , INSN_SIZE);
11957       break;
11958
11959     case BFD_RELOC_ARM_THUMB_OFFSET:
11960       newval = md_chars_to_number (buf, THUMB_SIZE);
11961       /* Exactly what ranges, and where the offset is inserted depends
11962          on the type of instruction, we can establish this from the
11963          top 4 bits.  */
11964       switch (newval >> 12)
11965         {
11966         case 4: /* PC load.  */
11967           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11968              forced to zero for these loads, so we will need to round
11969              up the offset if the instruction address is not word
11970              aligned (since the final address produced must be, and
11971              we can only describe word-aligned immediate offsets).  */
11972
11973           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11974             as_bad_where (fixP->fx_file, fixP->fx_line,
11975                           _("invalid offset, target not word aligned (0x%08X)"),
11976                           (unsigned int) (fixP->fx_frag->fr_address
11977                                           + fixP->fx_where + value));
11978
11979           if ((value + 2) & ~0x3fe)
11980             as_bad_where (fixP->fx_file, fixP->fx_line,
11981                           _("invalid offset, value too big (0x%08lX)"),
11982                           (long) value);
11983
11984           /* Round up, since pc will be rounded down.  */
11985           newval |= (value + 2) >> 2;
11986           break;
11987
11988         case 9: /* SP load/store.  */
11989           if (value & ~0x3fc)
11990             as_bad_where (fixP->fx_file, fixP->fx_line,
11991                           _("invalid offset, value too big (0x%08lX)"),
11992                           (long) value);
11993           newval |= value >> 2;
11994           break;
11995
11996         case 6: /* Word load/store.  */
11997           if (value & ~0x7c)
11998             as_bad_where (fixP->fx_file, fixP->fx_line,
11999                           _("invalid offset, value too big (0x%08lX)"),
12000                           (long) value);
12001           newval |= value << 4; /* 6 - 2.  */
12002           break;
12003
12004         case 7: /* Byte load/store.  */
12005           if (value & ~0x1f)
12006             as_bad_where (fixP->fx_file, fixP->fx_line,
12007                           _("invalid offset, value too big (0x%08lX)"),
12008                           (long) value);
12009           newval |= value << 6;
12010           break;
12011
12012         case 8: /* Halfword load/store.  */
12013           if (value & ~0x3e)
12014             as_bad_where (fixP->fx_file, fixP->fx_line,
12015                           _("invalid offset, value too big (0x%08lX)"),
12016                           (long) value);
12017           newval |= value << 5; /* 6 - 1.  */
12018           break;
12019
12020         default:
12021           as_bad_where (fixP->fx_file, fixP->fx_line,
12022                         "Unable to process relocation for thumb opcode: %lx",
12023                         (unsigned long) newval);
12024           break;
12025         }
12026       md_number_to_chars (buf, newval, THUMB_SIZE);
12027       break;
12028
12029     case BFD_RELOC_ARM_THUMB_ADD:
12030       /* This is a complicated relocation, since we use it for all of
12031          the following immediate relocations:
12032
12033             3bit ADD/SUB
12034             8bit ADD/SUB
12035             9bit ADD/SUB SP word-aligned
12036            10bit ADD PC/SP word-aligned
12037
12038          The type of instruction being processed is encoded in the
12039          instruction field:
12040
12041            0x8000  SUB
12042            0x00F0  Rd
12043            0x000F  Rs
12044       */
12045       newval = md_chars_to_number (buf, THUMB_SIZE);
12046       {
12047         int rd = (newval >> 4) & 0xf;
12048         int rs = newval & 0xf;
12049         int subtract = newval & 0x8000;
12050
12051         if (rd == REG_SP)
12052           {
12053             if (value & ~0x1fc)
12054               as_bad_where (fixP->fx_file, fixP->fx_line,
12055                             _("invalid immediate for stack address calculation"));
12056             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12057             newval |= value >> 2;
12058           }
12059         else if (rs == REG_PC || rs == REG_SP)
12060           {
12061             if (subtract ||
12062                 value & ~0x3fc)
12063               as_bad_where (fixP->fx_file, fixP->fx_line,
12064                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12065                             (unsigned long) value);
12066             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12067             newval |= rd << 8;
12068             newval |= value >> 2;
12069           }
12070         else if (rs == rd)
12071           {
12072             if (value & ~0xff)
12073               as_bad_where (fixP->fx_file, fixP->fx_line,
12074                             _("invalid 8bit immediate"));
12075             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12076             newval |= (rd << 8) | value;
12077           }
12078         else
12079           {
12080             if (value & ~0x7)
12081               as_bad_where (fixP->fx_file, fixP->fx_line,
12082                             _("invalid 3bit immediate"));
12083             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12084             newval |= rd | (rs << 3) | (value << 6);
12085           }
12086       }
12087       md_number_to_chars (buf, newval, THUMB_SIZE);
12088       break;
12089
12090     case BFD_RELOC_ARM_THUMB_IMM:
12091       newval = md_chars_to_number (buf, THUMB_SIZE);
12092       switch (newval >> 11)
12093         {
12094         case 0x04: /* 8bit immediate MOV.  */
12095         case 0x05: /* 8bit immediate CMP.  */
12096           if (value < 0 || value > 255)
12097             as_bad_where (fixP->fx_file, fixP->fx_line,
12098                           _("invalid immediate: %ld is too large"),
12099                           (long) value);
12100           newval |= value;
12101           break;
12102
12103         default:
12104           abort ();
12105         }
12106       md_number_to_chars (buf, newval, THUMB_SIZE);
12107       break;
12108
12109     case BFD_RELOC_ARM_THUMB_SHIFT:
12110       /* 5bit shift value (0..31).  */
12111       if (value < 0 || value > 31)
12112         as_bad_where (fixP->fx_file, fixP->fx_line,
12113                       _("illegal Thumb shift value: %ld"), (long) value);
12114       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12115       newval |= value << 6;
12116       md_number_to_chars (buf, newval, THUMB_SIZE);
12117       break;
12118
12119     case BFD_RELOC_VTABLE_INHERIT:
12120     case BFD_RELOC_VTABLE_ENTRY:
12121       fixP->fx_done = 0;
12122       return;
12123
12124     case BFD_RELOC_NONE:
12125     default:
12126       as_bad_where (fixP->fx_file, fixP->fx_line,
12127                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12128     }
12129 }
12130
12131 /* Translate internal representation of relocation info to BFD target
12132    format.  */
12133
12134 arelent *
12135 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
12136               fixS *     fixp)
12137 {
12138   arelent * reloc;
12139   bfd_reloc_code_real_type code;
12140
12141   reloc = xmalloc (sizeof (arelent));
12142
12143   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
12144   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12145   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12146
12147   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12148 #ifndef OBJ_ELF
12149   if (fixp->fx_pcrel == 0)
12150     reloc->addend = fixp->fx_offset;
12151   else
12152     reloc->addend = fixp->fx_offset = reloc->address;
12153 #else  /* OBJ_ELF */
12154   reloc->addend = fixp->fx_offset;
12155 #endif
12156
12157   switch (fixp->fx_r_type)
12158     {
12159     case BFD_RELOC_8:
12160       if (fixp->fx_pcrel)
12161         {
12162           code = BFD_RELOC_8_PCREL;
12163           break;
12164         }
12165
12166     case BFD_RELOC_16:
12167       if (fixp->fx_pcrel)
12168         {
12169           code = BFD_RELOC_16_PCREL;
12170           break;
12171         }
12172
12173     case BFD_RELOC_32:
12174       if (fixp->fx_pcrel)
12175         {
12176           code = BFD_RELOC_32_PCREL;
12177           break;
12178         }
12179
12180     case BFD_RELOC_ARM_PCREL_BRANCH:
12181     case BFD_RELOC_ARM_PCREL_BLX:
12182     case BFD_RELOC_RVA:
12183     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12184     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12185     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12186     case BFD_RELOC_THUMB_PCREL_BLX:
12187     case BFD_RELOC_VTABLE_ENTRY:
12188     case BFD_RELOC_VTABLE_INHERIT:
12189       code = fixp->fx_r_type;
12190       break;
12191
12192     case BFD_RELOC_ARM_LITERAL:
12193     case BFD_RELOC_ARM_HWLITERAL:
12194       /* If this is called then the a literal has
12195          been referenced across a section boundary.  */
12196       as_bad_where (fixp->fx_file, fixp->fx_line,
12197                     _("literal referenced across section boundary"));
12198       return NULL;
12199
12200 #ifdef OBJ_ELF
12201     case BFD_RELOC_ARM_GOT32:
12202     case BFD_RELOC_ARM_GOTOFF:
12203     case BFD_RELOC_ARM_PLT32:
12204     case BFD_RELOC_ARM_TARGET1:
12205     case BFD_RELOC_ARM_ROSEGREL32:
12206     case BFD_RELOC_ARM_SBREL32:
12207     case BFD_RELOC_ARM_PREL31:
12208     case BFD_RELOC_ARM_TARGET2:
12209       code = fixp->fx_r_type;
12210       break;
12211 #endif
12212
12213     case BFD_RELOC_ARM_IMMEDIATE:
12214       as_bad_where (fixp->fx_file, fixp->fx_line,
12215                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12216       return NULL;
12217
12218     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12219       as_bad_where (fixp->fx_file, fixp->fx_line,
12220                     _("ADRL used for a symbol not defined in the same file"));
12221       return NULL;
12222
12223     case BFD_RELOC_ARM_OFFSET_IMM:
12224       if (fixp->fx_addsy != NULL
12225           && !S_IS_DEFINED (fixp->fx_addsy)
12226           && S_IS_LOCAL (fixp->fx_addsy))
12227         {
12228           as_bad_where (fixp->fx_file, fixp->fx_line,
12229                         _("undefined local label `%s'"),
12230                         S_GET_NAME (fixp->fx_addsy));
12231           return NULL;
12232         }
12233
12234       as_bad_where (fixp->fx_file, fixp->fx_line,
12235                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12236       return NULL;
12237
12238     default:
12239       {
12240         char * type;
12241
12242         switch (fixp->fx_r_type)
12243           {
12244           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12245           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12246           case BFD_RELOC_ARM_SMI:          type = "SMI";          break;
12247           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12248           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12249           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12250           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12251           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12252           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12253           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12254           default:                         type = _("<unknown>"); break;
12255           }
12256         as_bad_where (fixp->fx_file, fixp->fx_line,
12257                       _("cannot represent %s relocation in this object file format"),
12258                       type);
12259         return NULL;
12260       }
12261     }
12262
12263 #ifdef OBJ_ELF
12264   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12265       && GOT_symbol
12266       && fixp->fx_addsy == GOT_symbol)
12267     {
12268       code = BFD_RELOC_ARM_GOTPC;
12269       reloc->addend = fixp->fx_offset = reloc->address;
12270     }
12271 #endif
12272
12273   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12274
12275   if (reloc->howto == NULL)
12276     {
12277       as_bad_where (fixp->fx_file, fixp->fx_line,
12278                     _("cannot represent %s relocation in this object file format"),
12279                     bfd_get_reloc_code_name (code));
12280       return NULL;
12281     }
12282
12283   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12284      vtable entry to be used in the relocation's section offset.  */
12285   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12286     reloc->address = fixp->fx_offset;
12287
12288   return reloc;
12289 }
12290
12291 int
12292 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
12293                                segT    segtype ATTRIBUTE_UNUSED)
12294 {
12295   as_fatal (_("md_estimate_size_before_relax\n"));
12296   return 1;
12297 }
12298
12299 /* We need to be able to fix up arbitrary expressions in some statements.
12300    This is so that we can handle symbols that are an arbitrary distance from
12301    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12302    which returns part of an address in a form which will be valid for
12303    a data instruction.  We do this by pushing the expression into a symbol
12304    in the expr_section, and creating a fix for that.  */
12305
12306 static void
12307 fix_new_arm (fragS *       frag,
12308              int           where,
12309              short int     size,
12310              expressionS * exp,
12311              int           pc_rel,
12312              int           reloc)
12313 {
12314   fixS *           new_fix;
12315   arm_fix_data *   arm_data;
12316
12317   switch (exp->X_op)
12318     {
12319     case O_constant:
12320     case O_symbol:
12321     case O_add:
12322     case O_subtract:
12323       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12324       break;
12325
12326     default:
12327       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12328                          pc_rel, reloc);
12329       break;
12330     }
12331
12332   /* Mark whether the fix is to a THUMB instruction, or an ARM
12333      instruction.  */
12334   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
12335   new_fix->tc_fix_data = (PTR) arm_data;
12336   arm_data->thumb_mode = thumb_mode;
12337 }
12338
12339 static void
12340 output_inst (const char * str)
12341 {
12342   char * to = NULL;
12343
12344   if (inst.error)
12345     {
12346       as_bad ("%s -- `%s'", inst.error, str);
12347       return;
12348     }
12349
12350   to = frag_more (inst.size);
12351
12352   if (thumb_mode && (inst.size > THUMB_SIZE))
12353     {
12354       assert (inst.size == (2 * THUMB_SIZE));
12355       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12356       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12357     }
12358   else if (inst.size > INSN_SIZE)
12359     {
12360       assert (inst.size == (2 * INSN_SIZE));
12361       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12362       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12363     }
12364   else
12365     md_number_to_chars (to, inst.instruction, inst.size);
12366
12367   if (inst.reloc.type != BFD_RELOC_NONE)
12368     fix_new_arm (frag_now, to - frag_now->fr_literal,
12369                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12370                  inst.reloc.type);
12371
12372 #ifdef OBJ_ELF
12373   dwarf2_emit_insn (inst.size);
12374 #endif
12375 }
12376
12377 void
12378 md_assemble (char * str)
12379 {
12380   char  c;
12381   char *p;
12382   char *start;
12383
12384   /* Align the instruction.
12385      This may not be the right thing to do but ...  */
12386 #if 0
12387   arm_align (2, 0);
12388 #endif
12389
12390   /* Align the previous label if needed.  */
12391   if (last_label_seen != NULL)
12392     {
12393       symbol_set_frag (last_label_seen, frag_now);
12394       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12395       S_SET_SEGMENT (last_label_seen, now_seg);
12396     }
12397
12398   memset (&inst, '\0', sizeof (inst));
12399   inst.reloc.type = BFD_RELOC_NONE;
12400
12401   skip_whitespace (str);
12402
12403   /* Scan up to the end of the op-code, which must end in white space or
12404      end of string.  */
12405   for (start = p = str; *p != '\0'; p++)
12406     if (*p == ' ')
12407       break;
12408
12409   if (p == str)
12410     {
12411       as_bad (_("no operator -- statement `%s'\n"), str);
12412       return;
12413     }
12414
12415   if (thumb_mode)
12416     {
12417       const struct thumb_opcode * opcode;
12418
12419       c = *p;
12420       *p = '\0';
12421       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12422       *p = c;
12423
12424       if (opcode)
12425         {
12426           /* Check that this instruction is supported for this CPU.  */
12427           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12428             {
12429               as_bad (_("selected processor does not support `%s'"), str);
12430               return;
12431             }
12432
12433           mapping_state (MAP_THUMB);
12434           inst.instruction = opcode->value;
12435           inst.size = opcode->size;
12436           opcode->parms (p);
12437           output_inst (str);
12438           return;
12439         }
12440     }
12441   else
12442     {
12443       const struct asm_opcode * opcode;
12444
12445       c = *p;
12446       *p = '\0';
12447       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
12448       *p = c;
12449
12450       if (opcode)
12451         {
12452           /* Check that this instruction is supported for this CPU.  */
12453           if ((opcode->variant & cpu_variant) == 0)
12454             {
12455               as_bad (_("selected processor does not support `%s'"), str);
12456               return;
12457             }
12458
12459           mapping_state (MAP_ARM);
12460           inst.instruction = opcode->value;
12461           inst.size = INSN_SIZE;
12462           opcode->parms (p);
12463           output_inst (str);
12464           return;
12465         }
12466     }
12467
12468   /* It wasn't an instruction, but it might be a register alias of the form
12469      alias .req reg.  */
12470   if (create_register_alias (str, p))
12471     return;
12472
12473   as_bad (_("bad instruction `%s'"), start);
12474 }
12475
12476 /* md_parse_option
12477       Invocation line includes a switch not recognized by the base assembler.
12478       See if it's a processor-specific option.
12479
12480       This routine is somewhat complicated by the need for backwards
12481       compatibility (since older releases of gcc can't be changed).
12482       The new options try to make the interface as compatible as
12483       possible with GCC.
12484
12485       New options (supported) are:
12486
12487               -mcpu=<cpu name>           Assemble for selected processor
12488               -march=<architecture name> Assemble for selected architecture
12489               -mfpu=<fpu architecture>   Assemble for selected FPU.
12490               -EB/-mbig-endian           Big-endian
12491               -EL/-mlittle-endian        Little-endian
12492               -k                         Generate PIC code
12493               -mthumb                    Start in Thumb mode
12494               -mthumb-interwork          Code supports ARM/Thumb interworking
12495
12496       For now we will also provide support for:
12497
12498               -mapcs-32                  32-bit Program counter
12499               -mapcs-26                  26-bit Program counter
12500               -macps-float               Floats passed in FP registers
12501               -mapcs-reentrant           Reentrant code
12502               -matpcs
12503       (sometime these will probably be replaced with -mapcs=<list of options>
12504       and -matpcs=<list of options>)
12505
12506       The remaining options are only supported for back-wards compatibility.
12507       Cpu variants, the arm part is optional:
12508               -m[arm]1                Currently not supported.
12509               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
12510               -m[arm]3                Arm 3 processor
12511               -m[arm]6[xx],           Arm 6 processors
12512               -m[arm]7[xx][t][[d]m]   Arm 7 processors
12513               -m[arm]8[10]            Arm 8 processors
12514               -m[arm]9[20][tdmi]      Arm 9 processors
12515               -mstrongarm[110[0]]     StrongARM processors
12516               -mxscale                XScale processors
12517               -m[arm]v[2345[t[e]]]    Arm architectures
12518               -mall                   All (except the ARM1)
12519       FP variants:
12520               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
12521               -mfpe-old               (No float load/store multiples)
12522               -mvfpxd                 VFP Single precision
12523               -mvfp                   All VFP
12524               -mno-fpu                Disable all floating point instructions
12525
12526       The following CPU names are recognized:
12527               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12528               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12529               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12530               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12531               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12532               arm10t arm10e, arm1020t, arm1020e, arm10200e,
12533               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
12534
12535       */
12536
12537 const char * md_shortopts = "m:k";
12538
12539 #ifdef ARM_BI_ENDIAN
12540 #define OPTION_EB (OPTION_MD_BASE + 0)
12541 #define OPTION_EL (OPTION_MD_BASE + 1)
12542 #else
12543 #if TARGET_BYTES_BIG_ENDIAN
12544 #define OPTION_EB (OPTION_MD_BASE + 0)
12545 #else
12546 #define OPTION_EL (OPTION_MD_BASE + 1)
12547 #endif
12548 #endif
12549
12550 struct option md_longopts[] =
12551 {
12552 #ifdef OPTION_EB
12553   {"EB", no_argument, NULL, OPTION_EB},
12554 #endif
12555 #ifdef OPTION_EL
12556   {"EL", no_argument, NULL, OPTION_EL},
12557 #endif
12558   {NULL, no_argument, NULL, 0}
12559 };
12560
12561 size_t md_longopts_size = sizeof (md_longopts);
12562
12563 struct arm_option_table
12564 {
12565   char *option;         /* Option name to match.  */
12566   char *help;           /* Help information.  */
12567   int  *var;            /* Variable to change.  */
12568   int   value;          /* What to change it to.  */
12569   char *deprecated;     /* If non-null, print this message.  */
12570 };
12571
12572 struct arm_option_table arm_opts[] =
12573 {
12574   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
12575   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
12576   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12577    &support_interwork, 1, NULL},
12578   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
12579   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12580   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12581   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12582    1, NULL},
12583   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12584   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12585   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12586   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
12587    NULL},
12588
12589   /* These are recognized by the assembler, but have no affect on code.  */
12590   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12591   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
12592
12593   /* DON'T add any new processors to this list -- we want the whole list
12594      to go away...  Add them to the processors table instead.  */
12595   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12596   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
12597   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12598   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
12599   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12600   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12601   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12602   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12603   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12604   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
12605   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12606   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
12607   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12608   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
12609   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12610   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
12611   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12612   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
12613   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12614   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
12615   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12616   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
12617   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12618   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
12619   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12620   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
12621   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12622   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
12623   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12624   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
12625   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12626   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
12627   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12628   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
12629   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12630   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12631   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12632   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12633   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12634   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12635   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12636   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
12637   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12638   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
12639   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12640   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
12641   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12642   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12643   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12644   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12645   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12646   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12647   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12648   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12649   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12650   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12651   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12652   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
12653   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12654   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
12655   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12656   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12657   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12658   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12659   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12660   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12661   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12662   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12663   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
12664   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12665    N_("use -mcpu=strongarm110")},
12666   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12667    N_("use -mcpu=strongarm1100")},
12668   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12669    N_("use -mcpu=strongarm1110")},
12670   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12671   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12672   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
12673
12674   /* Architecture variants -- don't add any more to this list either.  */
12675   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12676   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
12677   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12678   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12679   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12680   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
12681   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12682   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12683   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12684   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
12685   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12686   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12687   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12688   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
12689   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12690   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12691   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12692   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12693
12694   /* Floating point variants -- don't add any more to this list either.  */
12695   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12696   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12697   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12698   {"mno-fpu",  NULL, &legacy_fpu, 0,
12699    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
12700
12701   {NULL, NULL, NULL, 0, NULL}
12702 };
12703
12704 struct arm_cpu_option_table
12705 {
12706   char *name;
12707   int   value;
12708   /* For some CPUs we assume an FPU unless the user explicitly sets
12709      -mfpu=...  */
12710   int   default_fpu;
12711 };
12712
12713 /* This list should, at a minimum, contain all the cpu names
12714    recognized by GCC.  */
12715 static struct arm_cpu_option_table arm_cpus[] =
12716 {
12717   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12718   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
12719   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
12720   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12721   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
12722   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12723   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12724   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12725   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12726   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12727   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
12728   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
12729   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12730   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12731   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12732   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
12733   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12734   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12735   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12736   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12737   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12738   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
12739   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12740   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12741   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12742   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12743   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
12744   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
12745   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
12746   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12747   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
12748   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
12749   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
12750   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
12751   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
12752   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
12753   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12754   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
12755   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
12756   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12757   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12758   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12759   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
12760   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
12761   /* For V5 or later processors we default to using VFP; but the user
12762      should really set the FPU type explicitly.  */
12763   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12764   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12765   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12766   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12767   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
12768   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12769   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12770   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
12771   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12772   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12773   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12774   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12775   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
12776   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12777   {"arm1026ejs",        ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12778   {"arm1026ej-s",       ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
12779   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
12780   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
12781   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12782   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
12783   {"mpcore",            ARM_ARCH_V6K,    FPU_ARCH_VFP_V2},
12784   {"mpcorenovfp",       ARM_ARCH_V6K,    FPU_NONE},
12785   {"arm1176jz-s",       ARM_ARCH_V6ZK,   FPU_NONE},
12786   {"arm1176jzf-s",      ARM_ARCH_V6ZK,   FPU_ARCH_VFP_V2},
12787   /* ??? XSCALE is really an architecture.  */
12788   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12789   /* ??? iwmmxt is not a processor.  */
12790   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
12791   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
12792   /* Maverick */
12793   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
12794   {NULL, 0, 0}
12795 };
12796
12797 struct arm_arch_option_table
12798 {
12799   char *name;
12800   int   value;
12801   int   default_fpu;
12802 };
12803
12804 /* This list should, at a minimum, contain all the architecture names
12805    recognized by GCC.  */
12806 static struct arm_arch_option_table arm_archs[] =
12807 {
12808   {"all",               ARM_ANY,         FPU_ARCH_FPA},
12809   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
12810   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
12811   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12812   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
12813   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
12814   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
12815   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
12816   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
12817   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
12818   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
12819   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
12820   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
12821   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
12822   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
12823   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
12824   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
12825   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
12826   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
12827   {"armv6k",            ARM_ARCH_V6K,    FPU_ARCH_VFP},
12828   {"armv6z",            ARM_ARCH_V6Z,    FPU_ARCH_VFP},
12829   {"armv6zk",           ARM_ARCH_V6ZK,   FPU_ARCH_VFP},
12830   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
12831   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
12832   {NULL, 0, 0}
12833 };
12834
12835 /* ISA extensions in the co-processor space.  */
12836 struct arm_arch_extension_table
12837 {
12838   char *name;
12839   int value;
12840 };
12841
12842 static struct arm_arch_extension_table arm_extensions[] =
12843 {
12844   {"maverick",          ARM_CEXT_MAVERICK},
12845   {"xscale",            ARM_CEXT_XSCALE},
12846   {"iwmmxt",            ARM_CEXT_IWMMXT},
12847   {NULL,                0}
12848 };
12849
12850 struct arm_fpu_option_table
12851 {
12852   char *name;
12853   int   value;
12854 };
12855
12856 /* This list should, at a minimum, contain all the fpu names
12857    recognized by GCC.  */
12858 static struct arm_fpu_option_table arm_fpus[] =
12859 {
12860   {"softfpa",           FPU_NONE},
12861   {"fpe",               FPU_ARCH_FPE},
12862   {"fpe2",              FPU_ARCH_FPE},
12863   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
12864   {"fpa",               FPU_ARCH_FPA},
12865   {"fpa10",             FPU_ARCH_FPA},
12866   {"fpa11",             FPU_ARCH_FPA},
12867   {"arm7500fe",         FPU_ARCH_FPA},
12868   {"softvfp",           FPU_ARCH_VFP},
12869   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
12870   {"vfp",               FPU_ARCH_VFP_V2},
12871   {"vfp9",              FPU_ARCH_VFP_V2},
12872   {"vfp10",             FPU_ARCH_VFP_V2},
12873   {"vfp10-r0",          FPU_ARCH_VFP_V1},
12874   {"vfpxd",             FPU_ARCH_VFP_V1xD},
12875   {"arm1020t",          FPU_ARCH_VFP_V1},
12876   {"arm1020e",          FPU_ARCH_VFP_V2},
12877   {"arm1136jfs",        FPU_ARCH_VFP_V2},
12878   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
12879   {"maverick",          FPU_ARCH_MAVERICK},
12880   {NULL, 0}
12881 };
12882
12883 struct arm_float_abi_option_table
12884 {
12885   char *name;
12886   int value;
12887 };
12888
12889 static struct arm_float_abi_option_table arm_float_abis[] =
12890 {
12891   {"hard",      ARM_FLOAT_ABI_HARD},
12892   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
12893   {"soft",      ARM_FLOAT_ABI_SOFT},
12894   {NULL, 0}
12895 };
12896
12897 struct arm_eabi_option_table
12898 {
12899   char *name;
12900   unsigned int value;
12901 };
12902
12903 #ifdef OBJ_ELF
12904 /* We only know how to output GNU and ver 4 (AAELF) formats.  */
12905 static struct arm_eabi_option_table arm_eabis[] =
12906 {
12907   {"gnu",       EF_ARM_EABI_UNKNOWN},
12908   {"4",         EF_ARM_EABI_VER4},
12909   {NULL, 0}
12910 };
12911 #endif
12912
12913 struct arm_long_option_table
12914 {
12915   char * option;                /* Substring to match.  */
12916   char * help;                  /* Help information.  */
12917   int (* func) (char * subopt); /* Function to decode sub-option.  */
12918   char * deprecated;            /* If non-null, print this message.  */
12919 };
12920
12921 static int
12922 arm_parse_extension (char * str, int * opt_p)
12923 {
12924   while (str != NULL && *str != 0)
12925     {
12926       struct arm_arch_extension_table * opt;
12927       char * ext;
12928       int optlen;
12929
12930       if (*str != '+')
12931         {
12932           as_bad (_("invalid architectural extension"));
12933           return 0;
12934         }
12935
12936       str++;
12937       ext = strchr (str, '+');
12938
12939       if (ext != NULL)
12940         optlen = ext - str;
12941       else
12942         optlen = strlen (str);
12943
12944       if (optlen == 0)
12945         {
12946           as_bad (_("missing architectural extension"));
12947           return 0;
12948         }
12949
12950       for (opt = arm_extensions; opt->name != NULL; opt++)
12951         if (strncmp (opt->name, str, optlen) == 0)
12952           {
12953             *opt_p |= opt->value;
12954             break;
12955           }
12956
12957       if (opt->name == NULL)
12958         {
12959           as_bad (_("unknown architectural extnsion `%s'"), str);
12960           return 0;
12961         }
12962
12963       str = ext;
12964     };
12965
12966   return 1;
12967 }
12968
12969 static int
12970 arm_parse_cpu (char * str)
12971 {
12972   struct arm_cpu_option_table * opt;
12973   char * ext = strchr (str, '+');
12974   int optlen;
12975
12976   if (ext != NULL)
12977     optlen = ext - str;
12978   else
12979     optlen = strlen (str);
12980
12981   if (optlen == 0)
12982     {
12983       as_bad (_("missing cpu name `%s'"), str);
12984       return 0;
12985     }
12986
12987   for (opt = arm_cpus; opt->name != NULL; opt++)
12988     if (strncmp (opt->name, str, optlen) == 0)
12989       {
12990         mcpu_cpu_opt = opt->value;
12991         mcpu_fpu_opt = opt->default_fpu;
12992
12993         if (ext != NULL)
12994           return arm_parse_extension (ext, &mcpu_cpu_opt);
12995
12996         return 1;
12997       }
12998
12999   as_bad (_("unknown cpu `%s'"), str);
13000   return 0;
13001 }
13002
13003 static int
13004 arm_parse_arch (char * str)
13005 {
13006   struct arm_arch_option_table *opt;
13007   char *ext = strchr (str, '+');
13008   int optlen;
13009
13010   if (ext != NULL)
13011     optlen = ext - str;
13012   else
13013     optlen = strlen (str);
13014
13015   if (optlen == 0)
13016     {
13017       as_bad (_("missing architecture name `%s'"), str);
13018       return 0;
13019     }
13020
13021
13022   for (opt = arm_archs; opt->name != NULL; opt++)
13023     if (streq (opt->name, str))
13024       {
13025         march_cpu_opt = opt->value;
13026         march_fpu_opt = opt->default_fpu;
13027
13028         if (ext != NULL)
13029           return arm_parse_extension (ext, &march_cpu_opt);
13030
13031         return 1;
13032       }
13033
13034   as_bad (_("unknown architecture `%s'\n"), str);
13035   return 0;
13036 }
13037
13038 static int
13039 arm_parse_fpu (char * str)
13040 {
13041   struct arm_fpu_option_table * opt;
13042
13043   for (opt = arm_fpus; opt->name != NULL; opt++)
13044     if (streq (opt->name, str))
13045       {
13046         mfpu_opt = opt->value;
13047         return 1;
13048       }
13049
13050   as_bad (_("unknown floating point format `%s'\n"), str);
13051   return 0;
13052 }
13053
13054 static int
13055 arm_parse_float_abi (char * str)
13056 {
13057   struct arm_float_abi_option_table * opt;
13058
13059   for (opt = arm_float_abis; opt->name != NULL; opt++)
13060     if (streq (opt->name, str))
13061       {
13062         mfloat_abi_opt = opt->value;
13063         return 1;
13064       }
13065
13066   as_bad (_("unknown floating point abi `%s'\n"), str);
13067   return 0;
13068 }
13069
13070 #ifdef OBJ_ELF
13071 static int
13072 arm_parse_eabi (char * str)
13073 {
13074   struct arm_eabi_option_table *opt;
13075
13076   for (opt = arm_eabis; opt->name != NULL; opt++)
13077     if (streq (opt->name, str))
13078       {
13079         meabi_flags = opt->value;
13080         return 1;
13081       }
13082   as_bad (_("unknown EABI `%s'\n"), str);
13083   return 0;
13084 }
13085 #endif
13086
13087 struct arm_long_option_table arm_long_opts[] =
13088 {
13089   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13090    arm_parse_cpu, NULL},
13091   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13092    arm_parse_arch, NULL},
13093   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13094    arm_parse_fpu, NULL},
13095   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13096    arm_parse_float_abi, NULL},
13097 #ifdef OBJ_ELF
13098   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13099    arm_parse_eabi, NULL},
13100 #endif
13101   {NULL, NULL, 0, NULL}
13102 };
13103
13104 int
13105 md_parse_option (int c, char * arg)
13106 {
13107   struct arm_option_table *opt;
13108   struct arm_long_option_table *lopt;
13109
13110   switch (c)
13111     {
13112 #ifdef OPTION_EB
13113     case OPTION_EB:
13114       target_big_endian = 1;
13115       break;
13116 #endif
13117
13118 #ifdef OPTION_EL
13119     case OPTION_EL:
13120       target_big_endian = 0;
13121       break;
13122 #endif
13123
13124     case 'a':
13125       /* Listing option.  Just ignore these, we don't support additional
13126          ones.  */
13127       return 0;
13128
13129     default:
13130       for (opt = arm_opts; opt->option != NULL; opt++)
13131         {
13132           if (c == opt->option[0]
13133               && ((arg == NULL && opt->option[1] == 0)
13134                   || streq (arg, opt->option + 1)))
13135             {
13136 #if WARN_DEPRECATED
13137               /* If the option is deprecated, tell the user.  */
13138               if (opt->deprecated != NULL)
13139                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13140                            arg ? arg : "", _(opt->deprecated));
13141 #endif
13142
13143               if (opt->var != NULL)
13144                 *opt->var = opt->value;
13145
13146               return 1;
13147             }
13148         }
13149
13150       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13151         {
13152           /* These options are expected to have an argument.  */
13153           if (c == lopt->option[0]
13154               && arg != NULL
13155               && strncmp (arg, lopt->option + 1,
13156                           strlen (lopt->option + 1)) == 0)
13157             {
13158 #if WARN_DEPRECATED
13159               /* If the option is deprecated, tell the user.  */
13160               if (lopt->deprecated != NULL)
13161                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13162                            _(lopt->deprecated));
13163 #endif
13164
13165               /* Call the sup-option parser.  */
13166               return lopt->func (arg + strlen (lopt->option) - 1);
13167             }
13168         }
13169
13170       return 0;
13171     }
13172
13173   return 1;
13174 }
13175
13176 void
13177 md_show_usage (FILE * fp)
13178 {
13179   struct arm_option_table *opt;
13180   struct arm_long_option_table *lopt;
13181
13182   fprintf (fp, _(" ARM-specific assembler options:\n"));
13183
13184   for (opt = arm_opts; opt->option != NULL; opt++)
13185     if (opt->help != NULL)
13186       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13187
13188   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13189     if (lopt->help != NULL)
13190       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13191
13192 #ifdef OPTION_EB
13193   fprintf (fp, _("\
13194   -EB                     assemble code for a big-endian cpu\n"));
13195 #endif
13196
13197 #ifdef OPTION_EL
13198   fprintf (fp, _("\
13199   -EL                     assemble code for a little-endian cpu\n"));
13200 #endif
13201 }
13202
13203 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13204
13205 void
13206 cons_fix_new_arm (fragS *       frag,
13207                   int           where,
13208                   int           size,
13209                   expressionS * exp)
13210 {
13211   bfd_reloc_code_real_type type;
13212   int pcrel = 0;
13213
13214   /* Pick a reloc.
13215      FIXME: @@ Should look at CPU word size.  */
13216   switch (size)
13217     {
13218     case 1:
13219       type = BFD_RELOC_8;
13220       break;
13221     case 2:
13222       type = BFD_RELOC_16;
13223       break;
13224     case 4:
13225     default:
13226       type = BFD_RELOC_32;
13227       break;
13228     case 8:
13229       type = BFD_RELOC_64;
13230       break;
13231     }
13232
13233   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13234 }
13235
13236 /* A good place to do this, although this was probably not intended
13237    for this kind of use.  We need to dump the literal pool before
13238    references are made to a null symbol pointer.  */
13239
13240 void
13241 arm_cleanup (void)
13242 {
13243   literal_pool * pool;
13244
13245   for (pool = list_of_pools; pool; pool = pool->next)
13246     {
13247       /* Put it at the end of the relevent section.  */
13248       subseg_set (pool->section, pool->sub_section);
13249 #ifdef OBJ_ELF
13250       arm_elf_change_section ();
13251 #endif
13252       s_ltorg (0);
13253     }
13254 }
13255
13256 void
13257 arm_start_line_hook (void)
13258 {
13259   last_label_seen = NULL;
13260 }
13261
13262 void
13263 arm_frob_label (symbolS * sym)
13264 {
13265   last_label_seen = sym;
13266
13267   ARM_SET_THUMB (sym, thumb_mode);
13268
13269 #if defined OBJ_COFF || defined OBJ_ELF
13270   ARM_SET_INTERWORK (sym, support_interwork);
13271 #endif
13272
13273   /* Note - do not allow local symbols (.Lxxx) to be labeled
13274      as Thumb functions.  This is because these labels, whilst
13275      they exist inside Thumb code, are not the entry points for
13276      possible ARM->Thumb calls.  Also, these labels can be used
13277      as part of a computed goto or switch statement.  eg gcc
13278      can generate code that looks like this:
13279
13280                 ldr  r2, [pc, .Laaa]
13281                 lsl  r3, r3, #2
13282                 ldr  r2, [r3, r2]
13283                 mov  pc, r2
13284
13285        .Lbbb:  .word .Lxxx
13286        .Lccc:  .word .Lyyy
13287        ..etc...
13288        .Laaa:   .word Lbbb
13289
13290      The first instruction loads the address of the jump table.
13291      The second instruction converts a table index into a byte offset.
13292      The third instruction gets the jump address out of the table.
13293      The fourth instruction performs the jump.
13294
13295      If the address stored at .Laaa is that of a symbol which has the
13296      Thumb_Func bit set, then the linker will arrange for this address
13297      to have the bottom bit set, which in turn would mean that the
13298      address computation performed by the third instruction would end
13299      up with the bottom bit set.  Since the ARM is capable of unaligned
13300      word loads, the instruction would then load the incorrect address
13301      out of the jump table, and chaos would ensue.  */
13302   if (label_is_thumb_function_name
13303       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13304       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13305     {
13306       /* When the address of a Thumb function is taken the bottom
13307          bit of that address should be set.  This will allow
13308          interworking between Arm and Thumb functions to work
13309          correctly.  */
13310
13311       THUMB_SET_FUNC (sym, 1);
13312
13313       label_is_thumb_function_name = FALSE;
13314     }
13315 }
13316
13317 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13318    ARM ones.  */
13319
13320 void
13321 arm_adjust_symtab (void)
13322 {
13323 #ifdef OBJ_COFF
13324   symbolS * sym;
13325
13326   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13327     {
13328       if (ARM_IS_THUMB (sym))
13329         {
13330           if (THUMB_IS_FUNC (sym))
13331             {
13332               /* Mark the symbol as a Thumb function.  */
13333               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13334                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13335                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13336
13337               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13338                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13339               else
13340                 as_bad (_("%s: unexpected function type: %d"),
13341                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13342             }
13343           else switch (S_GET_STORAGE_CLASS (sym))
13344             {
13345             case C_EXT:
13346               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13347               break;
13348             case C_STAT:
13349               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13350               break;
13351             case C_LABEL:
13352               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13353               break;
13354             default:
13355               /* Do nothing.  */
13356               break;
13357             }
13358         }
13359
13360       if (ARM_IS_INTERWORK (sym))
13361         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13362     }
13363 #endif
13364 #ifdef OBJ_ELF
13365   symbolS * sym;
13366   char      bind;
13367
13368   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13369     {
13370       if (ARM_IS_THUMB (sym))
13371         {
13372           elf_symbol_type * elf_sym;
13373
13374           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13375           bind = ELF_ST_BIND (elf_sym);
13376
13377           /* If it's a .thumb_func, declare it as so,
13378              otherwise tag label as .code 16.  */
13379           if (THUMB_IS_FUNC (sym))
13380             elf_sym->internal_elf_sym.st_info =
13381               ELF_ST_INFO (bind, STT_ARM_TFUNC);
13382           else
13383             elf_sym->internal_elf_sym.st_info =
13384               ELF_ST_INFO (bind, STT_ARM_16BIT);
13385         }
13386     }
13387 #endif
13388 }
13389
13390 int
13391 arm_data_in_code (void)
13392 {
13393   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13394     {
13395       *input_line_pointer = '/';
13396       input_line_pointer += 5;
13397       *input_line_pointer = 0;
13398       return 1;
13399     }
13400
13401   return 0;
13402 }
13403
13404 char *
13405 arm_canonicalize_symbol_name (char * name)
13406 {
13407   int len;
13408
13409   if (thumb_mode && (len = strlen (name)) > 5
13410       && streq (name + len - 5, "/data"))
13411     *(name + len - 5) = 0;
13412
13413   return name;
13414 }
13415
13416 #if defined OBJ_COFF || defined OBJ_ELF
13417 void
13418 arm_validate_fix (fixS * fixP)
13419 {
13420   /* If the destination of the branch is a defined symbol which does not have
13421      the THUMB_FUNC attribute, then we must be calling a function which has
13422      the (interfacearm) attribute.  We look for the Thumb entry point to that
13423      function and change the branch to refer to that function instead.  */
13424   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13425       && fixP->fx_addsy != NULL
13426       && S_IS_DEFINED (fixP->fx_addsy)
13427       && ! THUMB_IS_FUNC (fixP->fx_addsy))
13428     {
13429       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13430     }
13431 }
13432 #endif
13433
13434 int
13435 arm_force_relocation (struct fix * fixp)
13436 {
13437 #if defined (OBJ_COFF) && defined (TE_PE)
13438   if (fixp->fx_r_type == BFD_RELOC_RVA)
13439     return 1;
13440 #endif
13441 #ifdef OBJ_ELF
13442   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
13443       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
13444       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
13445       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
13446     return 1;
13447 #endif
13448
13449   /* Resolve these relocations even if the symbol is extern or weak.  */
13450   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
13451       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
13452       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13453     return 0;
13454
13455   return generic_force_reloc (fixp);
13456 }
13457
13458 #ifdef OBJ_COFF
13459 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
13460    local labels from being added to the output symbol table when they
13461    are used with the ADRL pseudo op.  The ADRL relocation should always
13462    be resolved before the binbary is emitted, so it is safe to say that
13463    it is adjustable.  */
13464
13465 bfd_boolean
13466 arm_fix_adjustable (fixS * fixP)
13467 {
13468   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
13469     return 1;
13470   return 0;
13471 }
13472 #endif
13473
13474 #ifdef OBJ_ELF
13475 /* Relocations against Thumb function names must be left unadjusted,
13476    so that the linker can use this information to correctly set the
13477    bottom bit of their addresses.  The MIPS version of this function
13478    also prevents relocations that are mips-16 specific, but I do not
13479    know why it does this.
13480
13481    FIXME:
13482    There is one other problem that ought to be addressed here, but
13483    which currently is not:  Taking the address of a label (rather
13484    than a function) and then later jumping to that address.  Such
13485    addresses also ought to have their bottom bit set (assuming that
13486    they reside in Thumb code), but at the moment they will not.  */
13487
13488 bfd_boolean
13489 arm_fix_adjustable (fixS * fixP)
13490 {
13491   if (fixP->fx_addsy == NULL)
13492     return 1;
13493
13494   if (THUMB_IS_FUNC (fixP->fx_addsy)
13495       && fixP->fx_subsy == NULL)
13496     return 0;
13497
13498   /* We need the symbol name for the VTABLE entries.  */
13499   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
13500       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
13501     return 0;
13502
13503   /* Don't allow symbols to be discarded on GOT related relocs.  */
13504   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
13505       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
13506       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
13507       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
13508     return 0;
13509
13510   return 1;
13511 }
13512
13513 const char *
13514 elf32_arm_target_format (void)
13515 {
13516 #ifdef TE_SYMBIAN
13517   return (target_big_endian
13518           ? "elf32-bigarm-symbian"
13519           : "elf32-littlearm-symbian");
13520 #else
13521   if (target_big_endian)
13522     {
13523       if (target_oabi)
13524         return "elf32-bigarm-oabi";
13525       else
13526         return "elf32-bigarm";
13527     }
13528   else
13529     {
13530       if (target_oabi)
13531         return "elf32-littlearm-oabi";
13532       else
13533         return "elf32-littlearm";
13534     }
13535 #endif
13536 }
13537
13538 void
13539 armelf_frob_symbol (symbolS * symp,
13540                     int *     puntp)
13541 {
13542   elf_frob_symbol (symp, puntp);
13543 }
13544
13545 static void
13546 s_arm_elf_cons (int nbytes)
13547 {
13548   expressionS exp;
13549
13550 #ifdef md_flush_pending_output
13551   md_flush_pending_output ();
13552 #endif
13553
13554   if (is_it_end_of_statement ())
13555     {
13556       demand_empty_rest_of_line ();
13557       return;
13558     }
13559
13560 #ifdef md_cons_align
13561   md_cons_align (nbytes);
13562 #endif
13563
13564   mapping_state (MAP_DATA);
13565   do
13566     {
13567       bfd_reloc_code_real_type reloc;
13568
13569       expression (& exp);
13570
13571       if (exp.X_op == O_symbol
13572           && * input_line_pointer == '('
13573           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
13574         {
13575           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
13576           int size = bfd_get_reloc_size (howto);
13577
13578           if (size > nbytes)
13579             as_bad ("%s relocations do not fit in %d bytes",
13580                     howto->name, nbytes);
13581           else
13582             {
13583               char *p = frag_more ((int) nbytes);
13584               int offset = nbytes - size;
13585
13586               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
13587                            &exp, 0, reloc);
13588             }
13589         }
13590       else
13591         emit_expr (&exp, (unsigned int) nbytes);
13592     }
13593   while (*input_line_pointer++ == ',');
13594
13595   /* Put terminator back into stream.  */
13596   input_line_pointer --;
13597   demand_empty_rest_of_line ();
13598 }
13599
13600
13601 /* Parse a .rel31 directive.  */
13602
13603 static void
13604 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
13605 {
13606   expressionS exp;
13607   char *p;
13608   valueT highbit;
13609
13610   SKIP_WHITESPACE ();
13611
13612   highbit = 0;
13613   if (*input_line_pointer == '1')
13614     highbit = 0x80000000;
13615   else if (*input_line_pointer != '0')
13616     as_bad (_("expected 0 or 1"));
13617
13618   input_line_pointer++;
13619   SKIP_WHITESPACE ();
13620   if (*input_line_pointer != ',')
13621     as_bad (_("missing comma"));
13622   input_line_pointer++;
13623
13624 #ifdef md_flush_pending_output
13625   md_flush_pending_output ();
13626 #endif
13627
13628 #ifdef md_cons_align
13629   md_cons_align (4);
13630 #endif
13631
13632   mapping_state (MAP_DATA);
13633
13634   expression (&exp);
13635
13636   p = frag_more (4);
13637   md_number_to_chars (p, highbit, 4);
13638   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
13639                BFD_RELOC_ARM_PREL31);
13640
13641   demand_empty_rest_of_line ();
13642 }
13643 \f
13644 /* Code to deal with unwinding tables.  */
13645
13646 static void add_unwind_adjustsp (offsetT);
13647
13648 /* Switch to section NAME and create section if necessary.  It's
13649    rather ugly that we have to manipulate input_line_pointer but I
13650    don't see any other way to accomplish the same thing without
13651    changing obj-elf.c (which may be the Right Thing, in the end).
13652    Copied from tc-ia64.c.  */
13653
13654 static void
13655 set_section (char *name)
13656 {
13657   char *saved_input_line_pointer;
13658
13659   saved_input_line_pointer = input_line_pointer;
13660   input_line_pointer = name;
13661   obj_elf_section (0);
13662   input_line_pointer = saved_input_line_pointer;
13663 }
13664
13665 /* Cenerate and deferred unwind frame offset.  */
13666
13667 static void
13668 flush_pending_unwind (void)
13669 {
13670   offsetT offset;
13671
13672   offset = unwind.pending_offset;
13673   unwind.pending_offset = 0;
13674   if (offset != 0)
13675     add_unwind_adjustsp (offset);
13676 }
13677
13678 /* Add an opcode to this list for this function.  Two-byte opcodes should
13679    be passed as op[0] << 8 | op[1].  The list of opcodes is built in reverse
13680    order.  */
13681
13682 static void
13683 add_unwind_opcode (valueT op, int length)
13684 {
13685   /* Add any deferred stack adjustment.  */
13686   if (unwind.pending_offset)
13687     flush_pending_unwind ();
13688
13689   unwind.sp_restored = 0;
13690
13691   if (unwind.opcode_count + length > unwind.opcode_alloc)
13692     {
13693       unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
13694       if (unwind.opcodes)
13695         unwind.opcodes = xrealloc (unwind.opcodes,
13696                                    unwind.opcode_alloc);
13697       else
13698         unwind.opcodes = xmalloc (unwind.opcode_alloc);
13699     }
13700   while (length > 0)
13701     {
13702       length--;
13703       unwind.opcodes[unwind.opcode_count] = op & 0xff;
13704       op >>= 8;
13705       unwind.opcode_count++;
13706     }
13707 }
13708
13709 /* Add unwind opcodes to adjust the stack pointer.  */
13710
13711 static void
13712 add_unwind_adjustsp (offsetT offset)
13713 {
13714   valueT op;
13715
13716   if (offset > 0x200)
13717     {
13718       /* We need at most 5 bytes to hold a 32-bit value in a uleb128.  */
13719       char bytes[5];
13720       int n;
13721       valueT o;
13722
13723       /* Long form: 0xb2, uleb128.  */
13724       /* This might not fit in a word so add the individual bytes,
13725          remembering the list is built in reverse order.  */
13726       o = (valueT) ((offset - 0x204) >> 2);
13727       if (o == 0)
13728         add_unwind_opcode (0, 1);
13729
13730       /* Calculate the uleb128 encoding of the offset.  */
13731       n = 0;
13732       while (o)
13733         {
13734           bytes[n] = o & 0x7f;
13735           o >>= 7;
13736           if (o)
13737             bytes[n] |= 0x80;
13738           n++;
13739         }
13740       /* Add the insn.  */
13741       for (; n; n--)
13742         add_unwind_opcode (bytes[n - 1], 1);
13743       add_unwind_opcode (0xb2, 1);
13744     }
13745   else if (offset > 0x100)
13746     {
13747       /* Two short opcodes.  */
13748       add_unwind_opcode (0x3f, 1);
13749       op = (offset - 0x104) >> 2;
13750       add_unwind_opcode (op, 1);
13751     }
13752   else if (offset > 0)
13753     {
13754       /* Short opcode.  */
13755       op = (offset - 4) >> 2;
13756       add_unwind_opcode (op, 1);
13757     }
13758   else if (offset < 0)
13759     {
13760       offset = -offset;
13761       while (offset > 0x100)
13762         {
13763           add_unwind_opcode (0x7f, 1);
13764           offset -= 0x100;
13765         }
13766       op = ((offset - 4) >> 2) | 0x40;
13767       add_unwind_opcode (op, 1);
13768     }
13769 }
13770
13771 /* Finish the list of unwind opcodes for this function.  */
13772 static void
13773 finish_unwind_opcodes (void)
13774 {
13775   valueT op;
13776
13777   if (unwind.fp_used)
13778     {
13779       /* Adjust sp as neccessary.  */
13780       unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
13781       flush_pending_unwind ();
13782
13783       /* After restoring sp from the frame pointer.  */
13784       op = 0x90 | unwind.fp_reg;
13785       add_unwind_opcode (op, 1);
13786     }
13787   else
13788     flush_pending_unwind ();
13789 }
13790
13791
13792 /* Start an exception table entry.  If idx is nonzero this is an index table
13793    entry.  */
13794
13795 static void
13796 start_unwind_section (const segT text_seg, int idx)
13797 {
13798   const char * text_name;
13799   const char * prefix;
13800   const char * prefix_once;
13801   size_t prefix_len;
13802   size_t text_len;
13803   char * sec_name;
13804   size_t sec_name_len;
13805
13806   if (idx)
13807     {
13808       prefix = ELF_STRING_ARM_unwind;
13809       prefix_once = ELF_STRING_ARM_unwind_once;
13810     }
13811   else
13812     {
13813       prefix = ELF_STRING_ARM_unwind_info;
13814       prefix_once = ELF_STRING_ARM_unwind_info_once;
13815     }
13816
13817   text_name = segment_name (text_seg);
13818   if (streq (text_name, ".text"))
13819     text_name = "";
13820
13821   if (strncmp (text_name, ".gnu.linkonce.t.",
13822                strlen (".gnu.linkonce.t.")) == 0)
13823     {
13824       prefix = prefix_once;
13825       text_name += strlen (".gnu.linkonce.t.");
13826     }
13827
13828   prefix_len = strlen (prefix);
13829   text_len = strlen (text_name);
13830   sec_name_len = prefix_len + text_len;
13831   sec_name = alloca (sec_name_len + 1);
13832   memcpy (sec_name, prefix, prefix_len);
13833   memcpy (sec_name + prefix_len, text_name, text_len);
13834   sec_name[prefix_len + text_len] = '\0';
13835
13836   /* Handle COMDAT group.  */
13837   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
13838     {
13839       char *section;
13840       size_t len, group_name_len;
13841       const char *group_name = elf_group_name (text_seg);
13842
13843       if (group_name == NULL)
13844         {
13845           as_bad ("Group section `%s' has no group signature",
13846                   segment_name (text_seg));
13847           ignore_rest_of_line ();
13848           return;
13849         }
13850       /* We have to construct a fake section directive.  */
13851       group_name_len = strlen (group_name);
13852       if (idx)
13853         prefix_len = 13;
13854       else
13855         prefix_len = 16;
13856
13857       len = (sec_name_len
13858              + prefix_len             /* ,"aG",%sectiontype,  */
13859              + group_name_len         /* ,group_name  */
13860              + 7);                    /* ,comdat  */
13861
13862       section = alloca (len + 1);
13863       memcpy (section, sec_name, sec_name_len);
13864       if (idx)
13865           memcpy (section + sec_name_len, ",\"aG\",%exidx,", 13);
13866       else
13867           memcpy (section + sec_name_len, ",\"aG\",%progbits,", 16);
13868       memcpy (section + sec_name_len + prefix_len, group_name, group_name_len);
13869       memcpy (section + len - 7, ",comdat", 7);
13870       section [len] = '\0';
13871       set_section (section);
13872     }
13873   else
13874     {
13875       set_section (sec_name);
13876       bfd_set_section_flags (stdoutput, now_seg,
13877                              SEC_LOAD | SEC_ALLOC | SEC_READONLY);
13878     }
13879
13880   /* Set the setion link for index tables.  */
13881   if (idx)
13882     elf_linked_to_section (now_seg) = text_seg;
13883 }
13884
13885
13886 /* Start an unwind table entry.  HAVE_DATA is nonzero if we have additional
13887    personality routine data.  Returns zero, or the index table value for
13888    and inline entry.  */
13889
13890 static valueT
13891 create_unwind_entry (int have_data)
13892 {
13893   int size;
13894   addressT where;
13895   unsigned char *ptr;
13896   /* The current word of data.  */
13897   valueT data;
13898   /* The number of bytes left in this word.  */
13899   int n;
13900
13901   finish_unwind_opcodes ();
13902
13903   /* Remember the current text section.  */
13904   unwind.saved_seg = now_seg;
13905   unwind.saved_subseg = now_subseg;
13906
13907   start_unwind_section (now_seg, 0);
13908
13909   if (unwind.personality_routine == NULL)
13910     {
13911       if (unwind.personality_index == -2)
13912         {
13913           if (have_data)
13914             as_bad (_("handerdata in cantunwind frame"));
13915           return 1; /* EXIDX_CANTUNWIND.  */
13916         }
13917
13918       /* Use a default personality routine if none is specified.  */
13919       if (unwind.personality_index == -1)
13920         {
13921           if (unwind.opcode_count > 3)
13922             unwind.personality_index = 1;
13923           else
13924             unwind.personality_index = 0;
13925         }
13926
13927       /* Space for the personality routine entry.  */
13928       if (unwind.personality_index == 0)
13929         {
13930           if (unwind.opcode_count > 3)
13931             as_bad (_("too many unwind opcodes for personality routine 0"));
13932
13933           if (!have_data)
13934             {
13935               /* All the data is inline in the index table.  */
13936               data = 0x80;
13937               n = 3;
13938               while (unwind.opcode_count > 0)
13939                 {
13940                   unwind.opcode_count--;
13941                   data = (data << 8) | unwind.opcodes[unwind.opcode_count];
13942                   n--;
13943                 }
13944
13945               /* Pad with "finish" opcodes.  */
13946               while (n--)
13947                 data = (data << 8) | 0xb0;
13948
13949               return data;
13950             }
13951           size = 0;
13952         }
13953       else
13954         /* We get two opcodes "free" in the first word.  */
13955         size = unwind.opcode_count - 2;
13956     }
13957   else
13958     /* An extra byte is required for the opcode count.  */
13959     size = unwind.opcode_count + 1;
13960
13961   size = (size + 3) >> 2;
13962   if (size > 0xff)
13963     as_bad (_("too many unwind opcodes"));
13964
13965   frag_align (2, 0, 0);
13966   record_alignment (now_seg, 2);
13967   unwind.table_entry = expr_build_dot ();
13968
13969   /* Allocate the table entry.  */
13970   ptr = frag_more ((size << 2) + 4);
13971   where = frag_now_fix () - ((size << 2) + 4);
13972
13973   switch (unwind.personality_index)
13974     {
13975     case -1:
13976       /* ??? Should this be a PLT generating relocation?  */
13977       /* Custom personality routine.  */
13978       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
13979                BFD_RELOC_ARM_PREL31);
13980       where += 4;
13981       ptr += 4;
13982
13983       /* Set the first byte to the number of additional words.  */
13984       data = size - 1;
13985       n = 3;
13986       break;
13987
13988     /* ABI defined personality routines.  */
13989     /* TODO: Emit R_ARM_NONE to the personality routine.  */
13990     case 0:
13991       /* Three opcodes bytes are packed into the first word.  */
13992       data = 0x80;
13993       n = 3;
13994       break;
13995
13996     case 1:
13997     case 2:
13998       /* The size and first two opcode bytes go in the first word.  */
13999       data = ((0x80 + unwind.personality_index) << 8) | size;
14000       n = 2;
14001       break;
14002
14003     default:
14004       /* Should never happen.  */
14005       abort ();
14006     }
14007
14008   /* Pack the opcodes into words (MSB first), reversing the list at the same
14009      time.  */
14010   while (unwind.opcode_count > 0)
14011     {
14012       if (n == 0)
14013         {
14014           md_number_to_chars (ptr, data, 4);
14015           ptr += 4;
14016           n = 4;
14017           data = 0;
14018         }
14019       unwind.opcode_count--;
14020       n--;
14021       data = (data << 8) | unwind.opcodes[unwind.opcode_count];
14022     }
14023
14024   /* Finish off the last word.  */
14025   if (n < 4)
14026     {
14027       /* Pad with "finish" opcodes.  */
14028       while (n--)
14029         data = (data << 8) | 0xb0;
14030
14031       md_number_to_chars (ptr, data, 4);
14032     }
14033
14034   if (!have_data)
14035     {
14036       /* Add an empty descriptor if there is no user-specified data.   */
14037       ptr = frag_more (4);
14038       md_number_to_chars (ptr, 0, 4);
14039     }
14040
14041   return 0;
14042 }
14043
14044
14045 /* Parse an unwind_fnstart directive.  Simply records the current location.  */
14046
14047 static void
14048 s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
14049 {
14050   demand_empty_rest_of_line ();
14051   /* Mark the start of the function.  */
14052   unwind.proc_start = expr_build_dot ();
14053
14054   /* Reset the rest of the unwind info.  */
14055   unwind.opcode_count = 0;
14056   unwind.table_entry = NULL;
14057   unwind.personality_routine = NULL;
14058   unwind.personality_index = -1;
14059   unwind.frame_size = 0;
14060   unwind.fp_offset = 0;
14061   unwind.fp_reg = 13;
14062   unwind.fp_used = 0;
14063   unwind.sp_restored = 0;
14064 }
14065
14066
14067 /* Parse a handlerdata directive.  Creates the exception handling table entry
14068    for the function.  */
14069
14070 static void
14071 s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
14072 {
14073   demand_empty_rest_of_line ();
14074   if (unwind.table_entry)
14075     as_bad (_("dupicate .handlerdata directive"));
14076
14077   create_unwind_entry (1);
14078 }
14079
14080 /* Parse an unwind_fnend directive.  Generates the index table entry.  */
14081
14082 static void
14083 s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
14084 {
14085   long where;
14086   unsigned char *ptr;
14087   valueT val;
14088
14089   demand_empty_rest_of_line ();
14090
14091   /* Add eh table entry.  */
14092   if (unwind.table_entry == NULL)
14093     val = create_unwind_entry (0);
14094   else
14095     val = 0;
14096
14097   /* Add index table entry.  This is two words.  */
14098   start_unwind_section (unwind.saved_seg, 1);
14099   frag_align (2, 0, 0);
14100   record_alignment (now_seg, 2);
14101
14102   ptr = frag_more (8);
14103   where = frag_now_fix () - 8;
14104
14105   /* Self relative offset of the function start.  */
14106   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
14107            BFD_RELOC_32);
14108
14109   if (val)
14110     /* Inline exception table entry.  */
14111     md_number_to_chars (ptr + 4, val, 4);
14112   else
14113     /* Self relative offset of the table entry.  */
14114     fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
14115              BFD_RELOC_ARM_PREL31);
14116
14117   /* Restore the original section.  */
14118   subseg_set (unwind.saved_seg, unwind.saved_subseg);
14119 }
14120
14121
14122 /* Parse an unwind_cantunwind directive.  */
14123
14124 static void
14125 s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
14126 {
14127   demand_empty_rest_of_line ();
14128   if (unwind.personality_routine || unwind.personality_index != -1)
14129     as_bad (_("personality routine specified for cantunwind frame"));
14130
14131   unwind.personality_index = -2;
14132 }
14133
14134
14135 /* Parse a personalityindex directive.  */
14136
14137 static void
14138 s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
14139 {
14140   expressionS exp;
14141
14142   if (unwind.personality_routine || unwind.personality_index != -1)
14143     as_bad (_("duplicate .personalityindex directive"));
14144
14145   SKIP_WHITESPACE ();
14146
14147   expression (&exp);
14148
14149   if (exp.X_op != O_constant
14150       || exp.X_add_number < 0 || exp.X_add_number > 15)
14151     {
14152       as_bad (_("bad personality routine number"));
14153       ignore_rest_of_line ();
14154       return;
14155     }
14156
14157   unwind.personality_index = exp.X_add_number;
14158
14159   demand_empty_rest_of_line ();
14160 }
14161
14162
14163 /* Parse a personality directive.  */
14164
14165 static void
14166 s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
14167 {
14168   char *name, *p, c;
14169
14170   if (unwind.personality_routine || unwind.personality_index != -1)
14171     as_bad (_("duplicate .personality directive"));
14172
14173   SKIP_WHITESPACE ();
14174   name = input_line_pointer;
14175   c = get_symbol_end ();
14176   p = input_line_pointer;
14177   unwind.personality_routine = symbol_find_or_make (name);
14178   *p = c;
14179   SKIP_WHITESPACE ();
14180   demand_empty_rest_of_line ();
14181 }
14182
14183
14184 /* Parse a directive saving core registers.  */
14185
14186 static void
14187 s_arm_unwind_save_core (void)
14188 {
14189   valueT op;
14190   long range;
14191   int n;
14192
14193   SKIP_WHITESPACE ();
14194   range = reg_list (&input_line_pointer);
14195   if (range == FAIL)
14196     {
14197       as_bad (_("expected register list"));
14198       ignore_rest_of_line ();
14199       return;
14200     }
14201
14202   demand_empty_rest_of_line ();
14203
14204   /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
14205      into .unwind_save {..., sp...}.  We aren't bothered about the value of
14206      ip because it is clobbered by calls.  */
14207   if (unwind.sp_restored && unwind.fp_reg == 12
14208       && (range & 0x3000) == 0x1000)
14209     {
14210       unwind.opcode_count--;
14211       unwind.sp_restored = 0;
14212       range = (range | 0x2000) & ~0x1000;
14213       unwind.pending_offset = 0;
14214     }
14215
14216   /* See if we can use the short opcodes.  These pop a block of upto 8
14217      registers starting with r4, plus maybe r14.  */
14218   for (n = 0; n < 8; n++)
14219     {
14220       /* Break at the first non-saved register.  */
14221       if ((range & (1 << (n + 4))) == 0)
14222         break;
14223     }
14224   /* See if there are any other bits set.  */
14225   if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
14226     {
14227       /* Use the long form.  */
14228       op = 0x8000 | ((range >> 4) & 0xfff);
14229       add_unwind_opcode (op, 2);
14230     }
14231   else
14232     {
14233       /* Use the short form.  */
14234       if (range & 0x4000)
14235         op = 0xa8; /* Pop r14.  */
14236       else
14237         op = 0xa0; /* Do not pop r14.  */
14238       op |= (n - 1);
14239       add_unwind_opcode (op, 1);
14240     }
14241
14242   /* Pop r0-r3.  */
14243   if (range & 0xf)
14244     {
14245       op = 0xb100 | (range & 0xf);
14246       add_unwind_opcode (op, 2);
14247     }
14248
14249   /* Record the number of bytes pushed.  */
14250   for (n = 0; n < 16; n++)
14251     {
14252       if (range & (1 << n))
14253         unwind.frame_size += 4;
14254     }
14255 }
14256
14257
14258 /* Parse a directive saving FPA registers.  */
14259
14260 static void
14261 s_arm_unwind_save_fpa (int reg)
14262 {
14263   expressionS exp;
14264   int num_regs;
14265   valueT op;
14266
14267   /* Get Number of registers to transfer.  */
14268   if (skip_past_comma (&input_line_pointer) != FAIL)
14269     expression (&exp);
14270   else
14271     exp.X_op = O_illegal;
14272
14273   if (exp.X_op != O_constant)
14274     {
14275       as_bad (_("expected , <constant>"));
14276       ignore_rest_of_line ();
14277       return;
14278     }
14279
14280   num_regs = exp.X_add_number;
14281
14282   if (num_regs < 1 || num_regs > 4)
14283     {
14284       as_bad (_("number of registers must be in the range [1:4]"));
14285       ignore_rest_of_line ();
14286       return;
14287     }
14288
14289   demand_empty_rest_of_line ();
14290
14291   if (reg == 4)
14292     {
14293       /* Short form.  */
14294       op = 0xb4 | (num_regs - 1);
14295       add_unwind_opcode (op, 1);
14296     }
14297   else
14298     {
14299       /* Long form.  */
14300       op = 0xc800 | (reg << 4) | (num_regs - 1);
14301       add_unwind_opcode (op, 2);
14302     }
14303   unwind.frame_size += num_regs * 12;
14304 }
14305
14306
14307 /* Parse a directive saving VFP registers.  */
14308
14309 static void
14310 s_arm_unwind_save_vfp (void)
14311 {
14312   int count;
14313   int reg;
14314   valueT op;
14315
14316   count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
14317   if (count == FAIL)
14318     {
14319       as_bad (_("expected register list"));
14320       ignore_rest_of_line ();
14321       return;
14322     }
14323
14324   demand_empty_rest_of_line ();
14325
14326   if (reg == 8)
14327     {
14328       /* Short form.  */
14329       op = 0xb8 | (count - 1);
14330       add_unwind_opcode (op, 1);
14331     }
14332   else
14333     {
14334       /* Long form.  */
14335       op = 0xb300 | (reg << 4) | (count - 1);
14336       add_unwind_opcode (op, 2);
14337     }
14338   unwind.frame_size += count * 8 + 4;
14339 }
14340
14341
14342 /* Parse a directive saving iWMMXt registers.  */
14343
14344 static void
14345 s_arm_unwind_save_wmmx (void)
14346 {
14347   int reg;
14348   int hi_reg;
14349   int i;
14350   unsigned wcg_mask;
14351   unsigned wr_mask;
14352   valueT op;
14353
14354   if (*input_line_pointer == '{')
14355     input_line_pointer++;
14356
14357   wcg_mask = 0;
14358   wr_mask = 0;
14359   do
14360     {
14361       reg = arm_reg_parse (&input_line_pointer,
14362                            all_reg_maps[REG_TYPE_IWMMXT].htab);
14363
14364       if (wr_register (reg))
14365         {
14366           i = reg & ~WR_PREFIX;
14367           if (wr_mask >> i)
14368             as_tsktsk (_("register list not in ascending order"));
14369           wr_mask |= 1 << i;
14370         }
14371       else if (wcg_register (reg))
14372         {
14373           i = (reg & ~WC_PREFIX) - 8;
14374           if (wcg_mask >> i)
14375             as_tsktsk (_("register list not in ascending order"));
14376           wcg_mask |= 1 << i;
14377         }
14378       else
14379         {
14380           as_bad (_("expected wr or wcgr"));
14381           goto error;
14382         }
14383
14384       SKIP_WHITESPACE ();
14385       if (*input_line_pointer == '-')
14386         {
14387           hi_reg = arm_reg_parse (&input_line_pointer,
14388                                   all_reg_maps[REG_TYPE_IWMMXT].htab);
14389           if (wr_register (reg) && wr_register (hi_reg))
14390             {
14391               for (; reg < hi_reg; reg++)
14392                 wr_mask |= 1 << (reg & ~WR_PREFIX);
14393             }
14394           else if (wcg_register (reg) && wcg_register (hi_reg))
14395             {
14396               for (; reg < hi_reg; reg++)
14397                 wcg_mask |= 1 << ((reg & ~WC_PREFIX) - 8);
14398             }
14399           else
14400             {
14401               as_bad (_("bad register range"));
14402               goto error;
14403             }
14404         }
14405     }
14406   while (skip_past_comma (&input_line_pointer) != FAIL);
14407
14408   SKIP_WHITESPACE ();
14409   if (*input_line_pointer == '}')
14410     input_line_pointer++;
14411
14412   demand_empty_rest_of_line ();
14413
14414   if (wr_mask && wcg_mask)
14415     {
14416       as_bad (_("inconsistent register types"));
14417       goto error;
14418     }
14419
14420   /* Generate any deferred opcodes becuuse we're going to be looking at
14421      the list.  */
14422   flush_pending_unwind ();
14423
14424   if (wcg_mask)
14425     {
14426       for (i = 0; i < 16; i++)
14427         {
14428           if (wcg_mask & (1 << i))
14429             unwind.frame_size += 4;
14430         }
14431       op = 0xc700 | wcg_mask;
14432       add_unwind_opcode (op, 2);
14433     }
14434   else
14435     {
14436       for (i = 0; i < 16; i++)
14437         {
14438           if (wr_mask & (1 << i))
14439             unwind.frame_size += 8;
14440         }
14441       /* Attempt to combine with a previous opcode.  We do this because gcc
14442          likes to output separate unwind directives for a single block of
14443          registers.  */
14444       if (unwind.opcode_count > 0)
14445         {
14446           i = unwind.opcodes[unwind.opcode_count - 1];
14447           if ((i & 0xf8) == 0xc0)
14448             {
14449               i &= 7;
14450               /* Only merge if the blocks are contiguous.  */
14451               if (i < 6)
14452                 {
14453                   if ((wr_mask & 0xfe00) == (1 << 9))
14454                     {
14455                       wr_mask |= ((1 << (i + 11)) - 1) & 0xfc00;
14456                       unwind.opcode_count--;
14457                     }
14458                 }
14459               else if (i == 6 && unwind.opcode_count >= 2)
14460                 {
14461                   i = unwind.opcodes[unwind.opcode_count - 2];
14462                   reg = i >> 4;
14463                   i &= 0xf;
14464
14465                   op = 0xffff << (reg - 1);
14466                   if (reg > 0
14467                       || ((wr_mask & op) == (1u << (reg - 1))))
14468                     {
14469                       op = (1 << (reg + i + 1)) - 1;
14470                       op &= ~((1 << reg) - 1);
14471                       wr_mask |= op;
14472                       unwind.opcode_count -= 2;
14473                     }
14474                 }
14475             }
14476         }
14477
14478       hi_reg = 15;
14479       /* We want to generate opcodes in the order the registers have been
14480          saved, ie. descending order.  */
14481       for (reg = 15; reg >= -1; reg--)
14482         {
14483           /* Save registers in blocks.  */
14484           if (reg < 0
14485               || !(wr_mask & (1 << reg)))
14486             {
14487               /* We found an unsaved reg.  Generate opcodes to save the
14488                  preceeding block.  */
14489               if (reg != hi_reg)
14490                 {
14491                   if (reg == 9)
14492                     {
14493                       /* Short form.  */
14494                       op = 0xc0 | (hi_reg - 10);
14495                       add_unwind_opcode (op, 1);
14496                     }
14497                   else
14498                     {
14499                       /* Long form.  */
14500                       op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
14501                       add_unwind_opcode (op, 2);
14502                     }
14503                 }
14504               hi_reg = reg - 1;
14505             }
14506         }
14507     }
14508   return;
14509 error:
14510   ignore_rest_of_line ();
14511 }
14512
14513
14514 /* Parse an unwind_save directive.  */
14515
14516 static void
14517 s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
14518 {
14519   char *saved_ptr;
14520   int reg;
14521
14522   /* Figure out what sort of save we have.  */
14523   SKIP_WHITESPACE ();
14524   saved_ptr = input_line_pointer;
14525
14526   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_FN].htab);
14527   if (reg != FAIL)
14528     {
14529       s_arm_unwind_save_fpa (reg);
14530       return;
14531     }
14532
14533   if (*input_line_pointer == '{')
14534     input_line_pointer++;
14535
14536   SKIP_WHITESPACE ();
14537
14538   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_RN].htab);
14539   if (reg != FAIL)
14540     {
14541       input_line_pointer = saved_ptr;
14542       s_arm_unwind_save_core ();
14543       return;
14544     }
14545
14546   reg = arm_reg_parse (&input_line_pointer, all_reg_maps[REG_TYPE_DN].htab);
14547   if (reg != FAIL)
14548     {
14549       input_line_pointer = saved_ptr;
14550       s_arm_unwind_save_vfp ();
14551       return;
14552     }
14553
14554   reg = arm_reg_parse (&input_line_pointer,
14555                        all_reg_maps[REG_TYPE_IWMMXT].htab);
14556   if (reg != FAIL)
14557     {
14558       input_line_pointer = saved_ptr;
14559       s_arm_unwind_save_wmmx ();
14560       return;
14561     }
14562
14563   /* TODO: Maverick registers.  */
14564   as_bad (_("unrecognised register"));
14565 }
14566
14567
14568 /* Parse an unwind_movsp directive.  */
14569
14570 static void
14571 s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
14572 {
14573   int reg;
14574   valueT op;
14575
14576   SKIP_WHITESPACE ();
14577   reg = reg_required_here (&input_line_pointer, -1);
14578   if (reg == FAIL)
14579     {
14580       as_bad (_("ARM register expected"));
14581       ignore_rest_of_line ();
14582       return;
14583     }
14584
14585   if (reg == 13 || reg == 15)
14586     {
14587       as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
14588       ignore_rest_of_line ();
14589       return;
14590     }
14591
14592   if (unwind.fp_reg != 13)
14593     as_bad (_("unexpected .unwind_movsp directive"));
14594
14595   /* Generate opcode to restore the value.  */
14596   op = 0x90 | reg;
14597   add_unwind_opcode (op, 1);
14598
14599   /* Record the information for later.  */
14600   unwind.fp_reg = reg;
14601   unwind.fp_offset = unwind.frame_size;
14602   unwind.sp_restored = 1;
14603   demand_empty_rest_of_line ();
14604 }
14605
14606
14607 /* Parse #<number>.  */
14608
14609 static int
14610 require_hashconst (int * val)
14611 {
14612   expressionS exp;
14613
14614   SKIP_WHITESPACE ();
14615   if (*input_line_pointer == '#')
14616     {
14617       input_line_pointer++;
14618       expression (&exp);
14619     }
14620   else
14621     exp.X_op = O_illegal;
14622
14623   if (exp.X_op != O_constant)
14624     {
14625       as_bad (_("expected #constant"));
14626       ignore_rest_of_line ();
14627       return FAIL;
14628     }
14629   *val = exp.X_add_number;
14630   return SUCCESS;
14631 }
14632
14633 /* Parse an unwind_pad directive.  */
14634
14635 static void
14636 s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
14637 {
14638   int offset;
14639
14640   if (require_hashconst (&offset) == FAIL)
14641     return;
14642
14643   if (offset & 3)
14644     {
14645       as_bad (_("stack increment must be multiple of 4"));
14646       ignore_rest_of_line ();
14647       return;
14648     }
14649
14650   /* Don't generate any opcodes, just record the details for later.  */
14651   unwind.frame_size += offset;
14652   unwind.pending_offset += offset;
14653
14654   demand_empty_rest_of_line ();
14655 }
14656
14657 /* Parse an unwind_setfp directive.  */
14658
14659 static void
14660 s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
14661 {
14662   int sp_reg;
14663   int fp_reg;
14664   int offset;
14665
14666   fp_reg = reg_required_here (&input_line_pointer, -1);
14667   if (skip_past_comma (&input_line_pointer) == FAIL)
14668     sp_reg = FAIL;
14669   else
14670     sp_reg = reg_required_here (&input_line_pointer, -1);
14671
14672   if (fp_reg == FAIL || sp_reg == FAIL)
14673     {
14674       as_bad (_("expected <reg>, <reg>"));
14675       ignore_rest_of_line ();
14676       return;
14677     }
14678
14679   /* Optonal constant.  */
14680   if (skip_past_comma (&input_line_pointer) != FAIL)
14681     {
14682       if (require_hashconst (&offset) == FAIL)
14683         return;
14684     }
14685   else
14686     offset = 0;
14687
14688   demand_empty_rest_of_line ();
14689
14690   if (sp_reg != 13 && sp_reg != unwind.fp_reg)
14691     {
14692       as_bad (_("register must be either sp or set by a previous"
14693                 "unwind_movsp directive"));
14694       return;
14695     }
14696
14697   /* Don't generate any opcodes, just record the information for later.  */
14698   unwind.fp_reg = fp_reg;
14699   unwind.fp_used = 1;
14700   if (sp_reg == 13)
14701     unwind.fp_offset = unwind.frame_size - offset;
14702   else
14703     unwind.fp_offset -= offset;
14704 }
14705
14706 /* Parse an unwind_raw directive.  */
14707
14708 static void
14709 s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
14710 {
14711   expressionS exp;
14712   /* This is an arbitary limit.  */
14713   unsigned char op[16];
14714   int count;
14715
14716   SKIP_WHITESPACE ();
14717   expression (&exp);
14718   if (exp.X_op == O_constant
14719       && skip_past_comma (&input_line_pointer) != FAIL)
14720     {
14721       unwind.frame_size += exp.X_add_number;
14722       expression (&exp);
14723     }
14724   else
14725     exp.X_op = O_illegal;
14726
14727   if (exp.X_op != O_constant)
14728     {
14729       as_bad (_("expected <offset>, <opcode>"));
14730       ignore_rest_of_line ();
14731       return;
14732     }
14733
14734   count = 0;
14735
14736   /* Parse the opcode.  */
14737   for (;;)
14738     {
14739       if (count >= 16)
14740         {
14741           as_bad (_("unwind opcode too long"));
14742           ignore_rest_of_line ();
14743         }
14744       if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
14745         {
14746           as_bad (_("invalid unwind opcode"));
14747           ignore_rest_of_line ();
14748           return;
14749         }
14750       op[count++] = exp.X_add_number;
14751
14752       /* Parse the next byte.  */
14753       if (skip_past_comma (&input_line_pointer) == FAIL)
14754         break;
14755
14756       expression (&exp);
14757     }
14758
14759   /* Add the opcode bytes in reverse order.  */
14760   while (count--)
14761     add_unwind_opcode (op[count], 1);
14762
14763   demand_empty_rest_of_line ();
14764 }
14765
14766 #endif /* OBJ_ELF */
14767
14768 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14769    of an rs_align_code fragment.  */
14770
14771 void
14772 arm_handle_align (fragS * fragP)
14773 {
14774   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14775   static char const thumb_noop[2] = { 0xc0, 0x46 };
14776   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14777   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14778
14779   int bytes, fix, noop_size;
14780   char * p;
14781   const char * noop;
14782
14783   if (fragP->fr_type != rs_align_code)
14784     return;
14785
14786   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14787   p = fragP->fr_literal + fragP->fr_fix;
14788   fix = 0;
14789
14790   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14791     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14792
14793   if (fragP->tc_frag_data)
14794     {
14795       if (target_big_endian)
14796         noop = thumb_bigend_noop;
14797       else
14798         noop = thumb_noop;
14799       noop_size = sizeof (thumb_noop);
14800     }
14801   else
14802     {
14803       if (target_big_endian)
14804         noop = arm_bigend_noop;
14805       else
14806         noop = arm_noop;
14807       noop_size = sizeof (arm_noop);
14808     }
14809
14810   if (bytes & (noop_size - 1))
14811     {
14812       fix = bytes & (noop_size - 1);
14813       memset (p, 0, fix);
14814       p += fix;
14815       bytes -= fix;
14816     }
14817
14818   while (bytes >= noop_size)
14819     {
14820       memcpy (p, noop, noop_size);
14821       p += noop_size;
14822       bytes -= noop_size;
14823       fix += noop_size;
14824     }
14825
14826   fragP->fr_fix += fix;
14827   fragP->fr_var = noop_size;
14828 }
14829
14830 /* Called from md_do_align.  Used to create an alignment
14831    frag in a code section.  */
14832
14833 void
14834 arm_frag_align_code (int n, int max)
14835 {
14836   char * p;
14837
14838   /* We assume that there will never be a requirement
14839      to support alignments greater than 32 bytes.  */
14840   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14841     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14842
14843   p = frag_var (rs_align_code,
14844                 MAX_MEM_FOR_RS_ALIGN_CODE,
14845                 1,
14846                 (relax_substateT) max,
14847                 (symbolS *) NULL,
14848                 (offsetT) n,
14849                 (char *) NULL);
14850   *p = 0;
14851 }
14852
14853 /* Perform target specific initialisation of a frag.  */
14854
14855 void
14856 arm_init_frag (fragS * fragP)
14857 {
14858   /* Record whether this frag is in an ARM or a THUMB area.  */
14859   fragP->tc_frag_data = thumb_mode;
14860 }
14861
14862 /* This table describes all the machine specific pseudo-ops the assembler
14863    has to support.  The fields are:
14864      pseudo-op name without dot
14865      function to call to execute this pseudo-op
14866      Integer arg to pass to the function.  */
14867
14868 const pseudo_typeS md_pseudo_table[] =
14869 {
14870   /* Never called because '.req' does not start a line.  */
14871   { "req",         s_req,         0 },
14872   { "unreq",       s_unreq,       0 },
14873   { "bss",         s_bss,         0 },
14874   { "align",       s_align,       0 },
14875   { "arm",         s_arm,         0 },
14876   { "thumb",       s_thumb,       0 },
14877   { "code",        s_code,        0 },
14878   { "force_thumb", s_force_thumb, 0 },
14879   { "thumb_func",  s_thumb_func,  0 },
14880   { "thumb_set",   s_thumb_set,   0 },
14881   { "even",        s_even,        0 },
14882   { "ltorg",       s_ltorg,       0 },
14883   { "pool",        s_ltorg,       0 },
14884 #ifdef OBJ_ELF
14885   { "word",        s_arm_elf_cons, 4 },
14886   { "long",        s_arm_elf_cons, 4 },
14887   { "rel31",       s_arm_rel31,   0 },
14888   { "fnstart",          s_arm_unwind_fnstart,   0 },
14889   { "fnend",            s_arm_unwind_fnend,     0 },
14890   { "cantunwind",       s_arm_unwind_cantunwind, 0 },
14891   { "personality",      s_arm_unwind_personality, 0 },
14892   { "personalityindex", s_arm_unwind_personalityindex, 0 },
14893   { "handlerdata",      s_arm_unwind_handlerdata, 0 },
14894   { "save",             s_arm_unwind_save,      0 },
14895   { "movsp",            s_arm_unwind_movsp,     0 },
14896   { "pad",              s_arm_unwind_pad,       0 },
14897   { "setfp",            s_arm_unwind_setfp,     0 },
14898   { "unwind_raw",       s_arm_unwind_raw,       0 },
14899 #else
14900   { "word",        cons, 4},
14901 #endif
14902   { "extend",      float_cons, 'x' },
14903   { "ldouble",     float_cons, 'x' },
14904   { "packed",      float_cons, 'p' },
14905   { 0, 0, 0 }
14906 };