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