(mav_reg_required_here): Allow REG_TYPE_CN as alternative when REG_TYPE_MVF,
[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 enum arm_float_abi
50 {
51   ARM_FLOAT_ABI_HARD,
52   ARM_FLOAT_ABI_SOFTFP,
53   ARM_FLOAT_ABI_SOFT
54 };
55
56 /* Types of processor to assemble for.  */
57 #define ARM_1           ARM_ARCH_V1
58 #define ARM_2           ARM_ARCH_V2
59 #define ARM_3           ARM_ARCH_V2S
60 #define ARM_250         ARM_ARCH_V2S
61 #define ARM_6           ARM_ARCH_V3
62 #define ARM_7           ARM_ARCH_V3
63 #define ARM_8           ARM_ARCH_V4
64 #define ARM_9           ARM_ARCH_V4T
65 #define ARM_STRONG      ARM_ARCH_V4
66 #define ARM_CPU_MASK    0x0000000f              /* XXX? */
67
68 #ifndef CPU_DEFAULT
69 #if defined __XSCALE__
70 #define CPU_DEFAULT     (ARM_ARCH_XSCALE)
71 #else
72 #if defined __thumb__
73 #define CPU_DEFAULT     (ARM_ARCH_V5T)
74 #else
75 #define CPU_DEFAULT     ARM_ANY
76 #endif
77 #endif
78 #endif
79
80 #ifdef TE_LINUX
81 #define FPU_DEFAULT FPU_ARCH_FPA
82 #endif
83
84 #ifdef TE_NetBSD
85 #ifdef OBJ_ELF
86 #define FPU_DEFAULT FPU_ARCH_VFP        /* Soft-float, but VFP order.  */
87 #else
88 /* Legacy a.out format.  */
89 #define FPU_DEFAULT FPU_ARCH_FPA        /* Soft-float, but FPA order.  */
90 #endif
91 #endif
92
93 /* For backwards compatibility we default to the FPA.  */
94 #ifndef FPU_DEFAULT
95 #define FPU_DEFAULT FPU_ARCH_FPA
96 #endif
97
98 #define streq(a, b)           (strcmp (a, b) == 0)
99 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
100
101 static unsigned long cpu_variant;
102 static int target_oabi = 0;
103
104 /* Flags stored in private area of BFD structure.  */
105 static int uses_apcs_26      = FALSE;
106 static int atpcs             = FALSE;
107 static int support_interwork = FALSE;
108 static int uses_apcs_float   = FALSE;
109 static int pic_code          = FALSE;
110
111 /* Variables that we set while parsing command-line options.  Once all
112    options have been read we re-process these values to set the real
113    assembly flags.  */
114 static int legacy_cpu = -1;
115 static int legacy_fpu = -1;
116
117 static int mcpu_cpu_opt = -1;
118 static int mcpu_fpu_opt = -1;
119 static int march_cpu_opt = -1;
120 static int march_fpu_opt = -1;
121 static int mfpu_opt = -1;
122 static int mfloat_abi_opt = -1;
123 #ifdef OBJ_ELF
124 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
125 #endif
126
127 /* This array holds the chars that always start a comment.  If the
128    pre-processor is disabled, these aren't very useful.  */
129 const char comment_chars[] = "@";
130
131 /* This array holds the chars that only start a comment at the beginning of
132    a line.  If the line seems to have the form '# 123 filename'
133    .line and .file directives will appear in the pre-processed output.  */
134 /* Note that input_file.c hand checks for '#' at the beginning of the
135    first line of the input file.  This is because the compiler outputs
136    #NO_APP at the beginning of its output.  */
137 /* Also note that comments like this one will always work.  */
138 const char line_comment_chars[] = "#";
139
140 const char line_separator_chars[] = ";";
141
142 /* Chars that can be used to separate mant
143    from exp in floating point numbers.  */
144 const char EXP_CHARS[] = "eE";
145
146 /* Chars that mean this number is a floating point constant.  */
147 /* As in 0f12.456  */
148 /* or    0d1.2345e12  */
149
150 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
151
152 /* Prefix characters that indicate the start of an immediate
153    value.  */
154 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
155
156 #ifdef OBJ_ELF
157 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
158 symbolS * GOT_symbol;
159 #endif
160
161 /* Size of relocation record.  */
162 const int md_reloc_size = 8;
163
164 /* 0: assemble for ARM,
165    1: assemble for Thumb,
166    2: assemble for Thumb even though target CPU does not support thumb
167       instructions.  */
168 static int thumb_mode = 0;
169
170 typedef struct arm_fix
171 {
172   int thumb_mode;
173 } arm_fix_data;
174
175 struct arm_it
176 {
177   const char *  error;
178   unsigned long instruction;
179   int           size;
180   struct
181   {
182     bfd_reloc_code_real_type type;
183     expressionS              exp;
184     int                      pc_rel;
185   } reloc;
186 };
187
188 struct arm_it inst;
189
190 enum asm_shift_index
191 {
192   SHIFT_LSL = 0,
193   SHIFT_LSR,
194   SHIFT_ASR,
195   SHIFT_ROR,
196   SHIFT_RRX
197 };
198
199 struct asm_shift_properties
200 {
201   enum asm_shift_index index;
202   unsigned long        bit_field;
203   unsigned int         allows_0  : 1;
204   unsigned int         allows_32 : 1;
205 };
206
207 static const struct asm_shift_properties shift_properties [] =
208 {
209   { SHIFT_LSL, 0,    1, 0},
210   { SHIFT_LSR, 0x20, 0, 1},
211   { SHIFT_ASR, 0x40, 0, 1},
212   { SHIFT_ROR, 0x60, 0, 0},
213   { SHIFT_RRX, 0x60, 0, 0}
214 };
215
216 struct asm_shift_name
217 {
218   const char *                        name;
219   const struct asm_shift_properties * properties;
220 };
221
222 static const struct asm_shift_name shift_names [] =
223 {
224   { "asl", shift_properties + SHIFT_LSL },
225   { "lsl", shift_properties + SHIFT_LSL },
226   { "lsr", shift_properties + SHIFT_LSR },
227   { "asr", shift_properties + SHIFT_ASR },
228   { "ror", shift_properties + SHIFT_ROR },
229   { "rrx", shift_properties + SHIFT_RRX },
230   { "ASL", shift_properties + SHIFT_LSL },
231   { "LSL", shift_properties + SHIFT_LSL },
232   { "LSR", shift_properties + SHIFT_LSR },
233   { "ASR", shift_properties + SHIFT_ASR },
234   { "ROR", shift_properties + SHIFT_ROR },
235   { "RRX", shift_properties + SHIFT_RRX }
236 };
237
238 /* Any kind of shift is accepted.  */
239 #define NO_SHIFT_RESTRICT 1
240 /* The shift operand must be an immediate value, not a register.  */
241 #define SHIFT_IMMEDIATE   0
242 /* The shift must be LSL or ASR and the operand must be an immediate.  */
243 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
244 /* The shift must be ASR and the operand must be an immediate.  */
245 #define SHIFT_ASR_IMMEDIATE 3
246 /* The shift must be LSL and the operand must be an immediate.  */
247 #define SHIFT_LSL_IMMEDIATE 4
248
249 #define NUM_FLOAT_VALS 8
250
251 const char * fp_const[] =
252 {
253   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
254 };
255
256 /* Number of littlenums required to hold an extended precision number.  */
257 #define MAX_LITTLENUMS 6
258
259 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
260
261 #define FAIL    (-1)
262 #define SUCCESS (0)
263
264 /* Whether a Co-processor load/store operation accepts write-back forms.  */
265 #define CP_WB_OK 1
266 #define CP_NO_WB 0
267
268 #define SUFF_S 1
269 #define SUFF_D 2
270 #define SUFF_E 3
271 #define SUFF_P 4
272
273 #define CP_T_X   0x00008000
274 #define CP_T_Y   0x00400000
275 #define CP_T_Pre 0x01000000
276 #define CP_T_UD  0x00800000
277 #define CP_T_WB  0x00200000
278
279 #define CONDS_BIT        0x00100000
280 #define LOAD_BIT         0x00100000
281
282 #define DOUBLE_LOAD_FLAG 0x00000001
283
284 struct asm_cond
285 {
286   const char *  template;
287   unsigned long value;
288 };
289
290 #define COND_ALWAYS 0xe0000000
291 #define COND_MASK   0xf0000000
292
293 static const struct asm_cond conds[] =
294 {
295   {"eq", 0x00000000},
296   {"ne", 0x10000000},
297   {"cs", 0x20000000}, {"hs", 0x20000000},
298   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
299   {"mi", 0x40000000},
300   {"pl", 0x50000000},
301   {"vs", 0x60000000},
302   {"vc", 0x70000000},
303   {"hi", 0x80000000},
304   {"ls", 0x90000000},
305   {"ge", 0xa0000000},
306   {"lt", 0xb0000000},
307   {"gt", 0xc0000000},
308   {"le", 0xd0000000},
309   {"al", 0xe0000000},
310   {"nv", 0xf0000000}
311 };
312
313 struct asm_psr
314 {
315   const char *template;
316   bfd_boolean cpsr;
317   unsigned long field;
318 };
319
320 /* The bit that distinguishes CPSR and SPSR.  */
321 #define SPSR_BIT   (1 << 22)
322
323 /* How many bits to shift the PSR_xxx bits up by.  */
324 #define PSR_SHIFT  16
325
326 #define PSR_c   (1 << 0)
327 #define PSR_x   (1 << 1)
328 #define PSR_s   (1 << 2)
329 #define PSR_f   (1 << 3)
330
331 static const struct asm_psr psrs[] =
332 {
333   {"CPSR",      TRUE,  PSR_c | PSR_f},
334   {"CPSR_all",  TRUE,  PSR_c | PSR_f},
335   {"SPSR",      FALSE, PSR_c | PSR_f},
336   {"SPSR_all",  FALSE, PSR_c | PSR_f},
337   {"CPSR_flg",  TRUE,  PSR_f},
338   {"CPSR_f",    TRUE,  PSR_f},
339   {"SPSR_flg",  FALSE, PSR_f},
340   {"SPSR_f",    FALSE, PSR_f},
341   {"CPSR_c",    TRUE,  PSR_c},
342   {"CPSR_ctl",  TRUE,  PSR_c},
343   {"SPSR_c",    FALSE, PSR_c},
344   {"SPSR_ctl",  FALSE, PSR_c},
345   {"CPSR_x",    TRUE,  PSR_x},
346   {"CPSR_s",    TRUE,  PSR_s},
347   {"SPSR_x",    FALSE, PSR_x},
348   {"SPSR_s",    FALSE, PSR_s},
349   /* Combinations of flags.  */
350   {"CPSR_fs",   TRUE, PSR_f | PSR_s},
351   {"CPSR_fx",   TRUE, PSR_f | PSR_x},
352   {"CPSR_fc",   TRUE, PSR_f | PSR_c},
353   {"CPSR_sf",   TRUE, PSR_s | PSR_f},
354   {"CPSR_sx",   TRUE, PSR_s | PSR_x},
355   {"CPSR_sc",   TRUE, PSR_s | PSR_c},
356   {"CPSR_xf",   TRUE, PSR_x | PSR_f},
357   {"CPSR_xs",   TRUE, PSR_x | PSR_s},
358   {"CPSR_xc",   TRUE, PSR_x | PSR_c},
359   {"CPSR_cf",   TRUE, PSR_c | PSR_f},
360   {"CPSR_cs",   TRUE, PSR_c | PSR_s},
361   {"CPSR_cx",   TRUE, PSR_c | PSR_x},
362   {"CPSR_fsx",  TRUE, PSR_f | PSR_s | PSR_x},
363   {"CPSR_fsc",  TRUE, PSR_f | PSR_s | PSR_c},
364   {"CPSR_fxs",  TRUE, PSR_f | PSR_x | PSR_s},
365   {"CPSR_fxc",  TRUE, PSR_f | PSR_x | PSR_c},
366   {"CPSR_fcs",  TRUE, PSR_f | PSR_c | PSR_s},
367   {"CPSR_fcx",  TRUE, PSR_f | PSR_c | PSR_x},
368   {"CPSR_sfx",  TRUE, PSR_s | PSR_f | PSR_x},
369   {"CPSR_sfc",  TRUE, PSR_s | PSR_f | PSR_c},
370   {"CPSR_sxf",  TRUE, PSR_s | PSR_x | PSR_f},
371   {"CPSR_sxc",  TRUE, PSR_s | PSR_x | PSR_c},
372   {"CPSR_scf",  TRUE, PSR_s | PSR_c | PSR_f},
373   {"CPSR_scx",  TRUE, PSR_s | PSR_c | PSR_x},
374   {"CPSR_xfs",  TRUE, PSR_x | PSR_f | PSR_s},
375   {"CPSR_xfc",  TRUE, PSR_x | PSR_f | PSR_c},
376   {"CPSR_xsf",  TRUE, PSR_x | PSR_s | PSR_f},
377   {"CPSR_xsc",  TRUE, PSR_x | PSR_s | PSR_c},
378   {"CPSR_xcf",  TRUE, PSR_x | PSR_c | PSR_f},
379   {"CPSR_xcs",  TRUE, PSR_x | PSR_c | PSR_s},
380   {"CPSR_cfs",  TRUE, PSR_c | PSR_f | PSR_s},
381   {"CPSR_cfx",  TRUE, PSR_c | PSR_f | PSR_x},
382   {"CPSR_csf",  TRUE, PSR_c | PSR_s | PSR_f},
383   {"CPSR_csx",  TRUE, PSR_c | PSR_s | PSR_x},
384   {"CPSR_cxf",  TRUE, PSR_c | PSR_x | PSR_f},
385   {"CPSR_cxs",  TRUE, PSR_c | PSR_x | PSR_s},
386   {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
387   {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
388   {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
389   {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
390   {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
391   {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
392   {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
393   {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
394   {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
395   {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
396   {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
397   {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
398   {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
399   {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
400   {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
401   {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
402   {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
403   {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
404   {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
405   {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
406   {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
407   {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
408   {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
409   {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
410   {"SPSR_fs",   FALSE, PSR_f | PSR_s},
411   {"SPSR_fx",   FALSE, PSR_f | PSR_x},
412   {"SPSR_fc",   FALSE, PSR_f | PSR_c},
413   {"SPSR_sf",   FALSE, PSR_s | PSR_f},
414   {"SPSR_sx",   FALSE, PSR_s | PSR_x},
415   {"SPSR_sc",   FALSE, PSR_s | PSR_c},
416   {"SPSR_xf",   FALSE, PSR_x | PSR_f},
417   {"SPSR_xs",   FALSE, PSR_x | PSR_s},
418   {"SPSR_xc",   FALSE, PSR_x | PSR_c},
419   {"SPSR_cf",   FALSE, PSR_c | PSR_f},
420   {"SPSR_cs",   FALSE, PSR_c | PSR_s},
421   {"SPSR_cx",   FALSE, PSR_c | PSR_x},
422   {"SPSR_fsx",  FALSE, PSR_f | PSR_s | PSR_x},
423   {"SPSR_fsc",  FALSE, PSR_f | PSR_s | PSR_c},
424   {"SPSR_fxs",  FALSE, PSR_f | PSR_x | PSR_s},
425   {"SPSR_fxc",  FALSE, PSR_f | PSR_x | PSR_c},
426   {"SPSR_fcs",  FALSE, PSR_f | PSR_c | PSR_s},
427   {"SPSR_fcx",  FALSE, PSR_f | PSR_c | PSR_x},
428   {"SPSR_sfx",  FALSE, PSR_s | PSR_f | PSR_x},
429   {"SPSR_sfc",  FALSE, PSR_s | PSR_f | PSR_c},
430   {"SPSR_sxf",  FALSE, PSR_s | PSR_x | PSR_f},
431   {"SPSR_sxc",  FALSE, PSR_s | PSR_x | PSR_c},
432   {"SPSR_scf",  FALSE, PSR_s | PSR_c | PSR_f},
433   {"SPSR_scx",  FALSE, PSR_s | PSR_c | PSR_x},
434   {"SPSR_xfs",  FALSE, PSR_x | PSR_f | PSR_s},
435   {"SPSR_xfc",  FALSE, PSR_x | PSR_f | PSR_c},
436   {"SPSR_xsf",  FALSE, PSR_x | PSR_s | PSR_f},
437   {"SPSR_xsc",  FALSE, PSR_x | PSR_s | PSR_c},
438   {"SPSR_xcf",  FALSE, PSR_x | PSR_c | PSR_f},
439   {"SPSR_xcs",  FALSE, PSR_x | PSR_c | PSR_s},
440   {"SPSR_cfs",  FALSE, PSR_c | PSR_f | PSR_s},
441   {"SPSR_cfx",  FALSE, PSR_c | PSR_f | PSR_x},
442   {"SPSR_csf",  FALSE, PSR_c | PSR_s | PSR_f},
443   {"SPSR_csx",  FALSE, PSR_c | PSR_s | PSR_x},
444   {"SPSR_cxf",  FALSE, PSR_c | PSR_x | PSR_f},
445   {"SPSR_cxs",  FALSE, PSR_c | PSR_x | PSR_s},
446   {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
447   {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
448   {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
449   {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
450   {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
451   {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
452   {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
453   {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
454   {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
455   {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
456   {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
457   {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
458   {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
459   {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
460   {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
461   {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
462   {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
463   {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
464   {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
465   {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
466   {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
467   {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
468   {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
469   {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
470 };
471
472 enum wreg_type
473   {
474     IWMMXT_REG_WR = 0,
475     IWMMXT_REG_WC = 1,
476     IWMMXT_REG_WR_OR_WC = 2,
477     IWMMXT_REG_WCG
478   };
479
480 enum iwmmxt_insn_type
481 {
482   check_rd,
483   check_wr,
484   check_wrwr,
485   check_wrwrwr,
486   check_wrwrwcg,
487   check_tbcst,
488   check_tmovmsk,
489   check_tmia,
490   check_tmcrr,
491   check_tmrrc,
492   check_tmcr,
493   check_tmrc,
494   check_tinsr,
495   check_textrc,
496   check_waligni,
497   check_textrm,
498   check_wshufh
499 };
500
501 enum vfp_dp_reg_pos
502 {
503   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
504 };
505
506 enum vfp_sp_reg_pos
507 {
508   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
509 };
510
511 enum vfp_ldstm_type
512 {
513   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
514 };
515
516 /* VFP system registers.  */
517 struct vfp_reg
518 {
519   const char *name;
520   unsigned long regno;
521 };
522
523 static const struct vfp_reg vfp_regs[] =
524 {
525   {"fpsid", 0x00000000},
526   {"FPSID", 0x00000000},
527   {"fpscr", 0x00010000},
528   {"FPSCR", 0x00010000},
529   {"fpexc", 0x00080000},
530   {"FPEXC", 0x00080000}
531 };
532
533 /* Structure for a hash table entry for a register.  */
534 struct reg_entry
535 {
536   const char * name;
537   int          number;
538   bfd_boolean  builtin;
539 };
540
541 /* Some well known registers that we refer to directly elsewhere.  */
542 #define REG_SP  13
543 #define REG_LR  14
544 #define REG_PC  15
545
546 #define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
547 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
548 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
549
550 /* These are the standard names.  Users can add aliases with .req.
551    and delete them with .unreq.  */
552
553 /* Integer Register Numbers.  */
554 static const struct reg_entry rn_table[] =
555 {
556   {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
557   {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
558   {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
559   {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
560   /* ATPCS Synonyms.  */
561   {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
562   {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
563   {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
564   /* Well-known aliases.  */
565   {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
566   {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
567   {NULL, 0, TRUE}
568 };
569
570 #define WR_PREFIX 0x200
571 #define WC_PREFIX 0x400
572
573 static const struct reg_entry iwmmxt_table[] =
574 {
575   /* Intel Wireless MMX technology register names.  */
576   {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
577   {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
578   {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
579   {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
580   {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
581   { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
582   { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
583   { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
584   { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
585   {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
586   {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
587   {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
588
589   {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
590   {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
591   {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
592   {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
593   {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
594   { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
595   { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
596   { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
597   { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
598   {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
599   {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
600   {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
601   {NULL, 0, TRUE}
602 };
603
604 /* Co-processor Numbers.  */
605 static const struct reg_entry cp_table[] =
606 {
607   {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
608   {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
609   {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
610   {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
611   {NULL, 0, TRUE}
612 };
613
614 /* Co-processor Register Numbers.  */
615 static const struct reg_entry cn_table[] =
616 {
617   {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
618   {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
619   {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
620   {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
621   /* Not really valid, but kept for back-wards compatibility.  */
622   {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
623   {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
624   {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
625   {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
626   {NULL, 0, TRUE}
627 };
628
629 /* FPA Registers.  */
630 static const struct reg_entry fn_table[] =
631 {
632   {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
633   {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
634   {NULL, 0, TRUE}
635 };
636
637 /* VFP SP Registers.  */
638 static const struct reg_entry sn_table[] =
639 {
640   {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
641   {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
642   {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
643   {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
644   {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
645   {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
646   {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
647   {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
648   {NULL, 0, TRUE}
649 };
650
651 /* VFP DP Registers.  */
652 static const struct reg_entry dn_table[] =
653 {
654   {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
655   {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
656   {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
657   {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
658   {NULL, 0, TRUE}
659 };
660
661 /* Maverick DSP coprocessor registers.  */
662 static const struct reg_entry mav_mvf_table[] =
663 {
664   {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
665   {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
666   {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
667   {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
668   {NULL, 0, TRUE}
669 };
670
671 static const struct reg_entry mav_mvd_table[] =
672 {
673   {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
674   {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
675   {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
676   {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
677   {NULL, 0, TRUE}
678 };
679
680 static const struct reg_entry mav_mvfx_table[] =
681 {
682   {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
683   {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
684   {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
685   {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
686   {NULL, 0, TRUE}
687 };
688
689 static const struct reg_entry mav_mvdx_table[] =
690 {
691   {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
692   {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
693   {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
694   {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
695   {NULL, 0, TRUE}
696 };
697
698 static const struct reg_entry mav_mvax_table[] =
699 {
700   {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
701   {NULL, 0, TRUE}
702 };
703
704 static const struct reg_entry mav_dspsc_table[] =
705 {
706   {"dspsc", 0, TRUE},
707   {NULL, 0, TRUE}
708 };
709
710 struct reg_map
711 {
712   const struct reg_entry *names;
713   int max_regno;
714   struct hash_control *htab;
715   const char *expected;
716 };
717
718 struct reg_map all_reg_maps[] =
719 {
720   {rn_table,        15, NULL, N_("ARM register expected")},
721   {cp_table,        15, NULL, N_("bad or missing co-processor number")},
722   {cn_table,        15, NULL, N_("co-processor register expected")},
723   {fn_table,         7, NULL, N_("FPA register expected")},
724   {sn_table,        31, NULL, N_("VFP single precision register expected")},
725   {dn_table,        15, NULL, N_("VFP double precision register expected")},
726   {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
727   {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
728   {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
729   {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
730   {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
731   {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
732   {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
733 };
734
735 /* Enumeration matching entries in table above.  */
736 enum arm_reg_type
737 {
738   REG_TYPE_RN = 0,
739 #define REG_TYPE_FIRST REG_TYPE_RN
740   REG_TYPE_CP = 1,
741   REG_TYPE_CN = 2,
742   REG_TYPE_FN = 3,
743   REG_TYPE_SN = 4,
744   REG_TYPE_DN = 5,
745   REG_TYPE_MVF = 6,
746   REG_TYPE_MVD = 7,
747   REG_TYPE_MVFX = 8,
748   REG_TYPE_MVDX = 9,
749   REG_TYPE_MVAX = 10,
750   REG_TYPE_DSPSC = 11,
751   REG_TYPE_IWMMXT = 12,
752
753   REG_TYPE_MAX = 13
754 };
755
756 /* Functions called by parser.  */
757 /* ARM instructions.  */
758 static void do_arit             PARAMS ((char *));
759 static void do_cmp              PARAMS ((char *));
760 static void do_mov              PARAMS ((char *));
761 static void do_ldst             PARAMS ((char *));
762 static void do_ldstt            PARAMS ((char *));
763 static void do_ldmstm           PARAMS ((char *));
764 static void do_branch           PARAMS ((char *));
765 static void do_swi              PARAMS ((char *));
766
767 /* Pseudo Op codes.  */
768 static void do_adr              PARAMS ((char *));
769 static void do_adrl             PARAMS ((char *));
770 static void do_empty            PARAMS ((char *));
771
772 /* ARM v2.  */
773 static void do_mul              PARAMS ((char *));
774 static void do_mla              PARAMS ((char *));
775
776 /* ARM v2S.  */
777 static void do_swap             PARAMS ((char *));
778
779 /* ARM v3.  */
780 static void do_msr              PARAMS ((char *));
781 static void do_mrs              PARAMS ((char *));
782
783 /* ARM v3M.  */
784 static void do_mull             PARAMS ((char *));
785
786 /* ARM v4.  */
787 static void do_ldstv4           PARAMS ((char *));
788
789 /* ARM v4T.  */
790 static void do_bx               PARAMS ((char *));
791
792 /* ARM v5T.  */
793 static void do_blx              PARAMS ((char *));
794 static void do_bkpt             PARAMS ((char *));
795 static void do_clz              PARAMS ((char *));
796 static void do_lstc2            PARAMS ((char *));
797 static void do_cdp2             PARAMS ((char *));
798 static void do_co_reg2          PARAMS ((char *));
799
800 /* ARM v5TExP.  */
801 static void do_smla             PARAMS ((char *));
802 static void do_smlal            PARAMS ((char *));
803 static void do_smul             PARAMS ((char *));
804 static void do_qadd             PARAMS ((char *));
805
806 /* ARM v5TE.  */
807 static void do_pld              PARAMS ((char *));
808 static void do_ldrd             PARAMS ((char *));
809 static void do_co_reg2c         PARAMS ((char *));
810
811 /* ARM v5TEJ.  */
812 static void do_bxj              PARAMS ((char *));
813
814 /* ARM V6. */
815 static void do_cps              PARAMS ((char *));
816 static void do_cpsi             PARAMS ((char *));
817 static void do_ldrex            PARAMS ((char *));
818 static void do_pkhbt            PARAMS ((char *));
819 static void do_pkhtb            PARAMS ((char *));
820 static void do_qadd16           PARAMS ((char *));
821 static void do_rev              PARAMS ((char *));
822 static void do_rfe              PARAMS ((char *));
823 static void do_sxtah            PARAMS ((char *));
824 static void do_sxth             PARAMS ((char *));
825 static void do_setend           PARAMS ((char *));
826 static void do_smlad            PARAMS ((char *));
827 static void do_smlald           PARAMS ((char *));
828 static void do_smmul            PARAMS ((char *));
829 static void do_ssat             PARAMS ((char *));
830 static void do_usat             PARAMS ((char *));
831 static void do_srs              PARAMS ((char *));
832 static void do_ssat16           PARAMS ((char *));
833 static void do_usat16           PARAMS ((char *));
834 static void do_strex            PARAMS ((char *));
835 static void do_umaal            PARAMS ((char *));
836
837 static void do_cps_mode         PARAMS ((char **));
838 static void do_cps_flags        PARAMS ((char **, int));
839 static int do_endian_specifier  PARAMS ((char *));
840 static void do_pkh_core         PARAMS ((char *, int));
841 static void do_sat              PARAMS ((char **, int));
842 static void do_sat16            PARAMS ((char **, int));
843
844 /* Coprocessor Instructions.  */
845 static void do_cdp              PARAMS ((char *));
846 static void do_lstc             PARAMS ((char *));
847 static void do_co_reg           PARAMS ((char *));
848
849 /* FPA instructions.  */
850 static void do_fpa_ctrl         PARAMS ((char *));
851 static void do_fpa_ldst         PARAMS ((char *));
852 static void do_fpa_ldmstm       PARAMS ((char *));
853 static void do_fpa_dyadic       PARAMS ((char *));
854 static void do_fpa_monadic      PARAMS ((char *));
855 static void do_fpa_cmp          PARAMS ((char *));
856 static void do_fpa_from_reg     PARAMS ((char *));
857 static void do_fpa_to_reg       PARAMS ((char *));
858
859 /* VFP instructions.  */
860 static void do_vfp_sp_monadic   PARAMS ((char *));
861 static void do_vfp_dp_monadic   PARAMS ((char *));
862 static void do_vfp_sp_dyadic    PARAMS ((char *));
863 static void do_vfp_dp_dyadic    PARAMS ((char *));
864 static void do_vfp_reg_from_sp  PARAMS ((char *));
865 static void do_vfp_sp_from_reg  PARAMS ((char *));
866 static void do_vfp_reg2_from_sp2 PARAMS ((char *));
867 static void do_vfp_sp2_from_reg2 PARAMS ((char *));
868 static void do_vfp_reg_from_dp  PARAMS ((char *));
869 static void do_vfp_reg2_from_dp PARAMS ((char *));
870 static void do_vfp_dp_from_reg  PARAMS ((char *));
871 static void do_vfp_dp_from_reg2 PARAMS ((char *));
872 static void do_vfp_reg_from_ctrl PARAMS ((char *));
873 static void do_vfp_ctrl_from_reg PARAMS ((char *));
874 static void do_vfp_sp_ldst      PARAMS ((char *));
875 static void do_vfp_dp_ldst      PARAMS ((char *));
876 static void do_vfp_sp_ldstmia   PARAMS ((char *));
877 static void do_vfp_sp_ldstmdb   PARAMS ((char *));
878 static void do_vfp_dp_ldstmia   PARAMS ((char *));
879 static void do_vfp_dp_ldstmdb   PARAMS ((char *));
880 static void do_vfp_xp_ldstmia   PARAMS ((char *));
881 static void do_vfp_xp_ldstmdb   PARAMS ((char *));
882 static void do_vfp_sp_compare_z PARAMS ((char *));
883 static void do_vfp_dp_compare_z PARAMS ((char *));
884 static void do_vfp_dp_sp_cvt    PARAMS ((char *));
885 static void do_vfp_sp_dp_cvt    PARAMS ((char *));
886
887 /* XScale.  */
888 static void do_xsc_mia          PARAMS ((char *));
889 static void do_xsc_mar          PARAMS ((char *));
890 static void do_xsc_mra          PARAMS ((char *));
891
892 /* Maverick.  */
893 static void do_mav_binops       PARAMS ((char *, int, enum arm_reg_type,
894                                          enum arm_reg_type));
895 static void do_mav_binops_1a    PARAMS ((char *));
896 static void do_mav_binops_1b    PARAMS ((char *));
897 static void do_mav_binops_1c    PARAMS ((char *));
898 static void do_mav_binops_1d    PARAMS ((char *));
899 static void do_mav_binops_1e    PARAMS ((char *));
900 static void do_mav_binops_1f    PARAMS ((char *));
901 static void do_mav_binops_1g    PARAMS ((char *));
902 static void do_mav_binops_1h    PARAMS ((char *));
903 static void do_mav_binops_1i    PARAMS ((char *));
904 static void do_mav_binops_1j    PARAMS ((char *));
905 static void do_mav_binops_1k    PARAMS ((char *));
906 static void do_mav_binops_1l    PARAMS ((char *));
907 static void do_mav_binops_1m    PARAMS ((char *));
908 static void do_mav_binops_1n    PARAMS ((char *));
909 static void do_mav_binops_1o    PARAMS ((char *));
910 static void do_mav_binops_2a    PARAMS ((char *));
911 static void do_mav_binops_2b    PARAMS ((char *));
912 static void do_mav_binops_2c    PARAMS ((char *));
913 static void do_mav_binops_3a    PARAMS ((char *));
914 static void do_mav_binops_3b    PARAMS ((char *));
915 static void do_mav_binops_3c    PARAMS ((char *));
916 static void do_mav_binops_3d    PARAMS ((char *));
917 static void do_mav_triple       PARAMS ((char *, int, enum arm_reg_type,
918                                          enum arm_reg_type,
919                                          enum arm_reg_type));
920 static void do_mav_triple_4a    PARAMS ((char *));
921 static void do_mav_triple_4b    PARAMS ((char *));
922 static void do_mav_triple_5a    PARAMS ((char *));
923 static void do_mav_triple_5b    PARAMS ((char *));
924 static void do_mav_triple_5c    PARAMS ((char *));
925 static void do_mav_triple_5d    PARAMS ((char *));
926 static void do_mav_triple_5e    PARAMS ((char *));
927 static void do_mav_triple_5f    PARAMS ((char *));
928 static void do_mav_triple_5g    PARAMS ((char *));
929 static void do_mav_triple_5h    PARAMS ((char *));
930 static void do_mav_quad         PARAMS ((char *, int, enum arm_reg_type,
931                                          enum arm_reg_type,
932                                          enum arm_reg_type,
933                                          enum arm_reg_type));
934 static void do_mav_quad_6a      PARAMS ((char *));
935 static void do_mav_quad_6b      PARAMS ((char *));
936 static void do_mav_dspsc_1      PARAMS ((char *));
937 static void do_mav_dspsc_2      PARAMS ((char *));
938 static void do_mav_shift        PARAMS ((char *, enum arm_reg_type,
939                                          enum arm_reg_type));
940 static void do_mav_shift_1      PARAMS ((char *));
941 static void do_mav_shift_2      PARAMS ((char *));
942 static void do_mav_ldst         PARAMS ((char *, enum arm_reg_type));
943 static void do_mav_ldst_1       PARAMS ((char *));
944 static void do_mav_ldst_2       PARAMS ((char *));
945 static void do_mav_ldst_3       PARAMS ((char *));
946 static void do_mav_ldst_4       PARAMS ((char *));
947
948 static int mav_reg_required_here        PARAMS ((char **, int,
949                                                  enum arm_reg_type));
950 static int mav_parse_offset     PARAMS ((char **, int *));
951
952 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *,
953                                          int, int));
954 static int arm_reg_parse        PARAMS ((char **, struct hash_control *));
955 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
956 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
957 static void symbol_locate       PARAMS ((symbolS *, const char *, segT, valueT,
958                                          fragS *));
959 static int add_to_lit_pool      PARAMS ((void));
960 static unsigned validate_immediate PARAMS ((unsigned));
961 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
962                                                     unsigned int *));
963 static int validate_offset_imm  PARAMS ((unsigned int, int));
964 static void opcode_select       PARAMS ((int));
965 static void end_of_line         PARAMS ((char *));
966 static int reg_required_here    PARAMS ((char **, int));
967 static int psr_required_here    PARAMS ((char **));
968 static int co_proc_number       PARAMS ((char **));
969 static int cp_opc_expr          PARAMS ((char **, int, int));
970 static int cp_reg_required_here PARAMS ((char **, int));
971 static int fp_reg_required_here PARAMS ((char **, int));
972 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
973 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
974 static void vfp_sp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
975 static void vfp_dp_ldstm        PARAMS ((char *, enum vfp_ldstm_type));
976 static long vfp_sp_reg_list     PARAMS ((char **, enum vfp_sp_reg_pos));
977 static long vfp_dp_reg_list     PARAMS ((char **));
978 static int vfp_psr_required_here PARAMS ((char **str));
979 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
980 static int cp_address_offset    PARAMS ((char **));
981 static int cp_address_required_here     PARAMS ((char **, int));
982 static int my_get_float_expression      PARAMS ((char **));
983 static int skip_past_comma      PARAMS ((char **));
984 static int walk_no_bignums      PARAMS ((symbolS *));
985 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
986 static int data_op2             PARAMS ((char **));
987 static int fp_op2               PARAMS ((char **));
988 static long reg_list            PARAMS ((char **));
989 static void thumb_load_store    PARAMS ((char *, int, int));
990 static int decode_shift         PARAMS ((char **, int));
991 static int ldst_extend          PARAMS ((char **));
992 static int ldst_extend_v4               PARAMS ((char **));
993 static void thumb_add_sub       PARAMS ((char *, int));
994 static void insert_reg          PARAMS ((const struct reg_entry *,
995                                          struct hash_control *));
996 static void thumb_shift         PARAMS ((char *, int));
997 static void thumb_mov_compare   PARAMS ((char *, int));
998 static void build_arm_ops_hsh   PARAMS ((void));
999 static void set_constant_flonums        PARAMS ((void));
1000 static valueT md_chars_to_number        PARAMS ((char *, int));
1001 static void build_reg_hsh       PARAMS ((struct reg_map *));
1002 static void insert_reg_alias    PARAMS ((char *, int, struct hash_control *));
1003 static int create_register_alias        PARAMS ((char *, char *));
1004 static void output_inst         PARAMS ((const char *));
1005 static int accum0_required_here PARAMS ((char **));
1006 static int ld_mode_required_here PARAMS ((char **));
1007 static void do_branch25         PARAMS ((char *));
1008 static symbolS * find_real_start PARAMS ((symbolS *));
1009 #ifdef OBJ_ELF
1010 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1011 #endif
1012
1013 static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1014 static void do_iwmmxt_byte_addr PARAMS ((char *));
1015 static void do_iwmmxt_tandc     PARAMS ((char *));
1016 static void do_iwmmxt_tbcst     PARAMS ((char *));
1017 static void do_iwmmxt_textrc    PARAMS ((char *));
1018 static void do_iwmmxt_textrm    PARAMS ((char *));
1019 static void do_iwmmxt_tinsr     PARAMS ((char *));
1020 static void do_iwmmxt_tmcr      PARAMS ((char *));
1021 static void do_iwmmxt_tmcrr     PARAMS ((char *));
1022 static void do_iwmmxt_tmia      PARAMS ((char *));
1023 static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1024 static void do_iwmmxt_tmrc      PARAMS ((char *));
1025 static void do_iwmmxt_tmrrc     PARAMS ((char *));
1026 static void do_iwmmxt_torc      PARAMS ((char *));
1027 static void do_iwmmxt_waligni   PARAMS ((char *));
1028 static void do_iwmmxt_wmov      PARAMS ((char *));
1029 static void do_iwmmxt_word_addr PARAMS ((char *));
1030 static void do_iwmmxt_wrwr      PARAMS ((char *));
1031 static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1032 static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1033 static void do_iwmmxt_wshufh    PARAMS ((char *));
1034 static void do_iwmmxt_wzero     PARAMS ((char *));
1035 static int cp_byte_address_offset         PARAMS ((char **));
1036 static int cp_byte_address_required_here  PARAMS ((char **));
1037
1038 /* ARM instructions take 4bytes in the object file, Thumb instructions
1039    take 2:  */
1040 #define INSN_SIZE       4
1041
1042 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1043 #define MAV_MODE1       0x100c
1044
1045 /* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1046 #define MAV_MODE2       0x0c10
1047
1048 /* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1049 #define MAV_MODE3       0x100c
1050
1051 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1052 #define MAV_MODE4       0x0c0010
1053
1054 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1055 #define MAV_MODE5       0x00100c
1056
1057 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1058 #define MAV_MODE6       0x00100c05
1059
1060 struct asm_opcode
1061 {
1062   /* Basic string to match.  */
1063   const char * template;
1064
1065   /* Basic instruction code.  */
1066   unsigned long value;
1067
1068   /* Offset into the template where the condition code (if any) will be.
1069      If zero, then the instruction is never conditional.  */
1070   unsigned cond_offset;
1071
1072   /* Which architecture variant provides this instruction.  */
1073   unsigned long variant;
1074
1075   /* Function to call to parse args.  */
1076   void (* parms) PARAMS ((char *));
1077 };
1078
1079 static const struct asm_opcode insns[] =
1080 {
1081   /* Core ARM Instructions.  */
1082   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1083   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1084   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1085   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1086   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1087   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1088   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1089   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1090   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1091   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1092   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1093   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1094   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1095   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1096   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1097   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1098   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1099   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1100   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1101   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1102
1103   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1104   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1105   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1106   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1107   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1108   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1109   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1110   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1111   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1112   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1113   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1114   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1115
1116   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1117   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1118   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1119   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1120
1121   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1122   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1123   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1124   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1125   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1126   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1127   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1128   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1129
1130   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1131   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1132   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1133   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1134   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1135   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1136   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1137   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1138
1139   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1140   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1141   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1142   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1143   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1144   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1145   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1146   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1147
1148   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1149 #ifdef TE_WINCE
1150   /* XXX This is the wrong place to do this.  Think multi-arch.  */
1151   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1152   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1153 #else
1154   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1155   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1156 #endif
1157
1158   /* Pseudo ops.  */
1159   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1160   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1161   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1162
1163   /* ARM 2 multiplies.  */
1164   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1165   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1166   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1167   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1168
1169   /* Generic coprocessor instructions.  */
1170   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1171   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1172   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1173   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1174   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1175   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1176   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1177
1178   /* ARM 3 - swp instructions.  */
1179   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1180   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1181
1182   /* ARM 6 Status register instructions.  */
1183   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1184   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1185   /* ScottB: our code uses     0xe128f000 for msr.
1186      NickC:  but this is wrong because the bits 16 through 19 are
1187              handled by the PSR_xxx defines above.  */
1188
1189   /* ARM 7M long multiplies.  */
1190   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1191   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1192   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1193   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1194   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1195   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1196   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1197   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1198
1199   /* ARM Architecture 4.  */
1200   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1201   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1202   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1203   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1204
1205   /* ARM Architecture 4T.  */
1206   /* Note: bx (and blx) are required on V5, even if the processor does
1207      not support Thumb.  */
1208   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1209
1210   /*  ARM Architecture 5T.  */
1211   /* Note: blx has 2 variants, so the .value is set dynamically.
1212      Only one of the variants has conditional execution.  */
1213   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1214   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1215   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1216   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1217   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1218   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1219   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1220   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1221   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1222   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1223
1224   /*  ARM Architecture 5TExP.  */
1225   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1226   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1227   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1228   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1229
1230   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1231   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1232
1233   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1234   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1235   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1236   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1237
1238   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1239   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1240   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1241   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1242
1243   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1244   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1245
1246   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1247   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1248   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1249   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1250
1251   /*  ARM Architecture 5TE.  */
1252   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1253   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1254   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1255
1256   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1257   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1258
1259   /*  ARM Architecture 5TEJ.  */
1260   {"bxj",        0xe12fff20, 3,  ARM_EXT_V5J,      do_bxj},
1261
1262   /*  ARM V6.  */
1263   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1264   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1265   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1266   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1267   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1268   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1269   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1270   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1271   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1272   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1273   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1274   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1275   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1276   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1277   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1278   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1279   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1280   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1281   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1282   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1283   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1284   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1285   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1286   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1287   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1288   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1289   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1290   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1291   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1292   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1293   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1294   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1295   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1296   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1297   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1298   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1299   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1300   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1301   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1302   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1303   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1304   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1305   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1306   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1307   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1308   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1309   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1310   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1311   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1312   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1313   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1314   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1315   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1316   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1317   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1318   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1319   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1320   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1321   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1322   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1323   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1324   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1325   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1326   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1327   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1328   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1329   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1330   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1331   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1332   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1333   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1334   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1335   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1336   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1337   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1338   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1339   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1340   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1341   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1342   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1343   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1344   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1345   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1346   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1347   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1348   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1349   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1350   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1351   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1352   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1353   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1354   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1355   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1356   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1357   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1358   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1359   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1360   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1361   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1362
1363   /* Core FPA instruction set (V1).  */
1364   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1365   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1366   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1367   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1368
1369   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1370   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1371   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1372   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1373
1374   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1375   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1376   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1377   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1378
1379   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1380   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1381   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1382   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1383   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1384   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1385   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1386   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1387   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1388   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1389   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1390   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1391
1392   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1393   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1394   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1395   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1396   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1397   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1398   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1399   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1400   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1401   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1402   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1403   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1404
1405   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1406   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1407   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1408   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1409   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1410   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1411   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1412   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1413   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1414   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1415   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1416   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1417
1418   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1419   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1420   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1421   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1422   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1423   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1424   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1425   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1426   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1427   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1428   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1429   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1430
1431   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1432   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1433   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1434   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1435   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1436   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1437   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1438   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1439   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1440   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1441   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1442   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1443
1444   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1445   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1446   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1447   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1448   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1449   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1450   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456
1457   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1460   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1463   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469
1470   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1473   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1476   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482
1483   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1486   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1489   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495
1496   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1499   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1502   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508
1509   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1512   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1515   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521
1522   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1525   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1528   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534
1535   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1538   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1541   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547
1548   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1551   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1554   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560
1561   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1564   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1567   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573
1574   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1577   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1580   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586
1587   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1588   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1589   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1590   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1591   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1592   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1593   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1594   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1595   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1596   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1597   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1598   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1599
1600   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1601   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1602   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1603   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1604   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1605   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1606   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1607   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1608   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1609   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1610   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1611   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1612
1613   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1614   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1615   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1616   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1617   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1618   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1619   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1620   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1621   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1622   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1623   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1624   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1625
1626   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1627   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1628   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1629   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1630   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1631   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1632   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1633   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1634   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1635   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1636   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1637   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1638
1639   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1640   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1641   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1642   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1643   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1644   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1645   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1646   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1647   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1648   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1649   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1650   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1651
1652   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1653   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1654   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1655   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1656   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1657   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1658   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664
1665   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1668   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1671   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677
1678   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1681   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1684   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690
1691   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1694   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1697   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703
1704   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1707   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1710   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716
1717   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1720   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1723   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729
1730   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1733   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1736   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742
1743   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1746   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1749   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755
1756   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1757   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1758   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1759   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1760   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1761      not be an optional suffix, but part of the instruction.  To be
1762      compatible, we accept either.  */
1763   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1764   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1765
1766   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1767   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1768   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1769   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1770   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1771   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1772   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1773   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1774   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1775   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1776   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1777   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1778
1779   /* The implementation of the FIX instruction is broken on some
1780      assemblers, in that it accepts a precision specifier as well as a
1781      rounding specifier, despite the fact that this is meaningless.
1782      To be more compatible, we accept it as well, though of course it
1783      does not set any bits.  */
1784   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1785   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1786   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1787   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1788   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1789   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1790   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1791   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1792   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1793   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1794   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1795   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1796   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1797
1798   /* Instructions that were new with the real FPA, call them V2.  */
1799   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1800   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1801   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1802   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1803   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1804   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1805
1806   /* VFP V1xD (single precision).  */
1807   /* Moves and type conversions.  */
1808   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1809   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1810   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1811   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1812   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1813   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1814   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1815   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1816   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1817   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1818   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1819   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1820
1821   /* Memory operations.  */
1822   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1823   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1824   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1825   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1826   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1827   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1828   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1829   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1830   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1831   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1832   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1833   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1834   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1835   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1836   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1837   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1838   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1839   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1840
1841   /* Monadic operations.  */
1842   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1843   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1844   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1845
1846   /* Dyadic operations.  */
1847   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1848   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1849   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1850   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1851   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1852   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1853   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1854   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1855   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1856
1857   /* Comparisons.  */
1858   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1859   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1860   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1861   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1862
1863   /* VFP V1 (Double precision).  */
1864   /* Moves and type conversions.  */
1865   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1866   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1867   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1868   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1869   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1870   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1871   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1872   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1873   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1874   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1875   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1876   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1877   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1878
1879   /* Memory operations.  */
1880   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1881   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1882   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1883   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1884   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1885   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1886   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1887   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1888   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1889   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1890
1891   /* Monadic operations.  */
1892   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1893   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1894   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1895
1896   /* Dyadic operations.  */
1897   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1898   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1899   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1900   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1901   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1902   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1903   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1904   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1905   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1906
1907   /* Comparisons.  */
1908   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1909   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1910   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1911   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1912
1913   /* VFP V2.  */
1914   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
1915   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
1916   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1917   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1918
1919   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1920   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1921   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1922   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1923   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1924   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1925   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1926   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1927   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1928
1929   /* Intel Wireless MMX technology instructions.  */
1930   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1931   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1932   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1933   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1934   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1935   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1936   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1937   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1938   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1939   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1940   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1941   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1942   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1943   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1944   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1945   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1946   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1947   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1948   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
1949   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
1950   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1951   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1952   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1953   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1954   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1955   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1956   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1957   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1958   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1959   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
1960   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
1961   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1962   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1963   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1964   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1965   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1966   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1967   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1968   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1969   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1970   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1971   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1972   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1973   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1974   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1975   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1976   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
1977   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1978   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1979   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1980   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1981   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1982   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1983   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1984   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1985   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1986   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1987   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1988   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1989   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1990   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1991   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1992   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1993   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1994   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1995   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1996   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1997   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1998   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1999   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2000   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2001   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2002   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2003   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2004   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2005   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2006   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2007   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2008   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2009   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2010   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2011   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2012   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2013   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2014   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2015   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2016   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2017   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2018   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2019   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2020   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2021   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2022   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2023   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2024   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2025   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2026   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2027   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2028   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2029   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2030   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2031   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2032   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2033   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2034   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2035   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2036   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2041   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2043   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2045   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2047   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2049   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2051   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2053   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2055   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2057   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2059   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2060   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2061   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2062   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2063   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2065   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2066   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2067   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2068   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2069   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2073   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2074   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2075   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2076   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2077   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2078   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2082   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2083   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2084   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2085   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2086   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2087   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2092
2093   /* Cirrus Maverick instructions.  */
2094   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2095   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2096   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2097   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2098   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2099   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2100   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2101   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2102   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2103   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2104   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2105   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2106   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2107   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2108   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2109   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2110   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2111   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2112   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2113   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2114   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2115   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2116   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2117   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2118   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2119   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2120   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2121   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2122   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2123   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2124   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2125   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2126   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2127   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2128   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2129   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2130   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2131   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2132   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2133   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2134   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2135   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2136   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2137   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2138   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2139   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2140   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2141   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2142   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2143   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2144   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2145   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2146   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2147   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2148   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2149   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2150   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2151   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2152   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2153   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2154   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2155   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2156   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2157   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2158   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2159   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2160   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2161   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2162   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2163   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2164   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2165   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2166   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2167   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2168   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2169   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2170 };
2171
2172 /* Defines for various bits that we will want to toggle.  */
2173 #define INST_IMMEDIATE  0x02000000
2174 #define OFFSET_REG      0x02000000
2175 #define HWOFFSET_IMM    0x00400000
2176 #define SHIFT_BY_REG    0x00000010
2177 #define PRE_INDEX       0x01000000
2178 #define INDEX_UP        0x00800000
2179 #define WRITE_BACK      0x00200000
2180 #define LDM_TYPE_2_OR_3 0x00400000
2181
2182 #define LITERAL_MASK    0xf000f000
2183 #define OPCODE_MASK     0xfe1fffff
2184 #define V4_STR_BIT      0x00000020
2185
2186 #define DATA_OP_SHIFT   21
2187
2188 /* Codes to distinguish the arithmetic instructions.  */
2189 #define OPCODE_AND      0
2190 #define OPCODE_EOR      1
2191 #define OPCODE_SUB      2
2192 #define OPCODE_RSB      3
2193 #define OPCODE_ADD      4
2194 #define OPCODE_ADC      5
2195 #define OPCODE_SBC      6
2196 #define OPCODE_RSC      7
2197 #define OPCODE_TST      8
2198 #define OPCODE_TEQ      9
2199 #define OPCODE_CMP      10
2200 #define OPCODE_CMN      11
2201 #define OPCODE_ORR      12
2202 #define OPCODE_MOV      13
2203 #define OPCODE_BIC      14
2204 #define OPCODE_MVN      15
2205
2206 /* Thumb v1 (ARMv4T).  */
2207 static void do_t_nop            PARAMS ((char *));
2208 static void do_t_arit           PARAMS ((char *));
2209 static void do_t_add            PARAMS ((char *));
2210 static void do_t_asr            PARAMS ((char *));
2211 static void do_t_branch9        PARAMS ((char *));
2212 static void do_t_branch12       PARAMS ((char *));
2213 static void do_t_branch23       PARAMS ((char *));
2214 static void do_t_bx             PARAMS ((char *));
2215 static void do_t_compare        PARAMS ((char *));
2216 static void do_t_ldmstm         PARAMS ((char *));
2217 static void do_t_ldr            PARAMS ((char *));
2218 static void do_t_ldrb           PARAMS ((char *));
2219 static void do_t_ldrh           PARAMS ((char *));
2220 static void do_t_lds            PARAMS ((char *));
2221 static void do_t_lsl            PARAMS ((char *));
2222 static void do_t_lsr            PARAMS ((char *));
2223 static void do_t_mov            PARAMS ((char *));
2224 static void do_t_push_pop       PARAMS ((char *));
2225 static void do_t_str            PARAMS ((char *));
2226 static void do_t_strb           PARAMS ((char *));
2227 static void do_t_strh           PARAMS ((char *));
2228 static void do_t_sub            PARAMS ((char *));
2229 static void do_t_swi            PARAMS ((char *));
2230 static void do_t_adr            PARAMS ((char *));
2231
2232 /* Thumb v2 (ARMv5T).  */
2233 static void do_t_blx            PARAMS ((char *));
2234 static void do_t_bkpt           PARAMS ((char *));
2235
2236 /* ARM V6.  */
2237 static void do_t_cps            PARAMS ((char *));
2238 static void do_t_cpy            PARAMS ((char *));
2239 static void do_t_setend         PARAMS ((char *));;
2240
2241 #define T_OPCODE_MUL 0x4340
2242 #define T_OPCODE_TST 0x4200
2243 #define T_OPCODE_CMN 0x42c0
2244 #define T_OPCODE_NEG 0x4240
2245 #define T_OPCODE_MVN 0x43c0
2246
2247 #define T_OPCODE_ADD_R3 0x1800
2248 #define T_OPCODE_SUB_R3 0x1a00
2249 #define T_OPCODE_ADD_HI 0x4400
2250 #define T_OPCODE_ADD_ST 0xb000
2251 #define T_OPCODE_SUB_ST 0xb080
2252 #define T_OPCODE_ADD_SP 0xa800
2253 #define T_OPCODE_ADD_PC 0xa000
2254 #define T_OPCODE_ADD_I8 0x3000
2255 #define T_OPCODE_SUB_I8 0x3800
2256 #define T_OPCODE_ADD_I3 0x1c00
2257 #define T_OPCODE_SUB_I3 0x1e00
2258
2259 #define T_OPCODE_ASR_R  0x4100
2260 #define T_OPCODE_LSL_R  0x4080
2261 #define T_OPCODE_LSR_R  0x40c0
2262 #define T_OPCODE_ASR_I  0x1000
2263 #define T_OPCODE_LSL_I  0x0000
2264 #define T_OPCODE_LSR_I  0x0800
2265
2266 #define T_OPCODE_MOV_I8 0x2000
2267 #define T_OPCODE_CMP_I8 0x2800
2268 #define T_OPCODE_CMP_LR 0x4280
2269 #define T_OPCODE_MOV_HR 0x4600
2270 #define T_OPCODE_CMP_HR 0x4500
2271
2272 #define T_OPCODE_LDR_PC 0x4800
2273 #define T_OPCODE_LDR_SP 0x9800
2274 #define T_OPCODE_STR_SP 0x9000
2275 #define T_OPCODE_LDR_IW 0x6800
2276 #define T_OPCODE_STR_IW 0x6000
2277 #define T_OPCODE_LDR_IH 0x8800
2278 #define T_OPCODE_STR_IH 0x8000
2279 #define T_OPCODE_LDR_IB 0x7800
2280 #define T_OPCODE_STR_IB 0x7000
2281 #define T_OPCODE_LDR_RW 0x5800
2282 #define T_OPCODE_STR_RW 0x5000
2283 #define T_OPCODE_LDR_RH 0x5a00
2284 #define T_OPCODE_STR_RH 0x5200
2285 #define T_OPCODE_LDR_RB 0x5c00
2286 #define T_OPCODE_STR_RB 0x5400
2287
2288 #define T_OPCODE_PUSH   0xb400
2289 #define T_OPCODE_POP    0xbc00
2290
2291 #define T_OPCODE_BRANCH 0xe7fe
2292
2293 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
2294
2295 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
2296 #define THUMB_REG_LO    0x1
2297 #define THUMB_REG_HI    0x2
2298 #define THUMB_REG_ANY   0x3
2299
2300 #define THUMB_H1        0x0080
2301 #define THUMB_H2        0x0040
2302
2303 #define THUMB_ASR 0
2304 #define THUMB_LSL 1
2305 #define THUMB_LSR 2
2306
2307 #define THUMB_MOVE 0
2308 #define THUMB_COMPARE 1
2309 #define THUMB_CPY 2
2310
2311 #define THUMB_LOAD 0
2312 #define THUMB_STORE 1
2313
2314 #define THUMB_PP_PC_LR 0x0100
2315
2316 /* These three are used for immediate shifts, do not alter.  */
2317 #define THUMB_WORD 2
2318 #define THUMB_HALFWORD 1
2319 #define THUMB_BYTE 0
2320
2321 struct thumb_opcode
2322 {
2323   /* Basic string to match.  */
2324   const char * template;
2325
2326   /* Basic instruction code.  */
2327   unsigned long value;
2328
2329   int size;
2330
2331   /* Which CPU variants this exists for.  */
2332   unsigned long variant;
2333
2334   /* Function to call to parse args.  */
2335   void (* parms) PARAMS ((char *));
2336 };
2337
2338 static const struct thumb_opcode tinsns[] =
2339 {
2340   /* Thumb v1 (ARMv4T).  */
2341   {"adc",       0x4140,         2,      ARM_EXT_V4T, do_t_arit},
2342   {"add",       0x0000,         2,      ARM_EXT_V4T, do_t_add},
2343   {"and",       0x4000,         2,      ARM_EXT_V4T, do_t_arit},
2344   {"asr",       0x0000,         2,      ARM_EXT_V4T, do_t_asr},
2345   {"b",         T_OPCODE_BRANCH, 2,     ARM_EXT_V4T, do_t_branch12},
2346   {"beq",       0xd0fe,         2,      ARM_EXT_V4T, do_t_branch9},
2347   {"bne",       0xd1fe,         2,      ARM_EXT_V4T, do_t_branch9},
2348   {"bcs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2349   {"bhs",       0xd2fe,         2,      ARM_EXT_V4T, do_t_branch9},
2350   {"bcc",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2351   {"bul",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2352   {"blo",       0xd3fe,         2,      ARM_EXT_V4T, do_t_branch9},
2353   {"bmi",       0xd4fe,         2,      ARM_EXT_V4T, do_t_branch9},
2354   {"bpl",       0xd5fe,         2,      ARM_EXT_V4T, do_t_branch9},
2355   {"bvs",       0xd6fe,         2,      ARM_EXT_V4T, do_t_branch9},
2356   {"bvc",       0xd7fe,         2,      ARM_EXT_V4T, do_t_branch9},
2357   {"bhi",       0xd8fe,         2,      ARM_EXT_V4T, do_t_branch9},
2358   {"bls",       0xd9fe,         2,      ARM_EXT_V4T, do_t_branch9},
2359   {"bge",       0xdafe,         2,      ARM_EXT_V4T, do_t_branch9},
2360   {"blt",       0xdbfe,         2,      ARM_EXT_V4T, do_t_branch9},
2361   {"bgt",       0xdcfe,         2,      ARM_EXT_V4T, do_t_branch9},
2362   {"ble",       0xddfe,         2,      ARM_EXT_V4T, do_t_branch9},
2363   {"bal",       0xdefe,         2,      ARM_EXT_V4T, do_t_branch9},
2364   {"bic",       0x4380,         2,      ARM_EXT_V4T, do_t_arit},
2365   {"bl",        0xf7fffffe,     4,      ARM_EXT_V4T, do_t_branch23},
2366   {"bx",        0x4700,         2,      ARM_EXT_V4T, do_t_bx},
2367   {"cmn",       T_OPCODE_CMN,   2,      ARM_EXT_V4T, do_t_arit},
2368   {"cmp",       0x0000,         2,      ARM_EXT_V4T, do_t_compare},
2369   {"eor",       0x4040,         2,      ARM_EXT_V4T, do_t_arit},
2370   {"ldmia",     0xc800,         2,      ARM_EXT_V4T, do_t_ldmstm},
2371   {"ldr",       0x0000,         2,      ARM_EXT_V4T, do_t_ldr},
2372   {"ldrb",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrb},
2373   {"ldrh",      0x0000,         2,      ARM_EXT_V4T, do_t_ldrh},
2374   {"ldrsb",     0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2375   {"ldrsh",     0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2376   {"ldsb",      0x5600,         2,      ARM_EXT_V4T, do_t_lds},
2377   {"ldsh",      0x5e00,         2,      ARM_EXT_V4T, do_t_lds},
2378   {"lsl",       0x0000,         2,      ARM_EXT_V4T, do_t_lsl},
2379   {"lsr",       0x0000,         2,      ARM_EXT_V4T, do_t_lsr},
2380   {"mov",       0x0000,         2,      ARM_EXT_V4T, do_t_mov},
2381   {"mul",       T_OPCODE_MUL,   2,      ARM_EXT_V4T, do_t_arit},
2382   {"mvn",       T_OPCODE_MVN,   2,      ARM_EXT_V4T, do_t_arit},
2383   {"neg",       T_OPCODE_NEG,   2,      ARM_EXT_V4T, do_t_arit},
2384   {"orr",       0x4300,         2,      ARM_EXT_V4T, do_t_arit},
2385   {"pop",       0xbc00,         2,      ARM_EXT_V4T, do_t_push_pop},
2386   {"push",      0xb400,         2,      ARM_EXT_V4T, do_t_push_pop},
2387   {"ror",       0x41c0,         2,      ARM_EXT_V4T, do_t_arit},
2388   {"sbc",       0x4180,         2,      ARM_EXT_V4T, do_t_arit},
2389   {"stmia",     0xc000,         2,      ARM_EXT_V4T, do_t_ldmstm},
2390   {"str",       0x0000,         2,      ARM_EXT_V4T, do_t_str},
2391   {"strb",      0x0000,         2,      ARM_EXT_V4T, do_t_strb},
2392   {"strh",      0x0000,         2,      ARM_EXT_V4T, do_t_strh},
2393   {"swi",       0xdf00,         2,      ARM_EXT_V4T, do_t_swi},
2394   {"sub",       0x0000,         2,      ARM_EXT_V4T, do_t_sub},
2395   {"tst",       T_OPCODE_TST,   2,      ARM_EXT_V4T, do_t_arit},
2396   /* Pseudo ops:  */
2397   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2398   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2399   /* Thumb v2 (ARMv5T).  */
2400   {"blx",       0,              0,      ARM_EXT_V5T, do_t_blx},
2401   {"bkpt",      0xbe00,         2,      ARM_EXT_V5T, do_t_bkpt},
2402
2403   /* ARM V6.  */
2404   {"cpsie",     0xb660,         2,      ARM_EXT_V6,  do_t_cps},
2405   {"cpsid",     0xb670,         2,      ARM_EXT_V6,  do_t_cps},
2406   {"cpy",       0x4600,         2,      ARM_EXT_V6,  do_t_cpy},
2407   {"rev",       0xba00,         2,      ARM_EXT_V6,  do_t_arit},
2408   {"rev16",     0xba40,         2,      ARM_EXT_V6,  do_t_arit},
2409   {"revsh",     0xbac0,         2,      ARM_EXT_V6,  do_t_arit},
2410   {"setend",    0xb650,         2,      ARM_EXT_V6,  do_t_setend},
2411   {"sxth",      0xb200,         2,      ARM_EXT_V6,  do_t_arit},
2412   {"sxtb",      0xb240,         2,      ARM_EXT_V6,  do_t_arit},
2413   {"uxth",      0xb280,         2,      ARM_EXT_V6,  do_t_arit},
2414   {"uxtb",      0xb2c0,         2,      ARM_EXT_V6,  do_t_arit},
2415 };
2416
2417 #define BAD_ARGS        _("bad arguments to instruction")
2418 #define BAD_PC          _("r15 not allowed here")
2419 #define BAD_COND        _("instruction is not conditional")
2420 #define ERR_NO_ACCUM    _("acc0 expected")
2421
2422 static struct hash_control * arm_ops_hsh   = NULL;
2423 static struct hash_control * arm_tops_hsh  = NULL;
2424 static struct hash_control * arm_cond_hsh  = NULL;
2425 static struct hash_control * arm_shift_hsh = NULL;
2426 static struct hash_control * arm_psr_hsh   = NULL;
2427
2428 /* This table describes all the machine specific pseudo-ops the assembler
2429    has to support.  The fields are:
2430      pseudo-op name without dot
2431      function to call to execute this pseudo-op
2432      Integer arg to pass to the function.  */
2433
2434 static void s_req PARAMS ((int));
2435 static void s_unreq PARAMS ((int));
2436 static void s_align PARAMS ((int));
2437 static void s_bss PARAMS ((int));
2438 static void s_even PARAMS ((int));
2439 static void s_ltorg PARAMS ((int));
2440 static void s_arm PARAMS ((int));
2441 static void s_thumb PARAMS ((int));
2442 static void s_code PARAMS ((int));
2443 static void s_force_thumb PARAMS ((int));
2444 static void s_thumb_func PARAMS ((int));
2445 static void s_thumb_set PARAMS ((int));
2446 #ifdef OBJ_ELF
2447 static void s_arm_elf_cons PARAMS ((int));
2448 static void s_arm_rel31 (int nbytes);
2449 #endif
2450
2451 static int my_get_expression PARAMS ((expressionS *, char **));
2452
2453 const pseudo_typeS md_pseudo_table[] =
2454 {
2455   /* Never called because '.req' does not start a line.  */
2456   { "req",         s_req,         0 },
2457   { "unreq",       s_unreq,       0 },
2458   { "bss",         s_bss,         0 },
2459   { "align",       s_align,       0 },
2460   { "arm",         s_arm,         0 },
2461   { "thumb",       s_thumb,       0 },
2462   { "code",        s_code,        0 },
2463   { "force_thumb", s_force_thumb, 0 },
2464   { "thumb_func",  s_thumb_func,  0 },
2465   { "thumb_set",   s_thumb_set,   0 },
2466   { "even",        s_even,        0 },
2467   { "ltorg",       s_ltorg,       0 },
2468   { "pool",        s_ltorg,       0 },
2469 #ifdef OBJ_ELF
2470   { "word",        s_arm_elf_cons, 4 },
2471   { "long",        s_arm_elf_cons, 4 },
2472   { "rel31",       s_arm_rel31,   0 },
2473 #else
2474   { "word",        cons, 4},
2475 #endif
2476   { "extend",      float_cons, 'x' },
2477   { "ldouble",     float_cons, 'x' },
2478   { "packed",      float_cons, 'p' },
2479   { 0, 0, 0 }
2480 };
2481
2482 /* Other internal functions.  */
2483 static int arm_parse_extension PARAMS ((char *, int *));
2484 static int arm_parse_cpu PARAMS ((char *));
2485 static int arm_parse_arch PARAMS ((char *));
2486 static int arm_parse_fpu PARAMS ((char *));
2487 static int arm_parse_float_abi PARAMS ((char *));
2488 #ifdef OBJ_ELF
2489 static int arm_parse_eabi PARAMS ((char *));
2490 #endif
2491 #if 0 /* Suppressed - for now.  */
2492 #if defined OBJ_COFF || defined OBJ_ELF
2493 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2494 #endif
2495 #endif
2496
2497 /* Stuff needed to resolve the label ambiguity
2498    As:
2499      ...
2500      label:   <insn>
2501    may differ from:
2502      ...
2503      label:
2504               <insn>
2505 */
2506
2507 symbolS *  last_label_seen;
2508 static int label_is_thumb_function_name = FALSE;
2509
2510 /* Literal Pool stuff.  */
2511
2512 #define MAX_LITERAL_POOL_SIZE 1024
2513
2514 /* Literal pool structure.  Held on a per-section
2515    and per-sub-section basis.  */
2516 typedef struct literal_pool
2517 {
2518   expressionS    literals [MAX_LITERAL_POOL_SIZE];
2519   unsigned int   next_free_entry;
2520   unsigned int   id;
2521   symbolS *      symbol;
2522   segT           section;
2523   subsegT        sub_section;
2524   struct literal_pool * next;
2525 } literal_pool;
2526
2527 /* Pointer to a linked list of literal pools.  */
2528 literal_pool * list_of_pools = NULL;
2529
2530 static literal_pool * find_literal_pool PARAMS ((void));
2531 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2532
2533 static literal_pool *
2534 find_literal_pool ()
2535 {
2536   literal_pool * pool;
2537
2538   for (pool = list_of_pools; pool != NULL; pool = pool->next)
2539     {
2540       if (pool->section == now_seg
2541           && pool->sub_section == now_subseg)
2542         break;
2543     }
2544
2545   return pool;
2546 }
2547
2548 static literal_pool *
2549 find_or_make_literal_pool ()
2550 {
2551   /* Next literal pool ID number.  */
2552   static unsigned int latest_pool_num = 1;
2553   literal_pool *      pool;
2554
2555   pool = find_literal_pool ();
2556
2557   if (pool == NULL)
2558     {
2559       /* Create a new pool.  */
2560       pool = (literal_pool *) xmalloc (sizeof (* pool));
2561       if (! pool)
2562         return NULL;
2563
2564       pool->next_free_entry = 0;
2565       pool->section         = now_seg;
2566       pool->sub_section     = now_subseg;
2567       pool->next            = list_of_pools;
2568       pool->symbol          = NULL;
2569
2570       /* Add it to the list.  */
2571       list_of_pools = pool;
2572     }
2573
2574   /* New pools, and emptied pools, will have a NULL symbol.  */
2575   if (pool->symbol == NULL)
2576     {
2577       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2578                                     (valueT) 0, &zero_address_frag);
2579       pool->id = latest_pool_num ++;
2580     }
2581
2582   /* Done.  */
2583   return pool;
2584 }
2585
2586 /* Add the literal in the global 'inst'
2587    structure to the relevent literal pool.  */
2588 static int
2589 add_to_lit_pool ()
2590 {
2591   literal_pool * pool;
2592   unsigned int entry;
2593
2594   pool = find_or_make_literal_pool ();
2595
2596   /* Check if this literal value is already in the pool.  */
2597   for (entry = 0; entry < pool->next_free_entry; entry ++)
2598     {
2599       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2600           && (inst.reloc.exp.X_op == O_constant)
2601           && (pool->literals[entry].X_add_number
2602               == inst.reloc.exp.X_add_number)
2603           && (pool->literals[entry].X_unsigned
2604               == inst.reloc.exp.X_unsigned))
2605         break;
2606
2607       if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2608           && (inst.reloc.exp.X_op == O_symbol)
2609           && (pool->literals[entry].X_add_number
2610               == inst.reloc.exp.X_add_number)
2611           && (pool->literals[entry].X_add_symbol
2612               == inst.reloc.exp.X_add_symbol)
2613           && (pool->literals[entry].X_op_symbol
2614               == inst.reloc.exp.X_op_symbol))
2615         break;
2616     }
2617
2618   /* Do we need to create a new entry?  */
2619   if (entry == pool->next_free_entry)
2620     {
2621       if (entry >= MAX_LITERAL_POOL_SIZE)
2622         {
2623           inst.error = _("literal pool overflow");
2624           return FAIL;
2625         }
2626
2627       pool->literals[entry] = inst.reloc.exp;
2628       pool->next_free_entry += 1;
2629     }
2630
2631   inst.reloc.exp.X_op         = O_symbol;
2632   inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2633   inst.reloc.exp.X_add_symbol = pool->symbol;
2634
2635   return SUCCESS;
2636 }
2637
2638 /* Can't use symbol_new here, so have to create a symbol and then at
2639    a later date assign it a value. Thats what these functions do.  */
2640
2641 static void
2642 symbol_locate (symbolP, name, segment, valu, frag)
2643      symbolS *    symbolP;
2644      const char * name;         /* It is copied, the caller can modify.  */
2645      segT         segment;      /* Segment identifier (SEG_<something>).  */
2646      valueT       valu;         /* Symbol value.  */
2647      fragS *      frag;         /* Associated fragment.  */
2648 {
2649   unsigned int name_length;
2650   char * preserved_copy_of_name;
2651
2652   name_length = strlen (name) + 1;   /* +1 for \0.  */
2653   obstack_grow (&notes, name, name_length);
2654   preserved_copy_of_name = obstack_finish (&notes);
2655 #ifdef STRIP_UNDERSCORE
2656   if (preserved_copy_of_name[0] == '_')
2657     preserved_copy_of_name++;
2658 #endif
2659
2660 #ifdef tc_canonicalize_symbol_name
2661   preserved_copy_of_name =
2662     tc_canonicalize_symbol_name (preserved_copy_of_name);
2663 #endif
2664
2665   S_SET_NAME (symbolP, preserved_copy_of_name);
2666
2667   S_SET_SEGMENT (symbolP, segment);
2668   S_SET_VALUE (symbolP, valu);
2669   symbol_clear_list_pointers (symbolP);
2670
2671   symbol_set_frag (symbolP, frag);
2672
2673   /* Link to end of symbol chain.  */
2674   {
2675     extern int symbol_table_frozen;
2676     if (symbol_table_frozen)
2677       abort ();
2678   }
2679
2680   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2681
2682   obj_symbol_new_hook (symbolP);
2683
2684 #ifdef tc_symbol_new_hook
2685   tc_symbol_new_hook (symbolP);
2686 #endif
2687
2688 #ifdef DEBUG_SYMS
2689   verify_symbol_chain (symbol_rootP, symbol_lastP);
2690 #endif /* DEBUG_SYMS  */
2691 }
2692
2693 /* Check that an immediate is valid.
2694    If so, convert it to the right format.  */
2695
2696 static unsigned int
2697 validate_immediate (val)
2698      unsigned int val;
2699 {
2700   unsigned int a;
2701   unsigned int i;
2702
2703 #define rotate_left(v, n) (v << n | v >> (32 - n))
2704
2705   for (i = 0; i < 32; i += 2)
2706     if ((a = rotate_left (val, i)) <= 0xff)
2707       return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2708
2709   return FAIL;
2710 }
2711
2712 /* Check to see if an immediate can be computed as two separate immediate
2713    values, added together.  We already know that this value cannot be
2714    computed by just one ARM instruction.  */
2715
2716 static unsigned int
2717 validate_immediate_twopart (val, highpart)
2718      unsigned int   val;
2719      unsigned int * highpart;
2720 {
2721   unsigned int a;
2722   unsigned int i;
2723
2724   for (i = 0; i < 32; i += 2)
2725     if (((a = rotate_left (val, i)) & 0xff) != 0)
2726       {
2727         if (a & 0xff00)
2728           {
2729             if (a & ~ 0xffff)
2730               continue;
2731             * highpart = (a  >> 8) | ((i + 24) << 7);
2732           }
2733         else if (a & 0xff0000)
2734           {
2735             if (a & 0xff000000)
2736               continue;
2737             * highpart = (a >> 16) | ((i + 16) << 7);
2738           }
2739         else
2740           {
2741             assert (a & 0xff000000);
2742             * highpart = (a >> 24) | ((i + 8) << 7);
2743           }
2744
2745         return (a & 0xff) | (i << 7);
2746       }
2747
2748   return FAIL;
2749 }
2750
2751 static int
2752 validate_offset_imm (val, hwse)
2753      unsigned int val;
2754      int hwse;
2755 {
2756   if ((hwse && val > 255) || val > 4095)
2757     return FAIL;
2758   return val;
2759 }
2760
2761 \f
2762 #ifdef OBJ_ELF
2763 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2764    (This text is taken from version B-02 of the spec):
2765
2766       4.4.7 Mapping and tagging symbols
2767
2768       A section of an ARM ELF file can contain a mixture of ARM code,
2769       Thumb code, and data.  There are inline transitions between code
2770       and data at literal pool boundaries. There can also be inline
2771       transitions between ARM code and Thumb code, for example in
2772       ARM-Thumb inter-working veneers.  Linkers, machine-level
2773       debuggers, profiling tools, and disassembly tools need to map
2774       images accurately. For example, setting an ARM breakpoint on a
2775       Thumb location, or in a literal pool, can crash the program
2776       being debugged, ruining the debugging session.
2777
2778       ARM ELF entities are mapped (see section 4.4.7.1 below) and
2779       tagged (see section 4.4.7.2 below) using local symbols (with
2780       binding STB_LOCAL).  To assist consumers, mapping and tagging
2781       symbols should be collated first in the symbol table, before
2782       other symbols with binding STB_LOCAL.
2783
2784       To allow properly collated mapping and tagging symbols to be
2785       skipped by consumers that have no interest in them, the first
2786       such symbol should have the name $m and its st_value field equal
2787       to the total number of mapping and tagging symbols (including
2788       the $m) in the symbol table.
2789
2790       4.4.7.1 Mapping symbols
2791
2792       $a    Labels the first byte of a sequence of ARM instructions.
2793             Its type is STT_FUNC.
2794
2795       $d    Labels the first byte of a sequence of data items.
2796             Its type is STT_OBJECT.
2797
2798       $t    Labels the first byte of a sequence of Thumb instructions.
2799             Its type is STT_FUNC.
2800
2801       This list of mapping symbols may be extended in the future.
2802
2803       Section-relative mapping symbols
2804
2805       Mapping symbols defined in a section define a sequence of
2806       half-open address intervals that cover the address range of the
2807       section. Each interval starts at the address defined by a
2808       mapping symbol, and continues up to, but not including, the
2809       address defined by the next (in address order) mapping symbol or
2810       the end of the section. A corollary is that there must be a
2811       mapping symbol defined at the beginning of each section.
2812       Consumers can ignore the size of a section-relative mapping
2813       symbol. Producers can set it to 0.
2814
2815       Absolute mapping symbols
2816
2817       Because of the need to crystallize a Thumb address with the
2818       Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2819       STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2820       or $t.
2821
2822       The extent of a mapping symbol defined in SHN_ABS is [st_value,
2823       st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2824       where [x, y) denotes the half-open address range from x,
2825       inclusive, to y, exclusive.
2826
2827       In the absence of a mapping symbol, a consumer can interpret a
2828       function symbol with an odd value as the Thumb code address
2829       obtained by clearing the least significant bit of the
2830       value. This interpretation is deprecated, and it may not work in
2831       the future.
2832
2833    Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2834    the EABI (which is still under development), so they are not
2835    implemented here.  */
2836
2837 static enum mstate mapstate = MAP_UNDEFINED;
2838
2839 static void
2840 mapping_state (enum mstate state)
2841 {
2842   symbolS * symbolP;
2843   const char * symname;
2844   int type;
2845
2846   if (mapstate == state)
2847     /* The mapping symbol has already been emitted.
2848        There is nothing else to do.  */
2849     return;
2850
2851   mapstate = state;
2852
2853   switch (state)
2854     {
2855     case MAP_DATA:
2856       symname = "$d";
2857       type = BSF_OBJECT;
2858       break;
2859     case MAP_ARM:
2860       symname = "$a";
2861       type = BSF_FUNCTION;
2862       break;
2863     case MAP_THUMB:
2864       symname = "$t";
2865       type = BSF_FUNCTION;
2866       break;
2867     case MAP_UNDEFINED:
2868       return;     
2869     default:
2870       abort ();
2871     }
2872
2873   seg_info (now_seg)->tc_segment_info_data = state;
2874
2875   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2876   symbol_table_insert (symbolP);
2877   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2878   
2879   switch (state)
2880     {
2881     case MAP_ARM:
2882       THUMB_SET_FUNC (symbolP, 0);
2883       ARM_SET_THUMB (symbolP, 0);
2884       ARM_SET_INTERWORK (symbolP, support_interwork);
2885       break;
2886       
2887     case MAP_THUMB:
2888       THUMB_SET_FUNC (symbolP, 1);
2889       ARM_SET_THUMB (symbolP, 1);
2890       ARM_SET_INTERWORK (symbolP, support_interwork);
2891       break;
2892       
2893     case MAP_DATA:
2894     default:
2895       return;
2896     }
2897 }
2898
2899 /* When we change sections we need to issue a new mapping symbol.  */
2900
2901 void
2902 arm_elf_change_section (void)
2903 {
2904   flagword flags;
2905
2906   if (!SEG_NORMAL (now_seg))
2907     return;
2908
2909   flags = bfd_get_section_flags (stdoutput, now_seg);
2910
2911   /* We can ignore sections that only contain debug info.  */
2912   if ((flags & SEC_ALLOC) == 0)
2913     return;
2914
2915   mapstate = seg_info (now_seg)->tc_segment_info_data;
2916 }
2917 #else
2918 #define mapping_state(a)
2919 #endif /* OBJ_ELF */
2920 \f
2921
2922 static void
2923 s_req (a)
2924      int a ATTRIBUTE_UNUSED;
2925 {
2926   as_bad (_("invalid syntax for .req directive"));
2927 }
2928
2929 /* The .unreq directive deletes an alias which was previously defined
2930    by .req.  For example:
2931
2932        my_alias .req r11
2933        .unreq my_alias    */
2934
2935 static void
2936 s_unreq (int a ATTRIBUTE_UNUSED)
2937 {
2938   char *name;
2939   char saved_char;
2940
2941   skip_whitespace (input_line_pointer);
2942   name = input_line_pointer;
2943
2944   while (*input_line_pointer != 0
2945          && *input_line_pointer != ' '
2946          && *input_line_pointer != '\n')
2947     ++input_line_pointer;
2948
2949   saved_char = *input_line_pointer;
2950   *input_line_pointer = 0;
2951
2952   if (*name)
2953     {
2954       enum arm_reg_type req_type = arm_reg_parse_any (name);
2955
2956       if (req_type != REG_TYPE_MAX)
2957         {
2958           char *temp_name = name;
2959           int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
2960
2961           if (req_no != FAIL)
2962             {
2963               struct reg_entry *req_entry;
2964
2965               /* Check to see if this alias is a builtin one.  */
2966               req_entry = hash_delete (all_reg_maps[req_type].htab, name);
2967
2968               if (!req_entry)
2969                 as_bad (_("unreq: missing hash entry for \"%s\""), name);
2970               else if (req_entry->builtin)
2971                 /* FIXME: We are deleting a built in register alias which
2972                    points to a const data structure, so we only need to
2973                    free up the memory used by the key in the hash table.
2974                    Unfortunately we have not recorded this value, so this
2975                    is a memory leak.  */
2976                   /* FIXME: Should we issue a warning message ?  */
2977                 ;
2978               else
2979                 {
2980                   /* Deleting a user defined alias.  We need to free the
2981                      key and the value, but fortunately the key is the same
2982                      as the value->name field.  */
2983                   free ((char *) req_entry->name);
2984                   free (req_entry);
2985                 }
2986             }
2987           else
2988             as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
2989         }
2990       else
2991         as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
2992     }
2993   else
2994     as_bad (_("invalid syntax for .unreq directive"));
2995
2996   *input_line_pointer = saved_char;
2997   demand_empty_rest_of_line ();
2998 }
2999
3000 static void
3001 s_bss (ignore)
3002      int ignore ATTRIBUTE_UNUSED;
3003 {
3004   /* We don't support putting frags in the BSS segment, we fake it by
3005      marking in_bss, then looking at s_skip for clues.  */
3006   subseg_set (bss_section, 0);
3007   demand_empty_rest_of_line ();
3008   mapping_state (MAP_DATA);
3009 }
3010
3011 static void
3012 s_even (ignore)
3013      int ignore ATTRIBUTE_UNUSED;
3014 {
3015   /* Never make frag if expect extra pass.  */
3016   if (!need_pass_2)
3017     frag_align (1, 0, 0);
3018
3019   record_alignment (now_seg, 1);
3020
3021   demand_empty_rest_of_line ();
3022 }
3023
3024 static void
3025 s_ltorg (ignored)
3026      int ignored ATTRIBUTE_UNUSED;
3027 {
3028   unsigned int entry;
3029   literal_pool * pool;
3030   char sym_name[20];
3031
3032   pool = find_literal_pool ();
3033   if (pool == NULL
3034       || pool->symbol == NULL
3035       || pool->next_free_entry == 0)
3036     return;
3037
3038   mapping_state (MAP_DATA);
3039
3040   /* Align pool as you have word accesses.
3041      Only make a frag if we have to.  */
3042   if (!need_pass_2)
3043     frag_align (2, 0, 0);
3044
3045   record_alignment (now_seg, 2);
3046
3047   sprintf (sym_name, "$$lit_\002%x", pool->id);
3048
3049   symbol_locate (pool->symbol, sym_name, now_seg,
3050                  (valueT) frag_now_fix (), frag_now);
3051   symbol_table_insert (pool->symbol);
3052
3053   ARM_SET_THUMB (pool->symbol, thumb_mode);
3054
3055 #if defined OBJ_COFF || defined OBJ_ELF
3056   ARM_SET_INTERWORK (pool->symbol, support_interwork);
3057 #endif
3058
3059   for (entry = 0; entry < pool->next_free_entry; entry ++)
3060     /* First output the expression in the instruction to the pool.  */
3061     emit_expr (&(pool->literals[entry]), 4); /* .word  */
3062
3063   /* Mark the pool as empty.  */
3064   pool->next_free_entry = 0;
3065   pool->symbol = NULL;
3066 }
3067
3068 /* Same as s_align_ptwo but align 0 => align 2.  */
3069
3070 static void
3071 s_align (unused)
3072      int unused ATTRIBUTE_UNUSED;
3073 {
3074   register int temp;
3075   register long temp_fill;
3076   long max_alignment = 15;
3077
3078   temp = get_absolute_expression ();
3079   if (temp > max_alignment)
3080     as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3081   else if (temp < 0)
3082     {
3083       as_bad (_("alignment negative. 0 assumed."));
3084       temp = 0;
3085     }
3086
3087   if (*input_line_pointer == ',')
3088     {
3089       input_line_pointer++;
3090       temp_fill = get_absolute_expression ();
3091     }
3092   else
3093     temp_fill = 0;
3094
3095   if (!temp)
3096     temp = 2;
3097
3098   /* Only make a frag if we HAVE to.  */
3099   if (temp && !need_pass_2)
3100     frag_align (temp, (int) temp_fill, 0);
3101   demand_empty_rest_of_line ();
3102
3103   record_alignment (now_seg, temp);
3104 }
3105
3106 static void
3107 s_force_thumb (ignore)
3108      int ignore ATTRIBUTE_UNUSED;
3109 {
3110   /* If we are not already in thumb mode go into it, EVEN if
3111      the target processor does not support thumb instructions.
3112      This is used by gcc/config/arm/lib1funcs.asm for example
3113      to compile interworking support functions even if the
3114      target processor should not support interworking.  */
3115   if (! thumb_mode)
3116     {
3117       thumb_mode = 2;
3118
3119       record_alignment (now_seg, 1);
3120     }
3121
3122   demand_empty_rest_of_line ();
3123 }
3124
3125 static void
3126 s_thumb_func (ignore)
3127      int ignore ATTRIBUTE_UNUSED;
3128 {
3129   if (! thumb_mode)
3130     opcode_select (16);
3131
3132   /* The following label is the name/address of the start of a Thumb function.
3133      We need to know this for the interworking support.  */
3134   label_is_thumb_function_name = TRUE;
3135
3136   demand_empty_rest_of_line ();
3137 }
3138
3139 /* Perform a .set directive, but also mark the alias as
3140    being a thumb function.  */
3141
3142 static void
3143 s_thumb_set (equiv)
3144      int equiv;
3145 {
3146   /* XXX the following is a duplicate of the code for s_set() in read.c
3147      We cannot just call that code as we need to get at the symbol that
3148      is created.  */
3149   register char *    name;
3150   register char      delim;
3151   register char *    end_name;
3152   register symbolS * symbolP;
3153
3154   /* Especial apologies for the random logic:
3155      This just grew, and could be parsed much more simply!
3156      Dean - in haste.  */
3157   name      = input_line_pointer;
3158   delim     = get_symbol_end ();
3159   end_name  = input_line_pointer;
3160   *end_name = delim;
3161
3162   SKIP_WHITESPACE ();
3163
3164   if (*input_line_pointer != ',')
3165     {
3166       *end_name = 0;
3167       as_bad (_("expected comma after name \"%s\""), name);
3168       *end_name = delim;
3169       ignore_rest_of_line ();
3170       return;
3171     }
3172
3173   input_line_pointer++;
3174   *end_name = 0;
3175
3176   if (name[0] == '.' && name[1] == '\0')
3177     {
3178       /* XXX - this should not happen to .thumb_set.  */
3179       abort ();
3180     }
3181
3182   if ((symbolP = symbol_find (name)) == NULL
3183       && (symbolP = md_undefined_symbol (name)) == NULL)
3184     {
3185 #ifndef NO_LISTING
3186       /* When doing symbol listings, play games with dummy fragments living
3187          outside the normal fragment chain to record the file and line info
3188          for this symbol.  */
3189       if (listing & LISTING_SYMBOLS)
3190         {
3191           extern struct list_info_struct * listing_tail;
3192           fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3193
3194           memset (dummy_frag, 0, sizeof (fragS));
3195           dummy_frag->fr_type = rs_fill;
3196           dummy_frag->line = listing_tail;
3197           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3198           dummy_frag->fr_symbol = symbolP;
3199         }
3200       else
3201 #endif
3202         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3203
3204 #ifdef OBJ_COFF
3205       /* "set" symbols are local unless otherwise specified.  */
3206       SF_SET_LOCAL (symbolP);
3207 #endif /* OBJ_COFF  */
3208     }                           /* Make a new symbol.  */
3209
3210   symbol_table_insert (symbolP);
3211
3212   * end_name = delim;
3213
3214   if (equiv
3215       && S_IS_DEFINED (symbolP)
3216       && S_GET_SEGMENT (symbolP) != reg_section)
3217     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3218
3219   pseudo_set (symbolP);
3220
3221   demand_empty_rest_of_line ();
3222
3223   /* XXX Now we come to the Thumb specific bit of code.  */
3224
3225   THUMB_SET_FUNC (symbolP, 1);
3226   ARM_SET_THUMB (symbolP, 1);
3227 #if defined OBJ_ELF || defined OBJ_COFF
3228   ARM_SET_INTERWORK (symbolP, support_interwork);
3229 #endif
3230 }
3231
3232 static void
3233 opcode_select (width)
3234      int width;
3235 {
3236   switch (width)
3237     {
3238     case 16:
3239       if (! thumb_mode)
3240         {
3241           if (! (cpu_variant & ARM_EXT_V4T))
3242             as_bad (_("selected processor does not support THUMB opcodes"));
3243
3244           thumb_mode = 1;
3245           /* No need to force the alignment, since we will have been
3246              coming from ARM mode, which is word-aligned.  */
3247           record_alignment (now_seg, 1);
3248         }
3249       mapping_state (MAP_THUMB);
3250       break;
3251
3252     case 32:
3253       if (thumb_mode)
3254         {
3255           if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3256             as_bad (_("selected processor does not support ARM opcodes"));
3257
3258           thumb_mode = 0;
3259
3260           if (!need_pass_2)
3261             frag_align (2, 0, 0);
3262
3263           record_alignment (now_seg, 1);
3264         }
3265       mapping_state (MAP_ARM);
3266       break;
3267
3268     default:
3269       as_bad (_("invalid instruction size selected (%d)"), width);
3270     }
3271 }
3272
3273 static void
3274 s_arm (ignore)
3275      int ignore ATTRIBUTE_UNUSED;
3276 {
3277   opcode_select (32);
3278   demand_empty_rest_of_line ();
3279 }
3280
3281 static void
3282 s_thumb (ignore)
3283      int ignore ATTRIBUTE_UNUSED;
3284 {
3285   opcode_select (16);
3286   demand_empty_rest_of_line ();
3287 }
3288
3289 static void
3290 s_code (unused)
3291      int unused ATTRIBUTE_UNUSED;
3292 {
3293   register int temp;
3294
3295   temp = get_absolute_expression ();
3296   switch (temp)
3297     {
3298     case 16:
3299     case 32:
3300       opcode_select (temp);
3301       break;
3302
3303     default:
3304       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3305     }
3306 }
3307
3308 static void
3309 end_of_line (str)
3310      char *str;
3311 {
3312   skip_whitespace (str);
3313
3314   if (*str != '\0' && !inst.error)
3315     inst.error = _("garbage following instruction");
3316 }
3317
3318 static int
3319 skip_past_comma (str)
3320      char ** str;
3321 {
3322   char * p = * str, c;
3323   int comma = 0;
3324
3325   while ((c = *p) == ' ' || c == ',')
3326     {
3327       p++;
3328       if (c == ',' && comma++)
3329         return FAIL;
3330     }
3331
3332   if (c == '\0')
3333     return FAIL;
3334
3335   *str = p;
3336   return comma ? SUCCESS : FAIL;
3337 }
3338
3339 /* A standard register must be given at this point.
3340    SHIFT is the place to put it in inst.instruction.
3341    Restores input start point on error.
3342    Returns the reg#, or FAIL.  */
3343
3344 static int
3345 reg_required_here (str, shift)
3346      char ** str;
3347      int     shift;
3348 {
3349   static char buff [128]; /* XXX  */
3350   int         reg;
3351   char *      start = * str;
3352
3353   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3354     {
3355       if (shift >= 0)
3356         inst.instruction |= reg << shift;
3357       return reg;
3358     }
3359
3360   /* Restore the start point, we may have got a reg of the wrong class.  */
3361   *str = start;
3362
3363   /* In the few cases where we might be able to accept something else
3364      this error can be overridden.  */
3365   sprintf (buff, _("register expected, not '%.100s'"), start);
3366   inst.error = buff;
3367
3368   return FAIL;
3369 }
3370
3371 /* A Intel Wireless MMX technology register
3372    must be given at this point.
3373    Shift is the place to put it in inst.instruction.
3374    Restores input start point on err.
3375    Returns the reg#, or FAIL.  */
3376
3377 static int
3378 wreg_required_here (str, shift, reg_type)
3379      char ** str;
3380      int     shift;
3381      enum wreg_type reg_type;
3382 {
3383   static char buff [128];
3384   int    reg;
3385   char * start = *str;
3386
3387   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3388     {
3389       if (wr_register (reg)
3390           && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3391         {
3392           if (shift >= 0)
3393             inst.instruction |= (reg ^ WR_PREFIX) << shift;
3394           return reg;
3395         }
3396       else if (wc_register (reg)
3397                && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3398         {
3399           if (shift >= 0)
3400             inst.instruction |= (reg ^ WC_PREFIX) << shift;
3401           return reg;
3402         }
3403       else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3404         {
3405           if (shift >= 0)
3406             inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3407           return reg;
3408         }
3409     }
3410
3411   /* Restore the start point, we may have got a reg of the wrong class.  */
3412   *str = start;
3413
3414   /* In the few cases where we might be able to accept
3415      something else this error can be overridden.  */
3416   sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3417   inst.error = buff;
3418
3419   return FAIL;
3420 }
3421
3422 static const struct asm_psr *
3423 arm_psr_parse (ccp)
3424      register char ** ccp;
3425 {
3426   char * start = * ccp;
3427   char   c;
3428   char * p;
3429   const struct asm_psr * psr;
3430
3431   p = start;
3432
3433   /* Skip to the end of the next word in the input stream.  */
3434   do
3435     {
3436       c = *p++;
3437     }
3438   while (ISALPHA (c) || c == '_');
3439
3440   /* Terminate the word.  */
3441   *--p = 0;
3442
3443   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3444      feature for ease of use and backwards compatibility.  */
3445   if (!strncmp (start, "cpsr", 4))
3446     strncpy (start, "CPSR", 4);
3447   else if (!strncmp (start, "spsr", 4))
3448     strncpy (start, "SPSR", 4);
3449
3450   /* Now locate the word in the psr hash table.  */
3451   psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3452
3453   /* Restore the input stream.  */
3454   *p = c;
3455
3456   /* If we found a valid match, advance the
3457      stream pointer past the end of the word.  */
3458   *ccp = p;
3459
3460   return psr;
3461 }
3462
3463 /* Parse the input looking for a PSR flag.  */
3464
3465 static int
3466 psr_required_here (str)
3467      char ** str;
3468 {
3469   char * start = * str;
3470   const struct asm_psr * psr;
3471
3472   psr = arm_psr_parse (str);
3473
3474   if (psr)
3475     {
3476       /* If this is the SPSR that is being modified, set the R bit.  */
3477       if (! psr->cpsr)
3478         inst.instruction |= SPSR_BIT;
3479
3480       /* Set the psr flags in the MSR instruction.  */
3481       inst.instruction |= psr->field << PSR_SHIFT;
3482
3483       return SUCCESS;
3484     }
3485
3486   /* In the few cases where we might be able to accept
3487      something else this error can be overridden.  */
3488   inst.error = _("flag for {c}psr instruction expected");
3489
3490   /* Restore the start point.  */
3491   *str = start;
3492   return FAIL;
3493 }
3494
3495 static int
3496 co_proc_number (str)
3497      char **str;
3498 {
3499   int processor, pchar;
3500   char *start;
3501
3502   skip_whitespace (*str);
3503   start = *str;
3504
3505   /* The data sheet seems to imply that just a number on its own is valid
3506      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3507      accept either.  */
3508   if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3509       == FAIL)
3510     {
3511       *str = start;
3512
3513       pchar = *(*str)++;
3514       if (pchar >= '0' && pchar <= '9')
3515         {
3516           processor = pchar - '0';
3517           if (**str >= '0' && **str <= '9')
3518             {
3519               processor = processor * 10 + *(*str)++ - '0';
3520               if (processor > 15)
3521                 {
3522                   inst.error = _("illegal co-processor number");
3523                   return FAIL;
3524                 }
3525             }
3526         }
3527       else
3528         {
3529           inst.error = all_reg_maps[REG_TYPE_CP].expected;
3530           return FAIL;
3531         }
3532     }
3533
3534   inst.instruction |= processor << 8;
3535   return SUCCESS;
3536 }
3537
3538 static int
3539 cp_opc_expr (str, where, length)
3540      char ** str;
3541      int where;
3542      int length;
3543 {
3544   expressionS expr;
3545
3546   skip_whitespace (* str);
3547
3548   memset (&expr, '\0', sizeof (expr));
3549
3550   if (my_get_expression (&expr, str))
3551     return FAIL;
3552   if (expr.X_op != O_constant)
3553     {
3554       inst.error = _("bad or missing expression");
3555       return FAIL;
3556     }
3557
3558   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3559     {
3560       inst.error = _("immediate co-processor expression too large");
3561       return FAIL;
3562     }
3563
3564   inst.instruction |= expr.X_add_number << where;
3565   return SUCCESS;
3566 }
3567
3568 static int
3569 cp_reg_required_here (str, where)
3570      char ** str;
3571      int     where;
3572 {
3573   int    reg;
3574   char * start = *str;
3575
3576   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3577     {
3578       inst.instruction |= reg << where;
3579       return reg;
3580     }
3581
3582   /* In the few cases where we might be able to accept something else
3583      this error can be overridden.  */
3584   inst.error = all_reg_maps[REG_TYPE_CN].expected;
3585
3586   /* Restore the start point.  */
3587   *str = start;
3588   return FAIL;
3589 }
3590
3591 static int
3592 fp_reg_required_here (str, where)
3593      char ** str;
3594      int     where;
3595 {
3596   int    reg;
3597   char * start = * str;
3598
3599   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3600     {
3601       inst.instruction |= reg << where;
3602       return reg;
3603     }
3604
3605   /* In the few cases where we might be able to accept something else
3606      this error can be overridden.  */
3607   inst.error = all_reg_maps[REG_TYPE_FN].expected;
3608
3609   /* Restore the start point.  */
3610   *str = start;
3611   return FAIL;
3612 }
3613
3614 static int
3615 cp_address_offset (str)
3616      char ** str;
3617 {
3618   int offset;
3619
3620   skip_whitespace (* str);
3621
3622   if (! is_immediate_prefix (**str))
3623     {
3624       inst.error = _("immediate expression expected");
3625       return FAIL;
3626     }
3627
3628   (*str)++;
3629
3630   if (my_get_expression (& inst.reloc.exp, str))
3631     return FAIL;
3632
3633   if (inst.reloc.exp.X_op == O_constant)
3634     {
3635       offset = inst.reloc.exp.X_add_number;
3636
3637       if (offset & 3)
3638         {
3639           inst.error = _("co-processor address must be word aligned");
3640           return FAIL;
3641         }
3642
3643       if (offset > 1023 || offset < -1023)
3644         {
3645           inst.error = _("offset too large");
3646           return FAIL;
3647         }
3648
3649       if (offset >= 0)
3650         inst.instruction |= INDEX_UP;
3651       else
3652         offset = -offset;
3653
3654       inst.instruction |= offset >> 2;
3655     }
3656   else
3657     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3658
3659   return SUCCESS;
3660 }
3661
3662 static int
3663 cp_address_required_here (str, wb_ok)
3664      char ** str;
3665      int wb_ok;
3666 {
3667   char * p = * str;
3668   int    pre_inc = 0;
3669   int    write_back = 0;
3670
3671   if (*p == '[')
3672     {
3673       int reg;
3674
3675       p++;
3676       skip_whitespace (p);
3677
3678       if ((reg = reg_required_here (& p, 16)) == FAIL)
3679         return FAIL;
3680
3681       skip_whitespace (p);
3682
3683       if (*p == ']')
3684         {
3685           p++;
3686
3687           skip_whitespace (p);
3688
3689           if (*p == '\0')
3690             {
3691               /* As an extension to the official ARM syntax we allow:
3692                  
3693                    [Rn]
3694                    
3695                  as a short hand for:
3696
3697                    [Rn,#0]  */
3698               inst.instruction |= PRE_INDEX | INDEX_UP;
3699               *str = p;
3700               return SUCCESS;
3701             }
3702           
3703           if (skip_past_comma (& p) == FAIL)
3704             {
3705               inst.error = _("comma expected after closing square bracket");
3706               return FAIL;
3707             }
3708
3709           skip_whitespace (p);
3710
3711           if (*p == '#')
3712             {
3713               if (wb_ok)
3714                 {
3715                   /* [Rn], #expr  */
3716                   write_back = WRITE_BACK;
3717
3718                   if (reg == REG_PC)
3719                     {
3720                       inst.error = _("pc may not be used in post-increment");
3721                       return FAIL;
3722                     }
3723
3724                   if (cp_address_offset (& p) == FAIL)
3725                     return FAIL;
3726                 }
3727               else
3728                 pre_inc = PRE_INDEX | INDEX_UP;
3729             }
3730           else if (*p == '{')
3731             {
3732               int option;
3733
3734               /* [Rn], {<expr>}  */
3735               p++;
3736
3737               skip_whitespace (p);
3738
3739               if (my_get_expression (& inst.reloc.exp, & p))
3740                 return FAIL;
3741
3742               if (inst.reloc.exp.X_op == O_constant)
3743                 {
3744                   option = inst.reloc.exp.X_add_number;
3745
3746                   if (option > 255 || option < 0)
3747                     {
3748                       inst.error = _("'option' field too large");
3749                       return FAIL;
3750                     }
3751
3752                   skip_whitespace (p);
3753
3754                   if (*p != '}')
3755                     {
3756                       inst.error = _("'}' expected at end of 'option' field");
3757                       return FAIL;
3758                     }
3759                   else
3760                     {
3761                       p++;
3762                       inst.instruction |= option;
3763                       inst.instruction |= INDEX_UP;
3764                     }
3765                 }
3766               else
3767                 {
3768                   inst.error = _("non-constant expressions for 'option' field not supported");
3769                   return FAIL;
3770                 }
3771             }
3772           else
3773             {
3774               inst.error = _("# or { expected after comma");
3775               return FAIL;            
3776             }
3777         }
3778       else
3779         {
3780           /* '['Rn, #expr']'[!]  */
3781
3782           if (skip_past_comma (& p) == FAIL)
3783             {
3784               inst.error = _("pre-indexed expression expected");
3785               return FAIL;
3786             }
3787
3788           pre_inc = PRE_INDEX;
3789
3790           if (cp_address_offset (& p) == FAIL)
3791             return FAIL;
3792
3793           skip_whitespace (p);
3794
3795           if (*p++ != ']')
3796             {
3797               inst.error = _("missing ]");
3798               return FAIL;
3799             }
3800
3801           skip_whitespace (p);
3802
3803           if (wb_ok && *p == '!')
3804             {
3805               if (reg == REG_PC)
3806                 {
3807                   inst.error = _("pc may not be used with write-back");
3808                   return FAIL;
3809                 }
3810
3811               p++;
3812               write_back = WRITE_BACK;
3813             }
3814         }
3815     }
3816   else
3817     {
3818       if (my_get_expression (&inst.reloc.exp, &p))
3819         return FAIL;
3820
3821       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3822       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3823       inst.reloc.pc_rel = 1;
3824       inst.instruction |= (REG_PC << 16);
3825       pre_inc = PRE_INDEX;
3826     }
3827
3828   inst.instruction |= write_back | pre_inc;
3829   *str = p;
3830   return SUCCESS;
3831 }
3832
3833 static int
3834 cp_byte_address_offset (str)
3835      char ** str;
3836 {
3837   int offset;
3838
3839   skip_whitespace (* str);
3840
3841   if (! is_immediate_prefix (**str))
3842     {
3843       inst.error = _("immediate expression expected");
3844       return FAIL;
3845     }
3846
3847   (*str)++;
3848   
3849   if (my_get_expression (& inst.reloc.exp, str))
3850     return FAIL;
3851   
3852   if (inst.reloc.exp.X_op == O_constant)
3853     {
3854       offset = inst.reloc.exp.X_add_number;
3855       
3856       if (offset > 255 || offset < -255)
3857         {
3858           inst.error = _("offset too large");
3859           return FAIL;
3860         }
3861
3862       if (offset >= 0)
3863         inst.instruction |= INDEX_UP;
3864       else
3865         offset = -offset;
3866
3867       inst.instruction |= offset;
3868     }
3869   else
3870     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3871
3872   return SUCCESS;
3873 }
3874
3875 static int
3876 cp_byte_address_required_here (str)
3877      char ** str;
3878 {
3879   char * p = * str;
3880   int    pre_inc = 0;
3881   int    write_back = 0;
3882
3883   if (*p == '[')
3884     {
3885       int reg;
3886
3887       p++;
3888       skip_whitespace (p);
3889
3890       if ((reg = reg_required_here (& p, 16)) == FAIL)
3891         return FAIL;
3892
3893       skip_whitespace (p);
3894
3895       if (*p == ']')
3896         {
3897           p++;
3898           
3899           if (skip_past_comma (& p) == SUCCESS)
3900             {
3901               /* [Rn], #expr */
3902               write_back = WRITE_BACK;
3903               
3904               if (reg == REG_PC)
3905                 {
3906                   inst.error = _("pc may not be used in post-increment");
3907                   return FAIL;
3908                 }
3909
3910               if (cp_byte_address_offset (& p) == FAIL)
3911                 return FAIL;
3912             }
3913           else
3914             pre_inc = PRE_INDEX | INDEX_UP;
3915         }
3916       else
3917         {
3918           /* '['Rn, #expr']'[!] */
3919
3920           if (skip_past_comma (& p) == FAIL)
3921             {
3922               inst.error = _("pre-indexed expression expected");
3923               return FAIL;
3924             }
3925
3926           pre_inc = PRE_INDEX;
3927           
3928           if (cp_byte_address_offset (& p) == FAIL)
3929             return FAIL;
3930
3931           skip_whitespace (p);
3932
3933           if (*p++ != ']')
3934             {
3935               inst.error = _("missing ]");
3936               return FAIL;
3937             }
3938
3939           skip_whitespace (p);
3940
3941           if (*p == '!')
3942             {
3943               if (reg == REG_PC)
3944                 {
3945                   inst.error = _("pc may not be used with write-back");
3946                   return FAIL;
3947                 }
3948
3949               p++;
3950               write_back = WRITE_BACK;
3951             }
3952         }
3953     }
3954   else
3955     {
3956       if (my_get_expression (&inst.reloc.exp, &p))
3957         return FAIL;
3958
3959       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3960       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3961       inst.reloc.pc_rel = 1;
3962       inst.instruction |= (REG_PC << 16);
3963       pre_inc = PRE_INDEX;
3964     }
3965
3966   inst.instruction |= write_back | pre_inc;
3967   *str = p;
3968   return SUCCESS;
3969 }
3970
3971 static void
3972 do_empty (str)
3973      char * str;
3974 {
3975   /* Do nothing really.  */
3976   end_of_line (str);
3977 }
3978
3979 static void
3980 do_mrs (str)
3981      char *str;
3982 {
3983   int skip = 0;
3984
3985   /* Only one syntax.  */
3986   skip_whitespace (str);
3987
3988   if (reg_required_here (&str, 12) == FAIL)
3989     {
3990       inst.error = BAD_ARGS;
3991       return;
3992     }
3993
3994   if (skip_past_comma (&str) == FAIL)
3995     {
3996       inst.error = _("comma expected after register name");
3997       return;
3998     }
3999
4000   skip_whitespace (str);
4001
4002   if (   strcmp (str, "CPSR") == 0
4003       || strcmp (str, "SPSR") == 0
4004          /* Lower case versions for backwards compatibility.  */
4005       || strcmp (str, "cpsr") == 0
4006       || strcmp (str, "spsr") == 0)
4007     skip = 4;
4008
4009   /* This is for backwards compatibility with older toolchains.  */
4010   else if (   strcmp (str, "cpsr_all") == 0
4011            || strcmp (str, "spsr_all") == 0)
4012     skip = 8;
4013   else
4014     {
4015       inst.error = _("CPSR or SPSR expected");
4016       return;
4017     }
4018
4019   if (* str == 's' || * str == 'S')
4020     inst.instruction |= SPSR_BIT;
4021   str += skip;
4022
4023   end_of_line (str);
4024 }
4025
4026 /* Two possible forms:
4027       "{C|S}PSR_<field>, Rm",
4028       "{C|S}PSR_f, #expression".  */
4029
4030 static void
4031 do_msr (str)
4032      char * str;
4033 {
4034   skip_whitespace (str);
4035
4036   if (psr_required_here (& str) == FAIL)
4037     return;
4038
4039   if (skip_past_comma (& str) == FAIL)
4040     {
4041       inst.error = _("comma missing after psr flags");
4042       return;
4043     }
4044
4045   skip_whitespace (str);
4046
4047   if (reg_required_here (& str, 0) != FAIL)
4048     {
4049       inst.error = NULL;
4050       end_of_line (str);
4051       return;
4052     }
4053
4054   if (! is_immediate_prefix (* str))
4055     {
4056       inst.error =
4057         _("only a register or immediate value can follow a psr flag");
4058       return;
4059     }
4060
4061   str ++;
4062   inst.error = NULL;
4063
4064   if (my_get_expression (& inst.reloc.exp, & str))
4065     {
4066       inst.error =
4067         _("only a register or immediate value can follow a psr flag");
4068       return;
4069     }
4070
4071 #if 0  /* The first edition of the ARM architecture manual stated that
4072           writing anything other than the flags with an immediate operation
4073           had UNPREDICTABLE effects.  This constraint was removed in the
4074           second edition of the specification.  */
4075   if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4076       && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4077     {
4078       inst.error = _("immediate value cannot be used to set this field");
4079       return;
4080     }
4081 #endif
4082
4083   inst.instruction |= INST_IMMEDIATE;
4084
4085   if (inst.reloc.exp.X_add_symbol)
4086     {
4087       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4088       inst.reloc.pc_rel = 0;
4089     }
4090   else
4091     {
4092       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4093
4094       if (value == (unsigned) FAIL)
4095         {
4096           inst.error = _("invalid constant");
4097           return;
4098         }
4099
4100       inst.instruction |= value;
4101     }
4102
4103   inst.error = NULL;
4104   end_of_line (str);
4105 }
4106
4107 /* Long Multiply Parser
4108    UMULL RdLo, RdHi, Rm, Rs
4109    SMULL RdLo, RdHi, Rm, Rs
4110    UMLAL RdLo, RdHi, Rm, Rs
4111    SMLAL RdLo, RdHi, Rm, Rs.  */
4112
4113 static void
4114 do_mull (str)
4115      char * str;
4116 {
4117   int rdlo, rdhi, rm, rs;
4118
4119   /* Only one format "rdlo, rdhi, rm, rs".  */
4120   skip_whitespace (str);
4121
4122   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4123     {
4124       inst.error = BAD_ARGS;
4125       return;
4126     }
4127
4128   if (skip_past_comma (&str) == FAIL
4129       || (rdhi = reg_required_here (&str, 16)) == FAIL)
4130     {
4131       inst.error = BAD_ARGS;
4132       return;
4133     }
4134
4135   if (skip_past_comma (&str) == FAIL
4136       || (rm = reg_required_here (&str, 0)) == FAIL)
4137     {
4138       inst.error = BAD_ARGS;
4139       return;
4140     }
4141
4142   /* rdhi, rdlo and rm must all be different.  */
4143   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4144     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4145
4146   if (skip_past_comma (&str) == FAIL
4147       || (rs = reg_required_here (&str, 8)) == FAIL)
4148     {
4149       inst.error = BAD_ARGS;
4150       return;
4151     }
4152
4153   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4154     {
4155       inst.error = BAD_PC;
4156       return;
4157     }
4158
4159   end_of_line (str);
4160 }
4161
4162 static void
4163 do_mul (str)
4164      char * str;
4165 {
4166   int rd, rm;
4167
4168   /* Only one format "rd, rm, rs".  */
4169   skip_whitespace (str);
4170
4171   if ((rd = reg_required_here (&str, 16)) == FAIL)
4172     {
4173       inst.error = BAD_ARGS;
4174       return;
4175     }
4176
4177   if (rd == REG_PC)
4178     {
4179       inst.error = BAD_PC;
4180       return;
4181     }
4182
4183   if (skip_past_comma (&str) == FAIL
4184       || (rm = reg_required_here (&str, 0)) == FAIL)
4185     {
4186       inst.error = BAD_ARGS;
4187       return;
4188     }
4189
4190   if (rm == REG_PC)
4191     {
4192       inst.error = BAD_PC;
4193       return;
4194     }
4195
4196   if (rm == rd)
4197     as_tsktsk (_("rd and rm should be different in mul"));
4198
4199   if (skip_past_comma (&str) == FAIL
4200       || (rm = reg_required_here (&str, 8)) == FAIL)
4201     {
4202       inst.error = BAD_ARGS;
4203       return;
4204     }
4205
4206   if (rm == REG_PC)
4207     {
4208       inst.error = BAD_PC;
4209       return;
4210     }
4211
4212   end_of_line (str);
4213 }
4214
4215 static void
4216 do_mla (str)
4217      char * str;
4218 {
4219   int rd, rm;
4220
4221   /* Only one format "rd, rm, rs, rn".  */
4222   skip_whitespace (str);
4223
4224   if ((rd = reg_required_here (&str, 16)) == FAIL)
4225     {
4226       inst.error = BAD_ARGS;
4227       return;
4228     }
4229
4230   if (rd == REG_PC)
4231     {
4232       inst.error = BAD_PC;
4233       return;
4234     }
4235
4236   if (skip_past_comma (&str) == FAIL
4237       || (rm = reg_required_here (&str, 0)) == FAIL)
4238     {
4239       inst.error = BAD_ARGS;
4240       return;
4241     }
4242
4243   if (rm == REG_PC)
4244     {
4245       inst.error = BAD_PC;
4246       return;
4247     }
4248
4249   if (rm == rd)
4250     as_tsktsk (_("rd and rm should be different in mla"));
4251
4252   if (skip_past_comma (&str) == FAIL
4253       || (rd = reg_required_here (&str, 8)) == FAIL
4254       || skip_past_comma (&str) == FAIL
4255       || (rm = reg_required_here (&str, 12)) == FAIL)
4256     {
4257       inst.error = BAD_ARGS;
4258       return;
4259     }
4260
4261   if (rd == REG_PC || rm == REG_PC)
4262     {
4263       inst.error = BAD_PC;
4264       return;
4265     }
4266
4267   end_of_line (str);
4268 }
4269
4270 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4271    Advances *str to the next non-alphanumeric.
4272    Returns 0, or else FAIL (in which case sets inst.error).
4273
4274   (In a future XScale, there may be accumulators other than zero.
4275   At that time this routine and its callers can be upgraded to suit.)  */
4276
4277 static int
4278 accum0_required_here (str)
4279      char ** str;
4280 {
4281   static char buff [128];       /* Note the address is taken.  Hence, static.  */
4282   char * p = * str;
4283   char   c;
4284   int result = 0;               /* The accum number.  */
4285
4286   skip_whitespace (p);
4287
4288   *str = p;                     /* Advance caller's string pointer too.  */
4289   c = *p++;
4290   while (ISALNUM (c))
4291     c = *p++;
4292
4293   *--p = 0;                     /* Aap nul into input buffer at non-alnum.  */
4294
4295   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4296     {
4297       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4298       inst.error = buff;
4299       result = FAIL;
4300     }
4301
4302   *p = c;                       /* Unzap.  */
4303   *str = p;                     /* Caller's string pointer to after match.  */
4304   return result;
4305 }
4306
4307 /* Expects **str -> after a comma. May be leading blanks.
4308    Advances *str, recognizing a load  mode, and setting inst.instruction.
4309    Returns rn, or else FAIL (in which case may set inst.error
4310    and not advance str)
4311
4312    Note: doesn't know Rd, so no err checks that require such knowledge.  */
4313
4314 static int
4315 ld_mode_required_here (string)
4316      char ** string;
4317 {
4318   char * str = * string;
4319   int    rn;
4320   int    pre_inc = 0;
4321
4322   skip_whitespace (str);
4323
4324   if (* str == '[')
4325     {
4326       str++;
4327
4328       skip_whitespace (str);
4329
4330       if ((rn = reg_required_here (& str, 16)) == FAIL)
4331         return FAIL;
4332
4333       skip_whitespace (str);
4334
4335       if (* str == ']')
4336         {
4337           str ++;
4338
4339           if (skip_past_comma (& str) == SUCCESS)
4340             {
4341               /* [Rn],... (post inc) */
4342               if (ldst_extend_v4 (&str) == FAIL)
4343                 return FAIL;
4344             }
4345           else        /* [Rn] */
4346             {
4347               skip_whitespace (str);
4348
4349               if (* str == '!')
4350                 {
4351                   str ++;
4352                   inst.instruction |= WRITE_BACK;
4353                 }
4354
4355               inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4356               pre_inc = 1;
4357             }
4358         }
4359       else        /* [Rn,...] */
4360         {
4361           if (skip_past_comma (& str) == FAIL)
4362             {
4363               inst.error = _("pre-indexed expression expected");
4364               return FAIL;
4365             }
4366
4367           pre_inc = 1;
4368
4369           if (ldst_extend_v4 (&str) == FAIL)
4370             return FAIL;
4371
4372           skip_whitespace (str);
4373
4374           if (* str ++ != ']')
4375             {
4376               inst.error = _("missing ]");
4377               return FAIL;
4378             }
4379
4380           skip_whitespace (str);
4381
4382           if (* str == '!')
4383             {
4384               str ++;
4385               inst.instruction |= WRITE_BACK;
4386             }
4387         }
4388     }
4389   else if (* str == '=')        /* ldr's "r,=label" syntax */
4390     /* We should never reach here, because <text> = <expression> is
4391        caught gas/read.c read_a_source_file() as a .set operation.  */
4392     return FAIL;
4393   else                          /* PC +- 8 bit immediate offset.  */
4394     {
4395       if (my_get_expression (& inst.reloc.exp, & str))
4396         return FAIL;
4397
4398       inst.instruction            |= HWOFFSET_IMM;      /* The I bit.  */
4399       inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4400       inst.reloc.exp.X_add_number -= 8;                 /* PC rel adjust.  */
4401       inst.reloc.pc_rel            = 1;
4402       inst.instruction            |= (REG_PC << 16);
4403
4404       rn = REG_PC;
4405       pre_inc = 1;
4406     }
4407
4408   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4409   * string = str;
4410
4411   return rn;
4412 }
4413
4414 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4415    SMLAxy{cond} Rd,Rm,Rs,Rn
4416    SMLAWy{cond} Rd,Rm,Rs,Rn
4417    Error if any register is R15.  */
4418
4419 static void
4420 do_smla (str)
4421      char *        str;
4422 {
4423   int rd, rm, rs, rn;
4424
4425   skip_whitespace (str);
4426
4427   if ((rd = reg_required_here (& str, 16)) == FAIL
4428       || skip_past_comma (& str) == FAIL
4429       || (rm = reg_required_here (& str, 0)) == FAIL
4430       || skip_past_comma (& str) == FAIL
4431       || (rs = reg_required_here (& str, 8)) == FAIL
4432       || skip_past_comma (& str) == FAIL
4433       || (rn = reg_required_here (& str, 12)) == FAIL)
4434     inst.error = BAD_ARGS;
4435
4436   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4437     inst.error = BAD_PC;
4438
4439   else
4440     end_of_line (str);
4441 }
4442
4443 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4444    SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4445    Error if any register is R15.
4446    Warning if Rdlo == Rdhi.  */
4447
4448 static void
4449 do_smlal (str)
4450      char *        str;
4451 {
4452   int rdlo, rdhi, rm, rs;
4453
4454   skip_whitespace (str);
4455
4456   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4457       || skip_past_comma (& str) == FAIL
4458       || (rdhi = reg_required_here (& str, 16)) == FAIL
4459       || skip_past_comma (& str) == FAIL
4460       || (rm = reg_required_here (& str, 0)) == FAIL
4461       || skip_past_comma (& str) == FAIL
4462       || (rs = reg_required_here (& str, 8)) == FAIL)
4463     {
4464       inst.error = BAD_ARGS;
4465       return;
4466     }
4467
4468   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4469     {
4470       inst.error = BAD_PC;
4471       return;
4472     }
4473
4474   if (rdlo == rdhi)
4475     as_tsktsk (_("rdhi and rdlo must be different"));
4476
4477   end_of_line (str);
4478 }
4479
4480 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4481    SMULxy{cond} Rd,Rm,Rs
4482    Error if any register is R15.  */
4483
4484 static void
4485 do_smul (str)
4486      char *        str;
4487 {
4488   int rd, rm, rs;
4489
4490   skip_whitespace (str);
4491
4492   if ((rd = reg_required_here (& str, 16)) == FAIL
4493       || skip_past_comma (& str) == FAIL
4494       || (rm = reg_required_here (& str, 0)) == FAIL
4495       || skip_past_comma (& str) == FAIL
4496       || (rs = reg_required_here (& str, 8)) == FAIL)
4497     inst.error = BAD_ARGS;
4498
4499   else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4500     inst.error = BAD_PC;
4501
4502   else
4503     end_of_line (str);
4504 }
4505
4506 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4507    Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4508    Error if any register is R15.  */
4509
4510 static void
4511 do_qadd (str)
4512      char *        str;
4513 {
4514   int rd, rm, rn;
4515
4516   skip_whitespace (str);
4517
4518   if ((rd = reg_required_here (& str, 12)) == FAIL
4519       || skip_past_comma (& str) == FAIL
4520       || (rm = reg_required_here (& str, 0)) == FAIL
4521       || skip_past_comma (& str) == FAIL
4522       || (rn = reg_required_here (& str, 16)) == FAIL)
4523     inst.error = BAD_ARGS;
4524
4525   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4526     inst.error = BAD_PC;
4527
4528   else
4529     end_of_line (str);
4530 }
4531
4532 /* ARM V5E (el Segundo)
4533    MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4534    MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4535
4536    These are equivalent to the XScale instructions MAR and MRA,
4537    respectively, when coproc == 0, opcode == 0, and CRm == 0.
4538
4539    Result unpredicatable if Rd or Rn is R15.  */
4540
4541 static void
4542 do_co_reg2c (str)
4543      char *        str;
4544 {
4545   int rd, rn;
4546
4547   skip_whitespace (str);
4548
4549   if (co_proc_number (& str) == FAIL)
4550     {
4551       if (!inst.error)
4552         inst.error = BAD_ARGS;
4553       return;
4554     }
4555
4556   if (skip_past_comma (& str) == FAIL
4557       || cp_opc_expr (& str, 4, 4) == FAIL)
4558     {
4559       if (!inst.error)
4560         inst.error = BAD_ARGS;
4561       return;
4562     }
4563
4564   if (skip_past_comma (& str) == FAIL
4565       || (rd = reg_required_here (& str, 12)) == FAIL)
4566     {
4567       if (!inst.error)
4568         inst.error = BAD_ARGS;
4569       return;
4570     }
4571
4572   if (skip_past_comma (& str) == FAIL
4573       || (rn = reg_required_here (& str, 16)) == FAIL)
4574     {
4575       if (!inst.error)
4576         inst.error = BAD_ARGS;
4577       return;
4578     }
4579
4580   /* Unpredictable result if rd or rn is R15.  */
4581   if (rd == REG_PC || rn == REG_PC)
4582     as_tsktsk
4583       (_("Warning: instruction unpredictable when using r15"));
4584
4585   if (skip_past_comma (& str) == FAIL
4586       || cp_reg_required_here (& str, 0) == FAIL)
4587     {
4588       if (!inst.error)
4589         inst.error = BAD_ARGS;
4590       return;
4591     }
4592
4593   end_of_line (str);
4594 }
4595
4596 /* ARM V5 count-leading-zeroes instruction (argument parse)
4597      CLZ{<cond>} <Rd>, <Rm>
4598      Condition defaults to COND_ALWAYS.
4599      Error if Rd or Rm are R15.  */
4600
4601 static void
4602 do_clz (str)
4603      char *        str;
4604 {
4605   int rd, rm;
4606
4607   skip_whitespace (str);
4608
4609   if (((rd = reg_required_here (& str, 12)) == FAIL)
4610       || (skip_past_comma (& str) == FAIL)
4611       || ((rm = reg_required_here (& str, 0)) == FAIL))
4612     inst.error = BAD_ARGS;
4613
4614   else if (rd == REG_PC || rm == REG_PC )
4615     inst.error = BAD_PC;
4616
4617   else
4618     end_of_line (str);
4619 }
4620
4621 /* ARM V5 (argument parse)
4622      LDC2{L} <coproc>, <CRd>, <addressing mode>
4623      STC2{L} <coproc>, <CRd>, <addressing mode>
4624      Instruction is not conditional, and has 0xf in the condition field.
4625      Otherwise, it's the same as LDC/STC.  */
4626
4627 static void
4628 do_lstc2 (str)
4629      char *        str;
4630 {
4631   skip_whitespace (str);
4632
4633   if (co_proc_number (& str) == FAIL)
4634     {
4635       if (!inst.error)
4636         inst.error = BAD_ARGS;
4637     }
4638   else if (skip_past_comma (& str) == FAIL
4639            || cp_reg_required_here (& str, 12) == FAIL)
4640     {
4641       if (!inst.error)
4642         inst.error = BAD_ARGS;
4643     }
4644   else if (skip_past_comma (& str) == FAIL
4645            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4646     {
4647       if (! inst.error)
4648         inst.error = BAD_ARGS;
4649     }
4650   else
4651     end_of_line (str);
4652 }
4653
4654 /* ARM V5 (argument parse)
4655      CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4656      Instruction is not conditional, and has 0xf in the condition field.
4657      Otherwise, it's the same as CDP.  */
4658
4659 static void
4660 do_cdp2 (str)
4661      char *        str;
4662 {
4663   skip_whitespace (str);
4664
4665   if (co_proc_number (& str) == FAIL)
4666     {
4667       if (!inst.error)
4668         inst.error = BAD_ARGS;
4669       return;
4670     }
4671
4672   if (skip_past_comma (& str) == FAIL
4673       || cp_opc_expr (& str, 20,4) == FAIL)
4674     {
4675       if (!inst.error)
4676         inst.error = BAD_ARGS;
4677       return;
4678     }
4679
4680   if (skip_past_comma (& str) == FAIL
4681       || cp_reg_required_here (& str, 12) == FAIL)
4682     {
4683       if (!inst.error)
4684         inst.error = BAD_ARGS;
4685       return;
4686     }
4687
4688   if (skip_past_comma (& str) == FAIL
4689       || cp_reg_required_here (& str, 16) == FAIL)
4690     {
4691       if (!inst.error)
4692         inst.error = BAD_ARGS;
4693       return;
4694     }
4695
4696   if (skip_past_comma (& str) == FAIL
4697       || cp_reg_required_here (& str, 0) == FAIL)
4698     {
4699       if (!inst.error)
4700         inst.error = BAD_ARGS;
4701       return;
4702     }
4703
4704   if (skip_past_comma (& str) == SUCCESS)
4705     {
4706       if (cp_opc_expr (& str, 5, 3) == FAIL)
4707         {
4708           if (!inst.error)
4709             inst.error = BAD_ARGS;
4710           return;
4711         }
4712     }
4713
4714   end_of_line (str);
4715 }
4716
4717 /* ARM V5 (argument parse)
4718      MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4719      MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4720      Instruction is not conditional, and has 0xf in the condition field.
4721      Otherwise, it's the same as MCR/MRC.  */
4722
4723 static void
4724 do_co_reg2 (str)
4725      char *        str;
4726 {
4727   skip_whitespace (str);
4728
4729   if (co_proc_number (& str) == FAIL)
4730     {
4731       if (!inst.error)
4732         inst.error = BAD_ARGS;
4733       return;
4734     }
4735
4736   if (skip_past_comma (& str) == FAIL
4737       || cp_opc_expr (& str, 21, 3) == FAIL)
4738     {
4739       if (!inst.error)
4740         inst.error = BAD_ARGS;
4741       return;
4742     }
4743
4744   if (skip_past_comma (& str) == FAIL
4745       || reg_required_here (& str, 12) == FAIL)
4746     {
4747       if (!inst.error)
4748         inst.error = BAD_ARGS;
4749       return;
4750     }
4751
4752   if (skip_past_comma (& str) == FAIL
4753       || cp_reg_required_here (& str, 16) == FAIL)
4754     {
4755       if (!inst.error)
4756         inst.error = BAD_ARGS;
4757       return;
4758     }
4759
4760   if (skip_past_comma (& str) == FAIL
4761       || cp_reg_required_here (& str, 0) == FAIL)
4762     {
4763       if (!inst.error)
4764         inst.error = BAD_ARGS;
4765       return;
4766     }
4767
4768   if (skip_past_comma (& str) == SUCCESS)
4769     {
4770       if (cp_opc_expr (& str, 5, 3) == FAIL)
4771         {
4772           if (!inst.error)
4773             inst.error = BAD_ARGS;
4774           return;
4775         }
4776     }
4777
4778   end_of_line (str);
4779 }
4780
4781 /* ARM v5TEJ.  Jump to Jazelle code.  */
4782 static void
4783 do_bxj (str)
4784      char * str;
4785 {
4786   int reg;
4787
4788   skip_whitespace (str);
4789
4790   if ((reg = reg_required_here (&str, 0)) == FAIL)
4791     {
4792       inst.error = BAD_ARGS;
4793       return;
4794     }
4795
4796   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4797   if (reg == REG_PC)
4798     as_tsktsk (_("use of r15 in bxj is not really useful"));
4799
4800   end_of_line (str);
4801 }
4802
4803 /* ARM V6 umaal (argument parse). */
4804
4805 static void
4806 do_umaal (str)
4807      char *str;
4808 {
4809
4810   int rdlo, rdhi, rm, rs;
4811
4812   skip_whitespace (str);
4813   if ((rdlo = reg_required_here (& str, 12)) == FAIL
4814       || skip_past_comma (& str) == FAIL
4815       || (rdhi = reg_required_here (& str, 16)) == FAIL
4816       || skip_past_comma (& str) == FAIL
4817       || (rm = reg_required_here (& str, 0)) == FAIL
4818       || skip_past_comma (& str) == FAIL
4819       || (rs = reg_required_here (& str, 8)) == FAIL)
4820     {
4821       inst.error = BAD_ARGS;
4822       return;      
4823     }
4824
4825   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4826     {
4827       inst.error = BAD_PC;
4828       return;
4829     }
4830
4831   end_of_line (str);
4832 }
4833
4834 /* ARM V6 strex (argument parse). */
4835
4836 static void 
4837 do_strex (str)
4838      char *str;
4839 {
4840   int rd, rm, rn;
4841
4842   /* Parse Rd, Rm,. */
4843   skip_whitespace (str);
4844   if ((rd = reg_required_here (& str, 12)) == FAIL
4845       || skip_past_comma (& str) == FAIL
4846       || (rm = reg_required_here (& str, 0)) == FAIL
4847       || skip_past_comma (& str) == FAIL)
4848     {
4849       inst.error = BAD_ARGS;
4850       return;
4851     }
4852   if (rd == REG_PC || rm == REG_PC)
4853     {
4854       inst.error = BAD_PC;
4855       return;
4856     }
4857   if (rd == rm)
4858     {
4859       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4860       return;
4861     }
4862
4863   /* Skip past '['. */
4864   if ((strlen (str) >= 1) 
4865       && strncmp (str, "[", 1) == 0)
4866     str+=1;
4867   skip_whitespace (str);  
4868
4869   /* Parse Rn. */
4870   if ((rn = reg_required_here (& str, 16)) == FAIL)
4871     {
4872       inst.error = BAD_ARGS;
4873       return;
4874     }
4875   else if (rn == REG_PC)
4876     {
4877       inst.error = BAD_PC;
4878       return;
4879     }
4880   if (rd == rn)
4881     {
4882       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4883       return;
4884     }
4885   skip_whitespace (str);  
4886
4887   /* Skip past ']'. */
4888   if ((strlen (str) >= 1) 
4889       && strncmp (str, "]", 1) == 0)
4890     str+=1;
4891   
4892   end_of_line (str);
4893 }
4894
4895 /* ARM V6 ssat (argument parse). */
4896
4897 static void
4898 do_ssat (str)
4899      char* str;
4900 {
4901   do_sat (&str, /*bias=*/-1);
4902   end_of_line (str);
4903 }
4904
4905 /* ARM V6 usat (argument parse). */
4906
4907 static void
4908 do_usat (str)
4909      char* str;
4910 {
4911   do_sat (&str, /*bias=*/0);
4912   end_of_line (str);
4913 }
4914
4915 static void
4916 do_sat (str, bias)
4917      char **str;
4918      int    bias;
4919 {
4920   int rd, rm;
4921   expressionS expr;
4922
4923   skip_whitespace (*str);
4924   
4925   /* Parse <Rd>, field. */
4926   if ((rd = reg_required_here (str, 12)) == FAIL
4927       || skip_past_comma (str) == FAIL)
4928     {
4929       inst.error = BAD_ARGS;
4930       return;
4931     }
4932   if (rd == REG_PC)
4933     {
4934       inst.error = BAD_PC;
4935       return;
4936     }
4937
4938   /* Parse #<immed>,  field. */
4939   if (is_immediate_prefix (**str))
4940     (*str)++;
4941   else
4942     {
4943       inst.error = _("immediate expression expected");
4944       return;
4945     }
4946   if (my_get_expression (&expr, str))
4947     {
4948       inst.error = _("bad expression");
4949       return;
4950     }
4951   if (expr.X_op != O_constant)
4952     {
4953       inst.error = _("constant expression expected");
4954       return;
4955     }
4956   if (expr.X_add_number + bias < 0
4957       || expr.X_add_number + bias > 31)
4958     {
4959       inst.error = _("immediate value out of range");
4960       return;
4961     }
4962   inst.instruction |= (expr.X_add_number + bias) << 16;
4963   if (skip_past_comma (str) == FAIL)
4964     {
4965       inst.error = BAD_ARGS;
4966       return;
4967     }
4968
4969   /* Parse <Rm> field. */
4970   if ((rm = reg_required_here (str, 0)) == FAIL)
4971     {
4972       inst.error = BAD_ARGS;
4973       return;
4974     }
4975   if (rm == REG_PC)
4976     {
4977       inst.error = BAD_PC;
4978       return;
4979     }
4980
4981   if (skip_past_comma (str) == SUCCESS)
4982     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
4983 }
4984
4985 /* ARM V6 ssat16 (argument parse). */
4986
4987 static void
4988 do_ssat16 (str)
4989      char *str;
4990 {
4991   do_sat16 (&str, /*bias=*/-1);
4992   end_of_line (str);
4993 }
4994
4995 static void
4996 do_usat16 (str)
4997      char *str;
4998 {
4999   do_sat16 (&str, /*bias=*/0);
5000   end_of_line (str);
5001 }
5002
5003 static void
5004 do_sat16 (str, bias)
5005      char **str;
5006      int bias;
5007 {
5008   int rd, rm;
5009   expressionS expr;
5010
5011   skip_whitespace (*str);
5012
5013   /* Parse the <Rd> field. */
5014   if ((rd = reg_required_here (str, 12)) == FAIL
5015       || skip_past_comma (str) == FAIL)
5016     {
5017       inst.error = BAD_ARGS;
5018       return;
5019     }
5020   if (rd == REG_PC)
5021     {
5022       inst.error = BAD_PC;
5023       return;
5024     }
5025
5026   /* Parse #<immed>, field. */
5027   if (is_immediate_prefix (**str))
5028     (*str)++;
5029   else
5030     {
5031       inst.error = _("immediate expression expected");
5032       return;
5033     }
5034   if (my_get_expression (&expr, str))
5035     {
5036       inst.error = _("bad expression");
5037       return;
5038     }
5039   if (expr.X_op != O_constant)
5040     {
5041       inst.error = _("constant expression expected");
5042       return;
5043     }
5044   if (expr.X_add_number + bias < 0
5045       || expr.X_add_number + bias > 15)
5046     {
5047       inst.error = _("immediate value out of range");
5048       return;
5049     }
5050   inst.instruction |= (expr.X_add_number + bias) << 16;
5051   if (skip_past_comma (str) == FAIL)
5052     {
5053       inst.error = BAD_ARGS;
5054       return;
5055     }
5056
5057   /* Parse <Rm> field. */
5058   if ((rm = reg_required_here (str, 0)) == FAIL)
5059     {
5060       inst.error = BAD_ARGS;
5061       return;
5062     }
5063   if (rm == REG_PC)
5064     {
5065       inst.error = BAD_PC;
5066       return;
5067     }
5068 }
5069
5070 /* ARM V6 srs (argument parse). */
5071
5072 static void
5073 do_srs (str)
5074      char* str;
5075 {
5076   char *exclam;
5077   skip_whitespace (str);
5078   exclam = strchr (str, '!');
5079   if (exclam)
5080     *exclam = '\0';
5081   do_cps_mode (&str);
5082   if (exclam)
5083     *exclam = '!';
5084   if (*str == '!') 
5085     {
5086       inst.instruction |= WRITE_BACK;
5087       str++;
5088     }
5089   end_of_line (str);
5090 }
5091
5092 /* ARM V6 SMMUL (argument parse). */
5093
5094 static void
5095 do_smmul (str)
5096      char* str;
5097 {
5098   int rd, rm, rs;
5099   
5100   skip_whitespace (str);
5101   if ((rd = reg_required_here (&str, 16)) == FAIL
5102       || skip_past_comma (&str) == FAIL
5103       || (rm = reg_required_here (&str, 0)) == FAIL
5104       || skip_past_comma (&str) == FAIL
5105       || (rs = reg_required_here (&str, 8)) == FAIL)
5106     {
5107       inst.error = BAD_ARGS;
5108       return;
5109     }
5110
5111   if (rd == REG_PC 
5112       || rm == REG_PC
5113       || rs == REG_PC)
5114     {
5115       inst.error = BAD_PC;
5116       return;
5117     }
5118
5119   end_of_line (str);
5120   
5121 }
5122
5123 /* ARM V6 SMLALD (argument parse). */
5124
5125 static void
5126 do_smlald (str)
5127     char* str;
5128 {
5129   int rdlo, rdhi, rm, rs;
5130   skip_whitespace (str);
5131   if ((rdlo = reg_required_here (&str, 12)) == FAIL
5132       || skip_past_comma (&str) == FAIL
5133       || (rdhi = reg_required_here (&str, 16)) == FAIL
5134       || skip_past_comma (&str) == FAIL
5135       || (rm = reg_required_here (&str, 0)) == FAIL
5136       || skip_past_comma (&str) == FAIL
5137       || (rs = reg_required_here (&str, 8)) == FAIL)
5138     {
5139       inst.error = BAD_ARGS;
5140       return;
5141     }
5142
5143   if (rdlo == REG_PC 
5144       || rdhi == REG_PC 
5145       || rm == REG_PC
5146       || rs == REG_PC)
5147     {
5148       inst.error = BAD_PC;
5149       return;
5150     }
5151
5152   end_of_line (str);
5153 }
5154
5155 /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
5156    smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5157
5158 static void 
5159 do_smlad (str)
5160      char *str;
5161 {
5162   int rd, rm, rs, rn;
5163   
5164   skip_whitespace (str);
5165   if ((rd = reg_required_here (&str, 16)) == FAIL
5166       || skip_past_comma (&str) == FAIL
5167       || (rm = reg_required_here (&str, 0)) == FAIL
5168       || skip_past_comma (&str) == FAIL
5169       || (rs = reg_required_here (&str, 8)) == FAIL
5170       || skip_past_comma (&str) == FAIL
5171       || (rn = reg_required_here (&str, 12)) == FAIL)
5172     {
5173       inst.error = BAD_ARGS;
5174       return;
5175     }
5176   
5177   if (rd == REG_PC 
5178       || rn == REG_PC 
5179       || rs == REG_PC
5180       || rm == REG_PC)
5181     {
5182       inst.error = BAD_PC;
5183       return;
5184     }
5185
5186   end_of_line (str);
5187
5188
5189 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5190    preserving the other bits.
5191
5192    setend <endian_specifier>, where <endian_specifier> is either 
5193    BE or LE. */
5194
5195 static void 
5196 do_setend (str)
5197      char *str;
5198 {
5199   if (do_endian_specifier (str))
5200     inst.instruction |= 0x200;
5201 }
5202
5203 /* Returns true if the endian-specifier indicates big-endianness.  */
5204
5205 static int
5206 do_endian_specifier (str)
5207      char *str;
5208 {
5209   int big_endian = 0;
5210
5211   skip_whitespace (str);
5212   if (strlen (str) < 2)
5213     inst.error = _("missing endian specifier");
5214   else if (strncasecmp (str, "BE", 2) == 0)
5215     {
5216       str += 2;
5217       big_endian = 1;
5218     }
5219   else if (strncasecmp (str, "LE", 2) == 0)
5220     str += 2;
5221   else
5222     inst.error = _("valid endian specifiers are be or le");
5223
5224   end_of_line (str);
5225
5226   return big_endian;
5227 }
5228
5229 /* ARM V6 SXTH.
5230
5231    SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5232    Condition defaults to COND_ALWAYS.
5233    Error if any register uses R15. */
5234
5235 static void 
5236 do_sxth (str)
5237      char *str;
5238 {
5239   int rd, rm;
5240   expressionS expr;
5241   int rotation_clear_mask = 0xfffff3ff;
5242   int rotation_eight_mask = 0x00000400;
5243   int rotation_sixteen_mask = 0x00000800;
5244   int rotation_twenty_four_mask = 0x00000c00;
5245   
5246   skip_whitespace (str);
5247   if ((rd = reg_required_here (&str, 12)) == FAIL
5248       || skip_past_comma (&str) == FAIL
5249       || (rm = reg_required_here (&str, 0)) == FAIL)
5250     {
5251       inst.error = BAD_ARGS;
5252       return;
5253     }
5254
5255   else if (rd == REG_PC || rm == REG_PC)
5256     {
5257       inst.error = BAD_PC;
5258       return;
5259     }
5260   
5261   /* Zero out the rotation field. */
5262   inst.instruction &= rotation_clear_mask;
5263   
5264   /* Check for lack of optional rotation field. */
5265   if (skip_past_comma (&str) == FAIL)
5266     {
5267       end_of_line (str);
5268       return;
5269     }
5270   
5271   /* Move past 'ROR'. */
5272   skip_whitespace (str);
5273   if (strncasecmp (str, "ROR", 3) == 0)
5274     str+=3;
5275   else
5276     {
5277       inst.error = _("missing rotation field after comma");
5278       return;
5279     }
5280   
5281   /* Get the immediate constant. */
5282   skip_whitespace (str);
5283   if (is_immediate_prefix (* str))
5284     str++;
5285   else
5286     {
5287       inst.error = _("immediate expression expected");
5288       return;
5289     }
5290   
5291   if (my_get_expression (&expr, &str))
5292     {
5293       inst.error = _("bad expression");
5294       return;
5295     }
5296
5297   if (expr.X_op != O_constant)
5298     {
5299       inst.error = _("constant expression expected");
5300       return;
5301     }
5302   
5303   switch (expr.X_add_number) 
5304     {
5305     case 0:
5306       /* Rotation field has already been zeroed. */
5307       break;
5308     case 8:
5309       inst.instruction |= rotation_eight_mask;
5310       break;
5311
5312     case 16:
5313       inst.instruction |= rotation_sixteen_mask;
5314       break;
5315       
5316     case 24:
5317       inst.instruction |= rotation_twenty_four_mask;
5318       break;
5319
5320     default:
5321       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5322       break;
5323     }
5324
5325   end_of_line (str);
5326   
5327 }
5328
5329 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5330    extends it to 32-bits, and adds the result to a value in another
5331    register.  You can specify a rotation by 0, 8, 16, or 24 bits
5332    before extracting the 16-bit value.
5333    SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5334    Condition defaults to COND_ALWAYS.
5335    Error if any register uses R15. */
5336
5337 static void 
5338 do_sxtah (str)
5339      char *str;
5340 {
5341   int rd, rn, rm;
5342   expressionS expr;
5343   int rotation_clear_mask = 0xfffff3ff;
5344   int rotation_eight_mask = 0x00000400;
5345   int rotation_sixteen_mask = 0x00000800;
5346   int rotation_twenty_four_mask = 0x00000c00;
5347   
5348   skip_whitespace (str);
5349   if ((rd = reg_required_here (&str, 12)) == FAIL
5350       || skip_past_comma (&str) == FAIL
5351       || (rn = reg_required_here (&str, 16)) == FAIL
5352       || skip_past_comma (&str) == FAIL
5353       || (rm = reg_required_here (&str, 0)) == FAIL)
5354     {
5355       inst.error = BAD_ARGS;
5356       return;
5357     }
5358
5359   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5360     {
5361       inst.error = BAD_PC;
5362       return;
5363     }
5364   
5365   /* Zero out the rotation field. */
5366   inst.instruction &= rotation_clear_mask;
5367   
5368   /* Check for lack of optional rotation field. */
5369   if (skip_past_comma (&str) == FAIL)
5370     {
5371       end_of_line (str);
5372       return;
5373     }
5374   
5375   /* Move past 'ROR'. */
5376   skip_whitespace (str);
5377   if (strncasecmp (str, "ROR", 3) == 0)
5378     str+=3;
5379   else
5380     {
5381       inst.error = _("missing rotation field after comma");
5382       return;
5383     }
5384   
5385   /* Get the immediate constant. */
5386   skip_whitespace (str);
5387   if (is_immediate_prefix (* str))
5388     str++;
5389   else
5390     {
5391       inst.error = _("immediate expression expected");
5392       return;
5393     }
5394   
5395   if (my_get_expression (&expr, &str))
5396     {
5397       inst.error = _("bad expression");
5398       return;
5399     }
5400
5401   if (expr.X_op != O_constant)
5402     {
5403       inst.error = _("constant expression expected");
5404       return;
5405     }
5406   
5407   switch (expr.X_add_number) 
5408     {
5409     case 0:
5410       /* Rotation field has already been zeroed. */
5411       break;
5412
5413     case 8:
5414       inst.instruction |= rotation_eight_mask;
5415       break;
5416
5417     case 16:
5418       inst.instruction |= rotation_sixteen_mask;
5419       break;
5420       
5421     case 24:
5422       inst.instruction |= rotation_twenty_four_mask;
5423       break;
5424
5425     default:
5426       inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5427       break;
5428     }
5429
5430   end_of_line (str);
5431   
5432 }
5433    
5434
5435 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5436    word at the specified address and the following word
5437    respectively. 
5438    Unconditionally executed.
5439    Error if Rn is R15.   
5440 */
5441
5442 static void
5443 do_rfe (str)
5444      char *str;
5445 {
5446   int rn;
5447
5448   skip_whitespace (str);
5449   
5450   if ((rn = reg_required_here (&str, 16)) == FAIL)
5451     return;
5452
5453   if (rn == REG_PC)
5454     {
5455       inst.error = BAD_PC;
5456       return;
5457     }
5458
5459   skip_whitespace (str);
5460   
5461   if (*str == '!')
5462     {
5463       inst.instruction |= WRITE_BACK;
5464       str++;
5465     }
5466   end_of_line (str);
5467 }
5468
5469 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5470    register (argument parse).
5471    REV{<cond>} Rd, Rm.
5472    Condition defaults to COND_ALWAYS.
5473    Error if Rd or Rm are R15. */ 
5474
5475 static void
5476 do_rev (str)
5477      char* str;
5478 {
5479   int rd, rm;
5480
5481   skip_whitespace (str);
5482
5483   if ((rd = reg_required_here (&str, 12)) == FAIL
5484       || skip_past_comma (&str) == FAIL
5485       || (rm = reg_required_here (&str, 0)) == FAIL)
5486     inst.error = BAD_ARGS;
5487
5488   else if (rd == REG_PC || rm == REG_PC)
5489     inst.error = BAD_PC;
5490
5491   else
5492     end_of_line (str);
5493 }
5494
5495 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5496    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
5497    Condition defaults to COND_ALWAYS.
5498    Error if Rd, Rn or Rm are R15.  */
5499
5500 static void
5501 do_qadd16 (str) 
5502      char* str;
5503 {
5504   int rd, rm, rn;
5505
5506   skip_whitespace (str);
5507
5508   if ((rd = reg_required_here (&str, 12)) == FAIL
5509       || skip_past_comma (&str) == FAIL
5510       || (rn = reg_required_here (&str, 16)) == FAIL
5511       || skip_past_comma (&str) == FAIL
5512       || (rm = reg_required_here (&str, 0)) == FAIL)
5513     inst.error = BAD_ARGS;
5514
5515   else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5516     inst.error = BAD_PC;
5517
5518   else
5519     end_of_line (str);
5520 }
5521
5522 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5523    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
5524    Condition defaults to COND_ALWAYS.
5525    Error if Rd, Rn or Rm are R15.  */
5526
5527 static void 
5528 do_pkhbt (str)
5529      char* str;
5530 {
5531   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5532 }
5533
5534 /* ARM V6 PKHTB (Argument Parse). */
5535
5536 static void 
5537 do_pkhtb (str)
5538      char* str;
5539 {
5540   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5541 }
5542
5543 static void
5544 do_pkh_core (str, shift)
5545      char* str;
5546      int shift;
5547 {
5548   int rd, rn, rm;
5549
5550   skip_whitespace (str);
5551   if (((rd = reg_required_here (&str, 12)) == FAIL)
5552       || (skip_past_comma (&str) == FAIL)
5553       || ((rn = reg_required_here (&str, 16)) == FAIL)
5554       || (skip_past_comma (&str) == FAIL)
5555       || ((rm = reg_required_here (&str, 0)) == FAIL))
5556     {
5557       inst.error = BAD_ARGS;
5558       return;
5559     }
5560
5561   else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5562     {
5563       inst.error = BAD_PC;
5564       return;
5565     }
5566
5567   /* Check for optional shift immediate constant. */
5568   if (skip_past_comma (&str) == FAIL) 
5569     {
5570       if (shift == SHIFT_ASR_IMMEDIATE)
5571         {
5572           /* If the shift specifier is ommited, turn the instruction
5573              into pkhbt rd, rm, rn.  First, switch the instruction
5574              code, and clear the rn and rm fields.  */
5575           inst.instruction &= 0xfff0f010;
5576           /* Now, re-encode the registers.  */
5577           inst.instruction |= (rm << 16) | rn;
5578         }
5579       return;
5580     }
5581
5582   decode_shift (&str, shift);
5583 }
5584
5585 /* ARM V6 Load Register Exclusive instruction (argument parse).
5586    LDREX{<cond>} <Rd, [<Rn>]
5587    Condition defaults to COND_ALWAYS.
5588    Error if Rd or Rn are R15. 
5589    See ARMARMv6 A4.1.27: LDREX. */
5590
5591
5592 static void
5593 do_ldrex (str)
5594      char * str;
5595 {
5596   int rd, rn;
5597
5598   skip_whitespace (str);
5599
5600   /* Parse Rd. */
5601   if (((rd = reg_required_here (&str, 12)) == FAIL)
5602       || (skip_past_comma (&str) == FAIL))
5603     {
5604       inst.error = BAD_ARGS;
5605       return;
5606     }
5607   else if (rd == REG_PC)
5608     {
5609       inst.error = BAD_PC;
5610       return;
5611     }
5612   skip_whitespace (str);  
5613
5614   /* Skip past '['. */
5615   if ((strlen (str) >= 1) 
5616       &&strncmp (str, "[", 1) == 0)
5617     str+=1;
5618   skip_whitespace (str);  
5619
5620   /* Parse Rn. */
5621   if ((rn = reg_required_here (&str, 16)) == FAIL)
5622     {
5623       inst.error = BAD_ARGS;
5624       return;
5625     }
5626   else if (rn == REG_PC)
5627     {
5628       inst.error = BAD_PC;
5629       return;
5630     }
5631   skip_whitespace (str);  
5632
5633   /* Skip past ']'. */
5634   if ((strlen (str) >= 1) 
5635       && strncmp (str, "]", 1) == 0)
5636     str+=1;
5637   
5638   end_of_line (str);
5639 }
5640
5641 /* ARM V6 change processor state instruction (argument parse)
5642       CPS, CPSIE, CSPID . */
5643
5644 static void
5645 do_cps (str)
5646      char * str;
5647 {
5648   do_cps_mode (&str);
5649   end_of_line (str);
5650 }
5651
5652 static void
5653 do_cpsi (str)
5654      char * str;
5655 {
5656   do_cps_flags (&str, /*thumb_p=*/0);
5657
5658   if (skip_past_comma (&str) == SUCCESS)
5659     {
5660       skip_whitespace (str);
5661       do_cps_mode (&str);
5662     }
5663   end_of_line (str);
5664 }
5665
5666 static void
5667 do_cps_mode (str)
5668      char **str;
5669 {
5670   expressionS expr;
5671
5672   skip_whitespace (*str);
5673
5674   if (! is_immediate_prefix (**str))
5675     {
5676       inst.error = _("immediate expression expected");
5677       return;
5678     }
5679
5680   (*str)++; /* Strip off the immediate signifier. */
5681   if (my_get_expression (&expr, str))
5682     {
5683       inst.error = _("bad expression");
5684       return;
5685     }
5686
5687   if (expr.X_op != O_constant)
5688     {
5689       inst.error = _("constant expression expected");
5690       return;
5691     }
5692   
5693   /* The mode is a 5 bit field.  Valid values are 0-31. */
5694   if (((unsigned) expr.X_add_number) > 31
5695       || (inst.reloc.exp.X_add_number) < 0)
5696     {
5697       inst.error = _("invalid constant");
5698       return;
5699     }
5700   
5701   inst.instruction |= expr.X_add_number;
5702 }
5703
5704 static void
5705 do_cps_flags (str, thumb_p)
5706      char **str;
5707      int    thumb_p;
5708 {
5709   struct cps_flag { 
5710     char character;
5711     unsigned long arm_value;
5712     unsigned long thumb_value;
5713   };
5714   static struct cps_flag flag_table[] = {
5715     {'a', 0x100, 0x4 },
5716     {'i', 0x080, 0x2 },
5717     {'f', 0x040, 0x1 }
5718   };
5719
5720   int saw_a_flag = 0;
5721
5722   skip_whitespace (*str);
5723
5724   /* Get the a, f and i flags. */
5725   while (**str && **str != ',')
5726     {
5727       struct cps_flag *p;
5728       struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5729       for (p = flag_table; p < q; ++p)
5730         if (strncasecmp (*str, &p->character, 1) == 0)
5731           {
5732             inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5733             saw_a_flag = 1;
5734             break;
5735           }
5736       if (p == q)
5737         {
5738           inst.error = _("unrecognized flag");
5739           return;
5740         }
5741       (*str)++;
5742     }
5743   if (!saw_a_flag) 
5744     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5745 }
5746
5747 /* THUMB V5 breakpoint instruction (argument parse)
5748         BKPT <immed_8>.  */
5749
5750 static void
5751 do_t_bkpt (str)
5752      char * str;
5753 {
5754   expressionS expr;
5755   unsigned long number;
5756
5757   skip_whitespace (str);
5758
5759   /* Allow optional leading '#'.  */
5760   if (is_immediate_prefix (*str))
5761     str ++;
5762
5763   memset (& expr, '\0', sizeof (expr));
5764   if (my_get_expression (& expr, & str)
5765       || (expr.X_op != O_constant
5766           /* As a convenience we allow 'bkpt' without an operand.  */
5767           && expr.X_op != O_absent))
5768     {
5769       inst.error = _("bad expression");
5770       return;
5771     }
5772
5773   number = expr.X_add_number;
5774
5775   /* Check it fits an 8 bit unsigned.  */
5776   if (number != (number & 0xff))
5777     {
5778       inst.error = _("immediate value out of range");
5779       return;
5780     }
5781
5782   inst.instruction |= number;
5783
5784   end_of_line (str);
5785 }
5786
5787 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5788    Expects inst.instruction is set for BLX(1).
5789    Note: this is cloned from do_branch, and the reloc changed to be a
5790         new one that can cope with setting one extra bit (the H bit).  */
5791
5792 static void
5793 do_branch25 (str)
5794      char *        str;
5795 {
5796   if (my_get_expression (& inst.reloc.exp, & str))
5797     return;
5798
5799 #ifdef OBJ_ELF
5800   {
5801     char * save_in;
5802
5803     /* ScottB: February 5, 1998 */
5804     /* Check to see of PLT32 reloc required for the instruction.  */
5805
5806     /* arm_parse_reloc() works on input_line_pointer.
5807        We actually want to parse the operands to the branch instruction
5808        passed in 'str'.  Save the input pointer and restore it later.  */
5809     save_in = input_line_pointer;
5810     input_line_pointer = str;
5811
5812     if (inst.reloc.exp.X_op == O_symbol
5813         && *str == '('
5814         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5815       {
5816         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5817         inst.reloc.pc_rel = 0;
5818         /* Modify str to point to after parsed operands, otherwise
5819            end_of_line() will complain about the (PLT) left in str.  */
5820         str = input_line_pointer;
5821       }
5822     else
5823       {
5824         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5825         inst.reloc.pc_rel = 1;
5826       }
5827
5828     input_line_pointer = save_in;
5829   }
5830 #else
5831   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5832   inst.reloc.pc_rel = 1;
5833 #endif /* OBJ_ELF */
5834
5835   end_of_line (str);
5836 }
5837
5838 /* ARM V5 branch-link-exchange instruction (argument parse)
5839      BLX <target_addr>          ie BLX(1)
5840      BLX{<condition>} <Rm>      ie BLX(2)
5841    Unfortunately, there are two different opcodes for this mnemonic.
5842    So, the insns[].value is not used, and the code here zaps values
5843         into inst.instruction.
5844    Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5845
5846 static void
5847 do_blx (str)
5848      char *        str;
5849 {
5850   char * mystr = str;
5851   int rm;
5852
5853   skip_whitespace (mystr);
5854   rm = reg_required_here (& mystr, 0);
5855
5856   /* The above may set inst.error.  Ignore his opinion.  */
5857   inst.error = 0;
5858
5859   if (rm != FAIL)
5860     {
5861       /* Arg is a register.
5862          Use the condition code our caller put in inst.instruction.
5863          Pass ourselves off as a BX with a funny opcode.  */
5864       inst.instruction |= 0x012fff30;
5865       do_bx (str);
5866     }
5867   else
5868     {
5869       /* This must be is BLX <target address>, no condition allowed.  */
5870       if (inst.instruction != COND_ALWAYS)
5871         {
5872           inst.error = BAD_COND;
5873           return;
5874         }
5875
5876       inst.instruction = 0xfafffffe;
5877
5878       /* Process like a B/BL, but with a different reloc.
5879          Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5880       do_branch25 (str);
5881     }
5882 }
5883
5884 /* ARM V5 Thumb BLX (argument parse)
5885         BLX <target_addr>       which is BLX(1)
5886         BLX <Rm>                which is BLX(2)
5887    Unfortunately, there are two different opcodes for this mnemonic.
5888    So, the tinsns[].value is not used, and the code here zaps values
5889         into inst.instruction.  */
5890
5891 static void
5892 do_t_blx (str)
5893      char * str;
5894 {
5895   char * mystr = str;
5896   int rm;
5897
5898   skip_whitespace (mystr);
5899   inst.instruction = 0x4780;
5900
5901   /* Note that this call is to the ARM register recognizer.  BLX(2)
5902      uses the ARM register space, not the Thumb one, so a call to
5903      thumb_reg() would be wrong.  */
5904   rm = reg_required_here (& mystr, 3);
5905   inst.error = 0;
5906
5907   if (rm != FAIL)
5908     {
5909       /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5910       inst.size = 2;
5911     }
5912   else
5913     {
5914       /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5915       inst.instruction = 0xf7ffeffe;
5916       inst.size = 4;
5917
5918       if (my_get_expression (& inst.reloc.exp, & mystr))
5919         return;
5920
5921       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5922       inst.reloc.pc_rel = 1;
5923     }
5924
5925   end_of_line (mystr);
5926 }
5927
5928 /* ARM V5 breakpoint instruction (argument parse)
5929      BKPT <16 bit unsigned immediate>
5930      Instruction is not conditional.
5931         The bit pattern given in insns[] has the COND_ALWAYS condition,
5932         and it is an error if the caller tried to override that.  */
5933
5934 static void
5935 do_bkpt (str)
5936      char *        str;
5937 {
5938   expressionS expr;
5939   unsigned long number;
5940
5941   skip_whitespace (str);
5942
5943   /* Allow optional leading '#'.  */
5944   if (is_immediate_prefix (* str))
5945     str++;
5946
5947   memset (& expr, '\0', sizeof (expr));
5948
5949   if (my_get_expression (& expr, & str)
5950       || (expr.X_op != O_constant
5951           /* As a convenience we allow 'bkpt' without an operand.  */
5952           && expr.X_op != O_absent))
5953     {
5954       inst.error = _("bad expression");
5955       return;
5956     }
5957
5958   number = expr.X_add_number;
5959
5960   /* Check it fits a 16 bit unsigned.  */
5961   if (number != (number & 0xffff))
5962     {
5963       inst.error = _("immediate value out of range");
5964       return;
5965     }
5966
5967   /* Top 12 of 16 bits to bits 19:8.  */
5968   inst.instruction |= (number & 0xfff0) << 4;
5969
5970   /* Bottom 4 of 16 bits to bits 3:0.  */
5971   inst.instruction |= number & 0xf;
5972
5973   end_of_line (str);
5974 }
5975
5976 /* THUMB CPS instruction (argument parse).  */
5977
5978 static void
5979 do_t_cps (str)
5980      char *str;
5981 {
5982   do_cps_flags (&str, /*thumb_p=*/1);
5983   end_of_line (str);
5984 }
5985
5986 /* THUMB CPY instruction (argument parse).  */
5987
5988 static void
5989 do_t_cpy (str)
5990      char *str;
5991 {
5992   thumb_mov_compare (str, THUMB_CPY);
5993 }
5994
5995 /* THUMB SETEND instruction (argument parse).  */
5996
5997 static void
5998 do_t_setend (str)
5999      char *str;
6000 {
6001   if (do_endian_specifier (str))
6002     inst.instruction |= 0x8;
6003 }
6004
6005 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6006
6007 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6008
6009 static unsigned long
6010 check_iwmmxt_insn (str, insn_type, immediate_size)
6011      char * str;
6012      enum iwmmxt_insn_type insn_type;
6013      int immediate_size;
6014 {
6015   int reg = 0;
6016   const char *  inst_error;
6017   expressionS expr;
6018   unsigned long number;
6019
6020   inst_error = inst.error;
6021   if (!inst.error)
6022     inst.error = BAD_ARGS;
6023   skip_whitespace (str);
6024
6025   switch (insn_type)
6026     {
6027     case check_rd:
6028       if ((reg = reg_required_here (&str, 12)) == FAIL)
6029         return FAIL;
6030       break;
6031       
6032     case check_wr:
6033        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6034          return FAIL;
6035        break;
6036        
6037     case check_wrwr:
6038       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6039            || skip_past_comma (&str) == FAIL
6040            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6041         return FAIL;
6042       break;
6043       
6044     case check_wrwrwr:
6045       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6046            || skip_past_comma (&str) == FAIL
6047            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6048            || skip_past_comma (&str) == FAIL
6049            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6050         return FAIL;
6051       break;
6052       
6053     case check_wrwrwcg:
6054       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6055            || skip_past_comma (&str) == FAIL
6056            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6057            || skip_past_comma (&str) == FAIL
6058            || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6059         return FAIL;
6060       break;
6061       
6062     case check_tbcst:
6063       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6064            || skip_past_comma (&str) == FAIL
6065            || reg_required_here (&str, 12) == FAIL))
6066         return FAIL;
6067       break;
6068       
6069     case check_tmovmsk:
6070       if ((reg_required_here (&str, 12) == FAIL
6071            || skip_past_comma (&str) == FAIL
6072            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6073         return FAIL;
6074       break;
6075       
6076     case check_tmia:
6077       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6078            || skip_past_comma (&str) == FAIL
6079            || reg_required_here (&str, 0) == FAIL
6080            || skip_past_comma (&str) == FAIL
6081            || reg_required_here (&str, 12) == FAIL))
6082         return FAIL;
6083       break;
6084       
6085     case check_tmcrr:
6086       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6087            || skip_past_comma (&str) == FAIL
6088            || reg_required_here (&str, 12) == FAIL
6089            || skip_past_comma (&str) == FAIL
6090            || reg_required_here (&str, 16) == FAIL))
6091         return FAIL;
6092       break;
6093       
6094     case check_tmrrc:
6095       if ((reg_required_here (&str, 12) == FAIL
6096            || skip_past_comma (&str) == FAIL
6097            || reg_required_here (&str, 16) == FAIL
6098            || skip_past_comma (&str) == FAIL
6099            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6100         return FAIL;
6101       break;
6102       
6103     case check_tmcr:
6104       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6105            || skip_past_comma (&str) == FAIL
6106            || reg_required_here (&str, 12) == FAIL))
6107         return FAIL;
6108       break;
6109       
6110     case check_tmrc:
6111       if ((reg_required_here (&str, 12) == FAIL
6112            || skip_past_comma (&str) == FAIL
6113            || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6114         return FAIL;
6115       break;
6116       
6117     case check_tinsr:
6118       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6119            || skip_past_comma (&str) == FAIL
6120            || reg_required_here (&str, 12) == FAIL
6121            || skip_past_comma (&str) == FAIL))
6122         return FAIL;
6123       break;
6124       
6125     case check_textrc:
6126       if ((reg_required_here (&str, 12) == FAIL
6127            || skip_past_comma (&str) == FAIL))
6128         return FAIL;
6129       break;
6130       
6131     case check_waligni:
6132       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6133            || skip_past_comma (&str) == FAIL
6134            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6135            || skip_past_comma (&str) == FAIL
6136            || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6137            || skip_past_comma (&str) == FAIL))
6138         return FAIL;
6139       break;
6140       
6141     case check_textrm:
6142       if ((reg_required_here (&str, 12) == FAIL
6143            || skip_past_comma (&str) == FAIL
6144            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6145            || skip_past_comma (&str) == FAIL))
6146         return FAIL;
6147       break;
6148       
6149     case check_wshufh:
6150       if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6151            || skip_past_comma (&str) == FAIL
6152            || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6153            || skip_past_comma (&str) == FAIL))
6154         return FAIL;
6155       break;
6156     }
6157   
6158   if (immediate_size == 0)
6159     {
6160       end_of_line (str);
6161       inst.error = inst_error;
6162       return reg;
6163     }
6164   else
6165     {
6166       skip_whitespace (str);      
6167   
6168       /* Allow optional leading '#'. */
6169       if (is_immediate_prefix (* str))
6170         str++;
6171
6172       memset (& expr, '\0', sizeof (expr));
6173   
6174       if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6175         {
6176           inst.error = _("bad or missing expression");
6177           return FAIL;
6178         }
6179   
6180       number = expr.X_add_number;
6181   
6182       if (number != (number & immediate_size))
6183         {
6184           inst.error = _("immediate value out of range");
6185           return FAIL;
6186         }
6187       end_of_line (str);
6188       inst.error = inst_error;
6189       return number;
6190     }
6191 }
6192
6193 static void
6194 do_iwmmxt_byte_addr (str)
6195      char * str;
6196 {
6197   int op = (inst.instruction & 0x300) >> 8;
6198   int reg;
6199
6200   inst.instruction &= ~0x300;
6201   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6202
6203   skip_whitespace (str);
6204
6205   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6206       || skip_past_comma (& str) == FAIL
6207       || cp_byte_address_required_here (&str) == FAIL)
6208     {
6209       if (! inst.error)
6210         inst.error = BAD_ARGS;
6211     }
6212   else
6213     end_of_line (str);
6214
6215   if (wc_register (reg))
6216     {
6217       as_bad (_("non-word size not supported with control register"));
6218       inst.instruction |=  0xf0000100;
6219       inst.instruction &= ~0x00400000;
6220     }
6221 }
6222
6223 static void
6224 do_iwmmxt_tandc (str)
6225      char * str;
6226 {
6227   int reg;
6228
6229   reg = check_iwmmxt_insn (str, check_rd, 0);
6230
6231   if (reg != REG_PC && !inst.error)
6232     inst.error = _("only r15 allowed here");
6233 }
6234
6235 static void
6236 do_iwmmxt_tbcst (str)
6237      char * str;
6238 {
6239   check_iwmmxt_insn (str, check_tbcst, 0);
6240 }
6241
6242 static void
6243 do_iwmmxt_textrc (str)
6244      char * str;
6245 {
6246   unsigned long number;
6247
6248   if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6249     return;
6250
6251   inst.instruction |= number & 0x7;
6252 }
6253
6254 static void
6255 do_iwmmxt_textrm (str)
6256      char * str;
6257 {
6258   unsigned long number;
6259
6260   if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6261     return;
6262
6263   inst.instruction |= number & 0x7;
6264 }
6265
6266 static void
6267 do_iwmmxt_tinsr (str)
6268      char * str;
6269 {
6270   unsigned long number;
6271
6272   if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6273     return;
6274
6275   inst.instruction |= number & 0x7;
6276 }
6277
6278 static void
6279 do_iwmmxt_tmcr (str)
6280      char * str;
6281 {
6282   check_iwmmxt_insn (str, check_tmcr, 0);
6283 }
6284
6285 static void
6286 do_iwmmxt_tmcrr (str)
6287      char * str;
6288 {
6289   check_iwmmxt_insn (str, check_tmcrr, 0);
6290 }
6291
6292 static void
6293 do_iwmmxt_tmia (str)
6294      char * str;
6295 {
6296   check_iwmmxt_insn (str, check_tmia, 0);
6297 }
6298
6299 static void
6300 do_iwmmxt_tmovmsk (str)
6301      char * str;
6302 {
6303   check_iwmmxt_insn (str, check_tmovmsk, 0);
6304 }
6305
6306 static void
6307 do_iwmmxt_tmrc (str)
6308      char * str;
6309 {
6310   check_iwmmxt_insn (str, check_tmrc, 0);
6311 }
6312
6313 static void
6314 do_iwmmxt_tmrrc (str)
6315      char * str;
6316 {
6317   check_iwmmxt_insn (str, check_tmrrc, 0);
6318 }
6319
6320 static void
6321 do_iwmmxt_torc (str)
6322      char * str;
6323 {
6324   check_iwmmxt_insn (str, check_rd, 0);
6325 }
6326
6327 static void
6328 do_iwmmxt_waligni (str)
6329      char * str;
6330 {
6331   unsigned long number;
6332
6333   if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6334     return;
6335
6336   inst.instruction |= ((number & 0x7) << 20);
6337 }
6338
6339 static void
6340 do_iwmmxt_wmov (str)
6341      char * str;
6342 {
6343   if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6344     return;
6345   
6346   inst.instruction |= ((inst.instruction >> 16) & 0xf);
6347 }
6348
6349 static void
6350 do_iwmmxt_word_addr (str)
6351      char * str;
6352 {
6353   int op = (inst.instruction & 0x300) >> 8;
6354   int reg;
6355
6356   inst.instruction &= ~0x300;
6357   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
6358
6359   skip_whitespace (str);
6360
6361   if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6362       || skip_past_comma (& str) == FAIL
6363       || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6364     {
6365       if (! inst.error)
6366         inst.error = BAD_ARGS;
6367     }
6368   else
6369     end_of_line (str);
6370
6371   if (wc_register (reg))
6372     {
6373       if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6374         as_bad (_("conditional execution not supported with control register"));
6375       if (op != 2)
6376         as_bad (_("non-word size not supported with control register"));
6377       inst.instruction |=  0xf0000100;
6378       inst.instruction &= ~0x00400000;
6379     }
6380 }
6381
6382 static void
6383 do_iwmmxt_wrwr (str)
6384      char * str;
6385 {
6386   check_iwmmxt_insn (str, check_wrwr, 0);
6387 }
6388
6389 static void
6390 do_iwmmxt_wrwrwcg (str)
6391      char * str;
6392 {
6393   check_iwmmxt_insn (str, check_wrwrwcg, 0);
6394 }
6395
6396 static void
6397 do_iwmmxt_wrwrwr (str)
6398      char * str;
6399 {
6400   check_iwmmxt_insn (str, check_wrwrwr, 0);
6401 }
6402
6403 static void
6404 do_iwmmxt_wshufh (str)
6405      char * str;
6406 {
6407   unsigned long number;
6408
6409   if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6410     return;
6411
6412   inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6413 }
6414
6415 static void
6416 do_iwmmxt_wzero (str)
6417      char * str;
6418 {
6419   if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6420     return;
6421
6422   inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6423 }
6424
6425 /* Xscale multiply-accumulate (argument parse)
6426      MIAcc   acc0,Rm,Rs
6427      MIAPHcc acc0,Rm,Rs
6428      MIAxycc acc0,Rm,Rs.  */
6429
6430 static void
6431 do_xsc_mia (str)
6432      char * str;
6433 {
6434   int rs;
6435   int rm;
6436
6437   if (accum0_required_here (& str) == FAIL)
6438     inst.error = ERR_NO_ACCUM;
6439
6440   else if (skip_past_comma (& str) == FAIL
6441            || (rm = reg_required_here (& str, 0)) == FAIL)
6442     inst.error = BAD_ARGS;
6443
6444   else if (skip_past_comma (& str) == FAIL
6445            || (rs = reg_required_here (& str, 12)) == FAIL)
6446     inst.error = BAD_ARGS;
6447
6448   /* inst.instruction has now been zapped with both rm and rs.  */
6449   else if (rm == REG_PC || rs == REG_PC)
6450     inst.error = BAD_PC;        /* Undefined result if rm or rs is R15.  */
6451
6452   else
6453     end_of_line (str);
6454 }
6455
6456 /* Xscale move-accumulator-register (argument parse)
6457
6458      MARcc   acc0,RdLo,RdHi.  */
6459
6460 static void
6461 do_xsc_mar (str)
6462      char * str;
6463 {
6464   int rdlo, rdhi;
6465
6466   if (accum0_required_here (& str) == FAIL)
6467     inst.error = ERR_NO_ACCUM;
6468
6469   else if (skip_past_comma (& str) == FAIL
6470            || (rdlo = reg_required_here (& str, 12)) == FAIL)
6471     inst.error = BAD_ARGS;
6472
6473   else if (skip_past_comma (& str) == FAIL
6474            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6475     inst.error = BAD_ARGS;
6476
6477   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6478   else if (rdlo == REG_PC || rdhi == REG_PC)
6479     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6480
6481   else
6482     end_of_line (str);
6483 }
6484
6485 /* Xscale move-register-accumulator (argument parse)
6486
6487      MRAcc   RdLo,RdHi,acc0.  */
6488
6489 static void
6490 do_xsc_mra (str)
6491      char * str;
6492 {
6493   int rdlo;
6494   int rdhi;
6495
6496   skip_whitespace (str);
6497
6498   if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6499     inst.error = BAD_ARGS;
6500
6501   else if (skip_past_comma (& str) == FAIL
6502            || (rdhi = reg_required_here (& str, 16)) == FAIL)
6503     inst.error = BAD_ARGS;
6504
6505   else if  (skip_past_comma (& str) == FAIL
6506             || accum0_required_here (& str) == FAIL)
6507     inst.error = ERR_NO_ACCUM;
6508
6509   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6510   else if (rdlo == rdhi)
6511     inst.error = BAD_ARGS;      /* Undefined result if 2 writes to same reg.  */
6512
6513   else if (rdlo == REG_PC || rdhi == REG_PC)
6514     inst.error = BAD_PC;        /* Undefined result if rdlo or rdhi is R15.  */
6515   else
6516     end_of_line (str);
6517 }
6518
6519 /* ARMv5TE: Preload-Cache
6520
6521     PLD <addr_mode>
6522
6523   Syntactically, like LDR with B=1, W=0, L=1.  */
6524
6525 static void
6526 do_pld (str)
6527      char * str;
6528 {
6529   int rd;
6530
6531   skip_whitespace (str);
6532
6533   if (* str != '[')
6534     {
6535       inst.error = _("'[' expected after PLD mnemonic");
6536       return;
6537     }
6538
6539   ++str;
6540   skip_whitespace (str);
6541
6542   if ((rd = reg_required_here (& str, 16)) == FAIL)
6543     return;
6544
6545   skip_whitespace (str);
6546
6547   if (*str == ']')
6548     {
6549       /* [Rn], ... ?  */
6550       ++str;
6551       skip_whitespace (str);
6552
6553       /* Post-indexed addressing is not allowed with PLD.  */
6554       if (skip_past_comma (&str) == SUCCESS)
6555         {
6556           inst.error
6557             = _("post-indexed expression used in preload instruction");
6558           return;
6559         }
6560       else if (*str == '!') /* [Rn]! */
6561         {
6562           inst.error = _("writeback used in preload instruction");
6563           ++str;
6564         }
6565       else /* [Rn] */
6566         inst.instruction |= INDEX_UP | PRE_INDEX;
6567     }
6568   else /* [Rn, ...] */
6569     {
6570       if (skip_past_comma (& str) == FAIL)
6571         {
6572           inst.error = _("pre-indexed expression expected");
6573           return;
6574         }
6575
6576       if (ldst_extend (&str) == FAIL)
6577         return;
6578
6579       skip_whitespace (str);
6580
6581       if (* str != ']')
6582         {
6583           inst.error = _("missing ]");
6584           return;
6585         }
6586
6587       ++ str;
6588       skip_whitespace (str);
6589
6590       if (* str == '!') /* [Rn]! */
6591         {
6592           inst.error = _("writeback used in preload instruction");
6593           ++ str;
6594         }
6595
6596       inst.instruction |= PRE_INDEX;
6597     }
6598
6599   end_of_line (str);
6600 }
6601
6602 /* ARMv5TE load-consecutive (argument parse)
6603    Mode is like LDRH.
6604
6605      LDRccD R, mode
6606      STRccD R, mode.  */
6607
6608 static void
6609 do_ldrd (str)
6610      char * str;
6611 {
6612   int rd;
6613   int rn;
6614
6615   skip_whitespace (str);
6616
6617   if ((rd = reg_required_here (& str, 12)) == FAIL)
6618     {
6619       inst.error = BAD_ARGS;
6620       return;
6621     }
6622
6623   if (skip_past_comma (& str) == FAIL
6624       || (rn = ld_mode_required_here (& str)) == FAIL)
6625     {
6626       if (!inst.error)
6627         inst.error = BAD_ARGS;
6628       return;
6629     }
6630
6631   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6632   if (rd & 1)           /* Unpredictable result if Rd is odd.  */
6633     {
6634       inst.error = _("destination register must be even");
6635       return;
6636     }
6637
6638   if (rd == REG_LR)
6639     {
6640       inst.error = _("r14 not allowed here");
6641       return;
6642     }
6643
6644   if (((rd == rn) || (rd + 1 == rn))
6645       && ((inst.instruction & WRITE_BACK)
6646           || (!(inst.instruction & PRE_INDEX))))
6647     as_warn (_("pre/post-indexing used when modified address register is destination"));
6648
6649   /* For an index-register load, the index register must not overlap the
6650      destination (even if not write-back).  */
6651   if ((inst.instruction & V4_STR_BIT) == 0
6652       && (inst.instruction & HWOFFSET_IMM) == 0)
6653     {
6654       int rm = inst.instruction & 0x0000000f;
6655
6656       if (rm == rd || (rm == rd + 1))
6657         as_warn (_("ldrd destination registers must not overlap index register"));
6658     }
6659
6660   end_of_line (str);
6661 }
6662
6663 /* Returns the index into fp_values of a floating point number,
6664    or -1 if not in the table.  */
6665
6666 static int
6667 my_get_float_expression (str)
6668      char ** str;
6669 {
6670   LITTLENUM_TYPE words[MAX_LITTLENUMS];
6671   char *         save_in;
6672   expressionS    exp;
6673   int            i;
6674   int            j;
6675
6676   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6677
6678   /* Look for a raw floating point number.  */
6679   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6680       && is_end_of_line[(unsigned char) *save_in])
6681     {
6682       for (i = 0; i < NUM_FLOAT_VALS; i++)
6683         {
6684           for (j = 0; j < MAX_LITTLENUMS; j++)
6685             {
6686               if (words[j] != fp_values[i][j])
6687                 break;
6688             }
6689
6690           if (j == MAX_LITTLENUMS)
6691             {
6692               *str = save_in;
6693               return i;
6694             }
6695         }
6696     }
6697
6698   /* Try and parse a more complex expression, this will probably fail
6699      unless the code uses a floating point prefix (eg "0f").  */
6700   save_in = input_line_pointer;
6701   input_line_pointer = *str;
6702   if (expression (&exp) == absolute_section
6703       && exp.X_op == O_big
6704       && exp.X_add_number < 0)
6705     {
6706       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6707          Ditto for 15.  */
6708       if (gen_to_words (words, 5, (long) 15) == 0)
6709         {
6710           for (i = 0; i < NUM_FLOAT_VALS; i++)
6711             {
6712               for (j = 0; j < MAX_LITTLENUMS; j++)
6713                 {
6714                   if (words[j] != fp_values[i][j])
6715                     break;
6716                 }
6717
6718               if (j == MAX_LITTLENUMS)
6719                 {
6720                   *str = input_line_pointer;
6721                   input_line_pointer = save_in;
6722                   return i;
6723                 }
6724             }
6725         }
6726     }
6727
6728   *str = input_line_pointer;
6729   input_line_pointer = save_in;
6730   return -1;
6731 }
6732
6733 /* Return TRUE if anything in the expression is a bignum.  */
6734
6735 static int
6736 walk_no_bignums (sp)
6737      symbolS * sp;
6738 {
6739   if (symbol_get_value_expression (sp)->X_op == O_big)
6740     return 1;
6741
6742   if (symbol_get_value_expression (sp)->X_add_symbol)
6743     {
6744       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6745               || (symbol_get_value_expression (sp)->X_op_symbol
6746                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6747     }
6748
6749   return 0;
6750 }
6751
6752 static int in_my_get_expression = 0;
6753
6754 static int
6755 my_get_expression (ep, str)
6756      expressionS * ep;
6757      char ** str;
6758 {
6759   char * save_in;
6760   segT   seg;
6761
6762   save_in = input_line_pointer;
6763   input_line_pointer = *str;
6764   in_my_get_expression = 1;
6765   seg = expression (ep);
6766   in_my_get_expression = 0;
6767
6768   if (ep->X_op == O_illegal)
6769     {
6770       /* We found a bad expression in md_operand().  */
6771       *str = input_line_pointer;
6772       input_line_pointer = save_in;
6773       return 1;
6774     }
6775
6776 #ifdef OBJ_AOUT
6777   if (seg != absolute_section
6778       && seg != text_section
6779       && seg != data_section
6780       && seg != bss_section
6781       && seg != undefined_section)
6782     {
6783       inst.error = _("bad_segment");
6784       *str = input_line_pointer;
6785       input_line_pointer = save_in;
6786       return 1;
6787     }
6788 #endif
6789
6790   /* Get rid of any bignums now, so that we don't generate an error for which
6791      we can't establish a line number later on.  Big numbers are never valid
6792      in instructions, which is where this routine is always called.  */
6793   if (ep->X_op == O_big
6794       || (ep->X_add_symbol
6795           && (walk_no_bignums (ep->X_add_symbol)
6796               || (ep->X_op_symbol
6797                   && walk_no_bignums (ep->X_op_symbol)))))
6798     {
6799       inst.error = _("invalid constant");
6800       *str = input_line_pointer;
6801       input_line_pointer = save_in;
6802       return 1;
6803     }
6804
6805   *str = input_line_pointer;
6806   input_line_pointer = save_in;
6807   return 0;
6808 }
6809
6810 /* We handle all bad expressions here, so that we can report the faulty
6811    instruction in the error message.  */
6812 void
6813 md_operand (expr)
6814      expressionS *expr;
6815 {
6816   if (in_my_get_expression)
6817     {
6818       expr->X_op = O_illegal;
6819       if (inst.error == NULL)
6820         inst.error = _("bad expression");
6821     }
6822 }
6823
6824 /* KIND indicates what kind of shifts are accepted.  */
6825
6826 static int
6827 decode_shift (str, kind)
6828      char ** str;
6829      int     kind;
6830 {
6831   const struct asm_shift_name * shift;
6832   char * p;
6833   char   c;
6834
6835   skip_whitespace (* str);
6836
6837   for (p = * str; ISALPHA (* p); p ++)
6838     ;
6839
6840   if (p == * str)
6841     {
6842       inst.error = _("shift expression expected");
6843       return FAIL;
6844     }
6845
6846   c = * p;
6847   * p = '\0';
6848   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6849   * p = c;
6850
6851   if (shift == NULL)
6852     {
6853       inst.error = _("shift expression expected");
6854       return FAIL;
6855     }
6856
6857   assert (shift->properties->index == shift_properties[shift->properties->index].index);
6858
6859   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6860       && shift->properties->index != SHIFT_LSL
6861       && shift->properties->index != SHIFT_ASR)
6862     {
6863       inst.error = _("'LSL' or 'ASR' required");
6864       return FAIL;
6865     }
6866   else if (kind == SHIFT_LSL_IMMEDIATE
6867            && shift->properties->index != SHIFT_LSL)
6868     {
6869       inst.error = _("'LSL' required");
6870       return FAIL;
6871     }
6872   else if (kind == SHIFT_ASR_IMMEDIATE
6873            && shift->properties->index != SHIFT_ASR)
6874     {
6875       inst.error = _("'ASR' required");
6876       return FAIL;
6877     }
6878     
6879   if (shift->properties->index == SHIFT_RRX)
6880     {
6881       * str = p;
6882       inst.instruction |= shift->properties->bit_field;
6883       return SUCCESS;
6884     }
6885
6886   skip_whitespace (p);
6887
6888   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6889     {
6890       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6891       * str = p;
6892       return SUCCESS;
6893     }
6894   else if (! is_immediate_prefix (* p))
6895     {
6896       inst.error = (NO_SHIFT_RESTRICT
6897                     ? _("shift requires register or #expression")
6898                     : _("shift requires #expression"));
6899       * str = p;
6900       return FAIL;
6901     }
6902
6903   inst.error = NULL;
6904   p ++;
6905
6906   if (my_get_expression (& inst.reloc.exp, & p))
6907     return FAIL;
6908
6909   /* Validate some simple #expressions.  */
6910   if (inst.reloc.exp.X_op == O_constant)
6911     {
6912       unsigned num = inst.reloc.exp.X_add_number;
6913
6914       /* Reject operations greater than 32.  */
6915       if (num > 32
6916           /* Reject a shift of 0 unless the mode allows it.  */
6917           || (num == 0 && shift->properties->allows_0 == 0)
6918           /* Reject a shift of 32 unless the mode allows it.  */
6919           || (num == 32 && shift->properties->allows_32 == 0)
6920           )
6921         {
6922           /* As a special case we allow a shift of zero for
6923              modes that do not support it to be recoded as an
6924              logical shift left of zero (ie nothing).  We warn
6925              about this though.  */
6926           if (num == 0)
6927             {
6928               as_warn (_("shift of 0 ignored."));
6929               shift = & shift_names[0];
6930               assert (shift->properties->index == SHIFT_LSL);
6931             }
6932           else
6933             {
6934               inst.error = _("invalid immediate shift");
6935               return FAIL;
6936             }
6937         }
6938
6939       /* Shifts of 32 are encoded as 0, for those shifts that
6940          support it.  */
6941       if (num == 32)
6942         num = 0;
6943
6944       inst.instruction |= (num << 7) | shift->properties->bit_field;
6945     }
6946   else
6947     {
6948       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
6949       inst.reloc.pc_rel = 0;
6950       inst.instruction |= shift->properties->bit_field;
6951     }
6952
6953   * str = p;
6954   return SUCCESS;
6955 }
6956
6957 /* Do those data_ops which can take a negative immediate constant
6958    by altering the instruction.  A bit of a hack really.
6959         MOV <-> MVN
6960         AND <-> BIC
6961         ADC <-> SBC
6962         by inverting the second operand, and
6963         ADD <-> SUB
6964         CMP <-> CMN
6965         by negating the second operand.  */
6966
6967 static int
6968 negate_data_op (instruction, value)
6969      unsigned long * instruction;
6970      unsigned long   value;
6971 {
6972   int op, new_inst;
6973   unsigned long negated, inverted;
6974
6975   negated = validate_immediate (-value);
6976   inverted = validate_immediate (~value);
6977
6978   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
6979   switch (op)
6980     {
6981       /* First negates.  */
6982     case OPCODE_SUB:             /* ADD <-> SUB  */
6983       new_inst = OPCODE_ADD;
6984       value = negated;
6985       break;
6986
6987     case OPCODE_ADD:
6988       new_inst = OPCODE_SUB;
6989       value = negated;
6990       break;
6991
6992     case OPCODE_CMP:             /* CMP <-> CMN  */
6993       new_inst = OPCODE_CMN;
6994       value = negated;
6995       break;
6996
6997     case OPCODE_CMN:
6998       new_inst = OPCODE_CMP;
6999       value = negated;
7000       break;
7001
7002       /* Now Inverted ops.  */
7003     case OPCODE_MOV:             /* MOV <-> MVN  */
7004       new_inst = OPCODE_MVN;
7005       value = inverted;
7006       break;
7007
7008     case OPCODE_MVN:
7009       new_inst = OPCODE_MOV;
7010       value = inverted;
7011       break;
7012
7013     case OPCODE_AND:             /* AND <-> BIC  */
7014       new_inst = OPCODE_BIC;
7015       value = inverted;
7016       break;
7017
7018     case OPCODE_BIC:
7019       new_inst = OPCODE_AND;
7020       value = inverted;
7021       break;
7022
7023     case OPCODE_ADC:              /* ADC <-> SBC  */
7024       new_inst = OPCODE_SBC;
7025       value = inverted;
7026       break;
7027
7028     case OPCODE_SBC:
7029       new_inst = OPCODE_ADC;
7030       value = inverted;
7031       break;
7032
7033       /* We cannot do anything.  */
7034     default:
7035       return FAIL;
7036     }
7037
7038   if (value == (unsigned) FAIL)
7039     return FAIL;
7040
7041   *instruction &= OPCODE_MASK;
7042   *instruction |= new_inst << DATA_OP_SHIFT;
7043   return value;
7044 }
7045
7046 static int
7047 data_op2 (str)
7048      char ** str;
7049 {
7050   int value;
7051   expressionS expr;
7052
7053   skip_whitespace (* str);
7054
7055   if (reg_required_here (str, 0) != FAIL)
7056     {
7057       if (skip_past_comma (str) == SUCCESS)
7058         /* Shift operation on register.  */
7059         return decode_shift (str, NO_SHIFT_RESTRICT);
7060
7061       return SUCCESS;
7062     }
7063   else
7064     {
7065       /* Immediate expression.  */
7066       if (is_immediate_prefix (**str))
7067         {
7068           (*str)++;
7069           inst.error = NULL;
7070
7071           if (my_get_expression (&inst.reloc.exp, str))
7072             return FAIL;
7073
7074           if (inst.reloc.exp.X_add_symbol)
7075             {
7076               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7077               inst.reloc.pc_rel = 0;
7078             }
7079           else
7080             {
7081               if (skip_past_comma (str) == SUCCESS)
7082                 {
7083                   /* #x, y -- ie explicit rotation by Y.  */
7084                   if (my_get_expression (&expr, str))
7085                     return FAIL;
7086
7087                   if (expr.X_op != O_constant)
7088                     {
7089                       inst.error = _("constant expression expected");
7090                       return FAIL;
7091                     }
7092
7093                   /* Rotate must be a multiple of 2.  */
7094                   if (((unsigned) expr.X_add_number) > 30
7095                       || (expr.X_add_number & 1) != 0
7096                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7097                     {
7098                       inst.error = _("invalid constant");
7099                       return FAIL;
7100                     }
7101                   inst.instruction |= INST_IMMEDIATE;
7102                   inst.instruction |= inst.reloc.exp.X_add_number;
7103                   inst.instruction |= expr.X_add_number << 7;
7104                   return SUCCESS;
7105                 }
7106
7107               /* Implicit rotation, select a suitable one.  */
7108               value = validate_immediate (inst.reloc.exp.X_add_number);
7109
7110               if (value == FAIL)
7111                 {
7112                   /* Can't be done.  Perhaps the code reads something like
7113                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7114                   if ((value = negate_data_op (&inst.instruction,
7115                                                inst.reloc.exp.X_add_number))
7116                       == FAIL)
7117                     {
7118                       inst.error = _("invalid constant");
7119                       return FAIL;
7120                     }
7121                 }
7122
7123               inst.instruction |= value;
7124             }
7125
7126           inst.instruction |= INST_IMMEDIATE;
7127           return SUCCESS;
7128         }
7129
7130       (*str)++;
7131       inst.error = _("register or shift expression expected");
7132       return FAIL;
7133     }
7134 }
7135
7136 static int
7137 fp_op2 (str)
7138      char ** str;
7139 {
7140   skip_whitespace (* str);
7141
7142   if (fp_reg_required_here (str, 0) != FAIL)
7143     return SUCCESS;
7144   else
7145     {
7146       /* Immediate expression.  */
7147       if (*((*str)++) == '#')
7148         {
7149           int i;
7150
7151           inst.error = NULL;
7152
7153           skip_whitespace (* str);
7154
7155           /* First try and match exact strings, this is to guarantee
7156              that some formats will work even for cross assembly.  */
7157
7158           for (i = 0; fp_const[i]; i++)
7159             {
7160               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7161                 {
7162                   char *start = *str;
7163
7164                   *str += strlen (fp_const[i]);
7165                   if (is_end_of_line[(unsigned char) **str])
7166                     {
7167                       inst.instruction |= i + 8;
7168                       return SUCCESS;
7169                     }
7170                   *str = start;
7171                 }
7172             }
7173
7174           /* Just because we didn't get a match doesn't mean that the
7175              constant isn't valid, just that it is in a format that we
7176              don't automatically recognize.  Try parsing it with
7177              the standard expression routines.  */
7178           if ((i = my_get_float_expression (str)) >= 0)
7179             {
7180               inst.instruction |= i + 8;
7181               return SUCCESS;
7182             }
7183
7184           inst.error = _("invalid floating point immediate expression");
7185           return FAIL;
7186         }
7187       inst.error =
7188         _("floating point register or immediate expression expected");
7189       return FAIL;
7190     }
7191 }
7192
7193 static void
7194 do_arit (str)
7195      char * str;
7196 {
7197   skip_whitespace (str);
7198
7199   if (reg_required_here (&str, 12) == FAIL
7200       || skip_past_comma (&str) == FAIL
7201       || reg_required_here (&str, 16) == FAIL
7202       || skip_past_comma (&str) == FAIL
7203       || data_op2 (&str) == FAIL)
7204     {
7205       if (!inst.error)
7206         inst.error = BAD_ARGS;
7207       return;
7208     }
7209
7210   end_of_line (str);
7211 }
7212
7213 static void
7214 do_adr (str)
7215      char * str;
7216 {
7217   /* This is a pseudo-op of the form "adr rd, label" to be converted
7218      into a relative address of the form "add rd, pc, #label-.-8".  */
7219   skip_whitespace (str);
7220
7221   if (reg_required_here (&str, 12) == FAIL
7222       || skip_past_comma (&str) == FAIL
7223       || my_get_expression (&inst.reloc.exp, &str))
7224     {
7225       if (!inst.error)
7226         inst.error = BAD_ARGS;
7227       return;
7228     }
7229
7230   /* Frag hacking will turn this into a sub instruction if the offset turns
7231      out to be negative.  */
7232   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7233 #ifndef TE_WINCE
7234   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7235 #endif
7236   inst.reloc.pc_rel = 1;
7237
7238   end_of_line (str);
7239 }
7240
7241 static void
7242 do_adrl (str)
7243      char * str;
7244 {
7245   /* This is a pseudo-op of the form "adrl rd, label" to be converted
7246      into a relative address of the form:
7247      add rd, pc, #low(label-.-8)"
7248      add rd, rd, #high(label-.-8)"  */
7249
7250   skip_whitespace (str);
7251
7252   if (reg_required_here (&str, 12) == FAIL
7253       || skip_past_comma (&str) == FAIL
7254       || my_get_expression (&inst.reloc.exp, &str))
7255     {
7256       if (!inst.error)
7257         inst.error = BAD_ARGS;
7258
7259       return;
7260     }
7261
7262   end_of_line (str);
7263   /* Frag hacking will turn this into a sub instruction if the offset turns
7264      out to be negative.  */
7265   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7266 #ifndef TE_WINCE  
7267   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7268 #endif
7269   inst.reloc.pc_rel            = 1;
7270   inst.size                    = INSN_SIZE * 2;
7271 }
7272
7273 static void
7274 do_cmp (str)
7275      char * str;
7276 {
7277   skip_whitespace (str);
7278
7279   if (reg_required_here (&str, 16) == FAIL)
7280     {
7281       if (!inst.error)
7282         inst.error = BAD_ARGS;
7283       return;
7284     }
7285
7286   if (skip_past_comma (&str) == FAIL
7287       || data_op2 (&str) == FAIL)
7288     {
7289       if (!inst.error)
7290         inst.error = BAD_ARGS;
7291       return;
7292     }
7293
7294   end_of_line (str);
7295 }
7296
7297 static void
7298 do_mov (str)
7299      char * str;
7300 {
7301   skip_whitespace (str);
7302
7303   if (reg_required_here (&str, 12) == FAIL)
7304     {
7305       if (!inst.error)
7306         inst.error = BAD_ARGS;
7307       return;
7308     }
7309
7310   if (skip_past_comma (&str) == FAIL
7311       || data_op2 (&str) == FAIL)
7312     {
7313       if (!inst.error)
7314         inst.error = BAD_ARGS;
7315       return;
7316     }
7317
7318   end_of_line (str);
7319 }
7320
7321 static int
7322 ldst_extend (str)
7323      char ** str;
7324 {
7325   int add = INDEX_UP;
7326
7327   switch (**str)
7328     {
7329     case '#':
7330     case '$':
7331       (*str)++;
7332       if (my_get_expression (& inst.reloc.exp, str))
7333         return FAIL;
7334
7335       if (inst.reloc.exp.X_op == O_constant)
7336         {
7337           int value = inst.reloc.exp.X_add_number;
7338
7339           if (value < -4095 || value > 4095)
7340             {
7341               inst.error = _("address offset too large");
7342               return FAIL;
7343             }
7344
7345           if (value < 0)
7346             {
7347               value = -value;
7348               add = 0;
7349             }
7350
7351           inst.instruction |= add | value;
7352         }
7353       else
7354         {
7355           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7356           inst.reloc.pc_rel = 0;
7357         }
7358       return SUCCESS;
7359
7360     case '-':
7361       add = 0;
7362       /* Fall through.  */
7363
7364     case '+':
7365       (*str)++;
7366       /* Fall through.  */
7367
7368     default:
7369       if (reg_required_here (str, 0) == FAIL)
7370         return FAIL;
7371
7372       inst.instruction |= add | OFFSET_REG;
7373       if (skip_past_comma (str) == SUCCESS)
7374         return decode_shift (str, SHIFT_IMMEDIATE);
7375
7376       return SUCCESS;
7377     }
7378 }
7379
7380 static void
7381 do_ldst (str)
7382      char *        str;
7383 {
7384   int pre_inc = 0;
7385   int conflict_reg;
7386   int value;
7387
7388   skip_whitespace (str);
7389
7390   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7391     {
7392       if (!inst.error)
7393         inst.error = BAD_ARGS;
7394       return;
7395     }
7396
7397   if (skip_past_comma (&str) == FAIL)
7398     {
7399       inst.error = _("address expected");
7400       return;
7401     }
7402
7403   if (*str == '[')
7404     {
7405       int reg;
7406
7407       str++;
7408
7409       skip_whitespace (str);
7410
7411       if ((reg = reg_required_here (&str, 16)) == FAIL)
7412         return;
7413
7414       /* Conflicts can occur on stores as well as loads.  */
7415       conflict_reg = (conflict_reg == reg);
7416
7417       skip_whitespace (str);
7418
7419       if (*str == ']')
7420         {
7421           str ++;
7422
7423           if (skip_past_comma (&str) == SUCCESS)
7424             {
7425               /* [Rn],... (post inc)  */
7426               if (ldst_extend (&str) == FAIL)
7427                 return;
7428               if (conflict_reg)
7429                 as_warn (_("%s register same as write-back base"),
7430                          ((inst.instruction & LOAD_BIT)
7431                           ? _("destination") : _("source")));
7432             }
7433           else
7434             {
7435               /* [Rn]  */
7436               skip_whitespace (str);
7437
7438               if (*str == '!')
7439                 {
7440                   if (conflict_reg)
7441                     as_warn (_("%s register same as write-back base"),
7442                              ((inst.instruction & LOAD_BIT)
7443                               ? _("destination") : _("source")));
7444                   str++;
7445                   inst.instruction |= WRITE_BACK;
7446                 }
7447
7448               inst.instruction |= INDEX_UP;
7449               pre_inc = 1;
7450             }
7451         }
7452       else
7453         {
7454           /* [Rn,...]  */
7455           if (skip_past_comma (&str) == FAIL)
7456             {
7457               inst.error = _("pre-indexed expression expected");
7458               return;
7459             }
7460
7461           pre_inc = 1;
7462           if (ldst_extend (&str) == FAIL)
7463             return;
7464
7465           skip_whitespace (str);
7466
7467           if (*str++ != ']')
7468             {
7469               inst.error = _("missing ]");
7470               return;
7471             }
7472
7473           skip_whitespace (str);
7474
7475           if (*str == '!')
7476             {
7477               if (conflict_reg)
7478                 as_warn (_("%s register same as write-back base"),
7479                          ((inst.instruction & LOAD_BIT)
7480                           ? _("destination") : _("source")));
7481               str++;
7482               inst.instruction |= WRITE_BACK;
7483             }
7484         }
7485     }
7486   else if (*str == '=')
7487     {
7488       if ((inst.instruction & LOAD_BIT) == 0)
7489         {
7490           inst.error = _("invalid pseudo operation");
7491           return;
7492         }
7493
7494       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7495       str++;
7496
7497       skip_whitespace (str);
7498
7499       if (my_get_expression (&inst.reloc.exp, &str))
7500         return;
7501
7502       if (inst.reloc.exp.X_op != O_constant
7503           && inst.reloc.exp.X_op != O_symbol)
7504         {
7505           inst.error = _("constant expression expected");
7506           return;
7507         }
7508
7509       if (inst.reloc.exp.X_op == O_constant)
7510         {
7511           value = validate_immediate (inst.reloc.exp.X_add_number);
7512
7513           if (value != FAIL)
7514             {
7515               /* This can be done with a mov instruction.  */
7516               inst.instruction &= LITERAL_MASK;
7517               inst.instruction |= (INST_IMMEDIATE
7518                                    | (OPCODE_MOV << DATA_OP_SHIFT));
7519               inst.instruction |= value & 0xfff;
7520               end_of_line (str);
7521               return;
7522             }
7523
7524           value = validate_immediate (~inst.reloc.exp.X_add_number);
7525
7526           if (value != FAIL)
7527             {
7528               /* This can be done with a mvn instruction.  */
7529               inst.instruction &= LITERAL_MASK;
7530               inst.instruction |= (INST_IMMEDIATE
7531                                    | (OPCODE_MVN << DATA_OP_SHIFT));
7532               inst.instruction |= value & 0xfff;
7533               end_of_line (str);
7534               return;
7535             }
7536         }
7537
7538       /* Insert into literal pool.  */
7539       if (add_to_lit_pool () == FAIL)
7540         {
7541           if (!inst.error)
7542             inst.error = _("literal pool insertion failed");
7543           return;
7544         }
7545
7546       /* Change the instruction exp to point to the pool.  */
7547       inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7548       inst.reloc.pc_rel = 1;
7549       inst.instruction |= (REG_PC << 16);
7550       pre_inc = 1;
7551     }
7552   else
7553     {
7554       if (my_get_expression (&inst.reloc.exp, &str))
7555         return;
7556
7557       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7558 #ifndef TE_WINCE
7559       /* PC rel adjust.  */
7560       inst.reloc.exp.X_add_number -= 8;
7561 #endif
7562       inst.reloc.pc_rel = 1;
7563       inst.instruction |= (REG_PC << 16);
7564       pre_inc = 1;
7565     }
7566
7567   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7568   end_of_line (str);
7569 }
7570
7571 static void
7572 do_ldstt (str)
7573      char *        str;
7574 {
7575   int conflict_reg;
7576
7577   skip_whitespace (str);
7578
7579   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7580     {
7581       if (!inst.error)
7582         inst.error = BAD_ARGS;
7583       return;
7584     }
7585
7586   if (skip_past_comma (& str) == FAIL)
7587     {
7588       inst.error = _("address expected");
7589       return;
7590     }
7591
7592   if (*str == '[')
7593     {
7594       int reg;
7595
7596       str++;
7597
7598       skip_whitespace (str);
7599
7600       if ((reg = reg_required_here (&str, 16)) == FAIL)
7601         return;
7602
7603       /* ldrt/strt always use post-indexed addressing, so if the base is
7604          the same as Rd, we warn.  */
7605       if (conflict_reg == reg)
7606         as_warn (_("%s register same as write-back base"),
7607                  ((inst.instruction & LOAD_BIT)
7608                   ? _("destination") : _("source")));
7609
7610       skip_whitespace (str);
7611
7612       if (*str == ']')
7613         {
7614           str ++;
7615
7616           if (skip_past_comma (&str) == SUCCESS)
7617             {
7618               /* [Rn],... (post inc)  */
7619               if (ldst_extend (&str) == FAIL)
7620                 return;
7621             }
7622           else
7623             {
7624               /* [Rn]  */
7625               skip_whitespace (str);
7626
7627               /* Skip a write-back '!'.  */
7628               if (*str == '!')
7629                 str++;
7630
7631               inst.instruction |= INDEX_UP;
7632             }
7633         }
7634       else
7635         {
7636           inst.error = _("post-indexed expression expected");
7637           return;
7638         }
7639     }
7640   else
7641     {
7642       inst.error = _("post-indexed expression expected");
7643       return;
7644     }
7645
7646   end_of_line (str);
7647 }
7648
7649 static int
7650 ldst_extend_v4 (str)
7651      char ** str;
7652 {
7653   int add = INDEX_UP;
7654
7655   switch (**str)
7656     {
7657     case '#':
7658     case '$':
7659       (*str)++;
7660       if (my_get_expression (& inst.reloc.exp, str))
7661         return FAIL;
7662
7663       if (inst.reloc.exp.X_op == O_constant)
7664         {
7665           int value = inst.reloc.exp.X_add_number;
7666
7667           if (value < -255 || value > 255)
7668             {
7669               inst.error = _("address offset too large");
7670               return FAIL;
7671             }
7672
7673           if (value < 0)
7674             {
7675               value = -value;
7676               add = 0;
7677             }
7678
7679           /* Halfword and signextension instructions have the
7680              immediate value split across bits 11..8 and bits 3..0.  */
7681           inst.instruction |= (add | HWOFFSET_IMM
7682                                | ((value >> 4) << 8) | (value & 0xF));
7683         }
7684       else
7685         {
7686           inst.instruction |= HWOFFSET_IMM;
7687           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7688           inst.reloc.pc_rel = 0;
7689         }
7690       return SUCCESS;
7691
7692     case '-':
7693       add = 0;
7694       /* Fall through.  */
7695
7696     case '+':
7697       (*str)++;
7698       /* Fall through.  */
7699
7700     default:
7701       if (reg_required_here (str, 0) == FAIL)
7702         return FAIL;
7703
7704       inst.instruction |= add;
7705       return SUCCESS;
7706     }
7707 }
7708
7709 /* Halfword and signed-byte load/store operations.  */
7710 static void
7711 do_ldstv4 (str)
7712      char *        str;
7713 {
7714   int pre_inc = 0;
7715   int conflict_reg;
7716   int value;
7717
7718   skip_whitespace (str);
7719
7720   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7721     {
7722       if (!inst.error)
7723         inst.error = BAD_ARGS;
7724       return;
7725     }
7726
7727   if (skip_past_comma (& str) == FAIL)
7728     {
7729       inst.error = _("address expected");
7730       return;
7731     }
7732
7733   if (*str == '[')
7734     {
7735       int reg;
7736
7737       str++;
7738
7739       skip_whitespace (str);
7740
7741       if ((reg = reg_required_here (&str, 16)) == FAIL)
7742         return;
7743
7744       /* Conflicts can occur on stores as well as loads.  */
7745       conflict_reg = (conflict_reg == reg);
7746
7747       skip_whitespace (str);
7748
7749       if (*str == ']')
7750         {
7751           str ++;
7752
7753           if (skip_past_comma (&str) == SUCCESS)
7754             {
7755               /* [Rn],... (post inc)  */
7756               if (ldst_extend_v4 (&str) == FAIL)
7757                 return;
7758               if (conflict_reg)
7759                 as_warn (_("%s register same as write-back base"),
7760                          ((inst.instruction & LOAD_BIT)
7761                           ? _("destination") : _("source")));
7762             }
7763           else
7764             {
7765               /* [Rn]  */
7766               inst.instruction |= HWOFFSET_IMM;
7767
7768               skip_whitespace (str);
7769
7770               if (*str == '!')
7771                 {
7772                   if (conflict_reg)
7773                     as_warn (_("%s register same as write-back base"),
7774                              ((inst.instruction & LOAD_BIT)
7775                               ? _("destination") : _("source")));
7776                   str++;
7777                   inst.instruction |= WRITE_BACK;
7778                 }
7779
7780               inst.instruction |= INDEX_UP;
7781               pre_inc = 1;
7782             }
7783         }
7784       else
7785         {
7786           /* [Rn,...]  */
7787           if (skip_past_comma (&str) == FAIL)
7788             {
7789               inst.error = _("pre-indexed expression expected");
7790               return;
7791             }
7792
7793           pre_inc = 1;
7794           if (ldst_extend_v4 (&str) == FAIL)
7795             return;
7796
7797           skip_whitespace (str);
7798
7799           if (*str++ != ']')
7800             {
7801               inst.error = _("missing ]");
7802               return;
7803             }
7804
7805           skip_whitespace (str);
7806
7807           if (*str == '!')
7808             {
7809               if (conflict_reg)
7810                 as_warn (_("%s register same as write-back base"),
7811                          ((inst.instruction & LOAD_BIT)
7812                           ? _("destination") : _("source")));
7813               str++;
7814               inst.instruction |= WRITE_BACK;
7815             }
7816         }
7817     }
7818   else if (*str == '=')
7819     {
7820       if ((inst.instruction & LOAD_BIT) == 0)
7821         {
7822           inst.error = _("invalid pseudo operation");
7823           return;
7824         }
7825
7826       /* XXX Does this work correctly for half-word/byte ops?  */
7827       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7828       str++;
7829
7830       skip_whitespace (str);
7831
7832       if (my_get_expression (&inst.reloc.exp, &str))
7833         return;
7834
7835       if (inst.reloc.exp.X_op != O_constant
7836           && inst.reloc.exp.X_op != O_symbol)
7837         {
7838           inst.error = _("constant expression expected");
7839           return;
7840         }
7841
7842       if (inst.reloc.exp.X_op == O_constant)
7843         {
7844           value = validate_immediate (inst.reloc.exp.X_add_number);
7845
7846           if (value != FAIL)
7847             {
7848               /* This can be done with a mov instruction.  */
7849               inst.instruction &= LITERAL_MASK;
7850               inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7851               inst.instruction |= value & 0xfff;
7852               end_of_line (str);
7853               return;
7854             }
7855
7856           value = validate_immediate (~ inst.reloc.exp.X_add_number);
7857
7858           if (value != FAIL)
7859             {
7860               /* This can be done with a mvn instruction.  */
7861               inst.instruction &= LITERAL_MASK;
7862               inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7863               inst.instruction |= value & 0xfff;
7864               end_of_line (str);
7865               return;
7866             }
7867         }
7868
7869       /* Insert into literal pool.  */
7870       if (add_to_lit_pool () == FAIL)
7871         {
7872           if (!inst.error)
7873             inst.error = _("literal pool insertion failed");
7874           return;
7875         }
7876
7877       /* Change the instruction exp to point to the pool.  */
7878       inst.instruction |= HWOFFSET_IMM;
7879       inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7880       inst.reloc.pc_rel = 1;
7881       inst.instruction |= (REG_PC << 16);
7882       pre_inc = 1;
7883     }
7884   else
7885     {
7886       if (my_get_expression (&inst.reloc.exp, &str))
7887         return;
7888
7889       inst.instruction |= HWOFFSET_IMM;
7890       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7891 #ifndef TE_WINCE
7892       /* PC rel adjust.  */
7893       inst.reloc.exp.X_add_number -= 8;
7894 #endif
7895       inst.reloc.pc_rel = 1;
7896       inst.instruction |= (REG_PC << 16);
7897       pre_inc = 1;
7898     }
7899
7900   inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7901   end_of_line (str);
7902 }
7903
7904 static long
7905 reg_list (strp)
7906      char ** strp;
7907 {
7908   char * str = * strp;
7909   long   range = 0;
7910   int    another_range;
7911
7912   /* We come back here if we get ranges concatenated by '+' or '|'.  */
7913   do
7914     {
7915       another_range = 0;
7916
7917       if (*str == '{')
7918         {
7919           int in_range = 0;
7920           int cur_reg = -1;
7921
7922           str++;
7923           do
7924             {
7925               int reg;
7926
7927               skip_whitespace (str);
7928
7929               if ((reg = reg_required_here (& str, -1)) == FAIL)
7930                 return FAIL;
7931
7932               if (in_range)
7933                 {
7934                   int i;
7935
7936                   if (reg <= cur_reg)
7937                     {
7938                       inst.error = _("bad range in register list");
7939                       return FAIL;
7940                     }
7941
7942                   for (i = cur_reg + 1; i < reg; i++)
7943                     {
7944                       if (range & (1 << i))
7945                         as_tsktsk
7946                           (_("Warning: duplicated register (r%d) in register list"),
7947                            i);
7948                       else
7949                         range |= 1 << i;
7950                     }
7951                   in_range = 0;
7952                 }
7953
7954               if (range & (1 << reg))
7955                 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
7956                            reg);
7957               else if (reg <= cur_reg)
7958                 as_tsktsk (_("Warning: register range not in ascending order"));
7959
7960               range |= 1 << reg;
7961               cur_reg = reg;
7962             }
7963           while (skip_past_comma (&str) != FAIL
7964                  || (in_range = 1, *str++ == '-'));
7965           str--;
7966           skip_whitespace (str);
7967
7968           if (*str++ != '}')
7969             {
7970               inst.error = _("missing `}'");
7971               return FAIL;
7972             }
7973         }
7974       else
7975         {
7976           expressionS expr;
7977
7978           if (my_get_expression (&expr, &str))
7979             return FAIL;
7980
7981           if (expr.X_op == O_constant)
7982             {
7983               if (expr.X_add_number
7984                   != (expr.X_add_number & 0x0000ffff))
7985                 {
7986                   inst.error = _("invalid register mask");
7987                   return FAIL;
7988                 }
7989
7990               if ((range & expr.X_add_number) != 0)
7991                 {
7992                   int regno = range & expr.X_add_number;
7993
7994                   regno &= -regno;
7995                   regno = (1 << regno) - 1;
7996                   as_tsktsk
7997                     (_("Warning: duplicated register (r%d) in register list"),
7998                      regno);
7999                 }
8000
8001               range |= expr.X_add_number;
8002             }
8003           else
8004             {
8005               if (inst.reloc.type != 0)
8006                 {
8007                   inst.error = _("expression too complex");
8008                   return FAIL;
8009                 }
8010
8011               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8012               inst.reloc.type = BFD_RELOC_ARM_MULTI;
8013               inst.reloc.pc_rel = 0;
8014             }
8015         }
8016
8017       skip_whitespace (str);
8018
8019       if (*str == '|' || *str == '+')
8020         {
8021           str++;
8022           another_range = 1;
8023         }
8024     }
8025   while (another_range);
8026
8027   *strp = str;
8028   return range;
8029 }
8030
8031 static void
8032 do_ldmstm (str)
8033      char * str;
8034 {
8035   int base_reg;
8036   long range;
8037
8038   skip_whitespace (str);
8039
8040   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8041     return;
8042
8043   if (base_reg == REG_PC)
8044     {
8045       inst.error = _("r15 not allowed as base register");
8046       return;
8047     }
8048
8049   skip_whitespace (str);
8050
8051   if (*str == '!')
8052     {
8053       inst.instruction |= WRITE_BACK;
8054       str++;
8055     }
8056
8057   if (skip_past_comma (&str) == FAIL
8058       || (range = reg_list (&str)) == FAIL)
8059     {
8060       if (! inst.error)
8061         inst.error = BAD_ARGS;
8062       return;
8063     }
8064
8065   if (*str == '^')
8066     {
8067       str++;
8068       inst.instruction |= LDM_TYPE_2_OR_3;
8069     }
8070
8071   if (inst.instruction & WRITE_BACK)
8072     {
8073       /* Check for unpredictable uses of writeback.  */
8074       if (inst.instruction & LOAD_BIT)
8075         {
8076           /* Not allowed in LDM type 2.  */
8077           if ((inst.instruction & LDM_TYPE_2_OR_3)
8078               && ((range & (1 << REG_PC)) == 0))
8079             as_warn (_("writeback of base register is UNPREDICTABLE"));
8080           /* Only allowed if base reg not in list for other types.  */
8081           else if (range & (1 << base_reg))
8082             as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8083         }
8084       else /* STM.  */
8085         {
8086           /* Not allowed for type 2.  */
8087           if (inst.instruction & LDM_TYPE_2_OR_3)
8088             as_warn (_("writeback of base register is UNPREDICTABLE"));
8089           /* Only allowed if base reg not in list, or first in list.  */
8090           else if ((range & (1 << base_reg))
8091                    && (range & ((1 << base_reg) - 1)))
8092             as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8093         }
8094     }
8095
8096   inst.instruction |= range;
8097   end_of_line (str);
8098 }
8099
8100 static void
8101 do_swi (str)
8102      char * str;
8103 {
8104   skip_whitespace (str);
8105
8106   /* Allow optional leading '#'.  */
8107   if (is_immediate_prefix (*str))
8108     str++;
8109
8110   if (my_get_expression (& inst.reloc.exp, & str))
8111     return;
8112
8113   inst.reloc.type = BFD_RELOC_ARM_SWI;
8114   inst.reloc.pc_rel = 0;
8115   end_of_line (str);
8116 }
8117
8118 static void
8119 do_swap (str)
8120      char * str;
8121 {
8122   int reg;
8123
8124   skip_whitespace (str);
8125
8126   if ((reg = reg_required_here (&str, 12)) == FAIL)
8127     return;
8128
8129   if (reg == REG_PC)
8130     {
8131       inst.error = _("r15 not allowed in swap");
8132       return;
8133     }
8134
8135   if (skip_past_comma (&str) == FAIL
8136       || (reg = reg_required_here (&str, 0)) == FAIL)
8137     {
8138       if (!inst.error)
8139         inst.error = BAD_ARGS;
8140       return;
8141     }
8142
8143   if (reg == REG_PC)
8144     {
8145       inst.error = _("r15 not allowed in swap");
8146       return;
8147     }
8148
8149   if (skip_past_comma (&str) == FAIL
8150       || *str++ != '[')
8151     {
8152       inst.error = BAD_ARGS;
8153       return;
8154     }
8155
8156   skip_whitespace (str);
8157
8158   if ((reg = reg_required_here (&str, 16)) == FAIL)
8159     return;
8160
8161   if (reg == REG_PC)
8162     {
8163       inst.error = BAD_PC;
8164       return;
8165     }
8166
8167   skip_whitespace (str);
8168
8169   if (*str++ != ']')
8170     {
8171       inst.error = _("missing ]");
8172       return;
8173     }
8174
8175   end_of_line (str);
8176 }
8177
8178 static void
8179 do_branch (str)
8180      char * str;
8181 {
8182   if (my_get_expression (&inst.reloc.exp, &str))
8183     return;
8184
8185 #ifdef OBJ_ELF
8186   {
8187     char * save_in;
8188
8189     /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8190        required for the instruction.  */
8191
8192     /* arm_parse_reloc () works on input_line_pointer.
8193        We actually want to parse the operands to the branch instruction
8194        passed in 'str'.  Save the input pointer and restore it later.  */
8195     save_in = input_line_pointer;
8196     input_line_pointer = str;
8197     if (inst.reloc.exp.X_op == O_symbol
8198         && *str == '('
8199         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8200       {
8201         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8202         inst.reloc.pc_rel = 0;
8203         /* Modify str to point to after parsed operands, otherwise
8204            end_of_line() will complain about the (PLT) left in str.  */
8205         str = input_line_pointer;
8206       }
8207     else
8208       {
8209         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8210         inst.reloc.pc_rel = 1;
8211       }
8212     input_line_pointer = save_in;
8213   }
8214 #else
8215   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8216   inst.reloc.pc_rel = 1;
8217 #endif /* OBJ_ELF  */
8218
8219   end_of_line (str);
8220 }
8221
8222 static void
8223 do_bx (str)
8224      char * str;
8225 {
8226   int reg;
8227
8228   skip_whitespace (str);
8229
8230   if ((reg = reg_required_here (&str, 0)) == FAIL)
8231     {
8232       inst.error = BAD_ARGS;
8233       return;
8234     }
8235
8236   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8237   if (reg == REG_PC)
8238     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8239
8240   end_of_line (str);
8241 }
8242
8243 static void
8244 do_cdp (str)
8245      char * str;
8246 {
8247   /* Co-processor data operation.
8248      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8249   skip_whitespace (str);
8250
8251   if (co_proc_number (&str) == FAIL)
8252     {
8253       if (!inst.error)
8254         inst.error = BAD_ARGS;
8255       return;
8256     }
8257
8258   if (skip_past_comma (&str) == FAIL
8259       || cp_opc_expr (&str, 20,4) == FAIL)
8260     {
8261       if (!inst.error)
8262         inst.error = BAD_ARGS;
8263       return;
8264     }
8265
8266   if (skip_past_comma (&str) == FAIL
8267       || cp_reg_required_here (&str, 12) == FAIL)
8268     {
8269       if (!inst.error)
8270         inst.error = BAD_ARGS;
8271       return;
8272     }
8273
8274   if (skip_past_comma (&str) == FAIL
8275       || cp_reg_required_here (&str, 16) == FAIL)
8276     {
8277       if (!inst.error)
8278         inst.error = BAD_ARGS;
8279       return;
8280     }
8281
8282   if (skip_past_comma (&str) == FAIL
8283       || cp_reg_required_here (&str, 0) == FAIL)
8284     {
8285       if (!inst.error)
8286         inst.error = BAD_ARGS;
8287       return;
8288     }
8289
8290   if (skip_past_comma (&str) == SUCCESS)
8291     {
8292       if (cp_opc_expr (&str, 5, 3) == FAIL)
8293         {
8294           if (!inst.error)
8295             inst.error = BAD_ARGS;
8296           return;
8297         }
8298     }
8299
8300   end_of_line (str);
8301 }
8302
8303 static void
8304 do_lstc (str)
8305      char * str;
8306 {
8307   /* Co-processor register load/store.
8308      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8309
8310   skip_whitespace (str);
8311
8312   if (co_proc_number (&str) == FAIL)
8313     {
8314       if (!inst.error)
8315         inst.error = BAD_ARGS;
8316       return;
8317     }
8318
8319   if (skip_past_comma (&str) == FAIL
8320       || cp_reg_required_here (&str, 12) == FAIL)
8321     {
8322       if (!inst.error)
8323         inst.error = BAD_ARGS;
8324       return;
8325     }
8326
8327   if (skip_past_comma (&str) == FAIL
8328       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8329     {
8330       if (! inst.error)
8331         inst.error = BAD_ARGS;
8332       return;
8333     }
8334
8335   end_of_line (str);
8336 }
8337
8338 static void
8339 do_co_reg (str)
8340      char * str;
8341 {
8342   /* Co-processor register transfer.
8343      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8344
8345   skip_whitespace (str);
8346
8347   if (co_proc_number (&str) == FAIL)
8348     {
8349       if (!inst.error)
8350         inst.error = BAD_ARGS;
8351       return;
8352     }
8353
8354   if (skip_past_comma (&str) == FAIL
8355       || cp_opc_expr (&str, 21, 3) == FAIL)
8356     {
8357       if (!inst.error)
8358         inst.error = BAD_ARGS;
8359       return;
8360     }
8361
8362   if (skip_past_comma (&str) == FAIL
8363       || reg_required_here (&str, 12) == FAIL)
8364     {
8365       if (!inst.error)
8366         inst.error = BAD_ARGS;
8367       return;
8368     }
8369
8370   if (skip_past_comma (&str) == FAIL
8371       || cp_reg_required_here (&str, 16) == FAIL)
8372     {
8373       if (!inst.error)
8374         inst.error = BAD_ARGS;
8375       return;
8376     }
8377
8378   if (skip_past_comma (&str) == FAIL
8379       || cp_reg_required_here (&str, 0) == FAIL)
8380     {
8381       if (!inst.error)
8382         inst.error = BAD_ARGS;
8383       return;
8384     }
8385
8386   if (skip_past_comma (&str) == SUCCESS)
8387     {
8388       if (cp_opc_expr (&str, 5, 3) == FAIL)
8389         {
8390           if (!inst.error)
8391             inst.error = BAD_ARGS;
8392           return;
8393         }
8394     }
8395
8396   end_of_line (str);
8397 }
8398
8399 static void
8400 do_fpa_ctrl (str)
8401      char * str;
8402 {
8403   /* FP control registers.
8404      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8405
8406   skip_whitespace (str);
8407
8408   if (reg_required_here (&str, 12) == FAIL)
8409     {
8410       if (!inst.error)
8411         inst.error = BAD_ARGS;
8412       return;
8413     }
8414
8415   end_of_line (str);
8416 }
8417
8418 static void
8419 do_fpa_ldst (str)
8420      char * str;
8421 {
8422   skip_whitespace (str);
8423
8424   if (fp_reg_required_here (&str, 12) == FAIL)
8425     {
8426       if (!inst.error)
8427         inst.error = BAD_ARGS;
8428       return;
8429     }
8430
8431   if (skip_past_comma (&str) == FAIL
8432       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8433     {
8434       if (!inst.error)
8435         inst.error = BAD_ARGS;
8436       return;
8437     }
8438
8439   end_of_line (str);
8440 }
8441
8442 static void
8443 do_fpa_ldmstm (str)
8444      char * str;
8445 {
8446   int num_regs;
8447
8448   skip_whitespace (str);
8449
8450   if (fp_reg_required_here (&str, 12) == FAIL)
8451     {
8452       if (! inst.error)
8453         inst.error = BAD_ARGS;
8454       return;
8455     }
8456
8457   /* Get Number of registers to transfer.  */
8458   if (skip_past_comma (&str) == FAIL
8459       || my_get_expression (&inst.reloc.exp, &str))
8460     {
8461       if (! inst.error)
8462         inst.error = _("constant expression expected");
8463       return;
8464     }
8465
8466   if (inst.reloc.exp.X_op != O_constant)
8467     {
8468       inst.error = _("constant value required for number of registers");
8469       return;
8470     }
8471
8472   num_regs = inst.reloc.exp.X_add_number;
8473
8474   if (num_regs < 1 || num_regs > 4)
8475     {
8476       inst.error = _("number of registers must be in the range [1:4]");
8477       return;
8478     }
8479
8480   switch (num_regs)
8481     {
8482     case 1:
8483       inst.instruction |= CP_T_X;
8484       break;
8485     case 2:
8486       inst.instruction |= CP_T_Y;
8487       break;
8488     case 3:
8489       inst.instruction |= CP_T_Y | CP_T_X;
8490       break;
8491     case 4:
8492       break;
8493     default:
8494       abort ();
8495     }
8496
8497   if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8498     {
8499       int reg;
8500       int write_back;
8501       int offset;
8502
8503       /* The instruction specified "ea" or "fd", so we can only accept
8504          [Rn]{!}.  The instruction does not really support stacking or
8505          unstacking, so we have to emulate these by setting appropriate
8506          bits and offsets.  */
8507       if (skip_past_comma (&str) == FAIL
8508           || *str != '[')
8509         {
8510           if (! inst.error)
8511             inst.error = BAD_ARGS;
8512           return;
8513         }
8514
8515       str++;
8516       skip_whitespace (str);
8517
8518       if ((reg = reg_required_here (&str, 16)) == FAIL)
8519         return;
8520
8521       skip_whitespace (str);
8522
8523       if (*str != ']')
8524         {
8525           inst.error = BAD_ARGS;
8526           return;
8527         }
8528
8529       str++;
8530       if (*str == '!')
8531         {
8532           write_back = 1;
8533           str++;
8534           if (reg == REG_PC)
8535             {
8536               inst.error =
8537                 _("r15 not allowed as base register with write-back");
8538               return;
8539             }
8540         }
8541       else
8542         write_back = 0;
8543
8544       if (inst.instruction & CP_T_Pre)
8545         {
8546           /* Pre-decrement.  */
8547           offset = 3 * num_regs;
8548           if (write_back)
8549             inst.instruction |= CP_T_WB;
8550         }
8551       else
8552         {
8553           /* Post-increment.  */
8554           if (write_back)
8555             {
8556               inst.instruction |= CP_T_WB;
8557               offset = 3 * num_regs;
8558             }
8559           else
8560             {
8561               /* No write-back, so convert this into a standard pre-increment
8562                  instruction -- aesthetically more pleasing.  */
8563               inst.instruction |= CP_T_Pre | CP_T_UD;
8564               offset = 0;
8565             }
8566         }
8567
8568       inst.instruction |= offset;
8569     }
8570   else if (skip_past_comma (&str) == FAIL
8571            || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8572     {
8573       if (! inst.error)
8574         inst.error = BAD_ARGS;
8575       return;
8576     }
8577
8578   end_of_line (str);
8579 }
8580
8581 static void
8582 do_fpa_dyadic (str)
8583      char * str;
8584 {
8585   skip_whitespace (str);
8586
8587   if (fp_reg_required_here (&str, 12) == FAIL)
8588     {
8589       if (! inst.error)
8590         inst.error = BAD_ARGS;
8591       return;
8592     }
8593
8594   if (skip_past_comma (&str) == FAIL
8595       || fp_reg_required_here (&str, 16) == FAIL)
8596     {
8597       if (! inst.error)
8598         inst.error = BAD_ARGS;
8599       return;
8600     }
8601
8602   if (skip_past_comma (&str) == FAIL
8603       || fp_op2 (&str) == FAIL)
8604     {
8605       if (! inst.error)
8606         inst.error = BAD_ARGS;
8607       return;
8608     }
8609
8610   end_of_line (str);
8611 }
8612
8613 static void
8614 do_fpa_monadic (str)
8615      char * str;
8616 {
8617   skip_whitespace (str);
8618
8619   if (fp_reg_required_here (&str, 12) == FAIL)
8620     {
8621       if (! inst.error)
8622         inst.error = BAD_ARGS;
8623       return;
8624     }
8625
8626   if (skip_past_comma (&str) == FAIL
8627       || fp_op2 (&str) == FAIL)
8628     {
8629       if (! inst.error)
8630         inst.error = BAD_ARGS;
8631       return;
8632     }
8633
8634   end_of_line (str);
8635 }
8636
8637 static void
8638 do_fpa_cmp (str)
8639      char * str;
8640 {
8641   skip_whitespace (str);
8642
8643   if (fp_reg_required_here (&str, 16) == FAIL)
8644     {
8645       if (! inst.error)
8646         inst.error = BAD_ARGS;
8647       return;
8648     }
8649
8650   if (skip_past_comma (&str) == FAIL
8651       || fp_op2 (&str) == FAIL)
8652     {
8653       if (! inst.error)
8654         inst.error = BAD_ARGS;
8655       return;
8656     }
8657
8658   end_of_line (str);
8659 }
8660
8661 static void
8662 do_fpa_from_reg (str)
8663      char * str;
8664 {
8665   skip_whitespace (str);
8666
8667   if (fp_reg_required_here (&str, 16) == FAIL)
8668     {
8669       if (! inst.error)
8670         inst.error = BAD_ARGS;
8671       return;
8672     }
8673
8674   if (skip_past_comma (&str) == FAIL
8675       || reg_required_here (&str, 12) == FAIL)
8676     {
8677       if (! inst.error)
8678         inst.error = BAD_ARGS;
8679       return;
8680     }
8681
8682   end_of_line (str);
8683 }
8684
8685 static void
8686 do_fpa_to_reg (str)
8687      char * str;
8688 {
8689   skip_whitespace (str);
8690
8691   if (reg_required_here (&str, 12) == FAIL)
8692     return;
8693
8694   if (skip_past_comma (&str) == FAIL
8695       || fp_reg_required_here (&str, 0) == FAIL)
8696     {
8697       if (! inst.error)
8698         inst.error = BAD_ARGS;
8699       return;
8700     }
8701
8702   end_of_line (str);
8703 }
8704
8705 static int
8706 vfp_sp_reg_required_here (str, pos)
8707      char **str;
8708      enum vfp_sp_reg_pos pos;
8709 {
8710   int    reg;
8711   char *start = *str;
8712
8713   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8714     {
8715       switch (pos)
8716         {
8717         case VFP_REG_Sd:
8718           inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8719           break;
8720
8721         case VFP_REG_Sn:
8722           inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8723           break;
8724
8725         case VFP_REG_Sm:
8726           inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8727           break;
8728
8729         default:
8730           abort ();
8731         }
8732       return reg;
8733     }
8734
8735   /* In the few cases where we might be able to accept something else
8736      this error can be overridden.  */
8737   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8738
8739   /* Restore the start point.  */
8740   *str = start;
8741   return FAIL;
8742 }
8743
8744 static int
8745 vfp_dp_reg_required_here (str, pos)
8746      char **str;
8747      enum vfp_dp_reg_pos pos;
8748 {
8749   int   reg;
8750   char *start = *str;
8751
8752   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8753     {
8754       switch (pos)
8755         {
8756         case VFP_REG_Dd:
8757           inst.instruction |= reg << 12;
8758           break;
8759
8760         case VFP_REG_Dn:
8761           inst.instruction |= reg << 16;
8762           break;
8763
8764         case VFP_REG_Dm:
8765           inst.instruction |= reg << 0;
8766           break;
8767
8768         default:
8769           abort ();
8770         }
8771       return reg;
8772     }
8773
8774   /* In the few cases where we might be able to accept something else
8775      this error can be overridden.  */
8776   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8777
8778   /* Restore the start point.  */
8779   *str = start;
8780   return FAIL;
8781 }
8782
8783 static void
8784 do_vfp_sp_monadic (str)
8785      char *str;
8786 {
8787   skip_whitespace (str);
8788
8789   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8790     return;
8791
8792   if (skip_past_comma (&str) == FAIL
8793       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8794     {
8795       if (! inst.error)
8796         inst.error = BAD_ARGS;
8797       return;
8798     }
8799
8800   end_of_line (str);
8801 }
8802
8803 static void
8804 do_vfp_dp_monadic (str)
8805      char *str;
8806 {
8807   skip_whitespace (str);
8808
8809   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8810     return;
8811
8812   if (skip_past_comma (&str) == FAIL
8813       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8814     {
8815       if (! inst.error)
8816         inst.error = BAD_ARGS;
8817       return;
8818     }
8819
8820   end_of_line (str);
8821 }
8822
8823 static void
8824 do_vfp_sp_dyadic (str)
8825      char *str;
8826 {
8827   skip_whitespace (str);
8828
8829   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8830     return;
8831
8832   if (skip_past_comma (&str) == FAIL
8833       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8834       || skip_past_comma (&str) == FAIL
8835       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8836     {
8837       if (! inst.error)
8838         inst.error = BAD_ARGS;
8839       return;
8840     }
8841
8842   end_of_line (str);
8843 }
8844
8845 static void
8846 do_vfp_dp_dyadic (str)
8847      char *str;
8848 {
8849   skip_whitespace (str);
8850
8851   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8852     return;
8853
8854   if (skip_past_comma (&str) == FAIL
8855       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8856       || skip_past_comma (&str) == FAIL
8857       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8858     {
8859       if (! inst.error)
8860         inst.error = BAD_ARGS;
8861       return;
8862     }
8863
8864   end_of_line (str);
8865 }
8866
8867 static void
8868 do_vfp_reg_from_sp (str)
8869      char *str;
8870 {
8871   skip_whitespace (str);
8872
8873   if (reg_required_here (&str, 12) == FAIL)
8874     return;
8875
8876   if (skip_past_comma (&str) == FAIL
8877       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8878     {
8879       if (! inst.error)
8880         inst.error = BAD_ARGS;
8881       return;
8882     }
8883
8884   end_of_line (str);
8885 }
8886
8887 static void
8888 do_vfp_reg2_from_sp2 (str)
8889      char *str;
8890 {
8891   skip_whitespace (str);
8892
8893   if (reg_required_here (&str, 12) == FAIL
8894       || skip_past_comma (&str) == FAIL
8895       || reg_required_here (&str, 16) == FAIL
8896       || skip_past_comma (&str) == FAIL)
8897     {
8898       if (! inst.error)
8899         inst.error = BAD_ARGS;
8900       return;
8901     }
8902
8903   /* We require exactly two consecutive SP registers.  */
8904   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8905     {
8906       if (! inst.error)
8907         inst.error = _("only two consecutive VFP SP registers allowed here");
8908     }
8909
8910   end_of_line (str);
8911 }
8912
8913 static void
8914 do_vfp_sp_from_reg (str)
8915      char *str;
8916 {
8917   skip_whitespace (str);
8918
8919   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8920     return;
8921
8922   if (skip_past_comma (&str) == FAIL
8923       || reg_required_here (&str, 12) == FAIL)
8924     {
8925       if (! inst.error)
8926         inst.error = BAD_ARGS;
8927       return;
8928     }
8929
8930   end_of_line (str);
8931 }
8932
8933 static void
8934 do_vfp_sp2_from_reg2 (str)
8935      char *str;
8936 {
8937   skip_whitespace (str);
8938
8939   /* We require exactly two consecutive SP registers.  */
8940   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8941     {
8942       if (! inst.error)
8943         inst.error = _("only two consecutive VFP SP registers allowed here");
8944     }
8945
8946   if (skip_past_comma (&str) == FAIL
8947       || reg_required_here (&str, 12) == FAIL
8948       || skip_past_comma (&str) == FAIL
8949       || reg_required_here (&str, 16) == FAIL)
8950     {
8951       if (! inst.error)
8952         inst.error = BAD_ARGS;
8953       return;
8954     }
8955
8956   end_of_line (str);
8957 }
8958
8959 static void
8960 do_vfp_reg_from_dp (str)
8961      char *str;
8962 {
8963   skip_whitespace (str);
8964
8965   if (reg_required_here (&str, 12) == FAIL)
8966     return;
8967
8968   if (skip_past_comma (&str) == FAIL
8969       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
8970     {
8971       if (! inst.error)
8972         inst.error = BAD_ARGS;
8973       return;
8974     }
8975
8976   end_of_line (str);
8977 }
8978
8979 static void
8980 do_vfp_reg2_from_dp (str)
8981      char *str;
8982 {
8983   skip_whitespace (str);
8984
8985   if (reg_required_here (&str, 12) == FAIL)
8986     return;
8987
8988   if (skip_past_comma (&str) == FAIL
8989       || reg_required_here (&str, 16) == FAIL
8990       || skip_past_comma (&str) == FAIL
8991       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8992     {
8993       if (! inst.error)
8994         inst.error = BAD_ARGS;
8995       return;
8996     }
8997
8998   end_of_line (str);
8999 }
9000
9001 static void
9002 do_vfp_dp_from_reg (str)
9003      char *str;
9004 {
9005   skip_whitespace (str);
9006
9007   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9008     return;
9009
9010   if (skip_past_comma (&str) == FAIL
9011       || reg_required_here (&str, 12) == FAIL)
9012     {
9013       if (! inst.error)
9014         inst.error = BAD_ARGS;
9015       return;
9016     }
9017
9018   end_of_line (str);
9019 }
9020
9021 static void
9022 do_vfp_dp_from_reg2 (str)
9023      char *str;
9024 {
9025   skip_whitespace (str);
9026
9027   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9028     return;
9029
9030   if (skip_past_comma (&str) == FAIL
9031       || reg_required_here (&str, 12) == FAIL
9032       || skip_past_comma (&str) == FAIL
9033       || reg_required_here (&str, 16) == FAIL)
9034     {
9035       if (! inst.error)
9036         inst.error = BAD_ARGS;
9037       return;
9038     }
9039
9040   end_of_line (str);
9041 }
9042
9043 static const struct vfp_reg *
9044 vfp_psr_parse (str)
9045      char **str;
9046 {
9047   char *start = *str;
9048   char  c;
9049   char *p;
9050   const struct vfp_reg *vreg;
9051
9052   p = start;
9053
9054   /* Find the end of the current token.  */
9055   do
9056     {
9057       c = *p++;
9058     }
9059   while (ISALPHA (c));
9060
9061   /* Mark it.  */
9062   *--p = 0;
9063
9064   for (vreg = vfp_regs + 0;
9065        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9066        vreg++)
9067     {
9068       if (strcmp (start, vreg->name) == 0)
9069         {
9070           *p = c;
9071           *str = p;
9072           return vreg;
9073         }
9074     }
9075
9076   *p = c;
9077   return NULL;
9078 }
9079
9080 static int
9081 vfp_psr_required_here (str)
9082      char **str;
9083 {
9084   char *start = *str;
9085   const struct vfp_reg *vreg;
9086
9087   vreg = vfp_psr_parse (str);
9088
9089   if (vreg)
9090     {
9091       inst.instruction |= vreg->regno;
9092       return SUCCESS;
9093     }
9094
9095   inst.error = _("VFP system register expected");
9096
9097   *str = start;
9098   return FAIL;
9099 }
9100
9101 static void
9102 do_vfp_reg_from_ctrl (str)
9103      char *str;
9104 {
9105   skip_whitespace (str);
9106
9107   if (reg_required_here (&str, 12) == FAIL)
9108     return;
9109
9110   if (skip_past_comma (&str) == FAIL
9111       || vfp_psr_required_here (&str) == FAIL)
9112     {
9113       if (! inst.error)
9114         inst.error = BAD_ARGS;
9115       return;
9116     }
9117
9118   end_of_line (str);
9119 }
9120
9121 static void
9122 do_vfp_ctrl_from_reg (str)
9123      char *str;
9124 {
9125   skip_whitespace (str);
9126
9127   if (vfp_psr_required_here (&str) == FAIL)
9128     return;
9129
9130   if (skip_past_comma (&str) == FAIL
9131       || reg_required_here (&str, 12) == FAIL)
9132     {
9133       if (! inst.error)
9134         inst.error = BAD_ARGS;
9135       return;
9136     }
9137
9138   end_of_line (str);
9139 }
9140
9141 static void
9142 do_vfp_sp_ldst (str)
9143      char *str;
9144 {
9145   skip_whitespace (str);
9146
9147   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9148     {
9149       if (!inst.error)
9150         inst.error = BAD_ARGS;
9151       return;
9152     }
9153
9154   if (skip_past_comma (&str) == FAIL
9155       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9156     {
9157       if (!inst.error)
9158         inst.error = BAD_ARGS;
9159       return;
9160     }
9161
9162   end_of_line (str);
9163 }
9164
9165 static void
9166 do_vfp_dp_ldst (str)
9167      char *str;
9168 {
9169   skip_whitespace (str);
9170
9171   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9172     {
9173       if (!inst.error)
9174         inst.error = BAD_ARGS;
9175       return;
9176     }
9177
9178   if (skip_past_comma (&str) == FAIL
9179       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9180     {
9181       if (!inst.error)
9182         inst.error = BAD_ARGS;
9183       return;
9184     }
9185
9186   end_of_line (str);
9187 }
9188
9189 /* Parse and encode a VFP SP register list, storing the initial
9190    register in position POS and returning the range as the result.  If
9191    the string is invalid return FAIL (an invalid range).  */
9192 static long
9193 vfp_sp_reg_list (str, pos)
9194      char **str;
9195      enum vfp_sp_reg_pos pos;
9196 {
9197   long range = 0;
9198   int base_reg = 0;
9199   int new_base;
9200   long base_bits = 0;
9201   int count = 0;
9202   long tempinst;
9203   unsigned long mask = 0;
9204   int warned = 0;
9205
9206   if (**str != '{')
9207     return FAIL;
9208
9209   (*str)++;
9210   skip_whitespace (*str);
9211
9212   tempinst = inst.instruction;
9213
9214   do
9215     {
9216       inst.instruction = 0;
9217
9218       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9219         return FAIL;
9220
9221       if (count == 0 || base_reg > new_base)
9222         {
9223           base_reg = new_base;
9224           base_bits = inst.instruction;
9225         }
9226
9227       if (mask & (1 << new_base))
9228         {
9229           inst.error = _("invalid register list");
9230           return FAIL;
9231         }
9232
9233       if ((mask >> new_base) != 0 && ! warned)
9234         {
9235           as_tsktsk (_("register list not in ascending order"));
9236           warned = 1;
9237         }
9238
9239       mask |= 1 << new_base;
9240       count++;
9241
9242       skip_whitespace (*str);
9243
9244       if (**str == '-') /* We have the start of a range expression */
9245         {
9246           int high_range;
9247
9248           (*str)++;
9249
9250           if ((high_range
9251                = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9252               == FAIL)
9253             {
9254               inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9255               return FAIL;
9256             }
9257
9258           if (high_range <= new_base)
9259             {
9260               inst.error = _("register range not in ascending order");
9261               return FAIL;
9262             }
9263
9264           for (new_base++; new_base <= high_range; new_base++)
9265             {
9266               if (mask & (1 << new_base))
9267                 {
9268                   inst.error = _("invalid register list");
9269                   return FAIL;
9270                 }
9271
9272               mask |= 1 << new_base;
9273               count++;
9274             }
9275         }
9276     }
9277   while (skip_past_comma (str) != FAIL);
9278
9279   if (**str != '}')
9280     {
9281       inst.error = _("invalid register list");
9282       return FAIL;
9283     }
9284
9285   (*str)++;
9286
9287   range = count;
9288
9289   /* Sanity check -- should have raised a parse error above.  */
9290   if (count == 0 || count > 32)
9291     abort ();
9292
9293   /* Final test -- the registers must be consecutive.  */
9294   while (count--)
9295     {
9296       if ((mask & (1 << base_reg++)) == 0)
9297         {
9298           inst.error = _("non-contiguous register range");
9299           return FAIL;
9300         }
9301     }
9302
9303   inst.instruction = tempinst | base_bits;
9304   return range;
9305 }
9306
9307 static long
9308 vfp_dp_reg_list (str)
9309      char **str;
9310 {
9311   long range = 0;
9312   int base_reg = 0;
9313   int new_base;
9314   int count = 0;
9315   long tempinst;
9316   unsigned long mask = 0;
9317   int warned = 0;
9318
9319   if (**str != '{')
9320     return FAIL;
9321
9322   (*str)++;
9323   skip_whitespace (*str);
9324
9325   tempinst = inst.instruction;
9326
9327   do
9328     {
9329       inst.instruction = 0;
9330
9331       if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9332         return FAIL;
9333
9334       if (count == 0 || base_reg > new_base)
9335         {
9336           base_reg = new_base;
9337           range = inst.instruction;
9338         }
9339
9340       if (mask & (1 << new_base))
9341         {
9342           inst.error = _("invalid register list");
9343           return FAIL;
9344         }
9345
9346       if ((mask >> new_base) != 0 && ! warned)
9347         {
9348           as_tsktsk (_("register list not in ascending order"));
9349           warned = 1;
9350         }
9351
9352       mask |= 1 << new_base;
9353       count++;
9354
9355       skip_whitespace (*str);
9356
9357       if (**str == '-') /* We have the start of a range expression */
9358         {
9359           int high_range;
9360
9361           (*str)++;
9362
9363           if ((high_range
9364                = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9365               == FAIL)
9366             {
9367               inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9368               return FAIL;
9369             }
9370
9371           if (high_range <= new_base)
9372             {
9373               inst.error = _("register range not in ascending order");
9374               return FAIL;
9375             }
9376
9377           for (new_base++; new_base <= high_range; new_base++)
9378             {
9379               if (mask & (1 << new_base))
9380                 {
9381                   inst.error = _("invalid register list");
9382                   return FAIL;
9383                 }
9384
9385               mask |= 1 << new_base;
9386               count++;
9387             }
9388         }
9389     }
9390   while (skip_past_comma (str) != FAIL);
9391
9392   if (**str != '}')
9393     {
9394       inst.error = _("invalid register list");
9395       return FAIL;
9396     }
9397
9398   (*str)++;
9399
9400   range |= 2 * count;
9401
9402   /* Sanity check -- should have raised a parse error above.  */
9403   if (count == 0 || count > 16)
9404     abort ();
9405
9406   /* Final test -- the registers must be consecutive.  */
9407   while (count--)
9408     {
9409       if ((mask & (1 << base_reg++)) == 0)
9410         {
9411           inst.error = _("non-contiguous register range");
9412           return FAIL;
9413         }
9414     }
9415
9416   inst.instruction = tempinst;
9417   return range;
9418 }
9419
9420 static void
9421 vfp_sp_ldstm (str, ldstm_type)
9422      char *str;
9423      enum vfp_ldstm_type ldstm_type;
9424 {
9425   long range;
9426
9427   skip_whitespace (str);
9428
9429   if (reg_required_here (&str, 16) == FAIL)
9430     return;
9431
9432   skip_whitespace (str);
9433
9434   if (*str == '!')
9435     {
9436       inst.instruction |= WRITE_BACK;
9437       str++;
9438     }
9439   else if (ldstm_type != VFP_LDSTMIA)
9440     {
9441       inst.error = _("this addressing mode requires base-register writeback");
9442       return;
9443     }
9444
9445   if (skip_past_comma (&str) == FAIL
9446       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9447     {
9448       if (!inst.error)
9449         inst.error = BAD_ARGS;
9450       return;
9451     }
9452
9453   inst.instruction |= range;
9454   end_of_line (str);
9455 }
9456
9457 static void
9458 vfp_dp_ldstm (str, ldstm_type)
9459      char *str;
9460      enum vfp_ldstm_type ldstm_type;
9461 {
9462   long range;
9463
9464   skip_whitespace (str);
9465
9466   if (reg_required_here (&str, 16) == FAIL)
9467     return;
9468
9469   skip_whitespace (str);
9470
9471   if (*str == '!')
9472     {
9473       inst.instruction |= WRITE_BACK;
9474       str++;
9475     }
9476   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9477     {
9478       inst.error = _("this addressing mode requires base-register writeback");
9479       return;
9480     }
9481
9482   if (skip_past_comma (&str) == FAIL
9483       || (range = vfp_dp_reg_list (&str)) == FAIL)
9484     {
9485       if (!inst.error)
9486         inst.error = BAD_ARGS;
9487       return;
9488     }
9489
9490   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9491     range += 1;
9492
9493   inst.instruction |= range;
9494   end_of_line (str);
9495 }
9496
9497 static void
9498 do_vfp_sp_ldstmia (str)
9499      char *str;
9500 {
9501   vfp_sp_ldstm (str, VFP_LDSTMIA);
9502 }
9503
9504 static void
9505 do_vfp_sp_ldstmdb (str)
9506      char *str;
9507 {
9508   vfp_sp_ldstm (str, VFP_LDSTMDB);
9509 }
9510
9511 static void
9512 do_vfp_dp_ldstmia (str)
9513      char *str;
9514 {
9515   vfp_dp_ldstm (str, VFP_LDSTMIA);
9516 }
9517
9518 static void
9519 do_vfp_dp_ldstmdb (str)
9520      char *str;
9521 {
9522   vfp_dp_ldstm (str, VFP_LDSTMDB);
9523 }
9524
9525 static void
9526 do_vfp_xp_ldstmia (str)
9527      char *str;
9528 {
9529   vfp_dp_ldstm (str, VFP_LDSTMIAX);
9530 }
9531
9532 static void
9533 do_vfp_xp_ldstmdb (str)
9534      char *str;
9535 {
9536   vfp_dp_ldstm (str, VFP_LDSTMDBX);
9537 }
9538
9539 static void
9540 do_vfp_sp_compare_z (str)
9541      char *str;
9542 {
9543   skip_whitespace (str);
9544
9545   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9546     {
9547       if (!inst.error)
9548         inst.error = BAD_ARGS;
9549       return;
9550     }
9551
9552   end_of_line (str);
9553 }
9554
9555 static void
9556 do_vfp_dp_compare_z (str)
9557      char *str;
9558 {
9559   skip_whitespace (str);
9560
9561   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9562     {
9563       if (!inst.error)
9564         inst.error = BAD_ARGS;
9565       return;
9566     }
9567
9568   end_of_line (str);
9569 }
9570
9571 static void
9572 do_vfp_dp_sp_cvt (str)
9573      char *str;
9574 {
9575   skip_whitespace (str);
9576
9577   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9578     return;
9579
9580   if (skip_past_comma (&str) == FAIL
9581       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9582     {
9583       if (! inst.error)
9584         inst.error = BAD_ARGS;
9585       return;
9586     }
9587
9588   end_of_line (str);
9589 }
9590
9591 static void
9592 do_vfp_sp_dp_cvt (str)
9593      char *str;
9594 {
9595   skip_whitespace (str);
9596
9597   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9598     return;
9599
9600   if (skip_past_comma (&str) == FAIL
9601       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9602     {
9603       if (! inst.error)
9604         inst.error = BAD_ARGS;
9605       return;
9606     }
9607
9608   end_of_line (str);
9609 }
9610
9611 /* Thumb specific routines.  */
9612
9613 /* Parse and validate that a register is of the right form, this saves
9614    repeated checking of this information in many similar cases.
9615    Unlike the 32-bit case we do not insert the register into the opcode
9616    here, since the position is often unknown until the full instruction
9617    has been parsed.  */
9618
9619 static int
9620 thumb_reg (strp, hi_lo)
9621      char ** strp;
9622      int     hi_lo;
9623 {
9624   int reg;
9625
9626   if ((reg = reg_required_here (strp, -1)) == FAIL)
9627     return FAIL;
9628
9629   switch (hi_lo)
9630     {
9631     case THUMB_REG_LO:
9632       if (reg > 7)
9633         {
9634           inst.error = _("lo register required");
9635           return FAIL;
9636         }
9637       break;
9638
9639     case THUMB_REG_HI:
9640       if (reg < 8)
9641         {
9642           inst.error = _("hi register required");
9643           return FAIL;
9644         }
9645       break;
9646
9647     default:
9648       break;
9649     }
9650
9651   return reg;
9652 }
9653
9654 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9655    was SUB.  */
9656
9657 static void
9658 thumb_add_sub (str, subtract)
9659      char * str;
9660      int    subtract;
9661 {
9662   int Rd, Rs, Rn = FAIL;
9663
9664   skip_whitespace (str);
9665
9666   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9667       || skip_past_comma (&str) == FAIL)
9668     {
9669       if (! inst.error)
9670         inst.error = BAD_ARGS;
9671       return;
9672     }
9673
9674   if (is_immediate_prefix (*str))
9675     {
9676       Rs = Rd;
9677       str++;
9678       if (my_get_expression (&inst.reloc.exp, &str))
9679         return;
9680     }
9681   else
9682     {
9683       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9684         return;
9685
9686       if (skip_past_comma (&str) == FAIL)
9687         {
9688           /* Two operand format, shuffle the registers
9689              and pretend there are 3.  */
9690           Rn = Rs;
9691           Rs = Rd;
9692         }
9693       else if (is_immediate_prefix (*str))
9694         {
9695           str++;
9696           if (my_get_expression (&inst.reloc.exp, &str))
9697             return;
9698         }
9699       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9700         return;
9701     }
9702
9703   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9704      for the latter case, EXPR contains the immediate that was found.  */
9705   if (Rn != FAIL)
9706     {
9707       /* All register format.  */
9708       if (Rd > 7 || Rs > 7 || Rn > 7)
9709         {
9710           if (Rs != Rd)
9711             {
9712               inst.error = _("dest and source1 must be the same register");
9713               return;
9714             }
9715
9716           /* Can't do this for SUB.  */
9717           if (subtract)
9718             {
9719               inst.error = _("subtract valid only on lo regs");
9720               return;
9721             }
9722
9723           inst.instruction = (T_OPCODE_ADD_HI
9724                               | (Rd > 7 ? THUMB_H1 : 0)
9725                               | (Rn > 7 ? THUMB_H2 : 0));
9726           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9727         }
9728       else
9729         {
9730           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9731           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9732         }
9733     }
9734   else
9735     {
9736       /* Immediate expression, now things start to get nasty.  */
9737
9738       /* First deal with HI regs, only very restricted cases allowed:
9739          Adjusting SP, and using PC or SP to get an address.  */
9740       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9741           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9742         {
9743           inst.error = _("invalid Hi register with immediate");
9744           return;
9745         }
9746
9747       if (inst.reloc.exp.X_op != O_constant)
9748         {
9749           /* Value isn't known yet, all we can do is store all the fragments
9750              we know about in the instruction and let the reloc hacking
9751              work it all out.  */
9752           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9753           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9754         }
9755       else
9756         {
9757           int offset = inst.reloc.exp.X_add_number;
9758
9759           if (subtract)
9760             offset = - offset;
9761
9762           if (offset < 0)
9763             {
9764               offset = - offset;
9765               subtract = 1;
9766
9767               /* Quick check, in case offset is MIN_INT.  */
9768               if (offset < 0)
9769                 {
9770                   inst.error = _("immediate value out of range");
9771                   return;
9772                 }
9773             }
9774           /* Note - you cannot convert a subtract of 0 into an
9775              add of 0 because the carry flag is set differently.  */
9776           else if (offset > 0)
9777             subtract = 0;
9778
9779           if (Rd == REG_SP)
9780             {
9781               if (offset & ~0x1fc)
9782                 {
9783                   inst.error = _("invalid immediate value for stack adjust");
9784                   return;
9785                 }
9786               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9787               inst.instruction |= offset >> 2;
9788             }
9789           else if (Rs == REG_PC || Rs == REG_SP)
9790             {
9791               if (subtract
9792                   || (offset & ~0x3fc))
9793                 {
9794                   inst.error = _("invalid immediate for address calculation");
9795                   return;
9796                 }
9797               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9798                                   : T_OPCODE_ADD_SP);
9799               inst.instruction |= (Rd << 8) | (offset >> 2);
9800             }
9801           else if (Rs == Rd)
9802             {
9803               if (offset & ~0xff)
9804                 {
9805                   inst.error = _("immediate value out of range");
9806                   return;
9807                 }
9808               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9809               inst.instruction |= (Rd << 8) | offset;
9810             }
9811           else
9812             {
9813               if (offset & ~0x7)
9814                 {
9815                   inst.error = _("immediate value out of range");
9816                   return;
9817                 }
9818               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9819               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9820             }
9821         }
9822     }
9823
9824   end_of_line (str);
9825 }
9826
9827 static void
9828 thumb_shift (str, shift)
9829      char * str;
9830      int    shift;
9831 {
9832   int Rd, Rs, Rn = FAIL;
9833
9834   skip_whitespace (str);
9835
9836   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9837       || skip_past_comma (&str) == FAIL)
9838     {
9839       if (! inst.error)
9840         inst.error = BAD_ARGS;
9841       return;
9842     }
9843
9844   if (is_immediate_prefix (*str))
9845     {
9846       /* Two operand immediate format, set Rs to Rd.  */
9847       Rs = Rd;
9848       str ++;
9849       if (my_get_expression (&inst.reloc.exp, &str))
9850         return;
9851     }
9852   else
9853     {
9854       if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9855         return;
9856
9857       if (skip_past_comma (&str) == FAIL)
9858         {
9859           /* Two operand format, shuffle the registers
9860              and pretend there are 3.  */
9861           Rn = Rs;
9862           Rs = Rd;
9863         }
9864       else if (is_immediate_prefix (*str))
9865         {
9866           str++;
9867           if (my_get_expression (&inst.reloc.exp, &str))
9868             return;
9869         }
9870       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9871         return;
9872     }
9873
9874   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9875      for the latter case, EXPR contains the immediate that was found.  */
9876
9877   if (Rn != FAIL)
9878     {
9879       if (Rs != Rd)
9880         {
9881           inst.error = _("source1 and dest must be same register");
9882           return;
9883         }
9884
9885       switch (shift)
9886         {
9887         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9888         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9889         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9890         }
9891
9892       inst.instruction |= Rd | (Rn << 3);
9893     }
9894   else
9895     {
9896       switch (shift)
9897         {
9898         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9899         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9900         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9901         }
9902
9903       if (inst.reloc.exp.X_op != O_constant)
9904         {
9905           /* Value isn't known yet, create a dummy reloc and let reloc
9906              hacking fix it up.  */
9907           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9908         }
9909       else
9910         {
9911           unsigned shift_value = inst.reloc.exp.X_add_number;
9912
9913           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9914             {
9915               inst.error = _("invalid immediate for shift");
9916               return;
9917             }
9918
9919           /* Shifts of zero are handled by converting to LSL.  */
9920           if (shift_value == 0)
9921             inst.instruction = T_OPCODE_LSL_I;
9922
9923           /* Shifts of 32 are encoded as a shift of zero.  */
9924           if (shift_value == 32)
9925             shift_value = 0;
9926
9927           inst.instruction |= shift_value << 6;
9928         }
9929
9930       inst.instruction |= Rd | (Rs << 3);
9931     }
9932
9933   end_of_line (str);
9934 }
9935
9936 static void
9937 thumb_mov_compare (str, move)
9938      char * str;
9939      int    move;
9940 {
9941   int Rd, Rs = FAIL;
9942
9943   skip_whitespace (str);
9944
9945   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9946       || skip_past_comma (&str) == FAIL)
9947     {
9948       if (! inst.error)
9949         inst.error = BAD_ARGS;
9950       return;
9951     }
9952
9953   if (move != THUMB_CPY && is_immediate_prefix (*str))
9954     {
9955       str++;
9956       if (my_get_expression (&inst.reloc.exp, &str))
9957         return;
9958     }
9959   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9960     return;
9961
9962   if (Rs != FAIL)
9963     {
9964       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
9965         {
9966           if (move == THUMB_MOVE)
9967             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
9968                since a MOV instruction produces unpredictable results.  */
9969             inst.instruction = T_OPCODE_ADD_I3;
9970           else
9971             inst.instruction = T_OPCODE_CMP_LR;
9972           inst.instruction |= Rd | (Rs << 3);
9973         }
9974       else
9975         {
9976           if (move == THUMB_MOVE)
9977             inst.instruction = T_OPCODE_MOV_HR;
9978           else if (move != THUMB_CPY)
9979             inst.instruction = T_OPCODE_CMP_HR;
9980
9981           if (Rd > 7)
9982             inst.instruction |= THUMB_H1;
9983
9984           if (Rs > 7)
9985             inst.instruction |= THUMB_H2;
9986
9987           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
9988         }
9989     }
9990   else
9991     {
9992       if (Rd > 7)
9993         {
9994           inst.error = _("only lo regs allowed with immediate");
9995           return;
9996         }
9997
9998       if (move == THUMB_MOVE)
9999         inst.instruction = T_OPCODE_MOV_I8;
10000       else
10001         inst.instruction = T_OPCODE_CMP_I8;
10002
10003       inst.instruction |= Rd << 8;
10004
10005       if (inst.reloc.exp.X_op != O_constant)
10006         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10007       else
10008         {
10009           unsigned value = inst.reloc.exp.X_add_number;
10010
10011           if (value > 255)
10012             {
10013               inst.error = _("invalid immediate");
10014               return;
10015             }
10016
10017           inst.instruction |= value;
10018         }
10019     }
10020
10021   end_of_line (str);
10022 }
10023
10024 static void
10025 thumb_load_store (str, load_store, size)
10026      char * str;
10027      int    load_store;
10028      int    size;
10029 {
10030   int Rd, Rb, Ro = FAIL;
10031
10032   skip_whitespace (str);
10033
10034   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10035       || skip_past_comma (&str) == FAIL)
10036     {
10037       if (! inst.error)
10038         inst.error = BAD_ARGS;
10039       return;
10040     }
10041
10042   if (*str == '[')
10043     {
10044       str++;
10045       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10046         return;
10047
10048       if (skip_past_comma (&str) != FAIL)
10049         {
10050           if (is_immediate_prefix (*str))
10051             {
10052               str++;
10053               if (my_get_expression (&inst.reloc.exp, &str))
10054                 return;
10055             }
10056           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10057             return;
10058         }
10059       else
10060         {
10061           inst.reloc.exp.X_op = O_constant;
10062           inst.reloc.exp.X_add_number = 0;
10063         }
10064
10065       if (*str != ']')
10066         {
10067           inst.error = _("expected ']'");
10068           return;
10069         }
10070       str++;
10071     }
10072   else if (*str == '=')
10073     {
10074       if (load_store != THUMB_LOAD)
10075         {
10076           inst.error = _("invalid pseudo operation");
10077           return;
10078         }
10079
10080       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10081       str++;
10082
10083       skip_whitespace (str);
10084
10085       if (my_get_expression (& inst.reloc.exp, & str))
10086         return;
10087
10088       end_of_line (str);
10089
10090       if (   inst.reloc.exp.X_op != O_constant
10091           && inst.reloc.exp.X_op != O_symbol)
10092         {
10093           inst.error = "Constant expression expected";
10094           return;
10095         }
10096
10097       if (inst.reloc.exp.X_op == O_constant
10098           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10099         {
10100           /* This can be done with a mov instruction.  */
10101
10102           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10103           inst.instruction |= inst.reloc.exp.X_add_number;
10104           return;
10105         }
10106
10107       /* Insert into literal pool.  */
10108       if (add_to_lit_pool () == FAIL)
10109         {
10110           if (!inst.error)
10111             inst.error = "literal pool insertion failed";
10112           return;
10113         }
10114
10115       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10116       inst.reloc.pc_rel = 1;
10117       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10118       /* Adjust ARM pipeline offset to Thumb.  */
10119       inst.reloc.exp.X_add_number += 4;
10120
10121       return;
10122     }
10123   else
10124     {
10125       if (my_get_expression (&inst.reloc.exp, &str))
10126         return;
10127
10128       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10129       inst.reloc.pc_rel = 1;
10130       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10131       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10132       end_of_line (str);
10133       return;
10134     }
10135
10136   if (Rb == REG_PC || Rb == REG_SP)
10137     {
10138       if (size != THUMB_WORD)
10139         {
10140           inst.error = _("byte or halfword not valid for base register");
10141           return;
10142         }
10143       else if (Rb == REG_PC && load_store != THUMB_LOAD)
10144         {
10145           inst.error = _("r15 based store not allowed");
10146           return;
10147         }
10148       else if (Ro != FAIL)
10149         {
10150           inst.error = _("invalid base register for register offset");
10151           return;
10152         }
10153
10154       if (Rb == REG_PC)
10155         inst.instruction = T_OPCODE_LDR_PC;
10156       else if (load_store == THUMB_LOAD)
10157         inst.instruction = T_OPCODE_LDR_SP;
10158       else
10159         inst.instruction = T_OPCODE_STR_SP;
10160
10161       inst.instruction |= Rd << 8;
10162       if (inst.reloc.exp.X_op == O_constant)
10163         {
10164           unsigned offset = inst.reloc.exp.X_add_number;
10165
10166           if (offset & ~0x3fc)
10167             {
10168               inst.error = _("invalid offset");
10169               return;
10170             }
10171
10172           inst.instruction |= offset >> 2;
10173         }
10174       else
10175         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10176     }
10177   else if (Rb > 7)
10178     {
10179       inst.error = _("invalid base register in load/store");
10180       return;
10181     }
10182   else if (Ro == FAIL)
10183     {
10184       /* Immediate offset.  */
10185       if (size == THUMB_WORD)
10186         inst.instruction = (load_store == THUMB_LOAD
10187                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10188       else if (size == THUMB_HALFWORD)
10189         inst.instruction = (load_store == THUMB_LOAD
10190                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10191       else
10192         inst.instruction = (load_store == THUMB_LOAD
10193                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10194
10195       inst.instruction |= Rd | (Rb << 3);
10196
10197       if (inst.reloc.exp.X_op == O_constant)
10198         {
10199           unsigned offset = inst.reloc.exp.X_add_number;
10200
10201           if (offset & ~(0x1f << size))
10202             {
10203               inst.error = _("invalid offset");
10204               return;
10205             }
10206           inst.instruction |= (offset >> size) << 6;
10207         }
10208       else
10209         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10210     }
10211   else
10212     {
10213       /* Register offset.  */
10214       if (size == THUMB_WORD)
10215         inst.instruction = (load_store == THUMB_LOAD
10216                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10217       else if (size == THUMB_HALFWORD)
10218         inst.instruction = (load_store == THUMB_LOAD
10219                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10220       else
10221         inst.instruction = (load_store == THUMB_LOAD
10222                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10223
10224       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10225     }
10226
10227   end_of_line (str);
10228 }
10229
10230 /* A register must be given at this point.
10231
10232    Shift is the place to put it in inst.instruction.
10233
10234    Restores input start point on err.
10235    Returns the reg#, or FAIL.  */
10236
10237 static int
10238 mav_reg_required_here (str, shift, regtype)
10239      char ** str;
10240      int shift;
10241      enum arm_reg_type regtype;
10242 {
10243   int   reg;
10244   char *start = *str;
10245
10246   if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10247     {
10248       if (shift >= 0)
10249         inst.instruction |= reg << shift;
10250
10251       return reg;
10252     }
10253
10254   /* Restore the start point.  */
10255   *str = start;
10256
10257   /* Try generic coprocessor name if applicable.  */
10258   if (regtype == REG_TYPE_MVF ||
10259       regtype == REG_TYPE_MVD ||
10260       regtype == REG_TYPE_MVFX ||
10261       regtype == REG_TYPE_MVDX)
10262     {
10263       if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
10264         {
10265           if (shift >= 0)
10266             inst.instruction |= reg << shift;
10267
10268           return reg;
10269         }
10270
10271       /* Restore the start point.  */
10272       *str = start;
10273     }
10274
10275   /* In the few cases where we might be able to accept something else
10276      this error can be overridden.  */
10277   inst.error = _(all_reg_maps[regtype].expected);
10278
10279   return FAIL;
10280 }
10281
10282 /* Cirrus Maverick Instructions.  */
10283
10284 /* Wrapper functions.  */
10285
10286 static void
10287 do_mav_binops_1a (str)
10288      char * str;
10289 {
10290   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10291 }
10292
10293 static void
10294 do_mav_binops_1b (str)
10295      char * str;
10296 {
10297   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10298 }
10299
10300 static void
10301 do_mav_binops_1c (str)
10302      char * str;
10303 {
10304   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10305 }
10306
10307 static void
10308 do_mav_binops_1d (str)
10309      char * str;
10310 {
10311   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10312 }
10313
10314 static void
10315 do_mav_binops_1e (str)
10316      char * str;
10317 {
10318   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10319 }
10320
10321 static void
10322 do_mav_binops_1f (str)
10323      char * str;
10324 {
10325   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10326 }
10327
10328 static void
10329 do_mav_binops_1g (str)
10330      char * str;
10331 {
10332   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10333 }
10334
10335 static void
10336 do_mav_binops_1h (str)
10337      char * str;
10338 {
10339   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10340 }
10341
10342 static void
10343 do_mav_binops_1i (str)
10344      char * str;
10345 {
10346   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10347 }
10348
10349 static void
10350 do_mav_binops_1j (str)
10351      char * str;
10352 {
10353   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10354 }
10355
10356 static void
10357 do_mav_binops_1k (str)
10358      char * str;
10359 {
10360   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10361 }
10362
10363 static void
10364 do_mav_binops_1l (str)
10365      char * str;
10366 {
10367   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10368 }
10369
10370 static void
10371 do_mav_binops_1m (str)
10372      char * str;
10373 {
10374   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10375 }
10376
10377 static void
10378 do_mav_binops_1n (str)
10379      char * str;
10380 {
10381   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10382 }
10383
10384 static void
10385 do_mav_binops_1o (str)
10386      char * str;
10387 {
10388   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10389 }
10390
10391 static void
10392 do_mav_binops_2a (str)
10393      char * str;
10394 {
10395   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10396 }
10397
10398 static void
10399 do_mav_binops_2b (str)
10400      char * str;
10401 {
10402   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10403 }
10404
10405 static void
10406 do_mav_binops_2c (str)
10407      char * str;
10408 {
10409   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10410 }
10411
10412 static void
10413 do_mav_binops_3a (str)
10414      char * str;
10415 {
10416   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10417 }
10418
10419 static void
10420 do_mav_binops_3b (str)
10421      char * str;
10422 {
10423   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10424 }
10425
10426 static void
10427 do_mav_binops_3c (str)
10428      char * str;
10429 {
10430   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10431 }
10432
10433 static void
10434 do_mav_binops_3d (str)
10435      char * str;
10436 {
10437   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10438 }
10439
10440 static void
10441 do_mav_triple_4a (str)
10442      char * str;
10443 {
10444   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10445 }
10446
10447 static void
10448 do_mav_triple_4b (str)
10449      char * str;
10450 {
10451   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10452 }
10453
10454 static void
10455 do_mav_triple_5a (str)
10456      char * str;
10457 {
10458   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10459 }
10460
10461 static void
10462 do_mav_triple_5b (str)
10463      char * str;
10464 {
10465   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10466 }
10467
10468 static void
10469 do_mav_triple_5c (str)
10470      char * str;
10471 {
10472   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10473 }
10474
10475 static void
10476 do_mav_triple_5d (str)
10477      char * str;
10478 {
10479   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10480 }
10481
10482 static void
10483 do_mav_triple_5e (str)
10484      char * str;
10485 {
10486   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10487 }
10488
10489 static void
10490 do_mav_triple_5f (str)
10491      char * str;
10492 {
10493   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10494 }
10495
10496 static void
10497 do_mav_triple_5g (str)
10498      char * str;
10499 {
10500   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10501 }
10502
10503 static void
10504 do_mav_triple_5h (str)
10505      char * str;
10506 {
10507   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10508 }
10509
10510 static void
10511 do_mav_quad_6a (str)
10512      char * str;
10513 {
10514   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10515                REG_TYPE_MVFX);
10516 }
10517
10518 static void
10519 do_mav_quad_6b (str)
10520      char * str;
10521 {
10522   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10523                REG_TYPE_MVFX);
10524 }
10525
10526 /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
10527 static void
10528 do_mav_dspsc_1 (str)
10529      char * str;
10530 {
10531   skip_whitespace (str);
10532
10533   /* cfmvsc32.  */
10534   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10535       || skip_past_comma (&str) == FAIL
10536       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10537     {
10538       if (!inst.error)
10539         inst.error = BAD_ARGS;
10540
10541       return;
10542     }
10543
10544   end_of_line (str);
10545 }
10546
10547 /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
10548 static void
10549 do_mav_dspsc_2 (str)
10550      char * str;
10551 {
10552   skip_whitespace (str);
10553
10554   /* cfmv32sc.  */
10555   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10556       || skip_past_comma (&str) == FAIL
10557       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10558     {
10559       if (!inst.error)
10560         inst.error = BAD_ARGS;
10561
10562       return;
10563     }
10564
10565   end_of_line (str);
10566 }
10567
10568 static void
10569 do_mav_shift_1 (str)
10570      char * str;
10571 {
10572   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10573 }
10574
10575 static void
10576 do_mav_shift_2 (str)
10577      char * str;
10578 {
10579   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10580 }
10581
10582 static void
10583 do_mav_ldst_1 (str)
10584      char * str;
10585 {
10586   do_mav_ldst (str, REG_TYPE_MVF);
10587 }
10588
10589 static void
10590 do_mav_ldst_2 (str)
10591      char * str;
10592 {
10593   do_mav_ldst (str, REG_TYPE_MVD);
10594 }
10595
10596 static void
10597 do_mav_ldst_3 (str)
10598      char * str;
10599 {
10600   do_mav_ldst (str, REG_TYPE_MVFX);
10601 }
10602
10603 static void
10604 do_mav_ldst_4 (str)
10605      char * str;
10606 {
10607   do_mav_ldst (str, REG_TYPE_MVDX);
10608 }
10609
10610 /* Isnsn like "foo X,Y".  */
10611
10612 static void
10613 do_mav_binops (str, mode, reg0, reg1)
10614      char * str;
10615      int mode;
10616      enum arm_reg_type reg0;
10617      enum arm_reg_type reg1;
10618 {
10619   int shift0, shift1;
10620
10621   shift0 = mode & 0xff;
10622   shift1 = (mode >> 8) & 0xff;
10623
10624   skip_whitespace (str);
10625
10626   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10627       || skip_past_comma (&str) == FAIL
10628       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10629     {
10630       if (!inst.error)
10631         inst.error = BAD_ARGS;
10632     }
10633   else
10634     end_of_line (str);
10635 }
10636
10637 /* Isnsn like "foo X,Y,Z".  */
10638
10639 static void
10640 do_mav_triple (str, mode, reg0, reg1, reg2)
10641      char * str;
10642      int mode;
10643      enum arm_reg_type reg0;
10644      enum arm_reg_type reg1;
10645      enum arm_reg_type reg2;
10646 {
10647   int shift0, shift1, shift2;
10648
10649   shift0 = mode & 0xff;
10650   shift1 = (mode >> 8) & 0xff;
10651   shift2 = (mode >> 16) & 0xff;
10652
10653   skip_whitespace (str);
10654
10655   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10656       || skip_past_comma (&str) == FAIL
10657       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10658       || skip_past_comma (&str) == FAIL
10659       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10660     {
10661       if (!inst.error)
10662         inst.error = BAD_ARGS;
10663     }
10664   else
10665     end_of_line (str);
10666 }
10667
10668 /* Isnsn like "foo W,X,Y,Z".
10669     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10670
10671 static void
10672 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10673      char * str;
10674      int mode;
10675      enum arm_reg_type reg0;
10676      enum arm_reg_type reg1;
10677      enum arm_reg_type reg2;
10678      enum arm_reg_type reg3;
10679 {
10680   int shift0, shift1, shift2, shift3;
10681
10682   shift0= mode & 0xff;
10683   shift1 = (mode >> 8) & 0xff;
10684   shift2 = (mode >> 16) & 0xff;
10685   shift3 = (mode >> 24) & 0xff;
10686
10687   skip_whitespace (str);
10688
10689   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10690       || skip_past_comma (&str) == FAIL
10691       || mav_reg_required_here (&str, shift1, reg1) == FAIL
10692       || skip_past_comma (&str) == FAIL
10693       || mav_reg_required_here (&str, shift2, reg2) == FAIL
10694       || skip_past_comma (&str) == FAIL
10695       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10696     {
10697       if (!inst.error)
10698         inst.error = BAD_ARGS;
10699     }
10700   else
10701     end_of_line (str);
10702 }
10703
10704 /* Maverick shift immediate instructions.
10705    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10706    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10707
10708 static void
10709 do_mav_shift (str, reg0, reg1)
10710      char * str;
10711      enum arm_reg_type reg0;
10712      enum arm_reg_type reg1;
10713 {
10714   int error;
10715   int imm, neg = 0;
10716
10717   skip_whitespace (str);
10718
10719   error = 0;
10720
10721   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10722       || skip_past_comma (&str) == FAIL
10723       || mav_reg_required_here (&str, 16, reg1) == FAIL
10724       || skip_past_comma  (&str) == FAIL)
10725     {
10726       if (!inst.error)
10727         inst.error = BAD_ARGS;
10728       return;
10729     }
10730
10731   /* Calculate the immediate operand.
10732      The operand is a 7bit signed number.  */
10733   skip_whitespace (str);
10734
10735   if (*str == '#')
10736     ++str;
10737
10738   if (!ISDIGIT (*str) && *str != '-')
10739     {
10740       inst.error = _("expecting immediate, 7bit operand");
10741       return;
10742     }
10743
10744   if (*str == '-')
10745     {
10746       neg = 1;
10747       ++str;
10748     }
10749
10750   for (imm = 0; *str && ISDIGIT (*str); ++str)
10751     imm = imm * 10 + *str - '0';
10752
10753   if (imm > 64)
10754     {
10755       inst.error = _("immediate out of range");
10756       return;
10757     }
10758
10759   /* Make negative imm's into 7bit signed numbers.  */
10760   if (neg)
10761     {
10762       imm = -imm;
10763       imm &= 0x0000007f;
10764     }
10765
10766   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10767      Bits 5-7 of the insn should have bits 4-6 of the immediate.
10768      Bit 4 should be 0.  */
10769   imm = (imm & 0xf) | ((imm & 0x70) << 1);
10770
10771   inst.instruction |= imm;
10772   end_of_line (str);
10773 }
10774
10775 static int
10776 mav_parse_offset (str, negative)
10777      char ** str;
10778      int *negative;
10779 {
10780   char * p = *str;
10781   int offset;
10782
10783   *negative = 0;
10784
10785   skip_whitespace (p);
10786
10787   if (*p == '#')
10788     ++p;
10789
10790   if (*p == '-')
10791     {
10792       *negative = 1;
10793       ++p;
10794     }
10795
10796   if (!ISDIGIT (*p))
10797     {
10798       inst.error = _("offset expected");
10799       return 0;
10800     }
10801
10802   for (offset = 0; *p && ISDIGIT (*p); ++p)
10803     offset = offset * 10 + *p - '0';
10804
10805   if (offset > 0x3fc)
10806     {
10807       inst.error = _("offset out of range");
10808       return 0;
10809     }
10810   if (offset & 0x3)
10811     {
10812       inst.error = _("offset not a multiple of 4");
10813       return 0;
10814     }
10815
10816   *str = p;
10817
10818   return *negative ? -offset : offset;
10819 }
10820
10821 /* Maverick load/store instructions.
10822   <insn><cond> CRd,[Rn,<offset>]{!}.
10823   <insn><cond> CRd,[Rn],<offset>.  */
10824
10825 static void
10826 do_mav_ldst (str, reg0)
10827      char * str;
10828      enum arm_reg_type reg0;
10829 {
10830   int offset, negative;
10831
10832   skip_whitespace (str);
10833
10834   if (mav_reg_required_here (&str, 12, reg0) == FAIL
10835       || skip_past_comma (&str) == FAIL
10836       || *str++ != '['
10837       || reg_required_here (&str, 16) == FAIL)
10838     goto fail_ldst;
10839
10840   if (skip_past_comma (&str) == SUCCESS)
10841     {
10842       /* You are here: "<offset>]{!}".  */
10843       inst.instruction |= PRE_INDEX;
10844
10845       offset = mav_parse_offset (&str, &negative);
10846
10847       if (inst.error)
10848         return;
10849
10850       if (*str++ != ']')
10851         {
10852           inst.error = _("missing ]");
10853           return;
10854         }
10855
10856       if (*str == '!')
10857         {
10858           inst.instruction |= WRITE_BACK;
10859           ++str;
10860         }
10861     }
10862   else
10863     {
10864       /* You are here: "], <offset>".  */
10865       if (*str++ != ']')
10866         {
10867           inst.error = _("missing ]");
10868           return;
10869         }
10870
10871       if (skip_past_comma (&str) == FAIL
10872           || (offset = mav_parse_offset (&str, &negative), inst.error))
10873         goto fail_ldst;
10874
10875       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10876     }
10877
10878   if (negative)
10879     offset = -offset;
10880   else
10881     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10882
10883   inst.instruction |= offset >> 2;
10884   end_of_line (str);
10885   return;
10886
10887 fail_ldst:
10888   if (!inst.error)
10889      inst.error = BAD_ARGS;
10890 }
10891
10892 static void
10893 do_t_nop (str)
10894      char * str;
10895 {
10896   /* Do nothing.  */
10897   end_of_line (str);
10898 }
10899
10900 /* Handle the Format 4 instructions that do not have equivalents in other
10901    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10902    BIC and MVN.  */
10903
10904 static void
10905 do_t_arit (str)
10906      char * str;
10907 {
10908   int Rd, Rs, Rn;
10909
10910   skip_whitespace (str);
10911
10912   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10913       || skip_past_comma (&str) == FAIL
10914       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10915     {
10916       inst.error = BAD_ARGS;
10917       return;
10918     }
10919
10920   if (skip_past_comma (&str) != FAIL)
10921     {
10922       /* Three operand format not allowed for TST, CMN, NEG and MVN.
10923          (It isn't allowed for CMP either, but that isn't handled by this
10924          function.)  */
10925       if (inst.instruction == T_OPCODE_TST
10926           || inst.instruction == T_OPCODE_CMN
10927           || inst.instruction == T_OPCODE_NEG
10928           || inst.instruction == T_OPCODE_MVN)
10929         {
10930           inst.error = BAD_ARGS;
10931           return;
10932         }
10933
10934       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10935         return;
10936
10937       if (Rs != Rd)
10938         {
10939           inst.error = _("dest and source1 must be the same register");
10940           return;
10941         }
10942       Rs = Rn;
10943     }
10944
10945   if (inst.instruction == T_OPCODE_MUL
10946       && Rs == Rd)
10947     as_tsktsk (_("Rs and Rd must be different in MUL"));
10948
10949   inst.instruction |= Rd | (Rs << 3);
10950   end_of_line (str);
10951 }
10952
10953 static void
10954 do_t_add (str)
10955      char * str;
10956 {
10957   thumb_add_sub (str, 0);
10958 }
10959
10960 static void
10961 do_t_asr (str)
10962      char * str;
10963 {
10964   thumb_shift (str, THUMB_ASR);
10965 }
10966
10967 static void
10968 do_t_branch9 (str)
10969      char * str;
10970 {
10971   if (my_get_expression (&inst.reloc.exp, &str))
10972     return;
10973   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
10974   inst.reloc.pc_rel = 1;
10975   end_of_line (str);
10976 }
10977
10978 static void
10979 do_t_branch12 (str)
10980      char * str;
10981 {
10982   if (my_get_expression (&inst.reloc.exp, &str))
10983     return;
10984   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
10985   inst.reloc.pc_rel = 1;
10986   end_of_line (str);
10987 }
10988
10989 /* Find the real, Thumb encoded start of a Thumb function.  */
10990
10991 static symbolS *
10992 find_real_start (symbolP)
10993      symbolS * symbolP;
10994 {
10995   char *       real_start;
10996   const char * name = S_GET_NAME (symbolP);
10997   symbolS *    new_target;
10998
10999   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11000 #define STUB_NAME ".real_start_of"
11001
11002   if (name == NULL)
11003     abort ();
11004
11005   /* Names that start with '.' are local labels, not function entry points.
11006      The compiler may generate BL instructions to these labels because it
11007      needs to perform a branch to a far away location.  */
11008   if (name[0] == '.')
11009     return symbolP;
11010
11011   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11012   sprintf (real_start, "%s%s", STUB_NAME, name);
11013
11014   new_target = symbol_find (real_start);
11015
11016   if (new_target == NULL)
11017     {
11018       as_warn ("Failed to find real start of function: %s\n", name);
11019       new_target = symbolP;
11020     }
11021
11022   free (real_start);
11023
11024   return new_target;
11025 }
11026
11027 static void
11028 do_t_branch23 (str)
11029      char * str;
11030 {
11031   if (my_get_expression (& inst.reloc.exp, & str))
11032     return;
11033
11034   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11035   inst.reloc.pc_rel = 1;
11036   end_of_line (str);
11037
11038   /* If the destination of the branch is a defined symbol which does not have
11039      the THUMB_FUNC attribute, then we must be calling a function which has
11040      the (interfacearm) attribute.  We look for the Thumb entry point to that
11041      function and change the branch to refer to that function instead.  */
11042   if (   inst.reloc.exp.X_op == O_symbol
11043       && inst.reloc.exp.X_add_symbol != NULL
11044       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11045       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11046     inst.reloc.exp.X_add_symbol =
11047       find_real_start (inst.reloc.exp.X_add_symbol);
11048 }
11049
11050 static void
11051 do_t_bx (str)
11052      char * str;
11053 {
11054   int reg;
11055
11056   skip_whitespace (str);
11057
11058   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11059     return;
11060
11061   /* This sets THUMB_H2 from the top bit of reg.  */
11062   inst.instruction |= reg << 3;
11063
11064   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11065      should cause the alignment to be checked once it is known.  This is
11066      because BX PC only works if the instruction is word aligned.  */
11067
11068   end_of_line (str);
11069 }
11070
11071 static void
11072 do_t_compare (str)
11073      char * str;
11074 {
11075   thumb_mov_compare (str, THUMB_COMPARE);
11076 }
11077
11078 static void
11079 do_t_ldmstm (str)
11080      char * str;
11081 {
11082   int Rb;
11083   long range;
11084
11085   skip_whitespace (str);
11086
11087   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11088     return;
11089
11090   if (*str != '!')
11091     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11092   else
11093     str++;
11094
11095   if (skip_past_comma (&str) == FAIL
11096       || (range = reg_list (&str)) == FAIL)
11097     {
11098       if (! inst.error)
11099         inst.error = BAD_ARGS;
11100       return;
11101     }
11102
11103   if (inst.reloc.type != BFD_RELOC_NONE)
11104     {
11105       /* This really doesn't seem worth it.  */
11106       inst.reloc.type = BFD_RELOC_NONE;
11107       inst.error = _("expression too complex");
11108       return;
11109     }
11110
11111   if (range & ~0xff)
11112     {
11113       inst.error = _("only lo-regs valid in load/store multiple");
11114       return;
11115     }
11116
11117   inst.instruction |= (Rb << 8) | range;
11118   end_of_line (str);
11119 }
11120
11121 static void
11122 do_t_ldr (str)
11123      char * str;
11124 {
11125   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11126 }
11127
11128 static void
11129 do_t_ldrb (str)
11130      char * str;
11131 {
11132   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11133 }
11134
11135 static void
11136 do_t_ldrh (str)
11137      char * str;
11138 {
11139   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11140 }
11141
11142 static void
11143 do_t_lds (str)
11144      char * str;
11145 {
11146   int Rd, Rb, Ro;
11147
11148   skip_whitespace (str);
11149
11150   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11151       || skip_past_comma (&str) == FAIL
11152       || *str++ != '['
11153       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11154       || skip_past_comma (&str) == FAIL
11155       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11156       || *str++ != ']')
11157     {
11158       if (! inst.error)
11159         inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11160       return;
11161     }
11162
11163   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11164   end_of_line (str);
11165 }
11166
11167 static void
11168 do_t_lsl (str)
11169      char * str;
11170 {
11171   thumb_shift (str, THUMB_LSL);
11172 }
11173
11174 static void
11175 do_t_lsr (str)
11176      char * str;
11177 {
11178   thumb_shift (str, THUMB_LSR);
11179 }
11180
11181 static void
11182 do_t_mov (str)
11183      char * str;
11184 {
11185   thumb_mov_compare (str, THUMB_MOVE);
11186 }
11187
11188 static void
11189 do_t_push_pop (str)
11190      char * str;
11191 {
11192   long range;
11193
11194   skip_whitespace (str);
11195
11196   if ((range = reg_list (&str)) == FAIL)
11197     {
11198       if (! inst.error)
11199         inst.error = BAD_ARGS;
11200       return;
11201     }
11202
11203   if (inst.reloc.type != BFD_RELOC_NONE)
11204     {
11205       /* This really doesn't seem worth it.  */
11206       inst.reloc.type = BFD_RELOC_NONE;
11207       inst.error = _("expression too complex");
11208       return;
11209     }
11210
11211   if (range & ~0xff)
11212     {
11213       if ((inst.instruction == T_OPCODE_PUSH
11214            && (range & ~0xff) == 1 << REG_LR)
11215           || (inst.instruction == T_OPCODE_POP
11216               && (range & ~0xff) == 1 << REG_PC))
11217         {
11218           inst.instruction |= THUMB_PP_PC_LR;
11219           range &= 0xff;
11220         }
11221       else
11222         {
11223           inst.error = _("invalid register list to push/pop instruction");
11224           return;
11225         }
11226     }
11227
11228   inst.instruction |= range;
11229   end_of_line (str);
11230 }
11231
11232 static void
11233 do_t_str (str)
11234      char * str;
11235 {
11236   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11237 }
11238
11239 static void
11240 do_t_strb (str)
11241      char * str;
11242 {
11243   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11244 }
11245
11246 static void
11247 do_t_strh (str)
11248      char * str;
11249 {
11250   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11251 }
11252
11253 static void
11254 do_t_sub (str)
11255      char * str;
11256 {
11257   thumb_add_sub (str, 1);
11258 }
11259
11260 static void
11261 do_t_swi (str)
11262      char * str;
11263 {
11264   skip_whitespace (str);
11265
11266   if (my_get_expression (&inst.reloc.exp, &str))
11267     return;
11268
11269   inst.reloc.type = BFD_RELOC_ARM_SWI;
11270   end_of_line (str);
11271 }
11272
11273 static void
11274 do_t_adr (str)
11275      char * str;
11276 {
11277   int reg;
11278
11279   /* This is a pseudo-op of the form "adr rd, label" to be converted
11280      into a relative address of the form "add rd, pc, #label-.-4".  */
11281   skip_whitespace (str);
11282
11283   /* Store Rd in temporary location inside instruction.  */
11284   if ((reg = reg_required_here (&str, 4)) == FAIL
11285       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11286       || skip_past_comma (&str) == FAIL
11287       || my_get_expression (&inst.reloc.exp, &str))
11288     {
11289       if (!inst.error)
11290         inst.error = BAD_ARGS;
11291       return;
11292     }
11293
11294   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11295   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11296   inst.reloc.pc_rel = 1;
11297   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11298
11299   end_of_line (str);
11300 }
11301
11302 static void
11303 insert_reg (r, htab)
11304      const struct reg_entry *r;
11305      struct hash_control *htab;
11306 {
11307   int    len  = strlen (r->name) + 2;
11308   char * buf  = (char *) xmalloc (len);
11309   char * buf2 = (char *) xmalloc (len);
11310   int    i    = 0;
11311
11312 #ifdef REGISTER_PREFIX
11313   buf[i++] = REGISTER_PREFIX;
11314 #endif
11315
11316   strcpy (buf + i, r->name);
11317
11318   for (i = 0; buf[i]; i++)
11319     buf2[i] = TOUPPER (buf[i]);
11320
11321   buf2[i] = '\0';
11322
11323   hash_insert (htab, buf,  (PTR) r);
11324   hash_insert (htab, buf2, (PTR) r);
11325 }
11326
11327 static void
11328 build_reg_hsh (map)
11329      struct reg_map *map;
11330 {
11331   const struct reg_entry *r;
11332
11333   if ((map->htab = hash_new ()) == NULL)
11334     as_fatal (_("virtual memory exhausted"));
11335
11336   for (r = map->names; r->name != NULL; r++)
11337     insert_reg (r, map->htab);
11338 }
11339
11340 static void
11341 insert_reg_alias (str, regnum, htab)
11342      char *str;
11343      int regnum;
11344      struct hash_control *htab;
11345 {
11346   const char *error;
11347   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11348   const char *name = xmalloc (strlen (str) + 1);
11349   
11350   strcpy ((char *) name, str);
11351   
11352   new->name = name;
11353   new->number = regnum;
11354   new->builtin = FALSE;
11355
11356   error = hash_insert (htab, name, (PTR) new);
11357   if (error)
11358     {
11359       as_bad (_("failed to create an alias for %s, reason: %s"),
11360             str, error);
11361       free ((char *) name);
11362       free (new);
11363     }
11364 }
11365
11366 /* Look for the .req directive.  This is of the form:
11367
11368         new_register_name .req existing_register_name
11369
11370    If we find one, or if it looks sufficiently like one that we want to
11371    handle any error here, return non-zero.  Otherwise return zero.  */
11372 static int
11373 create_register_alias (newname, p)
11374      char *newname;
11375      char *p;
11376 {
11377   char *q;
11378   char c;
11379
11380   q = p;
11381   skip_whitespace (q);
11382
11383   c = *p;
11384   *p = '\0';
11385
11386   if (*q && !strncmp (q, ".req ", 5))
11387     {
11388       char *copy_of_str;
11389       char *r;
11390
11391 #ifndef IGNORE_OPCODE_CASE
11392       newname = original_case_string;
11393 #endif
11394       copy_of_str = newname;
11395
11396       q += 4;
11397       skip_whitespace (q);
11398
11399       for (r = q; *r != '\0'; r++)
11400         if (*r == ' ')
11401           break;
11402
11403       if (r != q)
11404         {
11405           enum arm_reg_type new_type, old_type;
11406           int old_regno;
11407           char d = *r;
11408
11409           *r = '\0';
11410           old_type = arm_reg_parse_any (q);
11411           *r = d;
11412
11413           new_type = arm_reg_parse_any (newname);
11414
11415           if (new_type == REG_TYPE_MAX)
11416             {
11417               if (old_type != REG_TYPE_MAX)
11418                 {
11419                   old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11420                   insert_reg_alias (newname, old_regno,
11421                                     all_reg_maps[old_type].htab);
11422                 }
11423               else
11424                 as_warn (_("register '%s' does not exist\n"), q);
11425             }
11426           else if (old_type == REG_TYPE_MAX)
11427             {
11428               as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11429                        copy_of_str, q);
11430             }
11431           else
11432             {
11433               /* Do not warn about redefinitions to the same alias.  */
11434               if (new_type != old_type
11435                   || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11436                       != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11437                 as_warn (_("ignoring redefinition of register alias '%s'"),
11438                          copy_of_str);
11439
11440             }
11441         }
11442       else
11443         as_warn (_("ignoring incomplete .req pseuso op"));
11444
11445       *p = c;
11446       return 1;
11447     }
11448   
11449   *p = c;
11450   return 0;
11451 }
11452
11453 static void
11454 set_constant_flonums ()
11455 {
11456   int i;
11457
11458   for (i = 0; i < NUM_FLOAT_VALS; i++)
11459     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11460       abort ();
11461 }
11462
11463 /* Iterate over the base tables to create the instruction patterns.  */
11464 static void
11465 build_arm_ops_hsh ()
11466 {
11467   unsigned int i;
11468   unsigned int j;
11469   static struct obstack insn_obstack;
11470
11471   obstack_begin (&insn_obstack, 4000);
11472
11473   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11474     {
11475       const struct asm_opcode *insn = insns + i;
11476
11477       if (insn->cond_offset != 0)
11478         {
11479           /* Insn supports conditional execution.  Build the varaints
11480              and insert them in the hash table.  */
11481           for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11482             {
11483               unsigned len = strlen (insn->template);
11484               struct asm_opcode *new;
11485               char *template;
11486
11487               new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11488               /* All condition codes are two characters.  */
11489               template = obstack_alloc (&insn_obstack, len + 3);
11490
11491               strncpy (template, insn->template, insn->cond_offset);
11492               strcpy (template + insn->cond_offset, conds[j].template);
11493               if (len > insn->cond_offset)
11494                 strcpy (template + insn->cond_offset + 2,
11495                         insn->template + insn->cond_offset);
11496               new->template = template;
11497               new->cond_offset = 0;
11498               new->variant = insn->variant;
11499               new->parms = insn->parms;
11500               new->value = (insn->value & ~COND_MASK) | conds[j].value;
11501
11502               hash_insert (arm_ops_hsh, new->template, (PTR) new);
11503             }
11504         }
11505       /* Finally, insert the unconditional insn in the table directly;
11506          no need to build a copy.  */
11507       hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11508     }
11509 }
11510
11511 #if 0 /* Suppressed - for now.  */
11512 #if defined OBJ_ELF || defined OBJ_COFF
11513
11514 #ifdef OBJ_ELF
11515 #define arm_Note Elf_External_Note
11516 #else
11517 typedef struct
11518 {
11519   unsigned char namesz[4];      /* Size of entry's owner string.  */
11520   unsigned char descsz[4];      /* Size of the note descriptor.  */
11521   unsigned char type[4];        /* Interpretation of the descriptor.  */
11522   char          name[1];        /* Start of the name+desc data.  */
11523 } arm_Note;
11524 #endif
11525
11526 /* The description is kept to a fix sized in order to make updating
11527    it and merging it easier.  */
11528 #define ARM_NOTE_DESCRIPTION_LENGTH     8
11529
11530 static void
11531 arm_add_note (name, description, type)
11532      const char * name;
11533      const char * description;
11534      unsigned int type;
11535 {
11536   arm_Note     note ATTRIBUTE_UNUSED;
11537   char *       p;
11538   unsigned int name_len;
11539
11540   name_len = (strlen (name) + 1 + 3) & ~3;
11541   
11542   p = frag_more (sizeof (note.namesz));
11543   md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11544
11545   p = frag_more (sizeof (note.descsz));
11546   md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11547
11548   p = frag_more (sizeof (note.type));
11549   md_number_to_chars (p, (valueT) type, sizeof (note.type));
11550
11551   p = frag_more (name_len);
11552   strcpy (p, name);
11553
11554   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11555   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11556   frag_align (2, 0, 0);
11557 }
11558 #endif
11559 #endif
11560
11561 void
11562 md_begin ()
11563 {
11564   unsigned mach;
11565   unsigned int i;
11566
11567   if (   (arm_ops_hsh = hash_new ()) == NULL
11568       || (arm_tops_hsh = hash_new ()) == NULL
11569       || (arm_cond_hsh = hash_new ()) == NULL
11570       || (arm_shift_hsh = hash_new ()) == NULL
11571       || (arm_psr_hsh = hash_new ()) == NULL)
11572     as_fatal (_("virtual memory exhausted"));
11573
11574   build_arm_ops_hsh ();
11575   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11576     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11577   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11578     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11579   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11580     hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11581   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11582     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11583
11584   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11585     build_reg_hsh (all_reg_maps + i);
11586
11587   set_constant_flonums ();
11588
11589   /* Set the cpu variant based on the command-line options.  We prefer
11590      -mcpu= over -march= if both are set (as for GCC); and we prefer
11591      -mfpu= over any other way of setting the floating point unit.
11592      Use of legacy options with new options are faulted.  */
11593   if (legacy_cpu != -1)
11594     {
11595       if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11596         as_bad (_("use of old and new-style options to set CPU type"));
11597
11598       mcpu_cpu_opt = legacy_cpu;
11599     }
11600   else if (mcpu_cpu_opt == -1)
11601     mcpu_cpu_opt = march_cpu_opt;
11602
11603   if (legacy_fpu != -1)
11604     {
11605       if (mfpu_opt != -1)
11606         as_bad (_("use of old and new-style options to set FPU type"));
11607
11608       mfpu_opt = legacy_fpu;
11609     }
11610   else if (mfpu_opt == -1)
11611     {
11612 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11613       /* Some environments specify a default FPU.  If they don't, infer it
11614          from the processor.  */
11615       if (mcpu_fpu_opt != -1)
11616         mfpu_opt = mcpu_fpu_opt;
11617       else
11618         mfpu_opt = march_fpu_opt;
11619 #else
11620       mfpu_opt = FPU_DEFAULT;
11621 #endif
11622     }
11623
11624   if (mfpu_opt == -1)
11625     {
11626       if (mcpu_cpu_opt == -1)
11627         mfpu_opt = FPU_DEFAULT;
11628       else if (mcpu_cpu_opt & ARM_EXT_V5)
11629         mfpu_opt = FPU_ARCH_VFP_V2;
11630       else
11631         mfpu_opt = FPU_ARCH_FPA;
11632     }
11633
11634   if (mcpu_cpu_opt == -1)
11635     mcpu_cpu_opt = CPU_DEFAULT;
11636
11637   cpu_variant = mcpu_cpu_opt | mfpu_opt;
11638
11639   {
11640     unsigned int flags = 0;
11641
11642 #if defined OBJ_ELF
11643     flags = meabi_flags;
11644
11645     switch (meabi_flags)
11646       {
11647       case EF_ARM_EABI_UNKNOWN:
11648 #endif
11649 #if defined OBJ_COFF || defined OBJ_ELF
11650         /* Set the flags in the private structure.  */
11651         if (uses_apcs_26)      flags |= F_APCS26;
11652         if (support_interwork) flags |= F_INTERWORK;
11653         if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11654         if (pic_code)          flags |= F_PIC;
11655         if ((cpu_variant & FPU_ANY) == FPU_NONE
11656              || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11657           flags |= F_SOFT_FLOAT;
11658
11659         switch (mfloat_abi_opt)
11660           {
11661           case ARM_FLOAT_ABI_SOFT:
11662           case ARM_FLOAT_ABI_SOFTFP:
11663             flags |= F_SOFT_FLOAT;
11664             break;
11665
11666           case ARM_FLOAT_ABI_HARD:
11667             if (flags & F_SOFT_FLOAT)
11668               as_bad (_("hard-float conflicts with specified fpu"));
11669             break;
11670           }
11671
11672         /* Using VFP conventions (even if soft-float).  */
11673         if (cpu_variant & FPU_VFP_EXT_NONE)
11674           flags |= F_VFP_FLOAT;
11675 #endif
11676 #if defined OBJ_ELF
11677         if (cpu_variant & FPU_ARCH_MAVERICK)
11678             flags |= EF_ARM_MAVERICK_FLOAT;
11679         break;
11680
11681       case EF_ARM_EABI_VER3:
11682         /* No additional flags to set.  */
11683         break;
11684
11685       default:
11686         abort ();
11687       }
11688 #endif
11689 #if defined OBJ_COFF || defined OBJ_ELF
11690     bfd_set_private_flags (stdoutput, flags);
11691
11692     /* We have run out flags in the COFF header to encode the
11693        status of ATPCS support, so instead we create a dummy,
11694        empty, debug section called .arm.atpcs.  */
11695     if (atpcs)
11696       {
11697         asection * sec;
11698
11699         sec = bfd_make_section (stdoutput, ".arm.atpcs");
11700
11701         if (sec != NULL)
11702           {
11703             bfd_set_section_flags
11704               (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11705             bfd_set_section_size (stdoutput, sec, 0);
11706             bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11707           }
11708       }
11709 #endif
11710   }
11711
11712   /* Record the CPU type as well.  */
11713   switch (cpu_variant & ARM_CPU_MASK)
11714     {
11715     case ARM_2:
11716       mach = bfd_mach_arm_2;
11717       break;
11718
11719     case ARM_3:                 /* Also ARM_250.  */
11720       mach = bfd_mach_arm_2a;
11721       break;
11722
11723     case ARM_6:                 /* Also ARM_7.  */
11724       mach = bfd_mach_arm_3;
11725       break;
11726
11727     default:
11728       mach = bfd_mach_arm_unknown;
11729       break;
11730     }
11731
11732   /* Catch special cases.  */
11733   if (cpu_variant & ARM_CEXT_IWMMXT)
11734     mach = bfd_mach_arm_iWMMXt;
11735   else if (cpu_variant & ARM_CEXT_XSCALE)
11736     mach = bfd_mach_arm_XScale;
11737   else if (cpu_variant & ARM_CEXT_MAVERICK)
11738     mach = bfd_mach_arm_ep9312;
11739   else if (cpu_variant & ARM_EXT_V5E)
11740     mach = bfd_mach_arm_5TE;
11741   else if (cpu_variant & ARM_EXT_V5)
11742     {
11743       if (cpu_variant & ARM_EXT_V4T)
11744         mach = bfd_mach_arm_5T;
11745       else
11746         mach = bfd_mach_arm_5;
11747     }
11748   else if (cpu_variant & ARM_EXT_V4)
11749     {
11750       if (cpu_variant & ARM_EXT_V4T)
11751         mach = bfd_mach_arm_4T;
11752       else
11753         mach = bfd_mach_arm_4;
11754     }
11755   else if (cpu_variant & ARM_EXT_V3M)
11756     mach = bfd_mach_arm_3M;
11757
11758 #if 0 /* Suppressed - for now.  */
11759 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11760
11761   /* Create a .note section to fully identify this arm binary.  */
11762
11763 #define NOTE_ARCH_STRING        "arch: "
11764
11765 #if defined OBJ_COFF && ! defined NT_VERSION
11766 #define NT_VERSION  1
11767 #define NT_ARCH     2
11768 #endif
11769   
11770   {
11771     segT current_seg = now_seg;
11772     subsegT current_subseg = now_subseg;
11773     asection * arm_arch;
11774     const char * arch_string;
11775
11776     arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11777
11778 #ifdef OBJ_COFF
11779     bfd_set_section_flags (stdoutput, arm_arch,
11780                            SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11781                            | SEC_HAS_CONTENTS);
11782 #else
11783     bfd_set_section_flags (stdoutput, arm_arch,
11784                            SEC_READONLY | SEC_HAS_CONTENTS);
11785 #endif
11786     arm_arch->output_section = arm_arch;
11787     subseg_set (arm_arch, 0);
11788
11789     switch (mach)
11790       {
11791       default:
11792       case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11793       case bfd_mach_arm_2:       arch_string = "armv2"; break;
11794       case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11795       case bfd_mach_arm_3:       arch_string = "armv3"; break;
11796       case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11797       case bfd_mach_arm_4:       arch_string = "armv4"; break;
11798       case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11799       case bfd_mach_arm_5:       arch_string = "armv5"; break;
11800       case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11801       case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11802       case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11803       case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11804       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break; 
11805       }
11806
11807     arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11808
11809     subseg_set (current_seg, current_subseg);
11810   }
11811 #endif
11812 #endif /* Suppressed code.  */
11813   
11814   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11815 }
11816
11817 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11818    for use in the a.out file, and stores them in the array pointed to by buf.
11819    This knows about the endian-ness of the target machine and does
11820    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11821    2 (short) and 4 (long)  Floating numbers are put out as a series of
11822    LITTLENUMS (shorts, here at least).  */
11823
11824 void
11825 md_number_to_chars (buf, val, n)
11826      char * buf;
11827      valueT val;
11828      int    n;
11829 {
11830   if (target_big_endian)
11831     number_to_chars_bigendian (buf, val, n);
11832   else
11833     number_to_chars_littleendian (buf, val, n);
11834 }
11835
11836 static valueT
11837 md_chars_to_number (buf, n)
11838      char * buf;
11839      int    n;
11840 {
11841   valueT result = 0;
11842   unsigned char * where = (unsigned char *) buf;
11843
11844   if (target_big_endian)
11845     {
11846       while (n--)
11847         {
11848           result <<= 8;
11849           result |= (*where++ & 255);
11850         }
11851     }
11852   else
11853     {
11854       while (n--)
11855         {
11856           result <<= 8;
11857           result |= (where[n] & 255);
11858         }
11859     }
11860
11861   return result;
11862 }
11863
11864 /* Turn a string in input_line_pointer into a floating point constant
11865    of type TYPE, and store the appropriate bytes in *LITP.  The number
11866    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11867    returned, or NULL on OK.
11868
11869    Note that fp constants aren't represent in the normal way on the ARM.
11870    In big endian mode, things are as expected.  However, in little endian
11871    mode fp constants are big-endian word-wise, and little-endian byte-wise
11872    within the words.  For example, (double) 1.1 in big endian mode is
11873    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11874    the byte sequence 99 99 f1 3f 9a 99 99 99.
11875
11876    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11877
11878 char *
11879 md_atof (type, litP, sizeP)
11880      char   type;
11881      char * litP;
11882      int *  sizeP;
11883 {
11884   int prec;
11885   LITTLENUM_TYPE words[MAX_LITTLENUMS];
11886   char *t;
11887   int i;
11888
11889   switch (type)
11890     {
11891     case 'f':
11892     case 'F':
11893     case 's':
11894     case 'S':
11895       prec = 2;
11896       break;
11897
11898     case 'd':
11899     case 'D':
11900     case 'r':
11901     case 'R':
11902       prec = 4;
11903       break;
11904
11905     case 'x':
11906     case 'X':
11907       prec = 6;
11908       break;
11909
11910     case 'p':
11911     case 'P':
11912       prec = 6;
11913       break;
11914
11915     default:
11916       *sizeP = 0;
11917       return _("bad call to MD_ATOF()");
11918     }
11919
11920   t = atof_ieee (input_line_pointer, type, words);
11921   if (t)
11922     input_line_pointer = t;
11923   *sizeP = prec * 2;
11924
11925   if (target_big_endian)
11926     {
11927       for (i = 0; i < prec; i++)
11928         {
11929           md_number_to_chars (litP, (valueT) words[i], 2);
11930           litP += 2;
11931         }
11932     }
11933   else
11934     {
11935       if (cpu_variant & FPU_ARCH_VFP)
11936         for (i = prec - 1; i >= 0; i--)
11937           {
11938             md_number_to_chars (litP, (valueT) words[i], 2);
11939             litP += 2;
11940           }
11941       else
11942         /* For a 4 byte float the order of elements in `words' is 1 0.
11943            For an 8 byte float the order is 1 0 3 2.  */
11944         for (i = 0; i < prec; i += 2)
11945           {
11946             md_number_to_chars (litP, (valueT) words[i + 1], 2);
11947             md_number_to_chars (litP + 2, (valueT) words[i], 2);
11948             litP += 4;
11949           }
11950     }
11951
11952   return 0;
11953 }
11954
11955 /* The knowledge of the PC's pipeline offset is built into the insns
11956    themselves.  */
11957
11958 long
11959 md_pcrel_from (fixP)
11960      fixS * fixP;
11961 {
11962   if (fixP->fx_addsy
11963       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11964       && fixP->fx_subsy == NULL)
11965     return 0;
11966
11967   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11968     {
11969       /* PC relative addressing on the Thumb is slightly odd
11970          as the bottom two bits of the PC are forced to zero
11971          for the calculation.  */
11972       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11973     }
11974
11975 #ifdef TE_WINCE
11976   /* The pattern was adjusted to accommodate CE's off-by-one fixups,
11977      so we un-adjust here to compensate for the accommodation.  */
11978   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
11979 #else
11980   return fixP->fx_where + fixP->fx_frag->fr_address;
11981 #endif
11982 }
11983
11984 /* Round up a section size to the appropriate boundary.  */
11985
11986 valueT
11987 md_section_align (segment, size)
11988      segT   segment ATTRIBUTE_UNUSED;
11989      valueT size;
11990 {
11991 #ifdef OBJ_ELF
11992   return size;
11993 #else
11994   /* Round all sects to multiple of 4.  */
11995   return (size + 3) & ~3;
11996 #endif
11997 }
11998
11999 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12000    Otherwise we have no need to default values of symbols.  */
12001
12002 symbolS *
12003 md_undefined_symbol (name)
12004      char * name ATTRIBUTE_UNUSED;
12005 {
12006 #ifdef OBJ_ELF
12007   if (name[0] == '_' && name[1] == 'G'
12008       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12009     {
12010       if (!GOT_symbol)
12011         {
12012           if (symbol_find (name))
12013             as_bad ("GOT already in the symbol table");
12014
12015           GOT_symbol = symbol_new (name, undefined_section,
12016                                    (valueT) 0, & zero_address_frag);
12017         }
12018
12019       return GOT_symbol;
12020     }
12021 #endif
12022
12023   return 0;
12024 }
12025
12026 /* arm_reg_parse () := if it looks like a register, return its token and
12027    advance the pointer.  */
12028
12029 static int
12030 arm_reg_parse (ccp, htab)
12031      register char ** ccp;
12032      struct hash_control *htab;
12033 {
12034   char * start = * ccp;
12035   char   c;
12036   char * p;
12037   struct reg_entry * reg;
12038
12039 #ifdef REGISTER_PREFIX
12040   if (*start != REGISTER_PREFIX)
12041     return FAIL;
12042   p = start + 1;
12043 #else
12044   p = start;
12045 #ifdef OPTIONAL_REGISTER_PREFIX
12046   if (*p == OPTIONAL_REGISTER_PREFIX)
12047     p++, start++;
12048 #endif
12049 #endif
12050   if (!ISALPHA (*p) || !is_name_beginner (*p))
12051     return FAIL;
12052
12053   c = *p++;
12054   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12055     c = *p++;
12056
12057   *--p = 0;
12058   reg = (struct reg_entry *) hash_find (htab, start);
12059   *p = c;
12060
12061   if (reg)
12062     {
12063       *ccp = p;
12064       return reg->number;
12065     }
12066
12067   return FAIL;
12068 }
12069
12070 /* Search for the following register name in each of the possible reg name
12071    tables.  Return the classification if found, or REG_TYPE_MAX if not
12072    present.  */
12073 static enum arm_reg_type
12074 arm_reg_parse_any (cp)
12075      char *cp;
12076 {
12077   int i;
12078
12079   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12080     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12081       return (enum arm_reg_type) i;
12082
12083   return REG_TYPE_MAX;
12084 }
12085
12086 void
12087 md_apply_fix3 (fixP, valP, seg)
12088      fixS *   fixP;
12089      valueT * valP;
12090      segT     seg;
12091 {
12092   offsetT        value = * valP;
12093   offsetT        newval;
12094   unsigned int   newimm;
12095   unsigned long  temp;
12096   int            sign;
12097   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12098   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12099
12100   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12101
12102   /* Note whether this will delete the relocation.  */
12103 #if 0
12104   /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12105      doesn't work fully.)  */
12106   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12107       && !fixP->fx_pcrel)
12108 #else
12109   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12110 #endif
12111     fixP->fx_done = 1;
12112
12113   /* If this symbol is in a different section then we need to leave it for
12114      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12115      so we have to undo it's effects here.  */
12116   if (fixP->fx_pcrel)
12117     {
12118       if (fixP->fx_addsy != NULL
12119           && S_IS_DEFINED (fixP->fx_addsy)
12120           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12121         {
12122           if (target_oabi
12123               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12124                   || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12125                   ))
12126             value = 0;
12127           else
12128             value += md_pcrel_from (fixP);
12129         }
12130     }
12131
12132   /* Remember value for emit_reloc.  */
12133   fixP->fx_addnumber = value;
12134
12135   switch (fixP->fx_r_type)
12136     {
12137     case BFD_RELOC_ARM_IMMEDIATE:
12138       /* We claim that this fixup has been processed here,
12139          even if in fact we generate an error because we do
12140          not have a reloc for it, so tc_gen_reloc will reject it.  */
12141       fixP->fx_done = 1;
12142
12143       if (fixP->fx_addsy
12144           && ! S_IS_DEFINED (fixP->fx_addsy))
12145         {
12146           as_bad_where (fixP->fx_file, fixP->fx_line,
12147                         _("undefined symbol %s used as an immediate value"),
12148                         S_GET_NAME (fixP->fx_addsy));
12149           break;
12150         }
12151
12152       newimm = validate_immediate (value);
12153       temp = md_chars_to_number (buf, INSN_SIZE);
12154
12155       /* If the instruction will fail, see if we can fix things up by
12156          changing the opcode.  */
12157       if (newimm == (unsigned int) FAIL
12158           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12159         {
12160           as_bad_where (fixP->fx_file, fixP->fx_line,
12161                         _("invalid constant (%lx) after fixup"),
12162                         (unsigned long) value);
12163           break;
12164         }
12165
12166       newimm |= (temp & 0xfffff000);
12167       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12168       break;
12169
12170     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12171       {
12172         unsigned int highpart = 0;
12173         unsigned int newinsn  = 0xe1a00000; /* nop.  */
12174
12175         newimm = validate_immediate (value);
12176         temp = md_chars_to_number (buf, INSN_SIZE);
12177
12178         /* If the instruction will fail, see if we can fix things up by
12179            changing the opcode.  */
12180         if (newimm == (unsigned int) FAIL
12181             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12182           {
12183             /* No ?  OK - try using two ADD instructions to generate
12184                the value.  */
12185             newimm = validate_immediate_twopart (value, & highpart);
12186
12187             /* Yes - then make sure that the second instruction is
12188                also an add.  */
12189             if (newimm != (unsigned int) FAIL)
12190               newinsn = temp;
12191             /* Still No ?  Try using a negated value.  */
12192             else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12193               temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12194             /* Otherwise - give up.  */
12195             else
12196               {
12197                 as_bad_where (fixP->fx_file, fixP->fx_line,
12198                               _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12199                               (long) value);
12200                 break;
12201               }
12202
12203             /* Replace the first operand in the 2nd instruction (which
12204                is the PC) with the destination register.  We have
12205                already added in the PC in the first instruction and we
12206                do not want to do it again.  */
12207             newinsn &= ~ 0xf0000;
12208             newinsn |= ((newinsn & 0x0f000) << 4);
12209           }
12210
12211         newimm |= (temp & 0xfffff000);
12212         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12213
12214         highpart |= (newinsn & 0xfffff000);
12215         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12216       }
12217       break;
12218
12219     case BFD_RELOC_ARM_OFFSET_IMM:
12220       sign = value >= 0;
12221
12222       if (value < 0)
12223         value = - value;
12224
12225       if (validate_offset_imm (value, 0) == FAIL)
12226         {
12227           as_bad_where (fixP->fx_file, fixP->fx_line,
12228                         _("bad immediate value for offset (%ld)"),
12229                         (long) value);
12230           break;
12231         }
12232
12233       newval = md_chars_to_number (buf, INSN_SIZE);
12234       newval &= 0xff7ff000;
12235       newval |= value | (sign ? INDEX_UP : 0);
12236       md_number_to_chars (buf, newval, INSN_SIZE);
12237       break;
12238
12239     case BFD_RELOC_ARM_OFFSET_IMM8:
12240     case BFD_RELOC_ARM_HWLITERAL:
12241       sign = value >= 0;
12242
12243       if (value < 0)
12244         value = - value;
12245
12246       if (validate_offset_imm (value, 1) == FAIL)
12247         {
12248           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12249             as_bad_where (fixP->fx_file, fixP->fx_line,
12250                           _("invalid literal constant: pool needs to be closer"));
12251           else
12252             as_bad (_("bad immediate value for half-word offset (%ld)"),
12253                     (long) value);
12254           break;
12255         }
12256
12257       newval = md_chars_to_number (buf, INSN_SIZE);
12258       newval &= 0xff7ff0f0;
12259       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12260       md_number_to_chars (buf, newval, INSN_SIZE);
12261       break;
12262
12263     case BFD_RELOC_ARM_LITERAL:
12264       sign = value >= 0;
12265
12266       if (value < 0)
12267         value = - value;
12268
12269       if (validate_offset_imm (value, 0) == FAIL)
12270         {
12271           as_bad_where (fixP->fx_file, fixP->fx_line,
12272                         _("invalid literal constant: pool needs to be closer"));
12273           break;
12274         }
12275
12276       newval = md_chars_to_number (buf, INSN_SIZE);
12277       newval &= 0xff7ff000;
12278       newval |= value | (sign ? INDEX_UP : 0);
12279       md_number_to_chars (buf, newval, INSN_SIZE);
12280       break;
12281
12282     case BFD_RELOC_ARM_SHIFT_IMM:
12283       newval = md_chars_to_number (buf, INSN_SIZE);
12284       if (((unsigned long) value) > 32
12285           || (value == 32
12286               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12287         {
12288           as_bad_where (fixP->fx_file, fixP->fx_line,
12289                         _("shift expression is too large"));
12290           break;
12291         }
12292
12293       if (value == 0)
12294         /* Shifts of zero must be done as lsl.  */
12295         newval &= ~0x60;
12296       else if (value == 32)
12297         value = 0;
12298       newval &= 0xfffff07f;
12299       newval |= (value & 0x1f) << 7;
12300       md_number_to_chars (buf, newval, INSN_SIZE);
12301       break;
12302
12303     case BFD_RELOC_ARM_SWI:
12304       if (arm_data->thumb_mode)
12305         {
12306           if (((unsigned long) value) > 0xff)
12307             as_bad_where (fixP->fx_file, fixP->fx_line,
12308                           _("invalid swi expression"));
12309           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12310           newval |= value;
12311           md_number_to_chars (buf, newval, THUMB_SIZE);
12312         }
12313       else
12314         {
12315           if (((unsigned long) value) > 0x00ffffff)
12316             as_bad_where (fixP->fx_file, fixP->fx_line,
12317                           _("invalid swi expression"));
12318           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12319           newval |= value;
12320           md_number_to_chars (buf, newval, INSN_SIZE);
12321         }
12322       break;
12323
12324     case BFD_RELOC_ARM_MULTI:
12325       if (((unsigned long) value) > 0xffff)
12326         as_bad_where (fixP->fx_file, fixP->fx_line,
12327                       _("invalid expression in load/store multiple"));
12328       newval = value | md_chars_to_number (buf, INSN_SIZE);
12329       md_number_to_chars (buf, newval, INSN_SIZE);
12330       break;
12331
12332     case BFD_RELOC_ARM_PCREL_BRANCH:
12333       newval = md_chars_to_number (buf, INSN_SIZE);
12334
12335       /* Sign-extend a 24-bit number.  */
12336 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12337
12338 #ifdef OBJ_ELF
12339       if (! target_oabi)
12340         value = fixP->fx_offset;
12341 #endif
12342
12343       /* We are going to store value (shifted right by two) in the
12344          instruction, in a 24 bit, signed field.  Thus we need to check
12345          that none of the top 8 bits of the shifted value (top 7 bits of
12346          the unshifted, unsigned value) are set, or that they are all set.  */
12347       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12348           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12349         {
12350 #ifdef OBJ_ELF
12351           /* Normally we would be stuck at this point, since we cannot store
12352              the absolute address that is the destination of the branch in the
12353              24 bits of the branch instruction.  If however, we happen to know
12354              that the destination of the branch is in the same section as the
12355              branch instruction itself, then we can compute the relocation for
12356              ourselves and not have to bother the linker with it.
12357
12358              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12359              because I have not worked out how to do this for OBJ_COFF or
12360              target_oabi.  */
12361           if (! target_oabi
12362               && fixP->fx_addsy != NULL
12363               && S_IS_DEFINED (fixP->fx_addsy)
12364               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12365             {
12366               /* Get pc relative value to go into the branch.  */
12367               value = * valP;
12368
12369               /* Permit a backward branch provided that enough bits
12370                  are set.  Allow a forwards branch, provided that
12371                  enough bits are clear.  */
12372               if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12373                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12374                 fixP->fx_done = 1;
12375             }
12376
12377           if (! fixP->fx_done)
12378 #endif
12379             as_bad_where (fixP->fx_file, fixP->fx_line,
12380                           _("GAS can't handle same-section branch dest >= 0x04000000"));
12381         }
12382
12383       value >>= 2;
12384       value += SEXT24 (newval);
12385
12386       if (    (value & ~ ((offsetT) 0xffffff)) != 0
12387           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12388         as_bad_where (fixP->fx_file, fixP->fx_line,
12389                       _("out of range branch"));
12390
12391       newval = (value & 0x00ffffff) | (newval & 0xff000000);
12392       md_number_to_chars (buf, newval, INSN_SIZE);
12393       break;
12394
12395     case BFD_RELOC_ARM_PCREL_BLX:
12396       {
12397         offsetT hbit;
12398         newval = md_chars_to_number (buf, INSN_SIZE);
12399
12400 #ifdef OBJ_ELF
12401         if (! target_oabi)
12402           value = fixP->fx_offset;
12403 #endif
12404         hbit   = (value >> 1) & 1;
12405         value  = (value >> 2) & 0x00ffffff;
12406         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12407         newval = value | (newval & 0xfe000000) | (hbit << 24);
12408         md_number_to_chars (buf, newval, INSN_SIZE);
12409       }
12410       break;
12411
12412     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12413       newval = md_chars_to_number (buf, THUMB_SIZE);
12414       {
12415         addressT diff = (newval & 0xff) << 1;
12416         if (diff & 0x100)
12417           diff |= ~0xff;
12418
12419         value += diff;
12420         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12421           as_bad_where (fixP->fx_file, fixP->fx_line,
12422                         _("branch out of range"));
12423         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12424       }
12425       md_number_to_chars (buf, newval, THUMB_SIZE);
12426       break;
12427
12428     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12429       newval = md_chars_to_number (buf, THUMB_SIZE);
12430       {
12431         addressT diff = (newval & 0x7ff) << 1;
12432         if (diff & 0x800)
12433           diff |= ~0x7ff;
12434
12435         value += diff;
12436         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12437           as_bad_where (fixP->fx_file, fixP->fx_line,
12438                         _("branch out of range"));
12439         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12440       }
12441       md_number_to_chars (buf, newval, THUMB_SIZE);
12442       break;
12443
12444     case BFD_RELOC_THUMB_PCREL_BLX:
12445     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12446       {
12447         offsetT newval2;
12448         addressT diff;
12449
12450         newval  = md_chars_to_number (buf, THUMB_SIZE);
12451         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12452         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12453         if (diff & 0x400000)
12454           diff |= ~0x3fffff;
12455 #ifdef OBJ_ELF
12456         value = fixP->fx_offset;
12457 #endif
12458         value += diff;
12459
12460         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12461           as_bad_where (fixP->fx_file, fixP->fx_line,
12462                         _("branch with link out of range"));
12463
12464         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12465         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12466         if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12467           /* For a BLX instruction, make sure that the relocation is rounded up
12468              to a word boundary.  This follows the semantics of the instruction
12469              which specifies that bit 1 of the target address will come from bit
12470              1 of the base address.  */
12471           newval2 = (newval2 + 1) & ~ 1;
12472         md_number_to_chars (buf, newval, THUMB_SIZE);
12473         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12474       }
12475       break;
12476
12477     case BFD_RELOC_8:
12478       if (fixP->fx_done || fixP->fx_pcrel)
12479         md_number_to_chars (buf, value, 1);
12480 #ifdef OBJ_ELF
12481       else if (!target_oabi)
12482         {
12483           value = fixP->fx_offset;
12484           md_number_to_chars (buf, value, 1);
12485         }
12486 #endif
12487       break;
12488
12489     case BFD_RELOC_16:
12490       if (fixP->fx_done || fixP->fx_pcrel)
12491         md_number_to_chars (buf, value, 2);
12492 #ifdef OBJ_ELF
12493       else if (!target_oabi)
12494         {
12495           value = fixP->fx_offset;
12496           md_number_to_chars (buf, value, 2);
12497         }
12498 #endif
12499       break;
12500
12501 #ifdef OBJ_ELF
12502     case BFD_RELOC_ARM_GOT32:
12503     case BFD_RELOC_ARM_GOTOFF:
12504     case BFD_RELOC_ARM_TARGET2:
12505       md_number_to_chars (buf, 0, 4);
12506       break;
12507 #endif
12508
12509     case BFD_RELOC_RVA:
12510     case BFD_RELOC_32:
12511     case BFD_RELOC_ARM_TARGET1:
12512     case BFD_RELOC_ARM_ROSEGREL32:
12513     case BFD_RELOC_ARM_SBREL32:
12514     case BFD_RELOC_32_PCREL:
12515       if (fixP->fx_done || fixP->fx_pcrel)
12516         md_number_to_chars (buf, value, 4);
12517 #ifdef OBJ_ELF
12518       else if (!target_oabi)
12519         {
12520           value = fixP->fx_offset;
12521           md_number_to_chars (buf, value, 4);
12522         }
12523 #endif
12524       break;
12525
12526 #ifdef OBJ_ELF
12527     case BFD_RELOC_ARM_PREL31:
12528       if (fixP->fx_done || fixP->fx_pcrel)
12529         {
12530           newval = md_chars_to_number (buf, 4) & 0x80000000;
12531           if ((value ^ (value >> 1)) & 0x40000000)
12532             {
12533               as_bad_where (fixP->fx_file, fixP->fx_line,
12534                             _("rel31 relocation overflow"));
12535             }
12536           newval |= value & 0x7fffffff;
12537           md_number_to_chars (buf, newval, 4);
12538         }
12539       break;
12540
12541     case BFD_RELOC_ARM_PLT32:
12542       /* It appears the instruction is fully prepared at this point.  */
12543       break;
12544 #endif
12545
12546     case BFD_RELOC_ARM_CP_OFF_IMM:
12547       sign = value >= 0;
12548       if (value < -1023 || value > 1023 || (value & 3))
12549         as_bad_where (fixP->fx_file, fixP->fx_line,
12550                       _("illegal value for co-processor offset"));
12551       if (value < 0)
12552         value = -value;
12553       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12554       newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12555       md_number_to_chars (buf, newval, INSN_SIZE);
12556       break;
12557
12558     case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12559       sign = value >= 0;
12560       if (value < -255 || value > 255)
12561         as_bad_where (fixP->fx_file, fixP->fx_line,
12562                       _("Illegal value for co-processor offset"));
12563       if (value < 0)
12564         value = -value;
12565       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12566       newval |= value | (sign ?  INDEX_UP : 0);
12567       md_number_to_chars (buf, newval , INSN_SIZE);
12568       break;
12569
12570     case BFD_RELOC_ARM_THUMB_OFFSET:
12571       newval = md_chars_to_number (buf, THUMB_SIZE);
12572       /* Exactly what ranges, and where the offset is inserted depends
12573          on the type of instruction, we can establish this from the
12574          top 4 bits.  */
12575       switch (newval >> 12)
12576         {
12577         case 4: /* PC load.  */
12578           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12579              forced to zero for these loads, so we will need to round
12580              up the offset if the instruction address is not word
12581              aligned (since the final address produced must be, and
12582              we can only describe word-aligned immediate offsets).  */
12583
12584           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12585             as_bad_where (fixP->fx_file, fixP->fx_line,
12586                           _("invalid offset, target not word aligned (0x%08X)"),
12587                           (unsigned int) (fixP->fx_frag->fr_address
12588                                           + fixP->fx_where + value));
12589
12590           if ((value + 2) & ~0x3fe)
12591             as_bad_where (fixP->fx_file, fixP->fx_line,
12592                           _("invalid offset, value too big (0x%08lX)"),
12593                           (long) value);
12594
12595           /* Round up, since pc will be rounded down.  */
12596           newval |= (value + 2) >> 2;
12597           break;
12598
12599         case 9: /* SP load/store.  */
12600           if (value & ~0x3fc)
12601             as_bad_where (fixP->fx_file, fixP->fx_line,
12602                           _("invalid offset, value too big (0x%08lX)"),
12603                           (long) value);
12604           newval |= value >> 2;
12605           break;
12606
12607         case 6: /* Word load/store.  */
12608           if (value & ~0x7c)
12609             as_bad_where (fixP->fx_file, fixP->fx_line,
12610                           _("invalid offset, value too big (0x%08lX)"),
12611                           (long) value);
12612           newval |= value << 4; /* 6 - 2.  */
12613           break;
12614
12615         case 7: /* Byte load/store.  */
12616           if (value & ~0x1f)
12617             as_bad_where (fixP->fx_file, fixP->fx_line,
12618                           _("invalid offset, value too big (0x%08lX)"),
12619                           (long) value);
12620           newval |= value << 6;
12621           break;
12622
12623         case 8: /* Halfword load/store.  */
12624           if (value & ~0x3e)
12625             as_bad_where (fixP->fx_file, fixP->fx_line,
12626                           _("invalid offset, value too big (0x%08lX)"),
12627                           (long) value);
12628           newval |= value << 5; /* 6 - 1.  */
12629           break;
12630
12631         default:
12632           as_bad_where (fixP->fx_file, fixP->fx_line,
12633                         "Unable to process relocation for thumb opcode: %lx",
12634                         (unsigned long) newval);
12635           break;
12636         }
12637       md_number_to_chars (buf, newval, THUMB_SIZE);
12638       break;
12639
12640     case BFD_RELOC_ARM_THUMB_ADD:
12641       /* This is a complicated relocation, since we use it for all of
12642          the following immediate relocations:
12643
12644             3bit ADD/SUB
12645             8bit ADD/SUB
12646             9bit ADD/SUB SP word-aligned
12647            10bit ADD PC/SP word-aligned
12648
12649          The type of instruction being processed is encoded in the
12650          instruction field:
12651
12652            0x8000  SUB
12653            0x00F0  Rd
12654            0x000F  Rs
12655       */
12656       newval = md_chars_to_number (buf, THUMB_SIZE);
12657       {
12658         int rd = (newval >> 4) & 0xf;
12659         int rs = newval & 0xf;
12660         int subtract = newval & 0x8000;
12661
12662         if (rd == REG_SP)
12663           {
12664             if (value & ~0x1fc)
12665               as_bad_where (fixP->fx_file, fixP->fx_line,
12666                             _("invalid immediate for stack address calculation"));
12667             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12668             newval |= value >> 2;
12669           }
12670         else if (rs == REG_PC || rs == REG_SP)
12671           {
12672             if (subtract ||
12673                 value & ~0x3fc)
12674               as_bad_where (fixP->fx_file, fixP->fx_line,
12675                             _("invalid immediate for address calculation (value = 0x%08lX)"),
12676                             (unsigned long) value);
12677             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12678             newval |= rd << 8;
12679             newval |= value >> 2;
12680           }
12681         else if (rs == rd)
12682           {
12683             if (value & ~0xff)
12684               as_bad_where (fixP->fx_file, fixP->fx_line,
12685                             _("invalid 8bit immediate"));
12686             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12687             newval |= (rd << 8) | value;
12688           }
12689         else
12690           {
12691             if (value & ~0x7)
12692               as_bad_where (fixP->fx_file, fixP->fx_line,
12693                             _("invalid 3bit immediate"));
12694             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12695             newval |= rd | (rs << 3) | (value << 6);
12696           }
12697       }
12698       md_number_to_chars (buf, newval, THUMB_SIZE);
12699       break;
12700
12701     case BFD_RELOC_ARM_THUMB_IMM:
12702       newval = md_chars_to_number (buf, THUMB_SIZE);
12703       switch (newval >> 11)
12704         {
12705         case 0x04: /* 8bit immediate MOV.  */
12706         case 0x05: /* 8bit immediate CMP.  */
12707           if (value < 0 || value > 255)
12708             as_bad_where (fixP->fx_file, fixP->fx_line,
12709                           _("invalid immediate: %ld is too large"),
12710                           (long) value);
12711           newval |= value;
12712           break;
12713
12714         default:
12715           abort ();
12716         }
12717       md_number_to_chars (buf, newval, THUMB_SIZE);
12718       break;
12719
12720     case BFD_RELOC_ARM_THUMB_SHIFT:
12721       /* 5bit shift value (0..31).  */
12722       if (value < 0 || value > 31)
12723         as_bad_where (fixP->fx_file, fixP->fx_line,
12724                       _("illegal Thumb shift value: %ld"), (long) value);
12725       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12726       newval |= value << 6;
12727       md_number_to_chars (buf, newval, THUMB_SIZE);
12728       break;
12729
12730     case BFD_RELOC_VTABLE_INHERIT:
12731     case BFD_RELOC_VTABLE_ENTRY:
12732       fixP->fx_done = 0;
12733       return;
12734
12735     case BFD_RELOC_NONE:
12736     default:
12737       as_bad_where (fixP->fx_file, fixP->fx_line,
12738                     _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12739     }
12740 }
12741
12742 /* Translate internal representation of relocation info to BFD target
12743    format.  */
12744
12745 arelent *
12746 tc_gen_reloc (section, fixp)
12747      asection * section ATTRIBUTE_UNUSED;
12748      fixS * fixp;
12749 {
12750   arelent * reloc;
12751   bfd_reloc_code_real_type code;
12752
12753   reloc = (arelent *) xmalloc (sizeof (arelent));
12754
12755   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12756   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12757   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12758
12759   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12760 #ifndef OBJ_ELF
12761   if (fixp->fx_pcrel == 0)
12762     reloc->addend = fixp->fx_offset;
12763   else
12764     reloc->addend = fixp->fx_offset = reloc->address;
12765 #else  /* OBJ_ELF */
12766   reloc->addend = fixp->fx_offset;
12767 #endif
12768
12769   switch (fixp->fx_r_type)
12770     {
12771     case BFD_RELOC_8:
12772       if (fixp->fx_pcrel)
12773         {
12774           code = BFD_RELOC_8_PCREL;
12775           break;
12776         }
12777
12778     case BFD_RELOC_16:
12779       if (fixp->fx_pcrel)
12780         {
12781           code = BFD_RELOC_16_PCREL;
12782           break;
12783         }
12784
12785     case BFD_RELOC_32:
12786       if (fixp->fx_pcrel)
12787         {
12788           code = BFD_RELOC_32_PCREL;
12789           break;
12790         }
12791
12792     case BFD_RELOC_ARM_PCREL_BRANCH:
12793     case BFD_RELOC_ARM_PCREL_BLX:
12794     case BFD_RELOC_RVA:
12795     case BFD_RELOC_THUMB_PCREL_BRANCH9:
12796     case BFD_RELOC_THUMB_PCREL_BRANCH12:
12797     case BFD_RELOC_THUMB_PCREL_BRANCH23:
12798     case BFD_RELOC_THUMB_PCREL_BLX:
12799     case BFD_RELOC_VTABLE_ENTRY:
12800     case BFD_RELOC_VTABLE_INHERIT:
12801       code = fixp->fx_r_type;
12802       break;
12803
12804     case BFD_RELOC_ARM_LITERAL:
12805     case BFD_RELOC_ARM_HWLITERAL:
12806       /* If this is called then the a literal has
12807          been referenced across a section boundary.  */
12808       as_bad_where (fixp->fx_file, fixp->fx_line,
12809                     _("literal referenced across section boundary"));
12810       return NULL;
12811
12812 #ifdef OBJ_ELF
12813     case BFD_RELOC_ARM_GOT32:
12814     case BFD_RELOC_ARM_GOTOFF:
12815     case BFD_RELOC_ARM_PLT32:
12816     case BFD_RELOC_ARM_TARGET1:
12817     case BFD_RELOC_ARM_ROSEGREL32:
12818     case BFD_RELOC_ARM_SBREL32:
12819     case BFD_RELOC_ARM_PREL31:
12820     case BFD_RELOC_ARM_TARGET2:
12821       code = fixp->fx_r_type;
12822       break;
12823 #endif
12824
12825     case BFD_RELOC_ARM_IMMEDIATE:
12826       as_bad_where (fixp->fx_file, fixp->fx_line,
12827                     _("internal relocation (type: IMMEDIATE) not fixed up"));
12828       return NULL;
12829
12830     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12831       as_bad_where (fixp->fx_file, fixp->fx_line,
12832                     _("ADRL used for a symbol not defined in the same file"));
12833       return NULL;
12834
12835     case BFD_RELOC_ARM_OFFSET_IMM:
12836       if (fixp->fx_addsy != NULL
12837           && !S_IS_DEFINED (fixp->fx_addsy)
12838           && S_IS_LOCAL (fixp->fx_addsy))
12839         {
12840           as_bad_where (fixp->fx_file, fixp->fx_line,
12841                         _("undefined local label `%s'"),
12842                         S_GET_NAME (fixp->fx_addsy));
12843           return NULL;
12844         }
12845
12846       as_bad_where (fixp->fx_file, fixp->fx_line,
12847                     _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12848       return NULL;
12849
12850     default:
12851       {
12852         char * type;
12853
12854         switch (fixp->fx_r_type)
12855           {
12856           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12857           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12858           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12859           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12860           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12861           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12862           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12863           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12864           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12865           default:                         type = _("<unknown>"); break;
12866           }
12867         as_bad_where (fixp->fx_file, fixp->fx_line,
12868                       _("cannot represent %s relocation in this object file format"),
12869                       type);
12870         return NULL;
12871       }
12872     }
12873
12874 #ifdef OBJ_ELF
12875   if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12876       && GOT_symbol
12877       && fixp->fx_addsy == GOT_symbol)
12878     {
12879       code = BFD_RELOC_ARM_GOTPC;
12880       reloc->addend = fixp->fx_offset = reloc->address;
12881     }
12882 #endif
12883
12884   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12885
12886   if (reloc->howto == NULL)
12887     {
12888       as_bad_where (fixp->fx_file, fixp->fx_line,
12889                     _("cannot represent %s relocation in this object file format"),
12890                     bfd_get_reloc_code_name (code));
12891       return NULL;
12892     }
12893
12894   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12895      vtable entry to be used in the relocation's section offset.  */
12896   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12897     reloc->address = fixp->fx_offset;
12898
12899   return reloc;
12900 }
12901
12902 int
12903 md_estimate_size_before_relax (fragP, segtype)
12904      fragS * fragP ATTRIBUTE_UNUSED;
12905      segT    segtype ATTRIBUTE_UNUSED;
12906 {
12907   as_fatal (_("md_estimate_size_before_relax\n"));
12908   return 1;
12909 }
12910
12911 static void
12912 output_inst (str)
12913      const char *str;
12914 {
12915   char * to = NULL;
12916
12917   if (inst.error)
12918     {
12919       as_bad ("%s -- `%s'", inst.error, str);
12920       return;
12921     }
12922
12923   to = frag_more (inst.size);
12924
12925   if (thumb_mode && (inst.size > THUMB_SIZE))
12926     {
12927       assert (inst.size == (2 * THUMB_SIZE));
12928       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12929       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12930     }
12931   else if (inst.size > INSN_SIZE)
12932     {
12933       assert (inst.size == (2 * INSN_SIZE));
12934       md_number_to_chars (to, inst.instruction, INSN_SIZE);
12935       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12936     }
12937   else
12938     md_number_to_chars (to, inst.instruction, inst.size);
12939
12940   if (inst.reloc.type != BFD_RELOC_NONE)
12941     fix_new_arm (frag_now, to - frag_now->fr_literal,
12942                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12943                  inst.reloc.type);
12944
12945 #ifdef OBJ_ELF
12946   dwarf2_emit_insn (inst.size);
12947 #endif
12948 }
12949
12950 void
12951 md_assemble (str)
12952      char * str;
12953 {
12954   char  c;
12955   char *p;
12956   char *start;
12957
12958   /* Align the instruction.
12959      This may not be the right thing to do but ...  */
12960 #if 0
12961   arm_align (2, 0);
12962 #endif
12963
12964   /* Align the previous label if needed.  */
12965   if (last_label_seen != NULL)
12966     {
12967       symbol_set_frag (last_label_seen, frag_now);
12968       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12969       S_SET_SEGMENT (last_label_seen, now_seg);
12970     }
12971
12972   memset (&inst, '\0', sizeof (inst));
12973   inst.reloc.type = BFD_RELOC_NONE;
12974
12975   skip_whitespace (str);
12976
12977   /* Scan up to the end of the op-code, which must end in white space or
12978      end of string.  */
12979   for (start = p = str; *p != '\0'; p++)
12980     if (*p == ' ')
12981       break;
12982
12983   if (p == str)
12984     {
12985       as_bad (_("no operator -- statement `%s'\n"), str);
12986       return;
12987     }
12988
12989   if (thumb_mode)
12990     {
12991       const struct thumb_opcode * opcode;
12992
12993       c = *p;
12994       *p = '\0';
12995       opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12996       *p = c;
12997
12998       if (opcode)
12999         {
13000           /* Check that this instruction is supported for this CPU.  */
13001           if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
13002             {
13003               as_bad (_("selected processor does not support `%s'"), str);
13004               return;
13005             }
13006
13007           mapping_state (MAP_THUMB);
13008           inst.instruction = opcode->value;
13009           inst.size = opcode->size;
13010           (*opcode->parms) (p);
13011           output_inst (str);
13012           return;
13013         }
13014     }
13015   else
13016     {
13017       const struct asm_opcode * opcode;
13018
13019       c = *p;
13020       *p = '\0';
13021       opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13022       *p = c;
13023
13024       if (opcode)
13025         {
13026           /* Check that this instruction is supported for this CPU.  */
13027           if ((opcode->variant & cpu_variant) == 0)
13028             {
13029               as_bad (_("selected processor does not support `%s'"), str);
13030               return;
13031             }
13032
13033           mapping_state (MAP_ARM);
13034           inst.instruction = opcode->value;
13035           inst.size = INSN_SIZE;
13036           (*opcode->parms) (p);
13037           output_inst (str);
13038           return;
13039         }
13040     }
13041
13042   /* It wasn't an instruction, but it might be a register alias of the form
13043      alias .req reg.  */
13044   if (create_register_alias (str, p))
13045     return;
13046
13047   as_bad (_("bad instruction `%s'"), start);
13048 }
13049
13050 /* md_parse_option
13051       Invocation line includes a switch not recognized by the base assembler.
13052       See if it's a processor-specific option.
13053
13054       This routine is somewhat complicated by the need for backwards
13055       compatibility (since older releases of gcc can't be changed).
13056       The new options try to make the interface as compatible as
13057       possible with GCC.
13058
13059       New options (supported) are:
13060
13061               -mcpu=<cpu name>           Assemble for selected processor
13062               -march=<architecture name> Assemble for selected architecture
13063               -mfpu=<fpu architecture>   Assemble for selected FPU.
13064               -EB/-mbig-endian           Big-endian
13065               -EL/-mlittle-endian        Little-endian
13066               -k                         Generate PIC code
13067               -mthumb                    Start in Thumb mode
13068               -mthumb-interwork          Code supports ARM/Thumb interworking
13069
13070       For now we will also provide support for:
13071
13072               -mapcs-32                  32-bit Program counter
13073               -mapcs-26                  26-bit Program counter
13074               -macps-float               Floats passed in FP registers
13075               -mapcs-reentrant           Reentrant code
13076               -matpcs
13077       (sometime these will probably be replaced with -mapcs=<list of options>
13078       and -matpcs=<list of options>)
13079
13080       The remaining options are only supported for back-wards compatibility.
13081       Cpu variants, the arm part is optional:
13082               -m[arm]1                Currently not supported.
13083               -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13084               -m[arm]3                Arm 3 processor
13085               -m[arm]6[xx],           Arm 6 processors
13086               -m[arm]7[xx][t][[d]m]   Arm 7 processors
13087               -m[arm]8[10]            Arm 8 processors
13088               -m[arm]9[20][tdmi]      Arm 9 processors
13089               -mstrongarm[110[0]]     StrongARM processors
13090               -mxscale                XScale processors
13091               -m[arm]v[2345[t[e]]]    Arm architectures
13092               -mall                   All (except the ARM1)
13093       FP variants:
13094               -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13095               -mfpe-old               (No float load/store multiples)
13096               -mvfpxd                 VFP Single precision
13097               -mvfp                   All VFP
13098               -mno-fpu                Disable all floating point instructions
13099
13100       The following CPU names are recognized:
13101               arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13102               arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13103               arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13104               arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13105               arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13106               arm10t arm10e, arm1020t, arm1020e, arm10200e,
13107               strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13108
13109       */
13110
13111 const char * md_shortopts = "m:k";
13112
13113 #ifdef ARM_BI_ENDIAN
13114 #define OPTION_EB (OPTION_MD_BASE + 0)
13115 #define OPTION_EL (OPTION_MD_BASE + 1)
13116 #else
13117 #if TARGET_BYTES_BIG_ENDIAN
13118 #define OPTION_EB (OPTION_MD_BASE + 0)
13119 #else
13120 #define OPTION_EL (OPTION_MD_BASE + 1)
13121 #endif
13122 #endif
13123
13124 struct option md_longopts[] =
13125 {
13126 #ifdef OPTION_EB
13127   {"EB", no_argument, NULL, OPTION_EB},
13128 #endif
13129 #ifdef OPTION_EL
13130   {"EL", no_argument, NULL, OPTION_EL},
13131 #endif
13132   {NULL, no_argument, NULL, 0}
13133 };
13134
13135 size_t md_longopts_size = sizeof (md_longopts);
13136
13137 struct arm_option_table
13138 {
13139   char *option;         /* Option name to match.  */
13140   char *help;           /* Help information.  */
13141   int  *var;            /* Variable to change.  */
13142   int   value;          /* What to change it to.  */
13143   char *deprecated;     /* If non-null, print this message.  */
13144 };
13145
13146 struct arm_option_table arm_opts[] =
13147 {
13148   {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13149   {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13150   {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13151    &support_interwork, 1, NULL},
13152   {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13153   {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13154   {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13155   {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13156    1, NULL},
13157   {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13158   {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13159   {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13160   {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13161    NULL},
13162
13163   /* These are recognized by the assembler, but have no affect on code.  */
13164   {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13165   {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13166
13167   /* DON'T add any new processors to this list -- we want the whole list
13168      to go away...  Add them to the processors table instead.  */
13169   {"marm1",      NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13170   {"m1",         NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13171   {"marm2",      NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13172   {"m2",         NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13173   {"marm250",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13174   {"m250",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13175   {"marm3",      NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13176   {"m3",         NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13177   {"marm6",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13178   {"m6",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13179   {"marm600",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13180   {"m600",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13181   {"marm610",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13182   {"m610",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13183   {"marm620",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13184   {"m620",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13185   {"marm7",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13186   {"m7",         NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13187   {"marm70",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13188   {"m70",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13189   {"marm700",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13190   {"m700",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13191   {"marm700i",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13192   {"m700i",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13193   {"marm710",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13194   {"m710",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13195   {"marm710c",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13196   {"m710c",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13197   {"marm720",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13198   {"m720",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13199   {"marm7d",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13200   {"m7d",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13201   {"marm7di",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13202   {"m7di",       NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13203   {"marm7m",     NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13204   {"m7m",        NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13205   {"marm7dm",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13206   {"m7dm",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13207   {"marm7dmi",   NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13208   {"m7dmi",      NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13209   {"marm7100",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13210   {"m7100",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13211   {"marm7500",   NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13212   {"m7500",      NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13213   {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13214   {"m7500fe",    NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13215   {"marm7t",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13216   {"m7t",        NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13217   {"marm7tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13218   {"m7tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13219   {"marm710t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13220   {"m710t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13221   {"marm720t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13222   {"m720t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13223   {"marm740t",   NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13224   {"m740t",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13225   {"marm8",      NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13226   {"m8",         NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13227   {"marm810",    NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13228   {"m810",       NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13229   {"marm9",      NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13230   {"m9",         NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13231   {"marm9tdmi",  NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13232   {"m9tdmi",     NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13233   {"marm920",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13234   {"m920",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13235   {"marm940",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13236   {"m940",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13237   {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13238   {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13239    N_("use -mcpu=strongarm110")},
13240   {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13241    N_("use -mcpu=strongarm1100")},
13242   {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13243    N_("use -mcpu=strongarm1110")},
13244   {"mxscale",    NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13245   {"miwmmxt",    NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13246   {"mall",       NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13247
13248   /* Architecture variants -- don't add any more to this list either.  */
13249   {"mv2",        NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13250   {"marmv2",     NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13251   {"mv2a",       NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13252   {"marmv2a",    NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13253   {"mv3",        NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13254   {"marmv3",     NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13255   {"mv3m",       NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13256   {"marmv3m",    NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13257   {"mv4",        NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13258   {"marmv4",     NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13259   {"mv4t",       NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13260   {"marmv4t",    NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13261   {"mv5",        NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13262   {"marmv5",     NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13263   {"mv5t",       NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13264   {"marmv5t",    NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13265   {"mv5e",       NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13266   {"marmv5e",    NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13267
13268   /* Floating point variants -- don't add any more to this list either.  */
13269   {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13270   {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13271   {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13272   {"mno-fpu",  NULL, &legacy_fpu, 0,
13273    N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13274
13275   {NULL, NULL, NULL, 0, NULL}
13276 };
13277
13278 struct arm_cpu_option_table
13279 {
13280   char *name;
13281   int   value;
13282   /* For some CPUs we assume an FPU unless the user explicitly sets
13283      -mfpu=...  */
13284   int   default_fpu;
13285 };
13286
13287 /* This list should, at a minimum, contain all the cpu names
13288    recognized by GCC.  */
13289 static struct arm_cpu_option_table arm_cpus[] =
13290 {
13291   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13292   {"arm1",              ARM_ARCH_V1,     FPU_ARCH_FPA},
13293   {"arm2",              ARM_ARCH_V2,     FPU_ARCH_FPA},
13294   {"arm250",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13295   {"arm3",              ARM_ARCH_V2S,    FPU_ARCH_FPA},
13296   {"arm6",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13297   {"arm60",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13298   {"arm600",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13299   {"arm610",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13300   {"arm620",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13301   {"arm7",              ARM_ARCH_V3,     FPU_ARCH_FPA},
13302   {"arm7m",             ARM_ARCH_V3M,    FPU_ARCH_FPA},
13303   {"arm7d",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13304   {"arm7dm",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13305   {"arm7di",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13306   {"arm7dmi",           ARM_ARCH_V3M,    FPU_ARCH_FPA},
13307   {"arm70",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13308   {"arm700",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13309   {"arm700i",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13310   {"arm710",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13311   {"arm710t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13312   {"arm720",            ARM_ARCH_V3,     FPU_ARCH_FPA},
13313   {"arm720t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13314   {"arm740t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13315   {"arm710c",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13316   {"arm7100",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13317   {"arm7500",           ARM_ARCH_V3,     FPU_ARCH_FPA},
13318   {"arm7500fe",         ARM_ARCH_V3,     FPU_ARCH_FPA},
13319   {"arm7t",             ARM_ARCH_V4T,    FPU_ARCH_FPA},
13320   {"arm7tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13321   {"arm7tdmi-s",        ARM_ARCH_V4T,    FPU_ARCH_FPA},
13322   {"arm8",              ARM_ARCH_V4,     FPU_ARCH_FPA},
13323   {"arm810",            ARM_ARCH_V4,     FPU_ARCH_FPA},
13324   {"strongarm",         ARM_ARCH_V4,     FPU_ARCH_FPA},
13325   {"strongarm1",        ARM_ARCH_V4,     FPU_ARCH_FPA},
13326   {"strongarm110",      ARM_ARCH_V4,     FPU_ARCH_FPA},
13327   {"strongarm1100",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13328   {"strongarm1110",     ARM_ARCH_V4,     FPU_ARCH_FPA},
13329   {"arm9",              ARM_ARCH_V4T,    FPU_ARCH_FPA},
13330   {"arm920",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13331   {"arm920t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13332   {"arm922t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13333   {"arm940t",           ARM_ARCH_V4T,    FPU_ARCH_FPA},
13334   {"arm9tdmi",          ARM_ARCH_V4T,    FPU_ARCH_FPA},
13335   /* For V5 or later processors we default to using VFP; but the user
13336      should really set the FPU type explicitly.  */
13337   {"arm9e-r0",          ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13338   {"arm9e",             ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13339   {"arm926ej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13340   {"arm926ejs",         ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13341   {"arm926ej-s",        ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2},
13342   {"arm946e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13343   {"arm946e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13344   {"arm966e-r0",        ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13345   {"arm966e",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13346   {"arm10t",            ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13347   {"arm10e",            ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13348   {"arm1020",           ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13349   {"arm1020t",          ARM_ARCH_V5T,    FPU_ARCH_VFP_V1},
13350   {"arm1020e",          ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13351   {"arm1026ejs",        ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13352   {"arm1026ej-s",       ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13353   {"arm1136js",         ARM_ARCH_V6,     FPU_NONE},
13354   {"arm1136j-s",        ARM_ARCH_V6,     FPU_NONE},
13355   {"arm1136jfs",        ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13356   {"arm1136jf-s",       ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13357   /* ??? XSCALE is really an architecture.  */
13358   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13359   /* ??? iwmmxt is not a processor.  */
13360   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13361   {"i80200",            ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13362   /* Maverick */
13363   {"ep9312",            ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13364   {NULL, 0, 0}
13365 };
13366
13367 struct arm_arch_option_table
13368 {
13369   char *name;
13370   int   value;
13371   int   default_fpu;
13372 };
13373
13374 /* This list should, at a minimum, contain all the architecture names
13375    recognized by GCC.  */
13376 static struct arm_arch_option_table arm_archs[] =
13377 {
13378   {"all",               ARM_ANY,         FPU_ARCH_FPA},
13379   {"armv1",             ARM_ARCH_V1,     FPU_ARCH_FPA},
13380   {"armv2",             ARM_ARCH_V2,     FPU_ARCH_FPA},
13381   {"armv2a",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13382   {"armv2s",            ARM_ARCH_V2S,    FPU_ARCH_FPA},
13383   {"armv3",             ARM_ARCH_V3,     FPU_ARCH_FPA},
13384   {"armv3m",            ARM_ARCH_V3M,    FPU_ARCH_FPA},
13385   {"armv4",             ARM_ARCH_V4,     FPU_ARCH_FPA},
13386   {"armv4xm",           ARM_ARCH_V4xM,   FPU_ARCH_FPA},
13387   {"armv4t",            ARM_ARCH_V4T,    FPU_ARCH_FPA},
13388   {"armv4txm",          ARM_ARCH_V4TxM,  FPU_ARCH_FPA},
13389   {"armv5",             ARM_ARCH_V5,     FPU_ARCH_VFP},
13390   {"armv5t",            ARM_ARCH_V5T,    FPU_ARCH_VFP},
13391   {"armv5txm",          ARM_ARCH_V5TxM,  FPU_ARCH_VFP},
13392   {"armv5te",           ARM_ARCH_V5TE,   FPU_ARCH_VFP},
13393   {"armv5texp",         ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13394   {"armv5tej",          ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13395   {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13396   {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13397   {"xscale",            ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13398   {"iwmmxt",            ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13399   {NULL, 0, 0}
13400 };
13401
13402 /* ISA extensions in the co-processor space.  */
13403 struct arm_arch_extension_table
13404 {
13405   char *name;
13406   int value;
13407 };
13408
13409 static struct arm_arch_extension_table arm_extensions[] =
13410 {
13411   {"maverick",          ARM_CEXT_MAVERICK},
13412   {"xscale",            ARM_CEXT_XSCALE},
13413   {"iwmmxt",            ARM_CEXT_IWMMXT},
13414   {NULL,                0}
13415 };
13416
13417 struct arm_fpu_option_table
13418 {
13419   char *name;
13420   int   value;
13421 };
13422
13423 /* This list should, at a minimum, contain all the fpu names
13424    recognized by GCC.  */
13425 static struct arm_fpu_option_table arm_fpus[] =
13426 {
13427   {"softfpa",           FPU_NONE},
13428   {"fpe",               FPU_ARCH_FPE},
13429   {"fpe2",              FPU_ARCH_FPE},
13430   {"fpe3",              FPU_ARCH_FPA},  /* Third release supports LFM/SFM.  */
13431   {"fpa",               FPU_ARCH_FPA},
13432   {"fpa10",             FPU_ARCH_FPA},
13433   {"fpa11",             FPU_ARCH_FPA},
13434   {"arm7500fe",         FPU_ARCH_FPA},
13435   {"softvfp",           FPU_ARCH_VFP},
13436   {"softvfp+vfp",       FPU_ARCH_VFP_V2},
13437   {"vfp",               FPU_ARCH_VFP_V2},
13438   {"vfp9",              FPU_ARCH_VFP_V2},
13439   {"vfp10",             FPU_ARCH_VFP_V2},
13440   {"vfp10-r0",          FPU_ARCH_VFP_V1},
13441   {"vfpxd",             FPU_ARCH_VFP_V1xD},
13442   {"arm1020t",          FPU_ARCH_VFP_V1},
13443   {"arm1020e",          FPU_ARCH_VFP_V2},
13444   {"arm1136jfs",        FPU_ARCH_VFP_V2},
13445   {"arm1136jf-s",       FPU_ARCH_VFP_V2},
13446   {"maverick",          FPU_ARCH_MAVERICK},
13447   {NULL, 0}
13448 };
13449
13450 struct arm_float_abi_option_table
13451 {
13452   char *name;
13453   int value;
13454 };
13455
13456 static struct arm_float_abi_option_table arm_float_abis[] =
13457 {
13458   {"hard",      ARM_FLOAT_ABI_HARD},
13459   {"softfp",    ARM_FLOAT_ABI_SOFTFP},
13460   {"soft",      ARM_FLOAT_ABI_SOFT},
13461   {NULL, 0}
13462 };
13463
13464 struct arm_eabi_option_table
13465 {
13466   char *name;
13467   unsigned int value;
13468 };
13469
13470 #ifdef OBJ_ELF
13471 /* We only know hot to output GNU and ver 3 (AAELF) formats.  */
13472 static struct arm_eabi_option_table arm_eabis[] =
13473 {
13474   {"gnu",       EF_ARM_EABI_UNKNOWN},
13475   {"3",         EF_ARM_EABI_VER3},
13476   {NULL, 0}
13477 };
13478 #endif
13479
13480 struct arm_long_option_table
13481 {
13482   char *option;         /* Substring to match.  */
13483   char *help;           /* Help information.  */
13484   int (*func) PARAMS ((char *subopt));  /* Function to decode sub-option.  */
13485   char *deprecated;     /* If non-null, print this message.  */
13486 };
13487
13488 static int
13489 arm_parse_extension (str, opt_p)
13490      char *str;
13491      int *opt_p;
13492 {
13493   while (str != NULL && *str != 0)
13494     {
13495       struct arm_arch_extension_table *opt;
13496       char *ext;
13497       int optlen;
13498
13499       if (*str != '+')
13500         {
13501           as_bad (_("invalid architectural extension"));
13502           return 0;
13503         }
13504
13505       str++;
13506       ext = strchr (str, '+');
13507
13508       if (ext != NULL)
13509         optlen = ext - str;
13510       else
13511         optlen = strlen (str);
13512
13513       if (optlen == 0)
13514         {
13515           as_bad (_("missing architectural extension"));
13516           return 0;
13517         }
13518
13519       for (opt = arm_extensions; opt->name != NULL; opt++)
13520         if (strncmp (opt->name, str, optlen) == 0)
13521           {
13522             *opt_p |= opt->value;
13523             break;
13524           }
13525
13526       if (opt->name == NULL)
13527         {
13528           as_bad (_("unknown architectural extnsion `%s'"), str);
13529           return 0;
13530         }
13531
13532       str = ext;
13533     };
13534
13535   return 1;
13536 }
13537
13538 static int
13539 arm_parse_cpu (str)
13540      char *str;
13541 {
13542   struct arm_cpu_option_table *opt;
13543   char *ext = strchr (str, '+');
13544   int optlen;
13545
13546   if (ext != NULL)
13547     optlen = ext - str;
13548   else
13549     optlen = strlen (str);
13550
13551   if (optlen == 0)
13552     {
13553       as_bad (_("missing cpu name `%s'"), str);
13554       return 0;
13555     }
13556
13557   for (opt = arm_cpus; opt->name != NULL; opt++)
13558     if (strncmp (opt->name, str, optlen) == 0)
13559       {
13560         mcpu_cpu_opt = opt->value;
13561         mcpu_fpu_opt = opt->default_fpu;
13562
13563         if (ext != NULL)
13564           return arm_parse_extension (ext, &mcpu_cpu_opt);
13565
13566         return 1;
13567       }
13568
13569   as_bad (_("unknown cpu `%s'"), str);
13570   return 0;
13571 }
13572
13573 static int
13574 arm_parse_arch (str)
13575      char *str;
13576 {
13577   struct arm_arch_option_table *opt;
13578   char *ext = strchr (str, '+');
13579   int optlen;
13580
13581   if (ext != NULL)
13582     optlen = ext - str;
13583   else
13584     optlen = strlen (str);
13585
13586   if (optlen == 0)
13587     {
13588       as_bad (_("missing architecture name `%s'"), str);
13589       return 0;
13590     }
13591
13592
13593   for (opt = arm_archs; opt->name != NULL; opt++)
13594     if (strcmp (opt->name, str) == 0)
13595       {
13596         march_cpu_opt = opt->value;
13597         march_fpu_opt = opt->default_fpu;
13598
13599         if (ext != NULL)
13600           return arm_parse_extension (ext, &march_cpu_opt);
13601
13602         return 1;
13603       }
13604
13605   as_bad (_("unknown architecture `%s'\n"), str);
13606   return 0;
13607 }
13608
13609 static int
13610 arm_parse_fpu (str)
13611      char *str;
13612 {
13613   struct arm_fpu_option_table *opt;
13614
13615   for (opt = arm_fpus; opt->name != NULL; opt++)
13616     if (strcmp (opt->name, str) == 0)
13617       {
13618         mfpu_opt = opt->value;
13619         return 1;
13620       }
13621
13622   as_bad (_("unknown floating point format `%s'\n"), str);
13623   return 0;
13624 }
13625
13626 static int
13627 arm_parse_float_abi (str)
13628      char * str;
13629 {
13630   struct arm_float_abi_option_table *opt;
13631
13632   for (opt = arm_float_abis; opt->name != NULL; opt++)
13633     if (strcmp (opt->name, str) == 0)
13634       {
13635         mfloat_abi_opt = opt->value;
13636         return 1;
13637       }
13638
13639   as_bad (_("unknown floating point abi `%s'\n"), str);
13640   return 0;
13641 }
13642
13643 #ifdef OBJ_ELF
13644 static int
13645 arm_parse_eabi (str)
13646      char * str;
13647 {
13648   struct arm_eabi_option_table *opt;
13649
13650   for (opt = arm_eabis; opt->name != NULL; opt++)
13651     if (strcmp (opt->name, str) == 0)
13652       {
13653         meabi_flags = opt->value;
13654         return 1;
13655       }
13656   as_bad (_("unknown EABI `%s'\n"), str);
13657   return 0;
13658 }
13659 #endif
13660
13661 struct arm_long_option_table arm_long_opts[] =
13662 {
13663   {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13664    arm_parse_cpu, NULL},
13665   {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13666    arm_parse_arch, NULL},
13667   {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13668    arm_parse_fpu, NULL},
13669   {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13670    arm_parse_float_abi, NULL},
13671 #ifdef OBJ_ELF
13672   {"meabi=", N_("<ver>\t  assemble for eabi version <ver>"),
13673    arm_parse_eabi, NULL},
13674 #endif
13675   {NULL, NULL, 0, NULL}
13676 };
13677
13678 int
13679 md_parse_option (c, arg)
13680      int    c;
13681      char * arg;
13682 {
13683   struct arm_option_table *opt;
13684   struct arm_long_option_table *lopt;
13685
13686   switch (c)
13687     {
13688 #ifdef OPTION_EB
13689     case OPTION_EB:
13690       target_big_endian = 1;
13691       break;
13692 #endif
13693
13694 #ifdef OPTION_EL
13695     case OPTION_EL:
13696       target_big_endian = 0;
13697       break;
13698 #endif
13699
13700     case 'a':
13701       /* Listing option.  Just ignore these, we don't support additional
13702          ones.  */
13703       return 0;
13704
13705     default:
13706       for (opt = arm_opts; opt->option != NULL; opt++)
13707         {
13708           if (c == opt->option[0]
13709               && ((arg == NULL && opt->option[1] == 0)
13710                   || strcmp (arg, opt->option + 1) == 0))
13711             {
13712 #if WARN_DEPRECATED
13713               /* If the option is deprecated, tell the user.  */
13714               if (opt->deprecated != NULL)
13715                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13716                            arg ? arg : "", _(opt->deprecated));
13717 #endif
13718
13719               if (opt->var != NULL)
13720                 *opt->var = opt->value;
13721
13722               return 1;
13723             }
13724         }
13725
13726       for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13727         {
13728           /* These options are expected to have an argument.  */
13729           if (c == lopt->option[0]
13730               && arg != NULL
13731               && strncmp (arg, lopt->option + 1,
13732                           strlen (lopt->option + 1)) == 0)
13733             {
13734 #if WARN_DEPRECATED
13735               /* If the option is deprecated, tell the user.  */
13736               if (lopt->deprecated != NULL)
13737                 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13738                            _(lopt->deprecated));
13739 #endif
13740
13741               /* Call the sup-option parser.  */
13742               return (*lopt->func)(arg + strlen (lopt->option) - 1);
13743             }
13744         }
13745
13746       return 0;
13747     }
13748
13749   return 1;
13750 }
13751
13752 void
13753 md_show_usage (fp)
13754      FILE * fp;
13755 {
13756   struct arm_option_table *opt;
13757   struct arm_long_option_table *lopt;
13758
13759   fprintf (fp, _(" ARM-specific assembler options:\n"));
13760
13761   for (opt = arm_opts; opt->option != NULL; opt++)
13762     if (opt->help != NULL)
13763       fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13764
13765   for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13766     if (lopt->help != NULL)
13767       fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13768
13769 #ifdef OPTION_EB
13770   fprintf (fp, _("\
13771   -EB                     assemble code for a big-endian cpu\n"));
13772 #endif
13773
13774 #ifdef OPTION_EL
13775   fprintf (fp, _("\
13776   -EL                     assemble code for a little-endian cpu\n"));
13777 #endif
13778 }
13779
13780 /* We need to be able to fix up arbitrary expressions in some statements.
13781    This is so that we can handle symbols that are an arbitrary distance from
13782    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13783    which returns part of an address in a form which will be valid for
13784    a data instruction.  We do this by pushing the expression into a symbol
13785    in the expr_section, and creating a fix for that.  */
13786
13787 static void
13788 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13789      fragS *       frag;
13790      int           where;
13791      short int     size;
13792      expressionS * exp;
13793      int           pc_rel;
13794      int           reloc;
13795 {
13796   fixS *           new_fix;
13797   arm_fix_data *   arm_data;
13798
13799   switch (exp->X_op)
13800     {
13801     case O_constant:
13802     case O_symbol:
13803     case O_add:
13804     case O_subtract:
13805       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13806       break;
13807
13808     default:
13809       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13810                          pc_rel, reloc);
13811       break;
13812     }
13813
13814   /* Mark whether the fix is to a THUMB instruction, or an ARM
13815      instruction.  */
13816   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13817   new_fix->tc_fix_data = (PTR) arm_data;
13818   arm_data->thumb_mode = thumb_mode;
13819 }
13820
13821 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13822
13823 void
13824 cons_fix_new_arm (frag, where, size, exp)
13825      fragS *       frag;
13826      int           where;
13827      int           size;
13828      expressionS * exp;
13829 {
13830   bfd_reloc_code_real_type type;
13831   int pcrel = 0;
13832
13833   /* Pick a reloc.
13834      FIXME: @@ Should look at CPU word size.  */
13835   switch (size)
13836     {
13837     case 1:
13838       type = BFD_RELOC_8;
13839       break;
13840     case 2:
13841       type = BFD_RELOC_16;
13842       break;
13843     case 4:
13844     default:
13845       type = BFD_RELOC_32;
13846       break;
13847     case 8:
13848       type = BFD_RELOC_64;
13849       break;
13850     }
13851
13852   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13853 }
13854
13855 /* A good place to do this, although this was probably not intended
13856    for this kind of use.  We need to dump the literal pool before
13857    references are made to a null symbol pointer.  */
13858
13859 void
13860 arm_cleanup ()
13861 {
13862   literal_pool * pool;
13863
13864   for (pool = list_of_pools; pool; pool = pool->next)
13865     {
13866       /* Put it at the end of the relevent section.  */
13867       subseg_set (pool->section, pool->sub_section);
13868 #ifdef OBJ_ELF
13869       arm_elf_change_section ();
13870 #endif
13871       s_ltorg (0);
13872     }
13873 }
13874
13875 void
13876 arm_start_line_hook ()
13877 {
13878   last_label_seen = NULL;
13879 }
13880
13881 void
13882 arm_frob_label (sym)
13883      symbolS * sym;
13884 {
13885   last_label_seen = sym;
13886
13887   ARM_SET_THUMB (sym, thumb_mode);
13888
13889 #if defined OBJ_COFF || defined OBJ_ELF
13890   ARM_SET_INTERWORK (sym, support_interwork);
13891 #endif
13892
13893   /* Note - do not allow local symbols (.Lxxx) to be labeled
13894      as Thumb functions.  This is because these labels, whilst
13895      they exist inside Thumb code, are not the entry points for
13896      possible ARM->Thumb calls.  Also, these labels can be used
13897      as part of a computed goto or switch statement.  eg gcc
13898      can generate code that looks like this:
13899
13900                 ldr  r2, [pc, .Laaa]
13901                 lsl  r3, r3, #2
13902                 ldr  r2, [r3, r2]
13903                 mov  pc, r2
13904
13905        .Lbbb:  .word .Lxxx
13906        .Lccc:  .word .Lyyy
13907        ..etc...
13908        .Laaa:   .word Lbbb
13909
13910      The first instruction loads the address of the jump table.
13911      The second instruction converts a table index into a byte offset.
13912      The third instruction gets the jump address out of the table.
13913      The fourth instruction performs the jump.
13914
13915      If the address stored at .Laaa is that of a symbol which has the
13916      Thumb_Func bit set, then the linker will arrange for this address
13917      to have the bottom bit set, which in turn would mean that the
13918      address computation performed by the third instruction would end
13919      up with the bottom bit set.  Since the ARM is capable of unaligned
13920      word loads, the instruction would then load the incorrect address
13921      out of the jump table, and chaos would ensue.  */
13922   if (label_is_thumb_function_name
13923       && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13924       && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13925     {
13926       /* When the address of a Thumb function is taken the bottom
13927          bit of that address should be set.  This will allow
13928          interworking between Arm and Thumb functions to work
13929          correctly.  */
13930
13931       THUMB_SET_FUNC (sym, 1);
13932
13933       label_is_thumb_function_name = FALSE;
13934     }
13935 }
13936
13937 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
13938    ARM ones.  */
13939
13940 void
13941 arm_adjust_symtab ()
13942 {
13943 #ifdef OBJ_COFF
13944   symbolS * sym;
13945
13946   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13947     {
13948       if (ARM_IS_THUMB (sym))
13949         {
13950           if (THUMB_IS_FUNC (sym))
13951             {
13952               /* Mark the symbol as a Thumb function.  */
13953               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13954                   || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13955                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13956
13957               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13958                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13959               else
13960                 as_bad (_("%s: unexpected function type: %d"),
13961                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13962             }
13963           else switch (S_GET_STORAGE_CLASS (sym))
13964             {
13965             case C_EXT:
13966               S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13967               break;
13968             case C_STAT:
13969               S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13970               break;
13971             case C_LABEL:
13972               S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13973               break;
13974             default:
13975               /* Do nothing.  */
13976               break;
13977             }
13978         }
13979
13980       if (ARM_IS_INTERWORK (sym))
13981         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13982     }
13983 #endif
13984 #ifdef OBJ_ELF
13985   symbolS * sym;
13986   char      bind;
13987
13988   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13989     {
13990       if (ARM_IS_THUMB (sym))
13991         {
13992           elf_symbol_type * elf_sym;
13993
13994           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13995           bind = ELF_ST_BIND (elf_sym);
13996
13997           /* If it's a .thumb_func, declare it as so,
13998              otherwise tag label as .code 16.  */
13999           if (THUMB_IS_FUNC (sym))
14000             elf_sym->internal_elf_sym.st_info =
14001               ELF_ST_INFO (bind, STT_ARM_TFUNC);
14002           else
14003             elf_sym->internal_elf_sym.st_info =
14004               ELF_ST_INFO (bind, STT_ARM_16BIT);
14005         }
14006     }
14007 #endif
14008 }
14009
14010 int
14011 arm_data_in_code ()
14012 {
14013   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
14014     {
14015       *input_line_pointer = '/';
14016       input_line_pointer += 5;
14017       *input_line_pointer = 0;
14018       return 1;
14019     }
14020
14021   return 0;
14022 }
14023
14024 char *
14025 arm_canonicalize_symbol_name (name)
14026      char * name;
14027 {
14028   int len;
14029
14030   if (thumb_mode && (len = strlen (name)) > 5
14031       && streq (name + len - 5, "/data"))
14032     *(name + len - 5) = 0;
14033
14034   return name;
14035 }
14036
14037 #if defined OBJ_COFF || defined OBJ_ELF
14038 void
14039 arm_validate_fix (fixP)
14040      fixS * fixP;
14041 {
14042   /* If the destination of the branch is a defined symbol which does not have
14043      the THUMB_FUNC attribute, then we must be calling a function which has
14044      the (interfacearm) attribute.  We look for the Thumb entry point to that
14045      function and change the branch to refer to that function instead.  */
14046   if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
14047       && fixP->fx_addsy != NULL
14048       && S_IS_DEFINED (fixP->fx_addsy)
14049       && ! THUMB_IS_FUNC (fixP->fx_addsy))
14050     {
14051       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
14052     }
14053 }
14054 #endif
14055
14056 int
14057 arm_force_relocation (fixp)
14058      struct fix * fixp;
14059 {
14060 #if defined (OBJ_COFF) && defined (TE_PE)
14061   if (fixp->fx_r_type == BFD_RELOC_RVA)
14062     return 1;
14063 #endif
14064 #ifdef OBJ_ELF
14065   if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14066       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14067       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14068       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14069     return 1;
14070 #endif
14071
14072   /* Resolve these relocations even if the symbol is extern or weak.  */
14073   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14074       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14075       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14076     return 0;
14077
14078   return generic_force_reloc (fixp);
14079 }
14080
14081 #ifdef OBJ_COFF
14082 /* This is a little hack to help the gas/arm/adrl.s test.  It prevents
14083    local labels from being added to the output symbol table when they
14084    are used with the ADRL pseudo op.  The ADRL relocation should always
14085    be resolved before the binbary is emitted, so it is safe to say that
14086    it is adjustable.  */
14087
14088 bfd_boolean
14089 arm_fix_adjustable (fixP)
14090    fixS * fixP;
14091 {
14092   if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14093     return 1;
14094   return 0;
14095 }
14096 #endif
14097
14098 #ifdef OBJ_ELF
14099 /* Relocations against Thumb function names must be left unadjusted,
14100    so that the linker can use this information to correctly set the
14101    bottom bit of their addresses.  The MIPS version of this function
14102    also prevents relocations that are mips-16 specific, but I do not
14103    know why it does this.
14104
14105    FIXME:
14106    There is one other problem that ought to be addressed here, but
14107    which currently is not:  Taking the address of a label (rather
14108    than a function) and then later jumping to that address.  Such
14109    addresses also ought to have their bottom bit set (assuming that
14110    they reside in Thumb code), but at the moment they will not.  */
14111
14112 bfd_boolean
14113 arm_fix_adjustable (fixP)
14114    fixS * fixP;
14115 {
14116   if (fixP->fx_addsy == NULL)
14117     return 1;
14118
14119   if (THUMB_IS_FUNC (fixP->fx_addsy)
14120       && fixP->fx_subsy == NULL)
14121     return 0;
14122
14123   /* We need the symbol name for the VTABLE entries.  */
14124   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14125       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14126     return 0;
14127
14128   /* Don't allow symbols to be discarded on GOT related relocs.  */
14129   if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14130       || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14131       || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
14132       || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
14133     return 0;
14134
14135   return 1;
14136 }
14137
14138 const char *
14139 elf32_arm_target_format ()
14140 {
14141 #ifdef TE_SYMBIAN
14142   return (target_big_endian
14143           ? "elf32-bigarm-symbian"
14144           : "elf32-littlearm-symbian");
14145 #else 
14146   if (target_big_endian)
14147     {
14148       if (target_oabi)
14149         return "elf32-bigarm-oabi";
14150       else
14151         return "elf32-bigarm";
14152     }
14153   else
14154     {
14155       if (target_oabi)
14156         return "elf32-littlearm-oabi";
14157       else
14158         return "elf32-littlearm";
14159     }
14160 #endif
14161 }
14162
14163 void
14164 armelf_frob_symbol (symp, puntp)
14165      symbolS * symp;
14166      int *     puntp;
14167 {
14168   elf_frob_symbol (symp, puntp);
14169 }
14170
14171 static bfd_reloc_code_real_type
14172 arm_parse_reloc ()
14173 {
14174   char         id [16];
14175   char *       ip;
14176   unsigned int i;
14177   static struct
14178   {
14179     char * str;
14180     int    len;
14181     bfd_reloc_code_real_type reloc;
14182   }
14183   reloc_map[] =
14184   {
14185 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14186     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14187     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14188     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14189        branch instructions generated by GCC for PLT relocs.  */
14190     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14191     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
14192     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
14193     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
14194     { NULL, 0,         BFD_RELOC_UNUSED }
14195 #undef MAP
14196   };
14197
14198   for (i = 0, ip = input_line_pointer;
14199        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14200        i++, ip++)
14201     id[i] = TOLOWER (*ip);
14202
14203   for (i = 0; reloc_map[i].str; i++)
14204     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14205       break;
14206
14207   input_line_pointer += reloc_map[i].len;
14208
14209   return reloc_map[i].reloc;
14210 }
14211
14212 static void
14213 s_arm_elf_cons (nbytes)
14214      int nbytes;
14215 {
14216   expressionS exp;
14217
14218 #ifdef md_flush_pending_output
14219   md_flush_pending_output ();
14220 #endif
14221
14222   if (is_it_end_of_statement ())
14223     {
14224       demand_empty_rest_of_line ();
14225       return;
14226     }
14227
14228 #ifdef md_cons_align
14229   md_cons_align (nbytes);
14230 #endif
14231
14232   mapping_state (MAP_DATA);
14233   do
14234     {
14235       bfd_reloc_code_real_type reloc;
14236
14237       expression (& exp);
14238
14239       if (exp.X_op == O_symbol
14240           && * input_line_pointer == '('
14241           && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14242         {
14243           reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14244           int size = bfd_get_reloc_size (howto);
14245
14246           if (size > nbytes)
14247             as_bad ("%s relocations do not fit in %d bytes",
14248                     howto->name, nbytes);
14249           else
14250             {
14251               register char *p = frag_more ((int) nbytes);
14252               int offset = nbytes - size;
14253
14254               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14255                            &exp, 0, reloc);
14256             }
14257         }
14258       else
14259         emit_expr (&exp, (unsigned int) nbytes);
14260     }
14261   while (*input_line_pointer++ == ',');
14262
14263   /* Put terminator back into stream.  */
14264   input_line_pointer --;
14265   demand_empty_rest_of_line ();
14266 }
14267
14268
14269 /* Parse a .rel31 directive.  */
14270
14271 static void
14272 s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
14273 {
14274   expressionS exp;
14275   char *p;
14276   valueT highbit;
14277     
14278   SKIP_WHITESPACE ();
14279
14280   highbit = 0;
14281   if (*input_line_pointer == '1')
14282     highbit = 0x80000000;
14283   else if (*input_line_pointer != '0')
14284     as_bad (_("expected 0 or 1"));
14285
14286   input_line_pointer++;
14287   SKIP_WHITESPACE ();
14288   if (*input_line_pointer != ',')
14289     as_bad (_("missing comma"));
14290   input_line_pointer++;
14291
14292 #ifdef md_flush_pending_output
14293   md_flush_pending_output ();
14294 #endif
14295
14296 #ifdef md_cons_align
14297   md_cons_align (4);
14298 #endif
14299
14300   mapping_state (MAP_DATA);
14301
14302   expression (&exp);
14303
14304   p = frag_more (4);
14305   md_number_to_chars (p, highbit, 4);
14306   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
14307                BFD_RELOC_ARM_PREL31);
14308
14309   demand_empty_rest_of_line ();
14310 }
14311
14312 #endif /* OBJ_ELF */
14313
14314 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14315    of an rs_align_code fragment.  */
14316
14317 void
14318 arm_handle_align (fragP)
14319      fragS *fragP;
14320 {
14321   static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14322   static char const thumb_noop[2] = { 0xc0, 0x46 };
14323   static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14324   static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14325
14326   int bytes, fix, noop_size;
14327   char * p;
14328   const char * noop;
14329
14330   if (fragP->fr_type != rs_align_code)
14331     return;
14332
14333   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14334   p = fragP->fr_literal + fragP->fr_fix;
14335   fix = 0;
14336
14337   if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14338     bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14339
14340   if (fragP->tc_frag_data)
14341     {
14342       if (target_big_endian)
14343         noop = thumb_bigend_noop;
14344       else
14345         noop = thumb_noop;
14346       noop_size = sizeof (thumb_noop);
14347     }
14348   else
14349     {
14350       if (target_big_endian)
14351         noop = arm_bigend_noop;
14352       else
14353         noop = arm_noop;
14354       noop_size = sizeof (arm_noop);
14355     }
14356
14357   if (bytes & (noop_size - 1))
14358     {
14359       fix = bytes & (noop_size - 1);
14360       memset (p, 0, fix);
14361       p += fix;
14362       bytes -= fix;
14363     }
14364
14365   while (bytes >= noop_size)
14366     {
14367       memcpy (p, noop, noop_size);
14368       p += noop_size;
14369       bytes -= noop_size;
14370       fix += noop_size;
14371     }
14372
14373   fragP->fr_fix += fix;
14374   fragP->fr_var = noop_size;
14375 }
14376
14377 /* Called from md_do_align.  Used to create an alignment
14378    frag in a code section.  */
14379
14380 void
14381 arm_frag_align_code (n, max)
14382      int n;
14383      int max;
14384 {
14385   char * p;
14386
14387   /* We assume that there will never be a requirement
14388      to support alignments greater than 32 bytes.  */
14389   if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14390     as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14391
14392   p = frag_var (rs_align_code,
14393                 MAX_MEM_FOR_RS_ALIGN_CODE,
14394                 1,
14395                 (relax_substateT) max,
14396                 (symbolS *) NULL,
14397                 (offsetT) n,
14398                 (char *) NULL);
14399   *p = 0;
14400
14401 }
14402
14403 /* Perform target specific initialisation of a frag.  */
14404
14405 void
14406 arm_init_frag (fragP)
14407      fragS *fragP;
14408 {
14409   /* Record whether this frag is in an ARM or a THUMB area.  */
14410   fragP->tc_frag_data = thumb_mode;
14411 }