1/* tc-arm.c -- Assemble for the ARM
2   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3   Free Software Foundation, Inc.
4   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5	Modified by David Taylor (dtaylor@armltd.co.uk)
6	Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7	Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8	Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
9
10   This file is part of GAS, the GNU Assembler.
11
12   GAS is free software; you can redistribute it and/or modify
13   it under the terms of the GNU General Public License as published by
14   the Free Software Foundation; either version 2, or (at your option)
15   any later version.
16
17   GAS is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20   GNU General Public License for more details.
21
22   You should have received a copy of the GNU General Public License
23   along with GAS; see the file COPYING.  If not, write to the Free
24   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25   02111-1307, USA.  */
26
27#include <string.h>
28#define  NO_RELOC 0
29#include "as.h"
30#include "safe-ctype.h"
31
32/* Need TARGET_CPU.  */
33#include "config.h"
34#include "subsegs.h"
35#include "obstack.h"
36#include "symbols.h"
37#include "listing.h"
38
39#ifdef OBJ_ELF
40#include "elf/arm.h"
41#include "dwarf2dbg.h"
42#endif
43
44/* XXX Set this to 1 after the next binutils release */
45#define WARN_DEPRECATED 0
46
47/* The following bitmasks control CPU extensions:  */
48#define ARM_EXT_V1	 0x00000001	/* All processors (core set).  */
49#define ARM_EXT_V2	 0x00000002	/* Multiply instructions.  */
50#define ARM_EXT_V2S	 0x00000004	/* SWP instructions.       */
51#define ARM_EXT_V3	 0x00000008	/* MSR MRS.                */
52#define ARM_EXT_V3M	 0x00000010	/* Allow long multiplies.  */
53#define ARM_EXT_V4	 0x00000020	/* Allow half word loads.  */
54#define ARM_EXT_V4T	 0x00000040	/* Thumb v1.               */
55#define ARM_EXT_V5	 0x00000080	/* Allow CLZ, etc.         */
56#define ARM_EXT_V5T	 0x00000100	/* Thumb v2.               */
57#define ARM_EXT_V5ExP	 0x00000200	/* DSP core set.           */
58#define ARM_EXT_V5E	 0x00000400	/* DSP Double transfers.   */
59#define ARM_EXT_V5J	 0x00000800	/* Jazelle extension.	   */
60#define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
61
62/* Co-processor space extensions.  */
63#define ARM_CEXT_XSCALE   0x00800000	/* Allow MIA etc.          */
64#define ARM_CEXT_MAVERICK 0x00400000	/* Use Cirrus/DSP coprocessor.  */
65#define ARM_CEXT_IWMMXT   0x00200000    /* Intel Wireless MMX technology coprocessor.   */
66
67/* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
68   defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
69   ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
70   three more to cover cores prior to ARM6.  Finally, there are cores which
71   implement further extensions in the co-processor space.  */
72#define ARM_ARCH_V1			  ARM_EXT_V1
73#define ARM_ARCH_V2	(ARM_ARCH_V1	| ARM_EXT_V2)
74#define ARM_ARCH_V2S	(ARM_ARCH_V2	| ARM_EXT_V2S)
75#define ARM_ARCH_V3	(ARM_ARCH_V2S	| ARM_EXT_V3)
76#define ARM_ARCH_V3M	(ARM_ARCH_V3	| ARM_EXT_V3M)
77#define ARM_ARCH_V4xM	(ARM_ARCH_V3	| ARM_EXT_V4)
78#define ARM_ARCH_V4	(ARM_ARCH_V3M	| ARM_EXT_V4)
79#define ARM_ARCH_V4TxM	(ARM_ARCH_V4xM	| ARM_EXT_V4T)
80#define ARM_ARCH_V4T	(ARM_ARCH_V4	| ARM_EXT_V4T)
81#define ARM_ARCH_V5xM	(ARM_ARCH_V4xM	| ARM_EXT_V5)
82#define ARM_ARCH_V5	(ARM_ARCH_V4	| ARM_EXT_V5)
83#define ARM_ARCH_V5TxM	(ARM_ARCH_V5xM	| ARM_EXT_V4T | ARM_EXT_V5T)
84#define ARM_ARCH_V5T	(ARM_ARCH_V5	| ARM_EXT_V4T | ARM_EXT_V5T)
85#define ARM_ARCH_V5TExP	(ARM_ARCH_V5T	| ARM_EXT_V5ExP)
86#define ARM_ARCH_V5TE	(ARM_ARCH_V5TExP | ARM_EXT_V5E)
87#define ARM_ARCH_V5TEJ	(ARM_ARCH_V5TE	| ARM_EXT_V5J)
88#define ARM_ARCH_V6     (ARM_ARCH_V5TEJ | ARM_EXT_V6)
89
90/* Processors with specific extensions in the co-processor space.  */
91#define ARM_ARCH_XSCALE	(ARM_ARCH_V5TE	| ARM_CEXT_XSCALE)
92#define ARM_ARCH_IWMMXT	(ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
93
94/* Some useful combinations:  */
95#define ARM_ANY		0x0000ffff	/* Any basic core.  */
96#define ARM_ALL		0x00ffffff	/* Any core + co-processor */
97#define CPROC_ANY	0x00ff0000	/* Any co-processor */
98#define FPU_ANY		0xff000000	/* Note this is ~ARM_ALL.  */
99
100
101#define FPU_FPA_EXT_V1	 0x80000000	/* Base FPA instruction set.  */
102#define FPU_FPA_EXT_V2	 0x40000000	/* LFM/SFM.		      */
103#define FPU_VFP_EXT_NONE 0x20000000	/* Use VFP word-ordering.     */
104#define FPU_VFP_EXT_V1xD 0x10000000	/* Base VFP instruction set.  */
105#define FPU_VFP_EXT_V1	 0x08000000	/* Double-precision insns.    */
106#define FPU_VFP_EXT_V2	 0x04000000	/* ARM10E VFPr1.	      */
107#define FPU_MAVERICK	 0x02000000	/* Cirrus Maverick.	      */
108#define FPU_NONE	 0
109
110#define FPU_ARCH_FPE	 FPU_FPA_EXT_V1
111#define FPU_ARCH_FPA	(FPU_ARCH_FPE | FPU_FPA_EXT_V2)
112
113#define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
114#define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
115#define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
116#define FPU_ARCH_VFP_V2	  (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
117
118#define FPU_ARCH_MAVERICK  FPU_MAVERICK
119
120enum arm_float_abi
121{
122  ARM_FLOAT_ABI_HARD,
123  ARM_FLOAT_ABI_SOFTFP,
124  ARM_FLOAT_ABI_SOFT
125};
126
127/* Types of processor to assemble for.  */
128#define ARM_1		ARM_ARCH_V1
129#define ARM_2		ARM_ARCH_V2
130#define ARM_3		ARM_ARCH_V2S
131#define ARM_250		ARM_ARCH_V2S
132#define ARM_6		ARM_ARCH_V3
133#define ARM_7		ARM_ARCH_V3
134#define ARM_8		ARM_ARCH_V4
135#define ARM_9		ARM_ARCH_V4T
136#define ARM_STRONG	ARM_ARCH_V4
137#define ARM_CPU_MASK	0x0000000f              /* XXX? */
138
139#ifndef CPU_DEFAULT
140#if defined __XSCALE__
141#define CPU_DEFAULT	(ARM_ARCH_XSCALE)
142#else
143#if defined __thumb__
144#define CPU_DEFAULT 	(ARM_ARCH_V5T)
145#else
146#define CPU_DEFAULT 	ARM_ANY
147#endif
148#endif
149#endif
150
151#ifdef TE_LINUX
152#define FPU_DEFAULT FPU_ARCH_FPA
153#endif
154
155#if defined(TE_NetBSD) || defined(TE_OpenBSD)
156#ifdef OBJ_ELF
157#define FPU_DEFAULT FPU_ARCH_VFP	/* Soft-float, but VFP order.  */
158#else
159/* Legacy a.out format.  */
160#define FPU_DEFAULT FPU_ARCH_FPA	/* Soft-float, but FPA order.  */
161#endif
162#endif
163
164/* For backwards compatibility we default to the FPA.  */
165#ifndef FPU_DEFAULT
166#define FPU_DEFAULT FPU_ARCH_FPA
167#endif
168
169#define streq(a, b)           (strcmp (a, b) == 0)
170#define skip_whitespace(str)  while (*(str) == ' ') ++(str)
171
172static unsigned long cpu_variant;
173static int target_oabi = 0;
174
175/* Flags stored in private area of BFD structure.  */
176static int uses_apcs_26      = FALSE;
177static int atpcs             = FALSE;
178static int support_interwork = FALSE;
179static int uses_apcs_float   = FALSE;
180static int pic_code          = FALSE;
181
182/* Variables that we set while parsing command-line options.  Once all
183   options have been read we re-process these values to set the real
184   assembly flags.  */
185static int legacy_cpu = -1;
186static int legacy_fpu = -1;
187
188static int mcpu_cpu_opt = -1;
189static int mcpu_fpu_opt = -1;
190static int march_cpu_opt = -1;
191static int march_fpu_opt = -1;
192static int mfpu_opt = -1;
193static int mfloat_abi_opt = -1;
194
195/* This array holds the chars that always start a comment.  If the
196   pre-processor is disabled, these aren't very useful.  */
197const char comment_chars[] = "@";
198
199/* This array holds the chars that only start a comment at the beginning of
200   a line.  If the line seems to have the form '# 123 filename'
201   .line and .file directives will appear in the pre-processed output.  */
202/* Note that input_file.c hand checks for '#' at the beginning of the
203   first line of the input file.  This is because the compiler outputs
204   #NO_APP at the beginning of its output.  */
205/* Also note that comments like this one will always work.  */
206const char line_comment_chars[] = "#";
207
208const char line_separator_chars[] = ";";
209
210/* Chars that can be used to separate mant
211   from exp in floating point numbers.  */
212const char EXP_CHARS[] = "eE";
213
214/* Chars that mean this number is a floating point constant.  */
215/* As in 0f12.456  */
216/* or    0d1.2345e12  */
217
218const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
219
220/* Prefix characters that indicate the start of an immediate
221   value.  */
222#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
223
224#ifdef OBJ_ELF
225/* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
226symbolS * GOT_symbol;
227#endif
228
229/* Size of relocation record.  */
230const int md_reloc_size = 8;
231
232/* 0: assemble for ARM,
233   1: assemble for Thumb,
234   2: assemble for Thumb even though target CPU does not support thumb
235      instructions.  */
236static int thumb_mode = 0;
237
238typedef struct arm_fix
239{
240  int thumb_mode;
241} arm_fix_data;
242
243struct arm_it
244{
245  const char *  error;
246  unsigned long instruction;
247  int           size;
248  struct
249  {
250    bfd_reloc_code_real_type type;
251    expressionS              exp;
252    int                      pc_rel;
253  } reloc;
254};
255
256struct arm_it inst;
257
258enum asm_shift_index
259{
260  SHIFT_LSL = 0,
261  SHIFT_LSR,
262  SHIFT_ASR,
263  SHIFT_ROR,
264  SHIFT_RRX
265};
266
267struct asm_shift_properties
268{
269  enum asm_shift_index index;
270  unsigned long        bit_field;
271  unsigned int         allows_0  : 1;
272  unsigned int         allows_32 : 1;
273};
274
275static const struct asm_shift_properties shift_properties [] =
276{
277  { SHIFT_LSL, 0,    1, 0},
278  { SHIFT_LSR, 0x20, 0, 1},
279  { SHIFT_ASR, 0x40, 0, 1},
280  { SHIFT_ROR, 0x60, 0, 0},
281  { SHIFT_RRX, 0x60, 0, 0}
282};
283
284struct asm_shift_name
285{
286  const char *                        name;
287  const struct asm_shift_properties * properties;
288};
289
290static const struct asm_shift_name shift_names [] =
291{
292  { "asl", shift_properties + SHIFT_LSL },
293  { "lsl", shift_properties + SHIFT_LSL },
294  { "lsr", shift_properties + SHIFT_LSR },
295  { "asr", shift_properties + SHIFT_ASR },
296  { "ror", shift_properties + SHIFT_ROR },
297  { "rrx", shift_properties + SHIFT_RRX },
298  { "ASL", shift_properties + SHIFT_LSL },
299  { "LSL", shift_properties + SHIFT_LSL },
300  { "LSR", shift_properties + SHIFT_LSR },
301  { "ASR", shift_properties + SHIFT_ASR },
302  { "ROR", shift_properties + SHIFT_ROR },
303  { "RRX", shift_properties + SHIFT_RRX }
304};
305
306/* Any kind of shift is accepted.  */
307#define NO_SHIFT_RESTRICT 1
308/* The shift operand must be an immediate value, not a register.  */
309#define SHIFT_IMMEDIATE	  0
310/* The shift must be LSL or ASR and the operand must be an immediate.  */
311#define SHIFT_LSL_OR_ASR_IMMEDIATE 2
312/* The shift must be ASR and the operand must be an immediate.  */
313#define SHIFT_ASR_IMMEDIATE 3
314/* The shift must be LSL and the operand must be an immediate.  */
315#define SHIFT_LSL_IMMEDIATE 4
316
317#define NUM_FLOAT_VALS 8
318
319const char * fp_const[] =
320{
321  "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
322};
323
324/* Number of littlenums required to hold an extended precision number.  */
325#define MAX_LITTLENUMS 6
326
327LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
328
329#define FAIL	(-1)
330#define SUCCESS (0)
331
332/* Whether a Co-processor load/store operation accepts write-back forms.  */
333#define CP_WB_OK 1
334#define CP_NO_WB 0
335
336#define SUFF_S 1
337#define SUFF_D 2
338#define SUFF_E 3
339#define SUFF_P 4
340
341#define CP_T_X   0x00008000
342#define CP_T_Y   0x00400000
343#define CP_T_Pre 0x01000000
344#define CP_T_UD  0x00800000
345#define CP_T_WB  0x00200000
346
347#define CONDS_BIT        0x00100000
348#define LOAD_BIT         0x00100000
349
350#define DOUBLE_LOAD_FLAG 0x00000001
351
352struct asm_cond
353{
354  const char *  template;
355  unsigned long value;
356};
357
358#define COND_ALWAYS 0xe0000000
359#define COND_MASK   0xf0000000
360
361static const struct asm_cond conds[] =
362{
363  {"eq", 0x00000000},
364  {"ne", 0x10000000},
365  {"cs", 0x20000000}, {"hs", 0x20000000},
366  {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
367  {"mi", 0x40000000},
368  {"pl", 0x50000000},
369  {"vs", 0x60000000},
370  {"vc", 0x70000000},
371  {"hi", 0x80000000},
372  {"ls", 0x90000000},
373  {"ge", 0xa0000000},
374  {"lt", 0xb0000000},
375  {"gt", 0xc0000000},
376  {"le", 0xd0000000},
377  {"al", 0xe0000000},
378  {"nv", 0xf0000000}
379};
380
381struct asm_psr
382{
383  const char *template;
384  bfd_boolean cpsr;
385  unsigned long field;
386};
387
388/* The bit that distinguishes CPSR and SPSR.  */
389#define SPSR_BIT   (1 << 22)
390
391/* How many bits to shift the PSR_xxx bits up by.  */
392#define PSR_SHIFT  16
393
394#define PSR_c   (1 << 0)
395#define PSR_x   (1 << 1)
396#define PSR_s   (1 << 2)
397#define PSR_f   (1 << 3)
398
399static const struct asm_psr psrs[] =
400{
401  {"CPSR",	TRUE,  PSR_c | PSR_f},
402  {"CPSR_all",	TRUE,  PSR_c | PSR_f},
403  {"SPSR",	FALSE, PSR_c | PSR_f},
404  {"SPSR_all",	FALSE, PSR_c | PSR_f},
405  {"CPSR_flg",	TRUE,  PSR_f},
406  {"CPSR_f",    TRUE,  PSR_f},
407  {"SPSR_flg",	FALSE, PSR_f},
408  {"SPSR_f",    FALSE, PSR_f},
409  {"CPSR_c",	TRUE,  PSR_c},
410  {"CPSR_ctl",	TRUE,  PSR_c},
411  {"SPSR_c",	FALSE, PSR_c},
412  {"SPSR_ctl",	FALSE, PSR_c},
413  {"CPSR_x",    TRUE,  PSR_x},
414  {"CPSR_s",    TRUE,  PSR_s},
415  {"SPSR_x",    FALSE, PSR_x},
416  {"SPSR_s",    FALSE, PSR_s},
417  /* Combinations of flags.  */
418  {"CPSR_fs",	TRUE, PSR_f | PSR_s},
419  {"CPSR_fx",	TRUE, PSR_f | PSR_x},
420  {"CPSR_fc",	TRUE, PSR_f | PSR_c},
421  {"CPSR_sf",	TRUE, PSR_s | PSR_f},
422  {"CPSR_sx",	TRUE, PSR_s | PSR_x},
423  {"CPSR_sc",	TRUE, PSR_s | PSR_c},
424  {"CPSR_xf",	TRUE, PSR_x | PSR_f},
425  {"CPSR_xs",	TRUE, PSR_x | PSR_s},
426  {"CPSR_xc",	TRUE, PSR_x | PSR_c},
427  {"CPSR_cf",	TRUE, PSR_c | PSR_f},
428  {"CPSR_cs",	TRUE, PSR_c | PSR_s},
429  {"CPSR_cx",	TRUE, PSR_c | PSR_x},
430  {"CPSR_fsx",	TRUE, PSR_f | PSR_s | PSR_x},
431  {"CPSR_fsc",	TRUE, PSR_f | PSR_s | PSR_c},
432  {"CPSR_fxs",	TRUE, PSR_f | PSR_x | PSR_s},
433  {"CPSR_fxc",	TRUE, PSR_f | PSR_x | PSR_c},
434  {"CPSR_fcs",	TRUE, PSR_f | PSR_c | PSR_s},
435  {"CPSR_fcx",	TRUE, PSR_f | PSR_c | PSR_x},
436  {"CPSR_sfx",	TRUE, PSR_s | PSR_f | PSR_x},
437  {"CPSR_sfc",	TRUE, PSR_s | PSR_f | PSR_c},
438  {"CPSR_sxf",	TRUE, PSR_s | PSR_x | PSR_f},
439  {"CPSR_sxc",	TRUE, PSR_s | PSR_x | PSR_c},
440  {"CPSR_scf",	TRUE, PSR_s | PSR_c | PSR_f},
441  {"CPSR_scx",	TRUE, PSR_s | PSR_c | PSR_x},
442  {"CPSR_xfs",	TRUE, PSR_x | PSR_f | PSR_s},
443  {"CPSR_xfc",	TRUE, PSR_x | PSR_f | PSR_c},
444  {"CPSR_xsf",	TRUE, PSR_x | PSR_s | PSR_f},
445  {"CPSR_xsc",	TRUE, PSR_x | PSR_s | PSR_c},
446  {"CPSR_xcf",	TRUE, PSR_x | PSR_c | PSR_f},
447  {"CPSR_xcs",	TRUE, PSR_x | PSR_c | PSR_s},
448  {"CPSR_cfs",	TRUE, PSR_c | PSR_f | PSR_s},
449  {"CPSR_cfx",	TRUE, PSR_c | PSR_f | PSR_x},
450  {"CPSR_csf",	TRUE, PSR_c | PSR_s | PSR_f},
451  {"CPSR_csx",	TRUE, PSR_c | PSR_s | PSR_x},
452  {"CPSR_cxf",	TRUE, PSR_c | PSR_x | PSR_f},
453  {"CPSR_cxs",	TRUE, PSR_c | PSR_x | PSR_s},
454  {"CPSR_fsxc",	TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
455  {"CPSR_fscx",	TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
456  {"CPSR_fxsc",	TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
457  {"CPSR_fxcs",	TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
458  {"CPSR_fcsx",	TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
459  {"CPSR_fcxs",	TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
460  {"CPSR_sfxc",	TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
461  {"CPSR_sfcx",	TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
462  {"CPSR_sxfc",	TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
463  {"CPSR_sxcf",	TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
464  {"CPSR_scfx",	TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
465  {"CPSR_scxf",	TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
466  {"CPSR_xfsc",	TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
467  {"CPSR_xfcs",	TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
468  {"CPSR_xsfc",	TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
469  {"CPSR_xscf",	TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
470  {"CPSR_xcfs",	TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
471  {"CPSR_xcsf",	TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
472  {"CPSR_cfsx",	TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
473  {"CPSR_cfxs",	TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
474  {"CPSR_csfx",	TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
475  {"CPSR_csxf",	TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
476  {"CPSR_cxfs",	TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
477  {"CPSR_cxsf",	TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
478  {"SPSR_fs",	FALSE, PSR_f | PSR_s},
479  {"SPSR_fx",	FALSE, PSR_f | PSR_x},
480  {"SPSR_fc",	FALSE, PSR_f | PSR_c},
481  {"SPSR_sf",	FALSE, PSR_s | PSR_f},
482  {"SPSR_sx",	FALSE, PSR_s | PSR_x},
483  {"SPSR_sc",	FALSE, PSR_s | PSR_c},
484  {"SPSR_xf",	FALSE, PSR_x | PSR_f},
485  {"SPSR_xs",	FALSE, PSR_x | PSR_s},
486  {"SPSR_xc",	FALSE, PSR_x | PSR_c},
487  {"SPSR_cf",	FALSE, PSR_c | PSR_f},
488  {"SPSR_cs",	FALSE, PSR_c | PSR_s},
489  {"SPSR_cx",	FALSE, PSR_c | PSR_x},
490  {"SPSR_fsx",	FALSE, PSR_f | PSR_s | PSR_x},
491  {"SPSR_fsc",	FALSE, PSR_f | PSR_s | PSR_c},
492  {"SPSR_fxs",	FALSE, PSR_f | PSR_x | PSR_s},
493  {"SPSR_fxc",	FALSE, PSR_f | PSR_x | PSR_c},
494  {"SPSR_fcs",	FALSE, PSR_f | PSR_c | PSR_s},
495  {"SPSR_fcx",	FALSE, PSR_f | PSR_c | PSR_x},
496  {"SPSR_sfx",	FALSE, PSR_s | PSR_f | PSR_x},
497  {"SPSR_sfc",	FALSE, PSR_s | PSR_f | PSR_c},
498  {"SPSR_sxf",	FALSE, PSR_s | PSR_x | PSR_f},
499  {"SPSR_sxc",	FALSE, PSR_s | PSR_x | PSR_c},
500  {"SPSR_scf",	FALSE, PSR_s | PSR_c | PSR_f},
501  {"SPSR_scx",	FALSE, PSR_s | PSR_c | PSR_x},
502  {"SPSR_xfs",	FALSE, PSR_x | PSR_f | PSR_s},
503  {"SPSR_xfc",	FALSE, PSR_x | PSR_f | PSR_c},
504  {"SPSR_xsf",	FALSE, PSR_x | PSR_s | PSR_f},
505  {"SPSR_xsc",	FALSE, PSR_x | PSR_s | PSR_c},
506  {"SPSR_xcf",	FALSE, PSR_x | PSR_c | PSR_f},
507  {"SPSR_xcs",	FALSE, PSR_x | PSR_c | PSR_s},
508  {"SPSR_cfs",	FALSE, PSR_c | PSR_f | PSR_s},
509  {"SPSR_cfx",	FALSE, PSR_c | PSR_f | PSR_x},
510  {"SPSR_csf",	FALSE, PSR_c | PSR_s | PSR_f},
511  {"SPSR_csx",	FALSE, PSR_c | PSR_s | PSR_x},
512  {"SPSR_cxf",	FALSE, PSR_c | PSR_x | PSR_f},
513  {"SPSR_cxs",	FALSE, PSR_c | PSR_x | PSR_s},
514  {"SPSR_fsxc",	FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
515  {"SPSR_fscx",	FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
516  {"SPSR_fxsc",	FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
517  {"SPSR_fxcs",	FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
518  {"SPSR_fcsx",	FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
519  {"SPSR_fcxs",	FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
520  {"SPSR_sfxc",	FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
521  {"SPSR_sfcx",	FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
522  {"SPSR_sxfc",	FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
523  {"SPSR_sxcf",	FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
524  {"SPSR_scfx",	FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
525  {"SPSR_scxf",	FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
526  {"SPSR_xfsc",	FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
527  {"SPSR_xfcs",	FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
528  {"SPSR_xsfc",	FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
529  {"SPSR_xscf",	FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
530  {"SPSR_xcfs",	FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
531  {"SPSR_xcsf",	FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
532  {"SPSR_cfsx",	FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
533  {"SPSR_cfxs",	FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
534  {"SPSR_csfx",	FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
535  {"SPSR_csxf",	FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
536  {"SPSR_cxfs",	FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
537  {"SPSR_cxsf",	FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
538};
539
540enum wreg_type
541  {
542    IWMMXT_REG_WR = 0,
543    IWMMXT_REG_WC = 1,
544    IWMMXT_REG_WR_OR_WC = 2,
545    IWMMXT_REG_WCG
546  };
547
548enum iwmmxt_insn_type
549{
550  check_rd,
551  check_wr,
552  check_wrwr,
553  check_wrwrwr,
554  check_wrwrwcg,
555  check_tbcst,
556  check_tmovmsk,
557  check_tmia,
558  check_tmcrr,
559  check_tmrrc,
560  check_tmcr,
561  check_tmrc,
562  check_tinsr,
563  check_textrc,
564  check_waligni,
565  check_textrm,
566  check_wshufh
567};
568
569enum vfp_dp_reg_pos
570{
571  VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
572};
573
574enum vfp_sp_reg_pos
575{
576  VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
577};
578
579enum vfp_ldstm_type
580{
581  VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
582};
583
584/* VFP system registers.  */
585struct vfp_reg
586{
587  const char *name;
588  unsigned long regno;
589};
590
591static const struct vfp_reg vfp_regs[] =
592{
593  {"fpsid", 0x00000000},
594  {"FPSID", 0x00000000},
595  {"fpscr", 0x00010000},
596  {"FPSCR", 0x00010000},
597  {"fpexc", 0x00080000},
598  {"FPEXC", 0x00080000}
599};
600
601/* Structure for a hash table entry for a register.  */
602struct reg_entry
603{
604  const char * name;
605  int          number;
606  bfd_boolean  builtin;
607};
608
609/* Some well known registers that we refer to directly elsewhere.  */
610#define REG_SP  13
611#define REG_LR  14
612#define REG_PC	15
613
614#define wr_register(reg)  ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
615#define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
616#define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
617
618/* These are the standard names.  Users can add aliases with .req.
619   and delete them with .unreq.  */
620
621/* Integer Register Numbers.  */
622static const struct reg_entry rn_table[] =
623{
624  {"r0",  0, TRUE},  {"r1",  1, TRUE},      {"r2",  2, TRUE},      {"r3",  3, TRUE},
625  {"r4",  4, TRUE},  {"r5",  5, TRUE},      {"r6",  6, TRUE},      {"r7",  7, TRUE},
626  {"r8",  8, TRUE},  {"r9",  9, TRUE},      {"r10", 10, TRUE},     {"r11", 11, TRUE},
627  {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
628  /* ATPCS Synonyms.  */
629  {"a1",  0, TRUE},  {"a2",  1, TRUE},      {"a3",  2, TRUE},      {"a4",  3, TRUE},
630  {"v1",  4, TRUE},  {"v2",  5, TRUE},      {"v3",  6, TRUE},      {"v4",  7, TRUE},
631  {"v5",  8, TRUE},  {"v6",  9, TRUE},      {"v7",  10, TRUE},     {"v8",  11, TRUE},
632  /* Well-known aliases.  */
633  {"wr",  7, TRUE},  {"sb",  9, TRUE},      {"sl",  10, TRUE},     {"fp",  11, TRUE},
634  {"ip",  12, TRUE}, {"sp",  REG_SP, TRUE}, {"lr",  REG_LR, TRUE}, {"pc",  REG_PC, TRUE},
635  {NULL, 0, TRUE}
636};
637
638#define WR_PREFIX 0x200
639#define WC_PREFIX 0x400
640
641static const struct reg_entry iwmmxt_table[] =
642{
643  /* Intel Wireless MMX technology register names.  */
644  {  "wr0", 0x0 | WR_PREFIX, TRUE},   {"wr1", 0x1 | WR_PREFIX, TRUE},
645  {  "wr2", 0x2 | WR_PREFIX, TRUE},   {"wr3", 0x3 | WR_PREFIX, TRUE},
646  {  "wr4", 0x4 | WR_PREFIX, TRUE},   {"wr5", 0x5 | WR_PREFIX, TRUE},
647  {  "wr6", 0x6 | WR_PREFIX, TRUE},   {"wr7", 0x7 | WR_PREFIX, TRUE},
648  {  "wr8", 0x8 | WR_PREFIX, TRUE},   {"wr9", 0x9 | WR_PREFIX, TRUE},
649  { "wr10", 0xa | WR_PREFIX, TRUE},  {"wr11", 0xb | WR_PREFIX, TRUE},
650  { "wr12", 0xc | WR_PREFIX, TRUE},  {"wr13", 0xd | WR_PREFIX, TRUE},
651  { "wr14", 0xe | WR_PREFIX, TRUE},  {"wr15", 0xf | WR_PREFIX, TRUE},
652  { "wcid", 0x0 | WC_PREFIX, TRUE},  {"wcon", 0x1 | WC_PREFIX, TRUE},
653  {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
654  {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
655  {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
656
657  {  "wR0", 0x0 | WR_PREFIX, TRUE},   {"wR1", 0x1 | WR_PREFIX, TRUE},
658  {  "wR2", 0x2 | WR_PREFIX, TRUE},   {"wR3", 0x3 | WR_PREFIX, TRUE},
659  {  "wR4", 0x4 | WR_PREFIX, TRUE},   {"wR5", 0x5 | WR_PREFIX, TRUE},
660  {  "wR6", 0x6 | WR_PREFIX, TRUE},   {"wR7", 0x7 | WR_PREFIX, TRUE},
661  {  "wR8", 0x8 | WR_PREFIX, TRUE},   {"wR9", 0x9 | WR_PREFIX, TRUE},
662  { "wR10", 0xa | WR_PREFIX, TRUE},  {"wR11", 0xb | WR_PREFIX, TRUE},
663  { "wR12", 0xc | WR_PREFIX, TRUE},  {"wR13", 0xd | WR_PREFIX, TRUE},
664  { "wR14", 0xe | WR_PREFIX, TRUE},  {"wR15", 0xf | WR_PREFIX, TRUE},
665  { "wCID", 0x0 | WC_PREFIX, TRUE},  {"wCon", 0x1 | WC_PREFIX, TRUE},
666  {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
667  {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
668  {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
669  {NULL, 0, TRUE}
670};
671
672/* Co-processor Numbers.  */
673static const struct reg_entry cp_table[] =
674{
675  {"p0",  0, TRUE},  {"p1",  1, TRUE},  {"p2",  2, TRUE},  {"p3", 3, TRUE},
676  {"p4",  4, TRUE},  {"p5",  5, TRUE},  {"p6",  6, TRUE},  {"p7", 7, TRUE},
677  {"p8",  8, TRUE},  {"p9",  9, TRUE},  {"p10", 10, TRUE}, {"p11", 11, TRUE},
678  {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
679  {NULL, 0, TRUE}
680};
681
682/* Co-processor Register Numbers.  */
683static const struct reg_entry cn_table[] =
684{
685  {"c0",   0, TRUE},  {"c1",   1, TRUE},  {"c2",   2, TRUE},  {"c3",   3, TRUE},
686  {"c4",   4, TRUE},  {"c5",   5, TRUE},  {"c6",   6, TRUE},  {"c7",   7, TRUE},
687  {"c8",   8, TRUE},  {"c9",   9, TRUE},  {"c10",  10, TRUE}, {"c11",  11, TRUE},
688  {"c12",  12, TRUE}, {"c13",  13, TRUE}, {"c14",  14, TRUE}, {"c15",  15, TRUE},
689  /* Not really valid, but kept for back-wards compatibility.  */
690  {"cr0",  0, TRUE},  {"cr1",  1, TRUE},  {"cr2",  2, TRUE},  {"cr3",  3, TRUE},
691  {"cr4",  4, TRUE},  {"cr5",  5, TRUE},  {"cr6",  6, TRUE},  {"cr7",  7, TRUE},
692  {"cr8",  8, TRUE},  {"cr9",  9, TRUE},  {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
693  {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
694  {NULL, 0, TRUE}
695};
696
697/* FPA Registers.  */
698static const struct reg_entry fn_table[] =
699{
700  {"f0", 0, TRUE},   {"f1", 1, TRUE},   {"f2", 2, TRUE},   {"f3", 3, TRUE},
701  {"f4", 4, TRUE},   {"f5", 5, TRUE},   {"f6", 6, TRUE},   {"f7", 7, TRUE},
702  {NULL, 0, TRUE}
703};
704
705/* VFP SP Registers.  */
706static const struct reg_entry sn_table[] =
707{
708  {"s0",  0, TRUE},  {"s1",  1, TRUE},  {"s2",  2, TRUE},  {"s3", 3, TRUE},
709  {"s4",  4, TRUE},  {"s5",  5, TRUE},  {"s6",  6, TRUE},  {"s7", 7, TRUE},
710  {"s8",  8, TRUE},  {"s9",  9, TRUE},  {"s10", 10, TRUE}, {"s11", 11, TRUE},
711  {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
712  {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
713  {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
714  {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
715  {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
716  {NULL, 0, TRUE}
717};
718
719/* VFP DP Registers.  */
720static const struct reg_entry dn_table[] =
721{
722  {"d0",  0, TRUE},  {"d1",  1, TRUE},  {"d2",  2, TRUE},  {"d3", 3, TRUE},
723  {"d4",  4, TRUE},  {"d5",  5, TRUE},  {"d6",  6, TRUE},  {"d7", 7, TRUE},
724  {"d8",  8, TRUE},  {"d9",  9, TRUE},  {"d10", 10, TRUE}, {"d11", 11, TRUE},
725  {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
726  {NULL, 0, TRUE}
727};
728
729/* Maverick DSP coprocessor registers.  */
730static const struct reg_entry mav_mvf_table[] =
731{
732  {"mvf0",  0, TRUE},  {"mvf1",  1, TRUE},  {"mvf2",  2, TRUE},  {"mvf3",  3, TRUE},
733  {"mvf4",  4, TRUE},  {"mvf5",  5, TRUE},  {"mvf6",  6, TRUE},  {"mvf7",  7, TRUE},
734  {"mvf8",  8, TRUE},  {"mvf9",  9, TRUE},  {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
735  {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
736  {NULL, 0, TRUE}
737};
738
739static const struct reg_entry mav_mvd_table[] =
740{
741  {"mvd0",  0, TRUE},  {"mvd1",  1, TRUE},  {"mvd2",  2, TRUE},  {"mvd3",  3, TRUE},
742  {"mvd4",  4, TRUE},  {"mvd5",  5, TRUE},  {"mvd6",  6, TRUE},  {"mvd7",  7, TRUE},
743  {"mvd8",  8, TRUE},  {"mvd9",  9, TRUE},  {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
744  {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
745  {NULL, 0, TRUE}
746};
747
748static const struct reg_entry mav_mvfx_table[] =
749{
750  {"mvfx0",  0, TRUE},  {"mvfx1",  1, TRUE},  {"mvfx2",  2, TRUE},  {"mvfx3",  3, TRUE},
751  {"mvfx4",  4, TRUE},  {"mvfx5",  5, TRUE},  {"mvfx6",  6, TRUE},  {"mvfx7",  7, TRUE},
752  {"mvfx8",  8, TRUE},  {"mvfx9",  9, TRUE},  {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
753  {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
754  {NULL, 0, TRUE}
755};
756
757static const struct reg_entry mav_mvdx_table[] =
758{
759  {"mvdx0",  0, TRUE},  {"mvdx1",  1, TRUE},  {"mvdx2",  2, TRUE},  {"mvdx3",  3, TRUE},
760  {"mvdx4",  4, TRUE},  {"mvdx5",  5, TRUE},  {"mvdx6",  6, TRUE},  {"mvdx7",  7, TRUE},
761  {"mvdx8",  8, TRUE},  {"mvdx9",  9, TRUE},  {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
762  {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
763  {NULL, 0, TRUE}
764};
765
766static const struct reg_entry mav_mvax_table[] =
767{
768  {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
769  {NULL, 0, TRUE}
770};
771
772static const struct reg_entry mav_dspsc_table[] =
773{
774  {"dspsc", 0, TRUE},
775  {NULL, 0, TRUE}
776};
777
778struct reg_map
779{
780  const struct reg_entry *names;
781  int max_regno;
782  struct hash_control *htab;
783  const char *expected;
784};
785
786struct reg_map all_reg_maps[] =
787{
788  {rn_table,        15, NULL, N_("ARM register expected")},
789  {cp_table,        15, NULL, N_("bad or missing co-processor number")},
790  {cn_table,        15, NULL, N_("co-processor register expected")},
791  {fn_table,         7, NULL, N_("FPA register expected")},
792  {sn_table,	    31, NULL, N_("VFP single precision register expected")},
793  {dn_table,	    15, NULL, N_("VFP double precision register expected")},
794  {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
795  {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
796  {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
797  {mav_mvdx_table,  15, NULL, N_("Maverick MVDX register expected")},
798  {mav_mvax_table,   3, NULL, N_("Maverick MVAX register expected")},
799  {mav_dspsc_table,  0, NULL, N_("Maverick DSPSC register expected")},
800  {iwmmxt_table,    23, NULL, N_("Intel Wireless MMX technology register expected")},
801};
802
803/* Enumeration matching entries in table above.  */
804enum arm_reg_type
805{
806  REG_TYPE_RN = 0,
807#define REG_TYPE_FIRST REG_TYPE_RN
808  REG_TYPE_CP = 1,
809  REG_TYPE_CN = 2,
810  REG_TYPE_FN = 3,
811  REG_TYPE_SN = 4,
812  REG_TYPE_DN = 5,
813  REG_TYPE_MVF = 6,
814  REG_TYPE_MVD = 7,
815  REG_TYPE_MVFX = 8,
816  REG_TYPE_MVDX = 9,
817  REG_TYPE_MVAX = 10,
818  REG_TYPE_DSPSC = 11,
819  REG_TYPE_IWMMXT = 12,
820
821  REG_TYPE_MAX = 13
822};
823
824/* Functions called by parser.  */
825/* ARM instructions.  */
826static void do_arit		PARAMS ((char *));
827static void do_cmp		PARAMS ((char *));
828static void do_mov		PARAMS ((char *));
829static void do_ldst		PARAMS ((char *));
830static void do_ldstt		PARAMS ((char *));
831static void do_ldmstm		PARAMS ((char *));
832static void do_branch		PARAMS ((char *));
833static void do_swi		PARAMS ((char *));
834
835/* Pseudo Op codes.  */
836static void do_adr		PARAMS ((char *));
837static void do_adrl		PARAMS ((char *));
838static void do_empty		PARAMS ((char *));
839
840/* ARM v2.  */
841static void do_mul		PARAMS ((char *));
842static void do_mla		PARAMS ((char *));
843
844/* ARM v2S.  */
845static void do_swap		PARAMS ((char *));
846
847/* ARM v3.  */
848static void do_msr		PARAMS ((char *));
849static void do_mrs		PARAMS ((char *));
850
851/* ARM v3M.  */
852static void do_mull		PARAMS ((char *));
853
854/* ARM v4.  */
855static void do_ldstv4		PARAMS ((char *));
856
857/* ARM v4T.  */
858static void do_bx               PARAMS ((char *));
859
860/* ARM v5T.  */
861static void do_blx		PARAMS ((char *));
862static void do_bkpt		PARAMS ((char *));
863static void do_clz		PARAMS ((char *));
864static void do_lstc2		PARAMS ((char *));
865static void do_cdp2		PARAMS ((char *));
866static void do_co_reg2		PARAMS ((char *));
867
868/* ARM v5TExP.  */
869static void do_smla		PARAMS ((char *));
870static void do_smlal		PARAMS ((char *));
871static void do_smul		PARAMS ((char *));
872static void do_qadd		PARAMS ((char *));
873
874/* ARM v5TE.  */
875static void do_pld		PARAMS ((char *));
876static void do_ldrd		PARAMS ((char *));
877static void do_co_reg2c		PARAMS ((char *));
878
879/* ARM v5TEJ.  */
880static void do_bxj		PARAMS ((char *));
881
882/* ARM V6. */
883static void do_cps              PARAMS ((char *));
884static void do_cpsi             PARAMS ((char *));
885static void do_ldrex            PARAMS ((char *));
886static void do_pkhbt            PARAMS ((char *));
887static void do_pkhtb            PARAMS ((char *));
888static void do_qadd16           PARAMS ((char *));
889static void do_rev              PARAMS ((char *));
890static void do_rfe              PARAMS ((char *));
891static void do_sxtah            PARAMS ((char *));
892static void do_sxth             PARAMS ((char *));
893static void do_setend           PARAMS ((char *));
894static void do_smlad            PARAMS ((char *));
895static void do_smlald           PARAMS ((char *));
896static void do_smmul            PARAMS ((char *));
897static void do_ssat             PARAMS ((char *));
898static void do_usat             PARAMS ((char *));
899static void do_srs              PARAMS ((char *));
900static void do_ssat16           PARAMS ((char *));
901static void do_usat16           PARAMS ((char *));
902static void do_strex            PARAMS ((char *));
903static void do_umaal            PARAMS ((char *));
904
905static void do_cps_mode         PARAMS ((char **));
906static void do_cps_flags        PARAMS ((char **, int));
907static int do_endian_specifier  PARAMS ((char *));
908static void do_pkh_core         PARAMS ((char *, int));
909static void do_sat              PARAMS ((char **, int));
910static void do_sat16            PARAMS ((char **, int));
911
912/* Coprocessor Instructions.  */
913static void do_cdp		PARAMS ((char *));
914static void do_lstc		PARAMS ((char *));
915static void do_co_reg		PARAMS ((char *));
916
917/* FPA instructions.  */
918static void do_fpa_ctrl		PARAMS ((char *));
919static void do_fpa_ldst		PARAMS ((char *));
920static void do_fpa_ldmstm	PARAMS ((char *));
921static void do_fpa_dyadic	PARAMS ((char *));
922static void do_fpa_monadic	PARAMS ((char *));
923static void do_fpa_cmp		PARAMS ((char *));
924static void do_fpa_from_reg	PARAMS ((char *));
925static void do_fpa_to_reg	PARAMS ((char *));
926
927/* VFP instructions.  */
928static void do_vfp_sp_monadic	PARAMS ((char *));
929static void do_vfp_dp_monadic	PARAMS ((char *));
930static void do_vfp_sp_dyadic	PARAMS ((char *));
931static void do_vfp_dp_dyadic	PARAMS ((char *));
932static void do_vfp_reg_from_sp  PARAMS ((char *));
933static void do_vfp_sp_from_reg  PARAMS ((char *));
934static void do_vfp_reg2_from_sp2 PARAMS ((char *));
935static void do_vfp_sp2_from_reg2 PARAMS ((char *));
936static void do_vfp_reg_from_dp  PARAMS ((char *));
937static void do_vfp_reg2_from_dp PARAMS ((char *));
938static void do_vfp_dp_from_reg  PARAMS ((char *));
939static void do_vfp_dp_from_reg2 PARAMS ((char *));
940static void do_vfp_reg_from_ctrl PARAMS ((char *));
941static void do_vfp_ctrl_from_reg PARAMS ((char *));
942static void do_vfp_sp_ldst	PARAMS ((char *));
943static void do_vfp_dp_ldst	PARAMS ((char *));
944static void do_vfp_sp_ldstmia	PARAMS ((char *));
945static void do_vfp_sp_ldstmdb	PARAMS ((char *));
946static void do_vfp_dp_ldstmia	PARAMS ((char *));
947static void do_vfp_dp_ldstmdb	PARAMS ((char *));
948static void do_vfp_xp_ldstmia	PARAMS ((char *));
949static void do_vfp_xp_ldstmdb	PARAMS ((char *));
950static void do_vfp_sp_compare_z	PARAMS ((char *));
951static void do_vfp_dp_compare_z	PARAMS ((char *));
952static void do_vfp_dp_sp_cvt	PARAMS ((char *));
953static void do_vfp_sp_dp_cvt	PARAMS ((char *));
954
955/* XScale.  */
956static void do_xsc_mia		PARAMS ((char *));
957static void do_xsc_mar		PARAMS ((char *));
958static void do_xsc_mra		PARAMS ((char *));
959
960/* Maverick.  */
961static void do_mav_binops	PARAMS ((char *, int, enum arm_reg_type,
962					 enum arm_reg_type));
963static void do_mav_binops_1a	PARAMS ((char *));
964static void do_mav_binops_1b	PARAMS ((char *));
965static void do_mav_binops_1c	PARAMS ((char *));
966static void do_mav_binops_1d	PARAMS ((char *));
967static void do_mav_binops_1e	PARAMS ((char *));
968static void do_mav_binops_1f	PARAMS ((char *));
969static void do_mav_binops_1g	PARAMS ((char *));
970static void do_mav_binops_1h	PARAMS ((char *));
971static void do_mav_binops_1i	PARAMS ((char *));
972static void do_mav_binops_1j	PARAMS ((char *));
973static void do_mav_binops_1k	PARAMS ((char *));
974static void do_mav_binops_1l	PARAMS ((char *));
975static void do_mav_binops_1m	PARAMS ((char *));
976static void do_mav_binops_1n	PARAMS ((char *));
977static void do_mav_binops_1o	PARAMS ((char *));
978static void do_mav_binops_2a	PARAMS ((char *));
979static void do_mav_binops_2b	PARAMS ((char *));
980static void do_mav_binops_2c	PARAMS ((char *));
981static void do_mav_binops_3a	PARAMS ((char *));
982static void do_mav_binops_3b	PARAMS ((char *));
983static void do_mav_binops_3c	PARAMS ((char *));
984static void do_mav_binops_3d	PARAMS ((char *));
985static void do_mav_triple	PARAMS ((char *, int, enum arm_reg_type,
986					 enum arm_reg_type,
987					 enum arm_reg_type));
988static void do_mav_triple_4a	PARAMS ((char *));
989static void do_mav_triple_4b	PARAMS ((char *));
990static void do_mav_triple_5a	PARAMS ((char *));
991static void do_mav_triple_5b	PARAMS ((char *));
992static void do_mav_triple_5c	PARAMS ((char *));
993static void do_mav_triple_5d	PARAMS ((char *));
994static void do_mav_triple_5e	PARAMS ((char *));
995static void do_mav_triple_5f	PARAMS ((char *));
996static void do_mav_triple_5g	PARAMS ((char *));
997static void do_mav_triple_5h	PARAMS ((char *));
998static void do_mav_quad		PARAMS ((char *, int, enum arm_reg_type,
999					 enum arm_reg_type,
1000					 enum arm_reg_type,
1001					 enum arm_reg_type));
1002static void do_mav_quad_6a	PARAMS ((char *));
1003static void do_mav_quad_6b	PARAMS ((char *));
1004static void do_mav_dspsc_1	PARAMS ((char *));
1005static void do_mav_dspsc_2	PARAMS ((char *));
1006static void do_mav_shift	PARAMS ((char *, enum arm_reg_type,
1007					 enum arm_reg_type));
1008static void do_mav_shift_1	PARAMS ((char *));
1009static void do_mav_shift_2	PARAMS ((char *));
1010static void do_mav_ldst		PARAMS ((char *, enum arm_reg_type));
1011static void do_mav_ldst_1	PARAMS ((char *));
1012static void do_mav_ldst_2	PARAMS ((char *));
1013static void do_mav_ldst_3	PARAMS ((char *));
1014static void do_mav_ldst_4	PARAMS ((char *));
1015
1016static int mav_reg_required_here	PARAMS ((char **, int,
1017						 enum arm_reg_type));
1018static int mav_parse_offset	PARAMS ((char **, int *));
1019
1020static void fix_new_arm		PARAMS ((fragS *, int, short, expressionS *,
1021					 int, int));
1022static int arm_reg_parse	PARAMS ((char **, struct hash_control *));
1023static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1024static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1025static void symbol_locate	PARAMS ((symbolS *, const char *, segT, valueT,
1026					 fragS *));
1027static int add_to_lit_pool	PARAMS ((void));
1028static unsigned validate_immediate PARAMS ((unsigned));
1029static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1030						    unsigned int *));
1031static int validate_offset_imm	PARAMS ((unsigned int, int));
1032static void opcode_select	PARAMS ((int));
1033static void end_of_line		PARAMS ((char *));
1034static int reg_required_here	PARAMS ((char **, int));
1035static int psr_required_here	PARAMS ((char **));
1036static int co_proc_number	PARAMS ((char **));
1037static int cp_opc_expr		PARAMS ((char **, int, int));
1038static int cp_reg_required_here	PARAMS ((char **, int));
1039static int fp_reg_required_here	PARAMS ((char **, int));
1040static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1041static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1042static void vfp_sp_ldstm	PARAMS ((char *, enum vfp_ldstm_type));
1043static void vfp_dp_ldstm	PARAMS ((char *, enum vfp_ldstm_type));
1044static long vfp_sp_reg_list	PARAMS ((char **, enum vfp_sp_reg_pos));
1045static long vfp_dp_reg_list	PARAMS ((char **));
1046static int vfp_psr_required_here PARAMS ((char **str));
1047static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1048static int cp_address_offset	PARAMS ((char **));
1049static int cp_address_required_here	PARAMS ((char **, int));
1050static int my_get_float_expression	PARAMS ((char **));
1051static int skip_past_comma	PARAMS ((char **));
1052static int walk_no_bignums	PARAMS ((symbolS *));
1053static int negate_data_op	PARAMS ((unsigned long *, unsigned long));
1054static int data_op2		PARAMS ((char **));
1055static int fp_op2		PARAMS ((char **));
1056static long reg_list		PARAMS ((char **));
1057static void thumb_load_store	PARAMS ((char *, int, int));
1058static int decode_shift		PARAMS ((char **, int));
1059static int ldst_extend		PARAMS ((char **));
1060static int ldst_extend_v4		PARAMS ((char **));
1061static void thumb_add_sub	PARAMS ((char *, int));
1062static void insert_reg		PARAMS ((const struct reg_entry *,
1063					 struct hash_control *));
1064static void thumb_shift		PARAMS ((char *, int));
1065static void thumb_mov_compare	PARAMS ((char *, int));
1066static void build_arm_ops_hsh	PARAMS ((void));
1067static void set_constant_flonums	PARAMS ((void));
1068static valueT md_chars_to_number	PARAMS ((char *, int));
1069static void build_reg_hsh	PARAMS ((struct reg_map *));
1070static void insert_reg_alias	PARAMS ((char *, int, struct hash_control *));
1071static int create_register_alias	PARAMS ((char *, char *));
1072static void output_inst		PARAMS ((const char *));
1073static int accum0_required_here PARAMS ((char **));
1074static int ld_mode_required_here PARAMS ((char **));
1075static void do_branch25         PARAMS ((char *));
1076static symbolS * find_real_start PARAMS ((symbolS *));
1077#ifdef OBJ_ELF
1078static bfd_reloc_code_real_type	arm_parse_reloc PARAMS ((void));
1079#endif
1080
1081static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
1082static void do_iwmmxt_byte_addr PARAMS ((char *));
1083static void do_iwmmxt_tandc     PARAMS ((char *));
1084static void do_iwmmxt_tbcst     PARAMS ((char *));
1085static void do_iwmmxt_textrc    PARAMS ((char *));
1086static void do_iwmmxt_textrm    PARAMS ((char *));
1087static void do_iwmmxt_tinsr     PARAMS ((char *));
1088static void do_iwmmxt_tmcr      PARAMS ((char *));
1089static void do_iwmmxt_tmcrr     PARAMS ((char *));
1090static void do_iwmmxt_tmia      PARAMS ((char *));
1091static void do_iwmmxt_tmovmsk   PARAMS ((char *));
1092static void do_iwmmxt_tmrc      PARAMS ((char *));
1093static void do_iwmmxt_tmrrc     PARAMS ((char *));
1094static void do_iwmmxt_torc      PARAMS ((char *));
1095static void do_iwmmxt_waligni   PARAMS ((char *));
1096static void do_iwmmxt_wmov      PARAMS ((char *));
1097static void do_iwmmxt_word_addr PARAMS ((char *));
1098static void do_iwmmxt_wrwr      PARAMS ((char *));
1099static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
1100static void do_iwmmxt_wrwrwr    PARAMS ((char *));
1101static void do_iwmmxt_wshufh    PARAMS ((char *));
1102static void do_iwmmxt_wzero     PARAMS ((char *));
1103static int cp_byte_address_offset         PARAMS ((char **));
1104static int cp_byte_address_required_here  PARAMS ((char **));
1105
1106/* ARM instructions take 4bytes in the object file, Thumb instructions
1107   take 2:  */
1108#define INSN_SIZE       4
1109
1110/* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1111#define MAV_MODE1	0x100c
1112
1113/* "INSN<cond> X,Y" where X:bit16, Y:bit12.  */
1114#define MAV_MODE2	0x0c10
1115
1116/* "INSN<cond> X,Y" where X:bit12, Y:bit16.  */
1117#define MAV_MODE3	0x100c
1118
1119/* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12.  */
1120#define MAV_MODE4	0x0c0010
1121
1122/* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0.  */
1123#define MAV_MODE5	0x00100c
1124
1125/* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0.  */
1126#define MAV_MODE6	0x00100c05
1127
1128struct asm_opcode
1129{
1130  /* Basic string to match.  */
1131  const char * template;
1132
1133  /* Basic instruction code.  */
1134  unsigned long value;
1135
1136  /* Offset into the template where the condition code (if any) will be.
1137     If zero, then the instruction is never conditional.  */
1138  unsigned cond_offset;
1139
1140  /* Which architecture variant provides this instruction.  */
1141  unsigned long variant;
1142
1143  /* Function to call to parse args.  */
1144  void (* parms) PARAMS ((char *));
1145};
1146
1147static const struct asm_opcode insns[] =
1148{
1149  /* Core ARM Instructions.  */
1150  {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
1151  {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
1152  {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
1153  {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
1154  {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
1155  {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
1156  {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
1157  {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
1158  {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
1159  {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
1160  {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
1161  {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
1162  {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
1163  {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
1164  {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
1165  {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
1166  {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
1167  {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
1168  {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
1169  {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
1170
1171  {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1172  {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
1173  {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
1174  {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1175  {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
1176  {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
1177  {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1178  {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
1179  {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
1180  {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1181  {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
1182  {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
1183
1184  {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
1185  {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
1186  {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
1187  {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
1188
1189  {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
1190  {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
1191  {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
1192  {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
1193  {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
1194  {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
1195  {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
1196  {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
1197
1198  {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1199  {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1200  {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1201  {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1202  {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
1203  {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
1204  {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
1205  {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
1206
1207  {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1208  {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1209  {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1210  {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1211  {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
1212  {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
1213  {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
1214  {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
1215
1216  {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
1217#ifdef TE_WINCE
1218  /* XXX This is the wrong place to do this.  Think multi-arch.  */
1219  {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
1220  {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
1221#else
1222  {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
1223  {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
1224#endif
1225
1226  /* Pseudo ops.  */
1227  {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
1228  {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
1229  {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
1230
1231  /* ARM 2 multiplies.  */
1232  {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
1233  {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
1234  {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
1235  {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
1236
1237  /* Generic coprocessor instructions.  */
1238  {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
1239  {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
1240  {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
1241  {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
1242  {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
1243  {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
1244  {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
1245
1246  /* ARM 3 - swp instructions.  */
1247  {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
1248  {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
1249
1250  /* ARM 6 Status register instructions.  */
1251  {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
1252  {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
1253  /* ScottB: our code uses     0xe128f000 for msr.
1254     NickC:  but this is wrong because the bits 16 through 19 are
1255             handled by the PSR_xxx defines above.  */
1256
1257  /* ARM 7M long multiplies.  */
1258  {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
1259  {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
1260  {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
1261  {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
1262  {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
1263  {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
1264  {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
1265  {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
1266
1267  /* ARM Architecture 4.  */
1268  {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1269  {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
1270  {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
1271  {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
1272
1273  /* ARM Architecture 4T.  */
1274  /* Note: bx (and blx) are required on V5, even if the processor does
1275     not support Thumb.  */
1276  {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1277
1278  /*  ARM Architecture 5T.  */
1279  /* Note: blx has 2 variants, so the .value is set dynamically.
1280     Only one of the variants has conditional execution.  */
1281  {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
1282  {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
1283  {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
1284  {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
1285  {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
1286  {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
1287  {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
1288  {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
1289  {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
1290  {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
1291
1292  /*  ARM Architecture 5TExP.  */
1293  {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
1294  {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
1295  {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1296  {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
1297
1298  {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
1299  {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
1300
1301  {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
1302  {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
1303  {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
1304  {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
1305
1306  {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
1307  {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1308  {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
1309  {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1310
1311  {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
1312  {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
1313
1314  {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
1315  {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
1316  {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
1317  {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
1318
1319  /*  ARM Architecture 5TE.  */
1320  {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
1321  {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
1322  {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
1323
1324  {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1325  {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
1326
1327  /*  ARM Architecture 5TEJ.  */
1328  {"bxj",	 0xe12fff20, 3,  ARM_EXT_V5J,	   do_bxj},
1329
1330  /*  ARM V6.  */
1331  { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
1332  { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
1333  { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
1334  { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
1335  { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
1336  { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
1337  { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
1338  { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
1339  { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
1340  { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
1341  { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
1342  { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
1343  { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
1344  { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
1345  { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
1346  { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
1347  { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
1348  { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
1349  { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
1350  { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
1351  { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
1352  { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
1353  { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
1354  { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
1355  { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
1356  { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
1357  { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
1358  { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
1359  { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
1360  { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
1361  { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
1362  { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
1363  { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
1364  { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
1365  { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
1366  { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
1367  { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
1368  { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
1369  { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
1370  { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
1371  { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
1372  { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
1373  { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
1374  { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
1375  { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
1376  { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
1377  { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
1378  { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1379  { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1380  { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1381  { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1382  { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
1383  { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
1384  { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
1385  { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
1386  { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
1387  { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
1388  { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
1389  { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
1390  { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
1391  { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
1392  { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
1393  { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
1394  { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
1395  { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
1396  { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
1397  { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
1398  { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
1399  { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
1400  { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
1401  { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
1402  { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
1403  { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
1404  { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
1405  { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
1406  { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
1407  { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
1408  { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
1409  { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
1410  { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
1411  { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
1412  { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
1413  { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
1414  { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
1415  { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
1416  { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
1417  { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
1418  { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
1419  { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
1420  { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
1421  { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
1422  { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
1423  { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
1424  { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
1425  { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
1426  { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
1427  { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
1428  { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
1429  { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
1430
1431  /* Core FPA instruction set (V1).  */
1432  {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1433  {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1434  {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1435  {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
1436
1437  {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1438  {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1439  {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1440  {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1441
1442  {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1443  {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1444  {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1445  {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
1446
1447  {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1448  {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1449  {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1450  {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1451  {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1452  {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1453  {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1454  {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1455  {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1456  {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1457  {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1458  {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1459
1460  {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1461  {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1462  {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1463  {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1464  {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1465  {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1466  {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1467  {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1468  {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1469  {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1470  {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1471  {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1472
1473  {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1474  {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1475  {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1476  {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1477  {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1478  {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1479  {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1480  {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1481  {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1482  {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1483  {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1484  {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1485
1486  {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1487  {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1488  {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1489  {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1490  {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1491  {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1492  {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1493  {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1494  {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1495  {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1496  {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1497  {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1498
1499  {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1500  {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1501  {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1502  {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1503  {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1504  {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1505  {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1506  {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1507  {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1508  {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1509  {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1510  {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1511
1512  {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1513  {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1514  {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1515  {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1516  {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1517  {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1518  {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1519  {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1520  {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1521  {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1522  {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1523  {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1524
1525  {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1526  {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1527  {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1528  {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1529  {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1530  {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1531  {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1532  {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1533  {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1534  {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1535  {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1536  {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1537
1538  {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1539  {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1540  {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1541  {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1542  {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1543  {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1544  {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1545  {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1546  {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1547  {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1548  {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1549  {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1550
1551  {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1552  {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1553  {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1554  {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1555  {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1556  {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1557  {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1558  {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1559  {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1560  {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1561  {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1562  {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1563
1564  {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1565  {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1566  {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1567  {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1568  {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1569  {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1570  {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1571  {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1572  {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1573  {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1574  {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1575  {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1576
1577  {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1578  {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1579  {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1580  {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1581  {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1582  {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1583  {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1584  {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1585  {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1586  {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1587  {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1588  {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1589
1590  {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1591  {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1592  {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1593  {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1594  {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1595  {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1596  {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1597  {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1598  {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1599  {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1600  {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1601  {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1602
1603  {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1604  {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1605  {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1606  {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1607  {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1608  {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1609  {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1610  {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1611  {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1612  {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1613  {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1614  {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1615
1616  {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1617  {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1618  {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1619  {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1620  {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1621  {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1622  {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1623  {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1624  {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1625  {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1626  {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1627  {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1628
1629  {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1630  {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1631  {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1632  {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1633  {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1634  {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1635  {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1636  {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1637  {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1638  {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1639  {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1640  {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1641
1642  {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1643  {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1644  {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1645  {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1646  {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1647  {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1648  {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1649  {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1650  {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1651  {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1652  {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1653  {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
1654
1655  {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1656  {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1657  {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1658  {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1659  {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1660  {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1661  {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1662  {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1663  {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1664  {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1665  {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1666  {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1667
1668  {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1669  {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1670  {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1671  {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1672  {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1673  {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1674  {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1675  {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1676  {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1677  {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1678  {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1679  {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1680
1681  {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1682  {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1683  {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1684  {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1685  {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1686  {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1687  {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1688  {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1689  {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1690  {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1691  {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1692  {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1693
1694  {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1695  {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1696  {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1697  {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1698  {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1699  {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1700  {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1701  {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1702  {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1703  {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1704  {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1705  {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1706
1707  {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1708  {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1709  {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1710  {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1711  {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1712  {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1713  {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1714  {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1715  {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1716  {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1717  {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1718  {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1719
1720  {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1721  {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1722  {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1723  {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1724  {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1725  {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1726  {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1727  {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1728  {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1729  {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1730  {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1731  {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1732
1733  {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1734  {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1735  {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1736  {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1737  {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1738  {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1739  {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1740  {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1741  {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1742  {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1743  {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1744  {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1745
1746  {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1747  {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1748  {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1749  {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1750  {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1751  {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1752  {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1753  {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1754  {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1755  {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1756  {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1757  {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1758
1759  {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1760  {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1761  {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1762  {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1763  {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1764  {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1765  {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1766  {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1767  {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1768  {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1769  {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1770  {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1771
1772  {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1773  {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1774  {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1775  {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1776  {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1777  {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1778  {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1779  {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1780  {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1781  {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1782  {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1783  {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1784
1785  {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1786  {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1787  {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1788  {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1789  {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1790  {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1791  {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1792  {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1793  {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1794  {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1795  {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1796  {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1797
1798  {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1799  {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1800  {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1801  {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1802  {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1803  {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1804  {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1805  {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1806  {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1807  {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1808  {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1809  {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1810
1811  {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1812  {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1813  {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1814  {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1815  {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1816  {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1817  {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1818  {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1819  {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1820  {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1821  {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1822  {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
1823
1824  {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1825  {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1826  {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1827  {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1828  /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1829     not be an optional suffix, but part of the instruction.  To be
1830     compatible, we accept either.  */
1831  {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1832  {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
1833
1834  {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1835  {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1836  {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1837  {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1838  {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1839  {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1840  {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1841  {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1842  {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1843  {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1844  {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1845  {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
1846
1847  /* The implementation of the FIX instruction is broken on some
1848     assemblers, in that it accepts a precision specifier as well as a
1849     rounding specifier, despite the fact that this is meaningless.
1850     To be more compatible, we accept it as well, though of course it
1851     does not set any bits.  */
1852  {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1853  {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1854  {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1855  {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1856  {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1857  {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1858  {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1859  {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1860  {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1861  {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1862  {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1863  {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1864  {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
1865
1866  /* Instructions that were new with the real FPA, call them V2.  */
1867  {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1868  {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1869  {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1870  {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1871  {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1872  {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
1873
1874  /* VFP V1xD (single precision).  */
1875  /* Moves and type conversions.  */
1876  {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1877  {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1878  {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1879  {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1880  {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1881  {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1882  {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1883  {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1884  {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1885  {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1886  {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1887  {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1888
1889  /* Memory operations.  */
1890  {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1891  {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1892  {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1893  {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1894  {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1895  {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1896  {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1897  {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1898  {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1899  {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1900  {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1901  {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1902  {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1903  {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1904  {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1905  {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1906  {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1907  {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1908
1909  /* Monadic operations.  */
1910  {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1911  {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1912  {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1913
1914  /* Dyadic operations.  */
1915  {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1916  {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1917  {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1918  {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919  {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920  {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921  {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1922  {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1923  {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1924
1925  /* Comparisons.  */
1926  {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1927  {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1928  {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1929  {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1930
1931  /* VFP V1 (Double precision).  */
1932  /* Moves and type conversions.  */
1933  {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1934  {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1935  {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1936  {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1937  {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
1938  {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1939  {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
1940  {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1941  {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
1942  {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1943  {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1944  {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1945  {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
1946
1947  /* Memory operations.  */
1948  {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1949  {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
1950  {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1951  {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1952  {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1953  {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1954  {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1955  {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
1956  {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1957  {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
1958
1959  /* Monadic operations.  */
1960  {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1961  {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1962  {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1963
1964  /* Dyadic operations.  */
1965  {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1966  {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1967  {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1968  {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1969  {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1970  {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1971  {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1972  {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1973  {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
1974
1975  /* Comparisons.  */
1976  {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1977  {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1978  {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
1979  {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
1980
1981  /* VFP V2.  */
1982  {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
1983  {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
1984  {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
1985  {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
1986
1987  /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
1988  {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
1989  {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1990  {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1991  {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1992  {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1993  {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
1994  {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
1995  {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
1996
1997  /* Intel Wireless MMX technology instructions.  */
1998  {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1999  {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2000  {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2001  {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2002  {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2003  {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2004  {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2005  {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2006  {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2007  {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2008  {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2009  {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2010  {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2011  {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2012  {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2013  {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2014  {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2015  {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2016  {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2017  {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2018  {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2019  {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2020  {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2021  {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2022  {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2023  {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2024  {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2025  {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2026  {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2027  {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2028  {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2029  {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2030  {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2031  {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2032  {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2033  {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2034  {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2035  {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2036  {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037  {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038  {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039  {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040  {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041  {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042  {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043  {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044  {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2045  {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2046  {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047  {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048  {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049  {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050  {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051  {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052  {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053  {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054  {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055  {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056  {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057  {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058  {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059  {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060  {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061  {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2062  {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2063  {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064  {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2065  {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2066  {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2067  {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2068  {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2069  {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070  {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071  {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072  {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073  {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074  {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075  {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076  {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077  {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078  {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079  {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080  {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081  {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082  {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083  {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2084  {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085  {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086  {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2087  {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2088  {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089  {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090  {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091  {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092  {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093  {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094  {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095  {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096  {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2097  {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098  {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2099  {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2100  {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2101  {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2102  {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2103  {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2104  {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2105  {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2106  {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2107  {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2108  {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2109  {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2110  {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2111  {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2112  {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2113  {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2114  {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2115  {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2116  {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2117  {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2118  {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2119  {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2120  {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2121  {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2122  {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2123  {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2124  {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2125  {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2126  {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2127  {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2128  {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2129  {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2130  {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2131  {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2132  {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2133  {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2134  {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135  {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136  {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137  {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2138  {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2139  {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2140  {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2141  {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2142  {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2143  {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2144  {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2145  {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2146  {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2147  {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2148  {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2149  {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2150  {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2151  {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2152  {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2153  {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2154  {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2155  {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2156  {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2157  {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2158  {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2159  {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2160
2161  /* Cirrus Maverick instructions.  */
2162  {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2163  {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2164  {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2165  {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2166  {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
2167  {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
2168  {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
2169  {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
2170  {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
2171  {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
2172  {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2173  {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2174  {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
2175  {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
2176  {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2177  {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2178  {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
2179  {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
2180  {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2181  {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2182  {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2183  {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2184  {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2185  {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2186  {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
2187  {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
2188  {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
2189  {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
2190  {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2191  {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2192  {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2193  {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2194  {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
2195  {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
2196  {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
2197  {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
2198  {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
2199  {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
2200  {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
2201  {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
2202  {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2203  {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2204  {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
2205  {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
2206  {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
2207  {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
2208  {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
2209  {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
2210  {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
2211  {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
2212  {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2213  {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2214  {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
2215  {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
2216  {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2217  {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2218  {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2219  {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2220  {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
2221  {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
2222  {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2223  {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2224  {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
2225  {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
2226  {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2227  {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2228  {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2229  {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2230  {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2231  {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
2232  {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2233  {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
2234  {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2235  {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
2236  {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2237  {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
2238};
2239
2240/* Defines for various bits that we will want to toggle.  */
2241#define INST_IMMEDIATE	0x02000000
2242#define OFFSET_REG	0x02000000
2243#define HWOFFSET_IMM    0x00400000
2244#define SHIFT_BY_REG	0x00000010
2245#define PRE_INDEX	0x01000000
2246#define INDEX_UP	0x00800000
2247#define WRITE_BACK	0x00200000
2248#define LDM_TYPE_2_OR_3	0x00400000
2249
2250#define LITERAL_MASK	0xf000f000
2251#define OPCODE_MASK	0xfe1fffff
2252#define V4_STR_BIT	0x00000020
2253
2254#define DATA_OP_SHIFT	21
2255
2256/* Codes to distinguish the arithmetic instructions.  */
2257#define OPCODE_AND	0
2258#define OPCODE_EOR	1
2259#define OPCODE_SUB	2
2260#define OPCODE_RSB	3
2261#define OPCODE_ADD	4
2262#define OPCODE_ADC	5
2263#define OPCODE_SBC	6
2264#define OPCODE_RSC	7
2265#define OPCODE_TST	8
2266#define OPCODE_TEQ	9
2267#define OPCODE_CMP	10
2268#define OPCODE_CMN	11
2269#define OPCODE_ORR	12
2270#define OPCODE_MOV	13
2271#define OPCODE_BIC	14
2272#define OPCODE_MVN	15
2273
2274/* Thumb v1 (ARMv4T).  */
2275static void do_t_nop		PARAMS ((char *));
2276static void do_t_arit		PARAMS ((char *));
2277static void do_t_add		PARAMS ((char *));
2278static void do_t_asr		PARAMS ((char *));
2279static void do_t_branch9	PARAMS ((char *));
2280static void do_t_branch12	PARAMS ((char *));
2281static void do_t_branch23	PARAMS ((char *));
2282static void do_t_bx		PARAMS ((char *));
2283static void do_t_compare	PARAMS ((char *));
2284static void do_t_ldmstm		PARAMS ((char *));
2285static void do_t_ldr		PARAMS ((char *));
2286static void do_t_ldrb		PARAMS ((char *));
2287static void do_t_ldrh		PARAMS ((char *));
2288static void do_t_lds		PARAMS ((char *));
2289static void do_t_lsl		PARAMS ((char *));
2290static void do_t_lsr		PARAMS ((char *));
2291static void do_t_mov		PARAMS ((char *));
2292static void do_t_push_pop	PARAMS ((char *));
2293static void do_t_str		PARAMS ((char *));
2294static void do_t_strb		PARAMS ((char *));
2295static void do_t_strh		PARAMS ((char *));
2296static void do_t_sub		PARAMS ((char *));
2297static void do_t_swi		PARAMS ((char *));
2298static void do_t_adr		PARAMS ((char *));
2299
2300/* Thumb v2 (ARMv5T).  */
2301static void do_t_blx		PARAMS ((char *));
2302static void do_t_bkpt		PARAMS ((char *));
2303
2304/* ARM V6.  */
2305static void do_t_cps            PARAMS ((char *));
2306static void do_t_cpy            PARAMS ((char *));
2307static void do_t_setend         PARAMS ((char *));;
2308
2309#define T_OPCODE_MUL 0x4340
2310#define T_OPCODE_TST 0x4200
2311#define T_OPCODE_CMN 0x42c0
2312#define T_OPCODE_NEG 0x4240
2313#define T_OPCODE_MVN 0x43c0
2314
2315#define T_OPCODE_ADD_R3	0x1800
2316#define T_OPCODE_SUB_R3 0x1a00
2317#define T_OPCODE_ADD_HI 0x4400
2318#define T_OPCODE_ADD_ST 0xb000
2319#define T_OPCODE_SUB_ST 0xb080
2320#define T_OPCODE_ADD_SP 0xa800
2321#define T_OPCODE_ADD_PC 0xa000
2322#define T_OPCODE_ADD_I8 0x3000
2323#define T_OPCODE_SUB_I8 0x3800
2324#define T_OPCODE_ADD_I3 0x1c00
2325#define T_OPCODE_SUB_I3 0x1e00
2326
2327#define T_OPCODE_ASR_R	0x4100
2328#define T_OPCODE_LSL_R	0x4080
2329#define T_OPCODE_LSR_R  0x40c0
2330#define T_OPCODE_ASR_I	0x1000
2331#define T_OPCODE_LSL_I	0x0000
2332#define T_OPCODE_LSR_I	0x0800
2333
2334#define T_OPCODE_MOV_I8	0x2000
2335#define T_OPCODE_CMP_I8 0x2800
2336#define T_OPCODE_CMP_LR 0x4280
2337#define T_OPCODE_MOV_HR 0x4600
2338#define T_OPCODE_CMP_HR 0x4500
2339
2340#define T_OPCODE_LDR_PC 0x4800
2341#define T_OPCODE_LDR_SP 0x9800
2342#define T_OPCODE_STR_SP 0x9000
2343#define T_OPCODE_LDR_IW 0x6800
2344#define T_OPCODE_STR_IW 0x6000
2345#define T_OPCODE_LDR_IH 0x8800
2346#define T_OPCODE_STR_IH 0x8000
2347#define T_OPCODE_LDR_IB 0x7800
2348#define T_OPCODE_STR_IB 0x7000
2349#define T_OPCODE_LDR_RW 0x5800
2350#define T_OPCODE_STR_RW 0x5000
2351#define T_OPCODE_LDR_RH 0x5a00
2352#define T_OPCODE_STR_RH 0x5200
2353#define T_OPCODE_LDR_RB 0x5c00
2354#define T_OPCODE_STR_RB 0x5400
2355
2356#define T_OPCODE_PUSH	0xb400
2357#define T_OPCODE_POP	0xbc00
2358
2359#define T_OPCODE_BRANCH 0xe7fe
2360
2361static int thumb_reg		PARAMS ((char ** str, int hi_lo));
2362
2363#define THUMB_SIZE	2	/* Size of thumb instruction.  */
2364#define THUMB_REG_LO	0x1
2365#define THUMB_REG_HI	0x2
2366#define THUMB_REG_ANY	0x3
2367
2368#define THUMB_H1	0x0080
2369#define THUMB_H2	0x0040
2370
2371#define THUMB_ASR 0
2372#define THUMB_LSL 1
2373#define THUMB_LSR 2
2374
2375#define THUMB_MOVE 0
2376#define THUMB_COMPARE 1
2377#define THUMB_CPY 2
2378
2379#define THUMB_LOAD 0
2380#define THUMB_STORE 1
2381
2382#define THUMB_PP_PC_LR 0x0100
2383
2384/* These three are used for immediate shifts, do not alter.  */
2385#define THUMB_WORD 2
2386#define THUMB_HALFWORD 1
2387#define THUMB_BYTE 0
2388
2389struct thumb_opcode
2390{
2391  /* Basic string to match.  */
2392  const char * template;
2393
2394  /* Basic instruction code.  */
2395  unsigned long value;
2396
2397  int size;
2398
2399  /* Which CPU variants this exists for.  */
2400  unsigned long variant;
2401
2402  /* Function to call to parse args.  */
2403  void (* parms) PARAMS ((char *));
2404};
2405
2406static const struct thumb_opcode tinsns[] =
2407{
2408  /* Thumb v1 (ARMv4T).  */
2409  {"adc",	0x4140,		2,	ARM_EXT_V4T, do_t_arit},
2410  {"add",	0x0000,		2,	ARM_EXT_V4T, do_t_add},
2411  {"and",	0x4000,		2,	ARM_EXT_V4T, do_t_arit},
2412  {"asr",	0x0000,		2,	ARM_EXT_V4T, do_t_asr},
2413  {"b",		T_OPCODE_BRANCH, 2,	ARM_EXT_V4T, do_t_branch12},
2414  {"beq",	0xd0fe,		2,	ARM_EXT_V4T, do_t_branch9},
2415  {"bne",	0xd1fe,		2,	ARM_EXT_V4T, do_t_branch9},
2416  {"bcs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
2417  {"bhs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
2418  {"bcc",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
2419  {"bul",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
2420  {"blo",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
2421  {"bmi",	0xd4fe,		2,	ARM_EXT_V4T, do_t_branch9},
2422  {"bpl",	0xd5fe,		2,	ARM_EXT_V4T, do_t_branch9},
2423  {"bvs",	0xd6fe,		2,	ARM_EXT_V4T, do_t_branch9},
2424  {"bvc",	0xd7fe,		2,	ARM_EXT_V4T, do_t_branch9},
2425  {"bhi",	0xd8fe,		2,	ARM_EXT_V4T, do_t_branch9},
2426  {"bls",	0xd9fe,		2,	ARM_EXT_V4T, do_t_branch9},
2427  {"bge",	0xdafe,		2,	ARM_EXT_V4T, do_t_branch9},
2428  {"blt",	0xdbfe,		2,	ARM_EXT_V4T, do_t_branch9},
2429  {"bgt",	0xdcfe,		2,	ARM_EXT_V4T, do_t_branch9},
2430  {"ble",	0xddfe,		2,	ARM_EXT_V4T, do_t_branch9},
2431  {"bal",	0xdefe,		2,	ARM_EXT_V4T, do_t_branch9},
2432  {"bic",	0x4380,		2,	ARM_EXT_V4T, do_t_arit},
2433  {"bl",	0xf7fffffe,	4,	ARM_EXT_V4T, do_t_branch23},
2434  {"bx",	0x4700,		2,	ARM_EXT_V4T, do_t_bx},
2435  {"cmn",	T_OPCODE_CMN,	2,	ARM_EXT_V4T, do_t_arit},
2436  {"cmp",	0x0000,		2,	ARM_EXT_V4T, do_t_compare},
2437  {"eor",	0x4040,		2,	ARM_EXT_V4T, do_t_arit},
2438  {"ldmia",	0xc800,		2,	ARM_EXT_V4T, do_t_ldmstm},
2439  {"ldr",	0x0000,		2,	ARM_EXT_V4T, do_t_ldr},
2440  {"ldrb",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrb},
2441  {"ldrh",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrh},
2442  {"ldrsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
2443  {"ldrsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
2444  {"ldsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
2445  {"ldsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
2446  {"lsl",	0x0000,		2,	ARM_EXT_V4T, do_t_lsl},
2447  {"lsr",	0x0000,		2,	ARM_EXT_V4T, do_t_lsr},
2448  {"mov",	0x0000,		2,	ARM_EXT_V4T, do_t_mov},
2449  {"mul",	T_OPCODE_MUL,	2,	ARM_EXT_V4T, do_t_arit},
2450  {"mvn",	T_OPCODE_MVN,	2,	ARM_EXT_V4T, do_t_arit},
2451  {"neg",	T_OPCODE_NEG,	2,	ARM_EXT_V4T, do_t_arit},
2452  {"orr",	0x4300,		2,	ARM_EXT_V4T, do_t_arit},
2453  {"pop",	0xbc00,		2,	ARM_EXT_V4T, do_t_push_pop},
2454  {"push",	0xb400,		2,	ARM_EXT_V4T, do_t_push_pop},
2455  {"ror",	0x41c0,		2,	ARM_EXT_V4T, do_t_arit},
2456  {"sbc",	0x4180,		2,	ARM_EXT_V4T, do_t_arit},
2457  {"stmia",	0xc000,		2,	ARM_EXT_V4T, do_t_ldmstm},
2458  {"str",	0x0000,		2,	ARM_EXT_V4T, do_t_str},
2459  {"strb",	0x0000,		2,	ARM_EXT_V4T, do_t_strb},
2460  {"strh",	0x0000,		2,	ARM_EXT_V4T, do_t_strh},
2461  {"swi",	0xdf00,		2,	ARM_EXT_V4T, do_t_swi},
2462  {"sub",	0x0000,		2,	ARM_EXT_V4T, do_t_sub},
2463  {"tst",	T_OPCODE_TST,	2,	ARM_EXT_V4T, do_t_arit},
2464  /* Pseudo ops:  */
2465  {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
2466  {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
2467  /* Thumb v2 (ARMv5T).  */
2468  {"blx",	0,		0,	ARM_EXT_V5T, do_t_blx},
2469  {"bkpt",	0xbe00,		2,	ARM_EXT_V5T, do_t_bkpt},
2470
2471  /* ARM V6.  */
2472  {"cpsie",	0xb660,		2,	ARM_EXT_V6,  do_t_cps},
2473  {"cpsid",     0xb670,		2,	ARM_EXT_V6,  do_t_cps},
2474  {"cpy",	0x4600,		2,	ARM_EXT_V6,  do_t_cpy},
2475  {"rev",	0xba00,		2,	ARM_EXT_V6,  do_t_arit},
2476  {"rev16",	0xba40,		2,	ARM_EXT_V6,  do_t_arit},
2477  {"revsh",	0xbac0,		2,	ARM_EXT_V6,  do_t_arit},
2478  {"setend",	0xb650,		2,	ARM_EXT_V6,  do_t_setend},
2479  {"sxth",	0xb200,		2,	ARM_EXT_V6,  do_t_arit},
2480  {"sxtb",	0xb240,		2,	ARM_EXT_V6,  do_t_arit},
2481  {"uxth",	0xb280,		2,	ARM_EXT_V6,  do_t_arit},
2482  {"uxtb",	0xb2c0,		2,	ARM_EXT_V6,  do_t_arit},
2483};
2484
2485#define BAD_ARGS 	_("bad arguments to instruction")
2486#define BAD_PC 		_("r15 not allowed here")
2487#define BAD_COND 	_("instruction is not conditional")
2488#define ERR_NO_ACCUM	_("acc0 expected")
2489
2490static struct hash_control * arm_ops_hsh   = NULL;
2491static struct hash_control * arm_tops_hsh  = NULL;
2492static struct hash_control * arm_cond_hsh  = NULL;
2493static struct hash_control * arm_shift_hsh = NULL;
2494static struct hash_control * arm_psr_hsh   = NULL;
2495
2496/* This table describes all the machine specific pseudo-ops the assembler
2497   has to support.  The fields are:
2498     pseudo-op name without dot
2499     function to call to execute this pseudo-op
2500     Integer arg to pass to the function.  */
2501
2502static void s_req PARAMS ((int));
2503static void s_unreq PARAMS ((int));
2504static void s_align PARAMS ((int));
2505static void s_bss PARAMS ((int));
2506static void s_even PARAMS ((int));
2507static void s_ltorg PARAMS ((int));
2508static void s_arm PARAMS ((int));
2509static void s_thumb PARAMS ((int));
2510static void s_code PARAMS ((int));
2511static void s_force_thumb PARAMS ((int));
2512static void s_thumb_func PARAMS ((int));
2513static void s_thumb_set PARAMS ((int));
2514#ifdef OBJ_ELF
2515static void s_arm_elf_cons PARAMS ((int));
2516#endif
2517
2518static int my_get_expression PARAMS ((expressionS *, char **));
2519
2520const pseudo_typeS md_pseudo_table[] =
2521{
2522  /* Never called because '.req' does not start a line.  */
2523  { "req",         s_req,         0 },
2524  { "unreq",       s_unreq,       0 },
2525  { "bss",         s_bss,         0 },
2526  { "align",       s_align,       0 },
2527  { "arm",         s_arm,         0 },
2528  { "thumb",       s_thumb,       0 },
2529  { "code",        s_code,        0 },
2530  { "force_thumb", s_force_thumb, 0 },
2531  { "thumb_func",  s_thumb_func,  0 },
2532  { "thumb_set",   s_thumb_set,   0 },
2533  { "even",        s_even,        0 },
2534  { "ltorg",       s_ltorg,       0 },
2535  { "pool",        s_ltorg,       0 },
2536#ifdef OBJ_ELF
2537  { "word",        s_arm_elf_cons, 4 },
2538  { "long",        s_arm_elf_cons, 4 },
2539#else
2540  { "word",        cons, 4},
2541#endif
2542  { "extend",      float_cons, 'x' },
2543  { "ldouble",     float_cons, 'x' },
2544  { "packed",      float_cons, 'p' },
2545  { 0, 0, 0 }
2546};
2547
2548/* Other internal functions.  */
2549static int arm_parse_extension PARAMS ((char *, int *));
2550static int arm_parse_cpu PARAMS ((char *));
2551static int arm_parse_arch PARAMS ((char *));
2552static int arm_parse_fpu PARAMS ((char *));
2553static int arm_parse_float_abi PARAMS ((char *));
2554#if 0 /* Suppressed - for now.  */
2555#if defined OBJ_COFF || defined OBJ_ELF
2556static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2557#endif
2558#endif
2559
2560/* Stuff needed to resolve the label ambiguity
2561   As:
2562     ...
2563     label:   <insn>
2564   may differ from:
2565     ...
2566     label:
2567              <insn>
2568*/
2569
2570symbolS *  last_label_seen;
2571static int label_is_thumb_function_name = FALSE;
2572
2573/* Literal Pool stuff.  */
2574
2575#define MAX_LITERAL_POOL_SIZE 1024
2576
2577/* Literal pool structure.  Held on a per-section
2578   and per-sub-section basis.  */
2579typedef struct literal_pool
2580{
2581  expressionS    literals [MAX_LITERAL_POOL_SIZE];
2582  unsigned int   next_free_entry;
2583  unsigned int   id;
2584  symbolS *      symbol;
2585  segT           section;
2586  subsegT        sub_section;
2587  struct literal_pool * next;
2588} literal_pool;
2589
2590/* Pointer to a linked list of literal pools.  */
2591literal_pool * list_of_pools = NULL;
2592
2593static literal_pool * find_literal_pool PARAMS ((void));
2594static literal_pool * find_or_make_literal_pool PARAMS ((void));
2595
2596static literal_pool *
2597find_literal_pool ()
2598{
2599  literal_pool * pool;
2600
2601  for (pool = list_of_pools; pool != NULL; pool = pool->next)
2602    {
2603      if (pool->section == now_seg
2604	  && pool->sub_section == now_subseg)
2605	break;
2606    }
2607
2608  return pool;
2609}
2610
2611static literal_pool *
2612find_or_make_literal_pool ()
2613{
2614  /* Next literal pool ID number.  */
2615  static unsigned int latest_pool_num = 1;
2616  literal_pool *      pool;
2617
2618  pool = find_literal_pool ();
2619
2620  if (pool == NULL)
2621    {
2622      /* Create a new pool.  */
2623      pool = (literal_pool *) xmalloc (sizeof (* pool));
2624      if (! pool)
2625	return NULL;
2626
2627      pool->next_free_entry = 0;
2628      pool->section         = now_seg;
2629      pool->sub_section     = now_subseg;
2630      pool->next            = list_of_pools;
2631      pool->symbol          = NULL;
2632
2633      /* Add it to the list.  */
2634      list_of_pools = pool;
2635    }
2636
2637  /* New pools, and emptied pools, will have a NULL symbol.  */
2638  if (pool->symbol == NULL)
2639    {
2640      pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2641				    (valueT) 0, &zero_address_frag);
2642      pool->id = latest_pool_num ++;
2643    }
2644
2645  /* Done.  */
2646  return pool;
2647}
2648
2649/* Add the literal in the global 'inst'
2650   structure to the relevent literal pool.  */
2651static int
2652add_to_lit_pool ()
2653{
2654  literal_pool * pool;
2655  unsigned int entry;
2656
2657  pool = find_or_make_literal_pool ();
2658
2659  /* Check if this literal value is already in the pool.  */
2660  for (entry = 0; entry < pool->next_free_entry; entry ++)
2661    {
2662      if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2663	  && (inst.reloc.exp.X_op == O_constant)
2664	  && (pool->literals[entry].X_add_number
2665	      == inst.reloc.exp.X_add_number)
2666	  && (pool->literals[entry].X_unsigned
2667	      == inst.reloc.exp.X_unsigned))
2668	break;
2669
2670      if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2671          && (inst.reloc.exp.X_op == O_symbol)
2672          && (pool->literals[entry].X_add_number
2673	      == inst.reloc.exp.X_add_number)
2674          && (pool->literals[entry].X_add_symbol
2675	      == inst.reloc.exp.X_add_symbol)
2676          && (pool->literals[entry].X_op_symbol
2677	      == inst.reloc.exp.X_op_symbol))
2678        break;
2679    }
2680
2681  /* Do we need to create a new entry?  */
2682  if (entry == pool->next_free_entry)
2683    {
2684      if (entry >= MAX_LITERAL_POOL_SIZE)
2685	{
2686	  inst.error = _("literal pool overflow");
2687	  return FAIL;
2688	}
2689
2690      pool->literals[entry] = inst.reloc.exp;
2691      pool->next_free_entry += 1;
2692    }
2693
2694  inst.reloc.exp.X_op         = O_symbol;
2695  inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2696  inst.reloc.exp.X_add_symbol = pool->symbol;
2697
2698  return SUCCESS;
2699}
2700
2701/* Can't use symbol_new here, so have to create a symbol and then at
2702   a later date assign it a value. Thats what these functions do.  */
2703
2704static void
2705symbol_locate (symbolP, name, segment, valu, frag)
2706     symbolS *    symbolP;
2707     const char * name;		/* It is copied, the caller can modify.  */
2708     segT         segment;	/* Segment identifier (SEG_<something>).  */
2709     valueT       valu;		/* Symbol value.  */
2710     fragS *      frag;		/* Associated fragment.  */
2711{
2712  unsigned int name_length;
2713  char * preserved_copy_of_name;
2714
2715  name_length = strlen (name) + 1;   /* +1 for \0.  */
2716  obstack_grow (&notes, name, name_length);
2717  preserved_copy_of_name = obstack_finish (&notes);
2718#ifdef STRIP_UNDERSCORE
2719  if (preserved_copy_of_name[0] == '_')
2720    preserved_copy_of_name++;
2721#endif
2722
2723#ifdef tc_canonicalize_symbol_name
2724  preserved_copy_of_name =
2725    tc_canonicalize_symbol_name (preserved_copy_of_name);
2726#endif
2727
2728  S_SET_NAME (symbolP, preserved_copy_of_name);
2729
2730  S_SET_SEGMENT (symbolP, segment);
2731  S_SET_VALUE (symbolP, valu);
2732  symbol_clear_list_pointers (symbolP);
2733
2734  symbol_set_frag (symbolP, frag);
2735
2736  /* Link to end of symbol chain.  */
2737  {
2738    extern int symbol_table_frozen;
2739    if (symbol_table_frozen)
2740      abort ();
2741  }
2742
2743  symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2744
2745  obj_symbol_new_hook (symbolP);
2746
2747#ifdef tc_symbol_new_hook
2748  tc_symbol_new_hook (symbolP);
2749#endif
2750
2751#ifdef DEBUG_SYMS
2752  verify_symbol_chain (symbol_rootP, symbol_lastP);
2753#endif /* DEBUG_SYMS  */
2754}
2755
2756/* Check that an immediate is valid.
2757   If so, convert it to the right format.  */
2758
2759static unsigned int
2760validate_immediate (val)
2761     unsigned int val;
2762{
2763  unsigned int a;
2764  unsigned int i;
2765
2766#define rotate_left(v, n) (v << n | v >> (32 - n))
2767
2768  for (i = 0; i < 32; i += 2)
2769    if ((a = rotate_left (val, i)) <= 0xff)
2770      return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
2771
2772  return FAIL;
2773}
2774
2775/* Check to see if an immediate can be computed as two separate immediate
2776   values, added together.  We already know that this value cannot be
2777   computed by just one ARM instruction.  */
2778
2779static unsigned int
2780validate_immediate_twopart (val, highpart)
2781     unsigned int   val;
2782     unsigned int * highpart;
2783{
2784  unsigned int a;
2785  unsigned int i;
2786
2787  for (i = 0; i < 32; i += 2)
2788    if (((a = rotate_left (val, i)) & 0xff) != 0)
2789      {
2790	if (a & 0xff00)
2791	  {
2792	    if (a & ~ 0xffff)
2793	      continue;
2794	    * highpart = (a  >> 8) | ((i + 24) << 7);
2795	  }
2796	else if (a & 0xff0000)
2797	  {
2798	    if (a & 0xff000000)
2799	      continue;
2800	    * highpart = (a >> 16) | ((i + 16) << 7);
2801	  }
2802	else
2803	  {
2804	    assert (a & 0xff000000);
2805	    * highpart = (a >> 24) | ((i + 8) << 7);
2806	  }
2807
2808	return (a & 0xff) | (i << 7);
2809      }
2810
2811  return FAIL;
2812}
2813
2814static int
2815validate_offset_imm (val, hwse)
2816     unsigned int val;
2817     int hwse;
2818{
2819  if ((hwse && val > 255) || val > 4095)
2820    return FAIL;
2821  return val;
2822}
2823
2824
2825#ifdef OBJ_ELF
2826/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2827   (This text is taken from version B-02 of the spec):
2828
2829      4.4.7 Mapping and tagging symbols
2830
2831      A section of an ARM ELF file can contain a mixture of ARM code,
2832      Thumb code, and data.  There are inline transitions between code
2833      and data at literal pool boundaries. There can also be inline
2834      transitions between ARM code and Thumb code, for example in
2835      ARM-Thumb inter-working veneers.  Linkers, machine-level
2836      debuggers, profiling tools, and disassembly tools need to map
2837      images accurately. For example, setting an ARM breakpoint on a
2838      Thumb location, or in a literal pool, can crash the program
2839      being debugged, ruining the debugging session.
2840
2841      ARM ELF entities are mapped (see section 4.4.7.1 below) and
2842      tagged (see section 4.4.7.2 below) using local symbols (with
2843      binding STB_LOCAL).  To assist consumers, mapping and tagging
2844      symbols should be collated first in the symbol table, before
2845      other symbols with binding STB_LOCAL.
2846
2847      To allow properly collated mapping and tagging symbols to be
2848      skipped by consumers that have no interest in them, the first
2849      such symbol should have the name $m and its st_value field equal
2850      to the total number of mapping and tagging symbols (including
2851      the $m) in the symbol table.
2852
2853      4.4.7.1 Mapping symbols
2854
2855      $a    Labels the first byte of a sequence of ARM instructions.
2856            Its type is STT_FUNC.
2857
2858      $d    Labels the first byte of a sequence of data items.
2859            Its type is STT_OBJECT.
2860
2861      $t    Labels the first byte of a sequence of Thumb instructions.
2862            Its type is STT_FUNC.
2863
2864      This list of mapping symbols may be extended in the future.
2865
2866      Section-relative mapping symbols
2867
2868      Mapping symbols defined in a section define a sequence of
2869      half-open address intervals that cover the address range of the
2870      section. Each interval starts at the address defined by a
2871      mapping symbol, and continues up to, but not including, the
2872      address defined by the next (in address order) mapping symbol or
2873      the end of the section. A corollary is that there must be a
2874      mapping symbol defined at the beginning of each section.
2875      Consumers can ignore the size of a section-relative mapping
2876      symbol. Producers can set it to 0.
2877
2878      Absolute mapping symbols
2879
2880      Because of the need to crystallize a Thumb address with the
2881      Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2882      STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2883      or $t.
2884
2885      The extent of a mapping symbol defined in SHN_ABS is [st_value,
2886      st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2887      where [x, y) denotes the half-open address range from x,
2888      inclusive, to y, exclusive.
2889
2890      In the absence of a mapping symbol, a consumer can interpret a
2891      function symbol with an odd value as the Thumb code address
2892      obtained by clearing the least significant bit of the
2893      value. This interpretation is deprecated, and it may not work in
2894      the future.
2895
2896   Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2897   the EABI (which is still under development), so they are not
2898   implemented here.  */
2899
2900static enum mstate mapstate = MAP_UNDEFINED;
2901
2902static void
2903mapping_state (enum mstate state)
2904{
2905  symbolS * symbolP;
2906  const char * symname;
2907  int type;
2908
2909  if (mapstate == state)
2910    /* The mapping symbol has already been emitted.
2911       There is nothing else to do.  */
2912    return;
2913
2914  mapstate = state;
2915
2916  switch (state)
2917    {
2918    case MAP_DATA:
2919      symname = "$d";
2920      type = BSF_OBJECT;
2921      break;
2922    case MAP_ARM:
2923      symname = "$a";
2924      type = BSF_FUNCTION;
2925      break;
2926    case MAP_THUMB:
2927      symname = "$t";
2928      type = BSF_FUNCTION;
2929      break;
2930    case MAP_UNDEFINED:
2931      return;
2932    default:
2933      abort ();
2934    }
2935
2936  seg_info (now_seg)->tc_segment_info_data = state;
2937
2938  symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2939  symbol_table_insert (symbolP);
2940  symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2941
2942  switch (state)
2943    {
2944    case MAP_ARM:
2945      THUMB_SET_FUNC (symbolP, 0);
2946      ARM_SET_THUMB (symbolP, 0);
2947      ARM_SET_INTERWORK (symbolP, support_interwork);
2948      break;
2949
2950    case MAP_THUMB:
2951      THUMB_SET_FUNC (symbolP, 1);
2952      ARM_SET_THUMB (symbolP, 1);
2953      ARM_SET_INTERWORK (symbolP, support_interwork);
2954      break;
2955
2956    case MAP_DATA:
2957    default:
2958      return;
2959    }
2960}
2961
2962/* When we change sections we need to issue a new mapping symbol.  */
2963
2964void
2965arm_elf_change_section (void)
2966{
2967  flagword flags;
2968
2969  if (!SEG_NORMAL (now_seg))
2970    return;
2971
2972  flags = bfd_get_section_flags (stdoutput, now_seg);
2973
2974  /* We can ignore sections that only contain debug info.  */
2975  if ((flags & SEC_ALLOC) == 0)
2976    return;
2977
2978  mapstate = seg_info (now_seg)->tc_segment_info_data;
2979}
2980#else
2981#define mapping_state(a)
2982#endif /* OBJ_ELF */
2983
2984
2985static void
2986s_req (a)
2987     int a ATTRIBUTE_UNUSED;
2988{
2989  as_bad (_("invalid syntax for .req directive"));
2990}
2991
2992/* The .unreq directive deletes an alias which was previously defined
2993   by .req.  For example:
2994
2995       my_alias .req r11
2996       .unreq my_alias    */
2997
2998static void
2999s_unreq (int a ATTRIBUTE_UNUSED)
3000{
3001  char *name;
3002  char saved_char;
3003
3004  skip_whitespace (input_line_pointer);
3005  name = input_line_pointer;
3006
3007  while (*input_line_pointer != 0
3008	 && *input_line_pointer != ' '
3009	 && *input_line_pointer != '\n')
3010    ++input_line_pointer;
3011
3012  saved_char = *input_line_pointer;
3013  *input_line_pointer = 0;
3014
3015  if (*name)
3016    {
3017      enum arm_reg_type req_type = arm_reg_parse_any (name);
3018
3019      if (req_type != REG_TYPE_MAX)
3020	{
3021	  char *temp_name = name;
3022	  int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3023
3024	  if (req_no != FAIL)
3025	    {
3026	      struct reg_entry *req_entry;
3027
3028	      /* Check to see if this alias is a builtin one.  */
3029	      req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3030
3031	      if (!req_entry)
3032		as_bad (_("unreq: missing hash entry for \"%s\""), name);
3033	      else if (req_entry->builtin)
3034		/* FIXME: We are deleting a built in register alias which
3035		   points to a const data structure, so we only need to
3036		   free up the memory used by the key in the hash table.
3037		   Unfortunately we have not recorded this value, so this
3038		   is a memory leak.  */
3039		  /* FIXME: Should we issue a warning message ?  */
3040		;
3041	      else
3042		{
3043		  /* Deleting a user defined alias.  We need to free the
3044		     key and the value, but fortunately the key is the same
3045		     as the value->name field.  */
3046		  free ((char *) req_entry->name);
3047		  free (req_entry);
3048		}
3049	    }
3050          else
3051            as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3052	}
3053      else
3054        as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3055    }
3056  else
3057    as_bad (_("invalid syntax for .unreq directive"));
3058
3059  *input_line_pointer = saved_char;
3060  demand_empty_rest_of_line ();
3061}
3062
3063static void
3064s_bss (ignore)
3065     int ignore ATTRIBUTE_UNUSED;
3066{
3067  /* We don't support putting frags in the BSS segment, we fake it by
3068     marking in_bss, then looking at s_skip for clues.  */
3069  subseg_set (bss_section, 0);
3070  demand_empty_rest_of_line ();
3071  mapping_state (MAP_DATA);
3072}
3073
3074static void
3075s_even (ignore)
3076     int ignore ATTRIBUTE_UNUSED;
3077{
3078  /* Never make frag if expect extra pass.  */
3079  if (!need_pass_2)
3080    frag_align (1, 0, 0);
3081
3082  record_alignment (now_seg, 1);
3083
3084  demand_empty_rest_of_line ();
3085}
3086
3087static void
3088s_ltorg (ignored)
3089     int ignored ATTRIBUTE_UNUSED;
3090{
3091  unsigned int entry;
3092  literal_pool * pool;
3093  char sym_name[20];
3094
3095  pool = find_literal_pool ();
3096  if (pool == NULL
3097      || pool->symbol == NULL
3098      || pool->next_free_entry == 0)
3099    return;
3100
3101  mapping_state (MAP_DATA);
3102
3103  /* Align pool as you have word accesses.
3104     Only make a frag if we have to.  */
3105  if (!need_pass_2)
3106    frag_align (2, 0, 0);
3107
3108  record_alignment (now_seg, 2);
3109
3110  sprintf (sym_name, "$$lit_\002%x", pool->id);
3111
3112  symbol_locate (pool->symbol, sym_name, now_seg,
3113		 (valueT) frag_now_fix (), frag_now);
3114  symbol_table_insert (pool->symbol);
3115
3116  ARM_SET_THUMB (pool->symbol, thumb_mode);
3117
3118#if defined OBJ_COFF || defined OBJ_ELF
3119  ARM_SET_INTERWORK (pool->symbol, support_interwork);
3120#endif
3121
3122  for (entry = 0; entry < pool->next_free_entry; entry ++)
3123    /* First output the expression in the instruction to the pool.  */
3124    emit_expr (&(pool->literals[entry]), 4); /* .word  */
3125
3126  /* Mark the pool as empty.  */
3127  pool->next_free_entry = 0;
3128  pool->symbol = NULL;
3129}
3130
3131/* Same as s_align_ptwo but align 0 => align 2.  */
3132
3133static void
3134s_align (unused)
3135     int unused ATTRIBUTE_UNUSED;
3136{
3137  register int temp;
3138  register long temp_fill;
3139  long max_alignment = 15;
3140
3141  temp = get_absolute_expression ();
3142  if (temp > max_alignment)
3143    as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3144  else if (temp < 0)
3145    {
3146      as_bad (_("alignment negative. 0 assumed."));
3147      temp = 0;
3148    }
3149
3150  if (*input_line_pointer == ',')
3151    {
3152      input_line_pointer++;
3153      temp_fill = get_absolute_expression ();
3154    }
3155  else
3156    temp_fill = 0;
3157
3158  if (!temp)
3159    temp = 2;
3160
3161  /* Only make a frag if we HAVE to.  */
3162  if (temp && !need_pass_2)
3163    frag_align (temp, (int) temp_fill, 0);
3164  demand_empty_rest_of_line ();
3165
3166  record_alignment (now_seg, temp);
3167}
3168
3169static void
3170s_force_thumb (ignore)
3171     int ignore ATTRIBUTE_UNUSED;
3172{
3173  /* If we are not already in thumb mode go into it, EVEN if
3174     the target processor does not support thumb instructions.
3175     This is used by gcc/config/arm/lib1funcs.asm for example
3176     to compile interworking support functions even if the
3177     target processor should not support interworking.  */
3178  if (! thumb_mode)
3179    {
3180      thumb_mode = 2;
3181
3182      record_alignment (now_seg, 1);
3183    }
3184
3185  demand_empty_rest_of_line ();
3186}
3187
3188static void
3189s_thumb_func (ignore)
3190     int ignore ATTRIBUTE_UNUSED;
3191{
3192  if (! thumb_mode)
3193    opcode_select (16);
3194
3195  /* The following label is the name/address of the start of a Thumb function.
3196     We need to know this for the interworking support.  */
3197  label_is_thumb_function_name = TRUE;
3198
3199  demand_empty_rest_of_line ();
3200}
3201
3202/* Perform a .set directive, but also mark the alias as
3203   being a thumb function.  */
3204
3205static void
3206s_thumb_set (equiv)
3207     int equiv;
3208{
3209  /* XXX the following is a duplicate of the code for s_set() in read.c
3210     We cannot just call that code as we need to get at the symbol that
3211     is created.  */
3212  register char *    name;
3213  register char      delim;
3214  register char *    end_name;
3215  register symbolS * symbolP;
3216
3217  /* Especial apologies for the random logic:
3218     This just grew, and could be parsed much more simply!
3219     Dean - in haste.  */
3220  name      = input_line_pointer;
3221  delim     = get_symbol_end ();
3222  end_name  = input_line_pointer;
3223  *end_name = delim;
3224
3225  SKIP_WHITESPACE ();
3226
3227  if (*input_line_pointer != ',')
3228    {
3229      *end_name = 0;
3230      as_bad (_("expected comma after name \"%s\""), name);
3231      *end_name = delim;
3232      ignore_rest_of_line ();
3233      return;
3234    }
3235
3236  input_line_pointer++;
3237  *end_name = 0;
3238
3239  if (name[0] == '.' && name[1] == '\0')
3240    {
3241      /* XXX - this should not happen to .thumb_set.  */
3242      abort ();
3243    }
3244
3245  if ((symbolP = symbol_find (name)) == NULL
3246      && (symbolP = md_undefined_symbol (name)) == NULL)
3247    {
3248#ifndef NO_LISTING
3249      /* When doing symbol listings, play games with dummy fragments living
3250	 outside the normal fragment chain to record the file and line info
3251         for this symbol.  */
3252      if (listing & LISTING_SYMBOLS)
3253	{
3254	  extern struct list_info_struct * listing_tail;
3255	  fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3256
3257	  memset (dummy_frag, 0, sizeof (fragS));
3258	  dummy_frag->fr_type = rs_fill;
3259	  dummy_frag->line = listing_tail;
3260	  symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3261	  dummy_frag->fr_symbol = symbolP;
3262	}
3263      else
3264#endif
3265	symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3266
3267#ifdef OBJ_COFF
3268      /* "set" symbols are local unless otherwise specified.  */
3269      SF_SET_LOCAL (symbolP);
3270#endif /* OBJ_COFF  */
3271    }				/* Make a new symbol.  */
3272
3273  symbol_table_insert (symbolP);
3274
3275  * end_name = delim;
3276
3277  if (equiv
3278      && S_IS_DEFINED (symbolP)
3279      && S_GET_SEGMENT (symbolP) != reg_section)
3280    as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3281
3282  pseudo_set (symbolP);
3283
3284  demand_empty_rest_of_line ();
3285
3286  /* XXX Now we come to the Thumb specific bit of code.  */
3287
3288  THUMB_SET_FUNC (symbolP, 1);
3289  ARM_SET_THUMB (symbolP, 1);
3290#if defined OBJ_ELF || defined OBJ_COFF
3291  ARM_SET_INTERWORK (symbolP, support_interwork);
3292#endif
3293}
3294
3295static void
3296opcode_select (width)
3297     int width;
3298{
3299  switch (width)
3300    {
3301    case 16:
3302      if (! thumb_mode)
3303	{
3304	  if (! (cpu_variant & ARM_EXT_V4T))
3305	    as_bad (_("selected processor does not support THUMB opcodes"));
3306
3307	  thumb_mode = 1;
3308	  /* No need to force the alignment, since we will have been
3309             coming from ARM mode, which is word-aligned.  */
3310	  record_alignment (now_seg, 1);
3311	}
3312      mapping_state (MAP_THUMB);
3313      break;
3314
3315    case 32:
3316      if (thumb_mode)
3317	{
3318	  if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3319	    as_bad (_("selected processor does not support ARM opcodes"));
3320
3321	  thumb_mode = 0;
3322
3323	  if (!need_pass_2)
3324	    frag_align (2, 0, 0);
3325
3326	  record_alignment (now_seg, 1);
3327	}
3328      mapping_state (MAP_ARM);
3329      break;
3330
3331    default:
3332      as_bad (_("invalid instruction size selected (%d)"), width);
3333    }
3334}
3335
3336static void
3337s_arm (ignore)
3338     int ignore ATTRIBUTE_UNUSED;
3339{
3340  opcode_select (32);
3341  demand_empty_rest_of_line ();
3342}
3343
3344static void
3345s_thumb (ignore)
3346     int ignore ATTRIBUTE_UNUSED;
3347{
3348  opcode_select (16);
3349  demand_empty_rest_of_line ();
3350}
3351
3352static void
3353s_code (unused)
3354     int unused ATTRIBUTE_UNUSED;
3355{
3356  register int temp;
3357
3358  temp = get_absolute_expression ();
3359  switch (temp)
3360    {
3361    case 16:
3362    case 32:
3363      opcode_select (temp);
3364      break;
3365
3366    default:
3367      as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3368    }
3369}
3370
3371static void
3372end_of_line (str)
3373     char *str;
3374{
3375  skip_whitespace (str);
3376
3377  if (*str != '\0' && !inst.error)
3378    inst.error = _("garbage following instruction");
3379}
3380
3381static int
3382skip_past_comma (str)
3383     char ** str;
3384{
3385  char * p = * str, c;
3386  int comma = 0;
3387
3388  while ((c = *p) == ' ' || c == ',')
3389    {
3390      p++;
3391      if (c == ',' && comma++)
3392	return FAIL;
3393    }
3394
3395  if (c == '\0')
3396    return FAIL;
3397
3398  *str = p;
3399  return comma ? SUCCESS : FAIL;
3400}
3401
3402/* A standard register must be given at this point.
3403   SHIFT is the place to put it in inst.instruction.
3404   Restores input start point on error.
3405   Returns the reg#, or FAIL.  */
3406
3407static int
3408reg_required_here (str, shift)
3409     char ** str;
3410     int     shift;
3411{
3412  static char buff [128]; /* XXX  */
3413  int         reg;
3414  char *      start = * str;
3415
3416  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3417    {
3418      if (shift >= 0)
3419	inst.instruction |= reg << shift;
3420      return reg;
3421    }
3422
3423  /* Restore the start point, we may have got a reg of the wrong class.  */
3424  *str = start;
3425
3426  /* In the few cases where we might be able to accept something else
3427     this error can be overridden.  */
3428  sprintf (buff, _("register expected, not '%.100s'"), start);
3429  inst.error = buff;
3430
3431  return FAIL;
3432}
3433
3434/* A Intel Wireless MMX technology register
3435   must be given at this point.
3436   Shift is the place to put it in inst.instruction.
3437   Restores input start point on err.
3438   Returns the reg#, or FAIL.  */
3439
3440static int
3441wreg_required_here (str, shift, reg_type)
3442     char ** str;
3443     int     shift;
3444     enum wreg_type reg_type;
3445{
3446  static char buff [128];
3447  int    reg;
3448  char * start = *str;
3449
3450  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3451    {
3452      if (wr_register (reg)
3453	  && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3454        {
3455          if (shift >= 0)
3456            inst.instruction |= (reg ^ WR_PREFIX) << shift;
3457          return reg;
3458        }
3459      else if (wc_register (reg)
3460	       && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3461        {
3462          if (shift >= 0)
3463            inst.instruction |= (reg ^ WC_PREFIX) << shift;
3464          return reg;
3465        }
3466      else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3467        {
3468          if (shift >= 0)
3469            inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3470          return reg;
3471        }
3472    }
3473
3474  /* Restore the start point, we may have got a reg of the wrong class.  */
3475  *str = start;
3476
3477  /* In the few cases where we might be able to accept
3478     something else this error can be overridden.  */
3479  sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3480  inst.error = buff;
3481
3482  return FAIL;
3483}
3484
3485static const struct asm_psr *
3486arm_psr_parse (ccp)
3487     register char ** ccp;
3488{
3489  char * start = * ccp;
3490  char   c;
3491  char * p;
3492  const struct asm_psr * psr;
3493
3494  p = start;
3495
3496  /* Skip to the end of the next word in the input stream.  */
3497  do
3498    {
3499      c = *p++;
3500    }
3501  while (ISALPHA (c) || c == '_');
3502
3503  /* Terminate the word.  */
3504  *--p = 0;
3505
3506  /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
3507     feature for ease of use and backwards compatibility.  */
3508  if (!strncmp (start, "cpsr", 4))
3509    strncpy (start, "CPSR", 4);
3510  else if (!strncmp (start, "spsr", 4))
3511    strncpy (start, "SPSR", 4);
3512
3513  /* Now locate the word in the psr hash table.  */
3514  psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3515
3516  /* Restore the input stream.  */
3517  *p = c;
3518
3519  /* If we found a valid match, advance the
3520     stream pointer past the end of the word.  */
3521  *ccp = p;
3522
3523  return psr;
3524}
3525
3526/* Parse the input looking for a PSR flag.  */
3527
3528static int
3529psr_required_here (str)
3530     char ** str;
3531{
3532  char * start = * str;
3533  const struct asm_psr * psr;
3534
3535  psr = arm_psr_parse (str);
3536
3537  if (psr)
3538    {
3539      /* If this is the SPSR that is being modified, set the R bit.  */
3540      if (! psr->cpsr)
3541	inst.instruction |= SPSR_BIT;
3542
3543      /* Set the psr flags in the MSR instruction.  */
3544      inst.instruction |= psr->field << PSR_SHIFT;
3545
3546      return SUCCESS;
3547    }
3548
3549  /* In the few cases where we might be able to accept
3550     something else this error can be overridden.  */
3551  inst.error = _("flag for {c}psr instruction expected");
3552
3553  /* Restore the start point.  */
3554  *str = start;
3555  return FAIL;
3556}
3557
3558static int
3559co_proc_number (str)
3560     char **str;
3561{
3562  int processor, pchar;
3563  char *start;
3564
3565  skip_whitespace (*str);
3566  start = *str;
3567
3568  /* The data sheet seems to imply that just a number on its own is valid
3569     here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
3570     accept either.  */
3571  if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3572      == FAIL)
3573    {
3574      *str = start;
3575
3576      pchar = *(*str)++;
3577      if (pchar >= '0' && pchar <= '9')
3578	{
3579	  processor = pchar - '0';
3580	  if (**str >= '0' && **str <= '9')
3581	    {
3582	      processor = processor * 10 + *(*str)++ - '0';
3583	      if (processor > 15)
3584		{
3585		  inst.error = _("illegal co-processor number");
3586		  return FAIL;
3587		}
3588	    }
3589	}
3590      else
3591	{
3592	  inst.error = _("bad or missing co-processor number");
3593	  return FAIL;
3594	}
3595    }
3596
3597  inst.instruction |= processor << 8;
3598  return SUCCESS;
3599}
3600
3601static int
3602cp_opc_expr (str, where, length)
3603     char ** str;
3604     int where;
3605     int length;
3606{
3607  expressionS expr;
3608
3609  skip_whitespace (* str);
3610
3611  memset (&expr, '\0', sizeof (expr));
3612
3613  if (my_get_expression (&expr, str))
3614    return FAIL;
3615  if (expr.X_op != O_constant)
3616    {
3617      inst.error = _("bad or missing expression");
3618      return FAIL;
3619    }
3620
3621  if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3622    {
3623      inst.error = _("immediate co-processor expression too large");
3624      return FAIL;
3625    }
3626
3627  inst.instruction |= expr.X_add_number << where;
3628  return SUCCESS;
3629}
3630
3631static int
3632cp_reg_required_here (str, where)
3633     char ** str;
3634     int     where;
3635{
3636  int    reg;
3637  char * start = *str;
3638
3639  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3640    {
3641      inst.instruction |= reg << where;
3642      return reg;
3643    }
3644
3645  /* In the few cases where we might be able to accept something else
3646     this error can be overridden.  */
3647  inst.error = _("co-processor register expected");
3648
3649  /* Restore the start point.  */
3650  *str = start;
3651  return FAIL;
3652}
3653
3654static int
3655fp_reg_required_here (str, where)
3656     char ** str;
3657     int     where;
3658{
3659  int    reg;
3660  char * start = * str;
3661
3662  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3663    {
3664      inst.instruction |= reg << where;
3665      return reg;
3666    }
3667
3668  /* In the few cases where we might be able to accept something else
3669     this error can be overridden.  */
3670  inst.error = _("floating point register expected");
3671
3672  /* Restore the start point.  */
3673  *str = start;
3674  return FAIL;
3675}
3676
3677static int
3678cp_address_offset (str)
3679     char ** str;
3680{
3681  int offset;
3682
3683  skip_whitespace (* str);
3684
3685  if (! is_immediate_prefix (**str))
3686    {
3687      inst.error = _("immediate expression expected");
3688      return FAIL;
3689    }
3690
3691  (*str)++;
3692
3693  if (my_get_expression (& inst.reloc.exp, str))
3694    return FAIL;
3695
3696  if (inst.reloc.exp.X_op == O_constant)
3697    {
3698      offset = inst.reloc.exp.X_add_number;
3699
3700      if (offset & 3)
3701	{
3702	  inst.error = _("co-processor address must be word aligned");
3703	  return FAIL;
3704	}
3705
3706      if (offset > 1023 || offset < -1023)
3707	{
3708	  inst.error = _("offset too large");
3709	  return FAIL;
3710	}
3711
3712      if (offset >= 0)
3713	inst.instruction |= INDEX_UP;
3714      else
3715	offset = -offset;
3716
3717      inst.instruction |= offset >> 2;
3718    }
3719  else
3720    inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3721
3722  return SUCCESS;
3723}
3724
3725static int
3726cp_address_required_here (str, wb_ok)
3727     char ** str;
3728     int wb_ok;
3729{
3730  char * p = * str;
3731  int    pre_inc = 0;
3732  int    write_back = 0;
3733
3734  if (*p == '[')
3735    {
3736      int reg;
3737
3738      p++;
3739      skip_whitespace (p);
3740
3741      if ((reg = reg_required_here (& p, 16)) == FAIL)
3742	return FAIL;
3743
3744      skip_whitespace (p);
3745
3746      if (*p == ']')
3747	{
3748	  p++;
3749
3750	  skip_whitespace (p);
3751
3752	  if (*p == '\0')
3753	    {
3754	      /* As an extension to the official ARM syntax we allow:
3755
3756		   [Rn]
3757
3758	         as a short hand for:
3759
3760		   [Rn,#0]  */
3761	      inst.instruction |= PRE_INDEX | INDEX_UP;
3762	      *str = p;
3763	      return SUCCESS;
3764	    }
3765
3766	  if (skip_past_comma (& p) == FAIL)
3767	    {
3768	      inst.error = _("comma expected after closing square bracket");
3769	      return FAIL;
3770	    }
3771
3772	  skip_whitespace (p);
3773
3774	  if (*p == '#')
3775	    {
3776	      if (wb_ok)
3777		{
3778		  /* [Rn], #expr  */
3779		  write_back = WRITE_BACK;
3780
3781		  if (reg == REG_PC)
3782		    {
3783		      inst.error = _("pc may not be used in post-increment");
3784		      return FAIL;
3785		    }
3786
3787		  if (cp_address_offset (& p) == FAIL)
3788		    return FAIL;
3789		}
3790	      else
3791		pre_inc = PRE_INDEX | INDEX_UP;
3792	    }
3793	  else if (*p == '{')
3794	    {
3795	      int option;
3796
3797	      /* [Rn], {<expr>}  */
3798	      p++;
3799
3800	      skip_whitespace (p);
3801
3802	      if (my_get_expression (& inst.reloc.exp, & p))
3803		return FAIL;
3804
3805	      if (inst.reloc.exp.X_op == O_constant)
3806		{
3807		  option = inst.reloc.exp.X_add_number;
3808
3809		  if (option > 255 || option < 0)
3810		    {
3811		      inst.error = _("'option' field too large");
3812		      return FAIL;
3813		    }
3814
3815		  skip_whitespace (p);
3816
3817		  if (*p != '}')
3818		    {
3819		      inst.error = _("'}' expected at end of 'option' field");
3820		      return FAIL;
3821		    }
3822		  else
3823		    {
3824		      p++;
3825		      inst.instruction |= option;
3826		      inst.instruction |= INDEX_UP;
3827		    }
3828		}
3829	      else
3830		{
3831		  inst.error = _("non-constant expressions for 'option' field not supported");
3832		  return FAIL;
3833		}
3834	    }
3835	  else
3836	    {
3837	      inst.error = _("# or { expected after comma");
3838	      return FAIL;
3839	    }
3840	}
3841      else
3842	{
3843	  /* '['Rn, #expr']'[!]  */
3844
3845	  if (skip_past_comma (& p) == FAIL)
3846	    {
3847	      inst.error = _("pre-indexed expression expected");
3848	      return FAIL;
3849	    }
3850
3851	  pre_inc = PRE_INDEX;
3852
3853	  if (cp_address_offset (& p) == FAIL)
3854	    return FAIL;
3855
3856	  skip_whitespace (p);
3857
3858	  if (*p++ != ']')
3859	    {
3860	      inst.error = _("missing ]");
3861	      return FAIL;
3862	    }
3863
3864	  skip_whitespace (p);
3865
3866	  if (wb_ok && *p == '!')
3867	    {
3868	      if (reg == REG_PC)
3869		{
3870		  inst.error = _("pc may not be used with write-back");
3871		  return FAIL;
3872		}
3873
3874	      p++;
3875	      write_back = WRITE_BACK;
3876	    }
3877	}
3878    }
3879  else
3880    {
3881      if (my_get_expression (&inst.reloc.exp, &p))
3882	return FAIL;
3883
3884      inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3885      inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
3886      inst.reloc.pc_rel = 1;
3887      inst.instruction |= (REG_PC << 16);
3888      pre_inc = PRE_INDEX;
3889    }
3890
3891  inst.instruction |= write_back | pre_inc;
3892  *str = p;
3893  return SUCCESS;
3894}
3895
3896static int
3897cp_byte_address_offset (str)
3898     char ** str;
3899{
3900  int offset;
3901
3902  skip_whitespace (* str);
3903
3904  if (! is_immediate_prefix (**str))
3905    {
3906      inst.error = _("immediate expression expected");
3907      return FAIL;
3908    }
3909
3910  (*str)++;
3911
3912  if (my_get_expression (& inst.reloc.exp, str))
3913    return FAIL;
3914
3915  if (inst.reloc.exp.X_op == O_constant)
3916    {
3917      offset = inst.reloc.exp.X_add_number;
3918
3919      if (offset > 255 || offset < -255)
3920        {
3921          inst.error = _("offset too large");
3922          return FAIL;
3923        }
3924
3925      if (offset >= 0)
3926        inst.instruction |= INDEX_UP;
3927      else
3928        offset = -offset;
3929
3930      inst.instruction |= offset;
3931    }
3932  else
3933    inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3934
3935  return SUCCESS;
3936}
3937
3938static int
3939cp_byte_address_required_here (str)
3940     char ** str;
3941{
3942  char * p = * str;
3943  int    pre_inc = 0;
3944  int    write_back = 0;
3945
3946  if (*p == '[')
3947    {
3948      int reg;
3949
3950      p++;
3951      skip_whitespace (p);
3952
3953      if ((reg = reg_required_here (& p, 16)) == FAIL)
3954        return FAIL;
3955
3956      skip_whitespace (p);
3957
3958      if (*p == ']')
3959        {
3960          p++;
3961
3962          if (skip_past_comma (& p) == SUCCESS)
3963            {
3964              /* [Rn], #expr */
3965              write_back = WRITE_BACK;
3966
3967              if (reg == REG_PC)
3968                {
3969                  inst.error = _("pc may not be used in post-increment");
3970                  return FAIL;
3971                }
3972
3973              if (cp_byte_address_offset (& p) == FAIL)
3974                return FAIL;
3975            }
3976          else
3977            pre_inc = PRE_INDEX | INDEX_UP;
3978        }
3979      else
3980        {
3981          /* '['Rn, #expr']'[!] */
3982
3983          if (skip_past_comma (& p) == FAIL)
3984            {
3985              inst.error = _("pre-indexed expression expected");
3986              return FAIL;
3987            }
3988
3989          pre_inc = PRE_INDEX;
3990
3991          if (cp_byte_address_offset (& p) == FAIL)
3992            return FAIL;
3993
3994          skip_whitespace (p);
3995
3996          if (*p++ != ']')
3997            {
3998              inst.error = _("missing ]");
3999              return FAIL;
4000            }
4001
4002          skip_whitespace (p);
4003
4004          if (*p == '!')
4005            {
4006              if (reg == REG_PC)
4007                {
4008                  inst.error = _("pc may not be used with write-back");
4009                  return FAIL;
4010                }
4011
4012              p++;
4013              write_back = WRITE_BACK;
4014            }
4015        }
4016    }
4017  else
4018    {
4019      if (my_get_expression (&inst.reloc.exp, &p))
4020        return FAIL;
4021
4022      inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4023      inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust.  */
4024      inst.reloc.pc_rel = 1;
4025      inst.instruction |= (REG_PC << 16);
4026      pre_inc = PRE_INDEX;
4027    }
4028
4029  inst.instruction |= write_back | pre_inc;
4030  *str = p;
4031  return SUCCESS;
4032}
4033
4034static void
4035do_empty (str)
4036     char * str;
4037{
4038  /* Do nothing really.  */
4039  end_of_line (str);
4040}
4041
4042static void
4043do_mrs (str)
4044     char *str;
4045{
4046  int skip = 0;
4047
4048  /* Only one syntax.  */
4049  skip_whitespace (str);
4050
4051  if (reg_required_here (&str, 12) == FAIL)
4052    {
4053      inst.error = BAD_ARGS;
4054      return;
4055    }
4056
4057  if (skip_past_comma (&str) == FAIL)
4058    {
4059      inst.error = _("comma expected after register name");
4060      return;
4061    }
4062
4063  skip_whitespace (str);
4064
4065  if (   strcmp (str, "CPSR") == 0
4066      || strcmp (str, "SPSR") == 0
4067	 /* Lower case versions for backwards compatibility.  */
4068      || strcmp (str, "cpsr") == 0
4069      || strcmp (str, "spsr") == 0)
4070    skip = 4;
4071
4072  /* This is for backwards compatibility with older toolchains.  */
4073  else if (   strcmp (str, "cpsr_all") == 0
4074	   || strcmp (str, "spsr_all") == 0)
4075    skip = 8;
4076  else
4077    {
4078      inst.error = _("CPSR or SPSR expected");
4079      return;
4080    }
4081
4082  if (* str == 's' || * str == 'S')
4083    inst.instruction |= SPSR_BIT;
4084  str += skip;
4085
4086  end_of_line (str);
4087}
4088
4089/* Two possible forms:
4090      "{C|S}PSR_<field>, Rm",
4091      "{C|S}PSR_f, #expression".  */
4092
4093static void
4094do_msr (str)
4095     char * str;
4096{
4097  skip_whitespace (str);
4098
4099  if (psr_required_here (& str) == FAIL)
4100    return;
4101
4102  if (skip_past_comma (& str) == FAIL)
4103    {
4104      inst.error = _("comma missing after psr flags");
4105      return;
4106    }
4107
4108  skip_whitespace (str);
4109
4110  if (reg_required_here (& str, 0) != FAIL)
4111    {
4112      inst.error = NULL;
4113      end_of_line (str);
4114      return;
4115    }
4116
4117  if (! is_immediate_prefix (* str))
4118    {
4119      inst.error =
4120	_("only a register or immediate value can follow a psr flag");
4121      return;
4122    }
4123
4124  str ++;
4125  inst.error = NULL;
4126
4127  if (my_get_expression (& inst.reloc.exp, & str))
4128    {
4129      inst.error =
4130	_("only a register or immediate value can follow a psr flag");
4131      return;
4132    }
4133
4134#if 0  /* The first edition of the ARM architecture manual stated that
4135	  writing anything other than the flags with an immediate operation
4136	  had UNPREDICTABLE effects.  This constraint was removed in the
4137	  second edition of the specification.  */
4138  if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4139      && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4140    {
4141      inst.error = _("immediate value cannot be used to set this field");
4142      return;
4143    }
4144#endif
4145
4146  inst.instruction |= INST_IMMEDIATE;
4147
4148  if (inst.reloc.exp.X_add_symbol)
4149    {
4150      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4151      inst.reloc.pc_rel = 0;
4152    }
4153  else
4154    {
4155      unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4156
4157      if (value == (unsigned) FAIL)
4158	{
4159	  inst.error = _("invalid constant");
4160	  return;
4161	}
4162
4163      inst.instruction |= value;
4164    }
4165
4166  inst.error = NULL;
4167  end_of_line (str);
4168}
4169
4170/* Long Multiply Parser
4171   UMULL RdLo, RdHi, Rm, Rs
4172   SMULL RdLo, RdHi, Rm, Rs
4173   UMLAL RdLo, RdHi, Rm, Rs
4174   SMLAL RdLo, RdHi, Rm, Rs.  */
4175
4176static void
4177do_mull (str)
4178     char * str;
4179{
4180  int rdlo, rdhi, rm, rs;
4181
4182  /* Only one format "rdlo, rdhi, rm, rs".  */
4183  skip_whitespace (str);
4184
4185  if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4186    {
4187      inst.error = BAD_ARGS;
4188      return;
4189    }
4190
4191  if (skip_past_comma (&str) == FAIL
4192      || (rdhi = reg_required_here (&str, 16)) == FAIL)
4193    {
4194      inst.error = BAD_ARGS;
4195      return;
4196    }
4197
4198  if (skip_past_comma (&str) == FAIL
4199      || (rm = reg_required_here (&str, 0)) == FAIL)
4200    {
4201      inst.error = BAD_ARGS;
4202      return;
4203    }
4204
4205  /* rdhi, rdlo and rm must all be different.  */
4206  if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4207    as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4208
4209  if (skip_past_comma (&str) == FAIL
4210      || (rs = reg_required_here (&str, 8)) == FAIL)
4211    {
4212      inst.error = BAD_ARGS;
4213      return;
4214    }
4215
4216  if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4217    {
4218      inst.error = BAD_PC;
4219      return;
4220    }
4221
4222  end_of_line (str);
4223}
4224
4225static void
4226do_mul (str)
4227     char * str;
4228{
4229  int rd, rm;
4230
4231  /* Only one format "rd, rm, rs".  */
4232  skip_whitespace (str);
4233
4234  if ((rd = reg_required_here (&str, 16)) == FAIL)
4235    {
4236      inst.error = BAD_ARGS;
4237      return;
4238    }
4239
4240  if (rd == REG_PC)
4241    {
4242      inst.error = BAD_PC;
4243      return;
4244    }
4245
4246  if (skip_past_comma (&str) == FAIL
4247      || (rm = reg_required_here (&str, 0)) == FAIL)
4248    {
4249      inst.error = BAD_ARGS;
4250      return;
4251    }
4252
4253  if (rm == REG_PC)
4254    {
4255      inst.error = BAD_PC;
4256      return;
4257    }
4258
4259  if (rm == rd)
4260    as_tsktsk (_("rd and rm should be different in mul"));
4261
4262  if (skip_past_comma (&str) == FAIL
4263      || (rm = reg_required_here (&str, 8)) == FAIL)
4264    {
4265      inst.error = BAD_ARGS;
4266      return;
4267    }
4268
4269  if (rm == REG_PC)
4270    {
4271      inst.error = BAD_PC;
4272      return;
4273    }
4274
4275  end_of_line (str);
4276}
4277
4278static void
4279do_mla (str)
4280     char * str;
4281{
4282  int rd, rm;
4283
4284  /* Only one format "rd, rm, rs, rn".  */
4285  skip_whitespace (str);
4286
4287  if ((rd = reg_required_here (&str, 16)) == FAIL)
4288    {
4289      inst.error = BAD_ARGS;
4290      return;
4291    }
4292
4293  if (rd == REG_PC)
4294    {
4295      inst.error = BAD_PC;
4296      return;
4297    }
4298
4299  if (skip_past_comma (&str) == FAIL
4300      || (rm = reg_required_here (&str, 0)) == FAIL)
4301    {
4302      inst.error = BAD_ARGS;
4303      return;
4304    }
4305
4306  if (rm == REG_PC)
4307    {
4308      inst.error = BAD_PC;
4309      return;
4310    }
4311
4312  if (rm == rd)
4313    as_tsktsk (_("rd and rm should be different in mla"));
4314
4315  if (skip_past_comma (&str) == FAIL
4316      || (rd = reg_required_here (&str, 8)) == FAIL
4317      || skip_past_comma (&str) == FAIL
4318      || (rm = reg_required_here (&str, 12)) == FAIL)
4319    {
4320      inst.error = BAD_ARGS;
4321      return;
4322    }
4323
4324  if (rd == REG_PC || rm == REG_PC)
4325    {
4326      inst.error = BAD_PC;
4327      return;
4328    }
4329
4330  end_of_line (str);
4331}
4332
4333/* Expects *str -> the characters "acc0", possibly with leading blanks.
4334   Advances *str to the next non-alphanumeric.
4335   Returns 0, or else FAIL (in which case sets inst.error).
4336
4337  (In a future XScale, there may be accumulators other than zero.
4338  At that time this routine and its callers can be upgraded to suit.)  */
4339
4340static int
4341accum0_required_here (str)
4342     char ** str;
4343{
4344  static char buff [128];	/* Note the address is taken.  Hence, static.  */
4345  char * p = * str;
4346  char   c;
4347  int result = 0;		/* The accum number.  */
4348
4349  skip_whitespace (p);
4350
4351  *str = p;			/* Advance caller's string pointer too.  */
4352  c = *p++;
4353  while (ISALNUM (c))
4354    c = *p++;
4355
4356  *--p = 0;			/* Aap nul into input buffer at non-alnum.  */
4357
4358  if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4359    {
4360      sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4361      inst.error = buff;
4362      result = FAIL;
4363    }
4364
4365  *p = c;			/* Unzap.  */
4366  *str = p;			/* Caller's string pointer to after match.  */
4367  return result;
4368}
4369
4370/* Expects **str -> after a comma. May be leading blanks.
4371   Advances *str, recognizing a load  mode, and setting inst.instruction.
4372   Returns rn, or else FAIL (in which case may set inst.error
4373   and not advance str)
4374
4375   Note: doesn't know Rd, so no err checks that require such knowledge.  */
4376
4377static int
4378ld_mode_required_here (string)
4379     char ** string;
4380{
4381  char * str = * string;
4382  int    rn;
4383  int    pre_inc = 0;
4384
4385  skip_whitespace (str);
4386
4387  if (* str == '[')
4388    {
4389      str++;
4390
4391      skip_whitespace (str);
4392
4393      if ((rn = reg_required_here (& str, 16)) == FAIL)
4394	return FAIL;
4395
4396      skip_whitespace (str);
4397
4398      if (* str == ']')
4399	{
4400	  str ++;
4401
4402	  if (skip_past_comma (& str) == SUCCESS)
4403	    {
4404	      /* [Rn],... (post inc) */
4405	      if (ldst_extend_v4 (&str) == FAIL)
4406		return FAIL;
4407	    }
4408	  else 	      /* [Rn] */
4409	    {
4410	      skip_whitespace (str);
4411
4412	      if (* str == '!')
4413		{
4414		  str ++;
4415		  inst.instruction |= WRITE_BACK;
4416		}
4417
4418	      inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4419	      pre_inc = 1;
4420	    }
4421	}
4422      else	  /* [Rn,...] */
4423	{
4424	  if (skip_past_comma (& str) == FAIL)
4425	    {
4426	      inst.error = _("pre-indexed expression expected");
4427	      return FAIL;
4428	    }
4429
4430	  pre_inc = 1;
4431
4432	  if (ldst_extend_v4 (&str) == FAIL)
4433	    return FAIL;
4434
4435	  skip_whitespace (str);
4436
4437	  if (* str ++ != ']')
4438	    {
4439	      inst.error = _("missing ]");
4440	      return FAIL;
4441	    }
4442
4443	  skip_whitespace (str);
4444
4445	  if (* str == '!')
4446	    {
4447	      str ++;
4448	      inst.instruction |= WRITE_BACK;
4449	    }
4450	}
4451    }
4452  else if (* str == '=')	/* ldr's "r,=label" syntax */
4453    /* We should never reach here, because <text> = <expression> is
4454       caught gas/read.c read_a_source_file() as a .set operation.  */
4455    return FAIL;
4456  else				/* PC +- 8 bit immediate offset.  */
4457    {
4458      if (my_get_expression (& inst.reloc.exp, & str))
4459	return FAIL;
4460
4461      inst.instruction            |= HWOFFSET_IMM;	/* The I bit.  */
4462      inst.reloc.type              = BFD_RELOC_ARM_OFFSET_IMM8;
4463      inst.reloc.exp.X_add_number -= 8;  		/* PC rel adjust.  */
4464      inst.reloc.pc_rel            = 1;
4465      inst.instruction            |= (REG_PC << 16);
4466
4467      rn = REG_PC;
4468      pre_inc = 1;
4469    }
4470
4471  inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4472  * string = str;
4473
4474  return rn;
4475}
4476
4477/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4478   SMLAxy{cond} Rd,Rm,Rs,Rn
4479   SMLAWy{cond} Rd,Rm,Rs,Rn
4480   Error if any register is R15.  */
4481
4482static void
4483do_smla (str)
4484     char *        str;
4485{
4486  int rd, rm, rs, rn;
4487
4488  skip_whitespace (str);
4489
4490  if ((rd = reg_required_here (& str, 16)) == FAIL
4491      || skip_past_comma (& str) == FAIL
4492      || (rm = reg_required_here (& str, 0)) == FAIL
4493      || skip_past_comma (& str) == FAIL
4494      || (rs = reg_required_here (& str, 8)) == FAIL
4495      || skip_past_comma (& str) == FAIL
4496      || (rn = reg_required_here (& str, 12)) == FAIL)
4497    inst.error = BAD_ARGS;
4498
4499  else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4500    inst.error = BAD_PC;
4501
4502  else
4503    end_of_line (str);
4504}
4505
4506/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4507   SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4508   Error if any register is R15.
4509   Warning if Rdlo == Rdhi.  */
4510
4511static void
4512do_smlal (str)
4513     char *        str;
4514{
4515  int rdlo, rdhi, rm, rs;
4516
4517  skip_whitespace (str);
4518
4519  if ((rdlo = reg_required_here (& str, 12)) == FAIL
4520      || skip_past_comma (& str) == FAIL
4521      || (rdhi = reg_required_here (& str, 16)) == FAIL
4522      || skip_past_comma (& str) == FAIL
4523      || (rm = reg_required_here (& str, 0)) == FAIL
4524      || skip_past_comma (& str) == FAIL
4525      || (rs = reg_required_here (& str, 8)) == FAIL)
4526    {
4527      inst.error = BAD_ARGS;
4528      return;
4529    }
4530
4531  if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4532    {
4533      inst.error = BAD_PC;
4534      return;
4535    }
4536
4537  if (rdlo == rdhi)
4538    as_tsktsk (_("rdhi and rdlo must be different"));
4539
4540  end_of_line (str);
4541}
4542
4543/* ARM V5E (El Segundo) signed-multiply (argument parse)
4544   SMULxy{cond} Rd,Rm,Rs
4545   Error if any register is R15.  */
4546
4547static void
4548do_smul (str)
4549     char *        str;
4550{
4551  int rd, rm, rs;
4552
4553  skip_whitespace (str);
4554
4555  if ((rd = reg_required_here (& str, 16)) == FAIL
4556      || skip_past_comma (& str) == FAIL
4557      || (rm = reg_required_here (& str, 0)) == FAIL
4558      || skip_past_comma (& str) == FAIL
4559      || (rs = reg_required_here (& str, 8)) == FAIL)
4560    inst.error = BAD_ARGS;
4561
4562  else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4563    inst.error = BAD_PC;
4564
4565  else
4566    end_of_line (str);
4567}
4568
4569/* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4570   Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4571   Error if any register is R15.  */
4572
4573static void
4574do_qadd (str)
4575     char *        str;
4576{
4577  int rd, rm, rn;
4578
4579  skip_whitespace (str);
4580
4581  if ((rd = reg_required_here (& str, 12)) == FAIL
4582      || skip_past_comma (& str) == FAIL
4583      || (rm = reg_required_here (& str, 0)) == FAIL
4584      || skip_past_comma (& str) == FAIL
4585      || (rn = reg_required_here (& str, 16)) == FAIL)
4586    inst.error = BAD_ARGS;
4587
4588  else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4589    inst.error = BAD_PC;
4590
4591  else
4592    end_of_line (str);
4593}
4594
4595/* ARM V5E (el Segundo)
4596   MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4597   MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4598
4599   These are equivalent to the XScale instructions MAR and MRA,
4600   respectively, when coproc == 0, opcode == 0, and CRm == 0.
4601
4602   Result unpredicatable if Rd or Rn is R15.  */
4603
4604static void
4605do_co_reg2c (str)
4606     char *        str;
4607{
4608  int rd, rn;
4609
4610  skip_whitespace (str);
4611
4612  if (co_proc_number (& str) == FAIL)
4613    {
4614      if (!inst.error)
4615	inst.error = BAD_ARGS;
4616      return;
4617    }
4618
4619  if (skip_past_comma (& str) == FAIL
4620      || cp_opc_expr (& str, 4, 4) == FAIL)
4621    {
4622      if (!inst.error)
4623	inst.error = BAD_ARGS;
4624      return;
4625    }
4626
4627  if (skip_past_comma (& str) == FAIL
4628      || (rd = reg_required_here (& str, 12)) == FAIL)
4629    {
4630      if (!inst.error)
4631	inst.error = BAD_ARGS;
4632      return;
4633    }
4634
4635  if (skip_past_comma (& str) == FAIL
4636      || (rn = reg_required_here (& str, 16)) == FAIL)
4637    {
4638      if (!inst.error)
4639	inst.error = BAD_ARGS;
4640      return;
4641    }
4642
4643  /* Unpredictable result if rd or rn is R15.  */
4644  if (rd == REG_PC || rn == REG_PC)
4645    as_tsktsk
4646      (_("Warning: instruction unpredictable when using r15"));
4647
4648  if (skip_past_comma (& str) == FAIL
4649      || cp_reg_required_here (& str, 0) == FAIL)
4650    {
4651      if (!inst.error)
4652	inst.error = BAD_ARGS;
4653      return;
4654    }
4655
4656  end_of_line (str);
4657}
4658
4659/* ARM V5 count-leading-zeroes instruction (argument parse)
4660     CLZ{<cond>} <Rd>, <Rm>
4661     Condition defaults to COND_ALWAYS.
4662     Error if Rd or Rm are R15.  */
4663
4664static void
4665do_clz (str)
4666     char *        str;
4667{
4668  int rd, rm;
4669
4670  skip_whitespace (str);
4671
4672  if (((rd = reg_required_here (& str, 12)) == FAIL)
4673      || (skip_past_comma (& str) == FAIL)
4674      || ((rm = reg_required_here (& str, 0)) == FAIL))
4675    inst.error = BAD_ARGS;
4676
4677  else if (rd == REG_PC || rm == REG_PC )
4678    inst.error = BAD_PC;
4679
4680  else
4681    end_of_line (str);
4682}
4683
4684/* ARM V5 (argument parse)
4685     LDC2{L} <coproc>, <CRd>, <addressing mode>
4686     STC2{L} <coproc>, <CRd>, <addressing mode>
4687     Instruction is not conditional, and has 0xf in the condition field.
4688     Otherwise, it's the same as LDC/STC.  */
4689
4690static void
4691do_lstc2 (str)
4692     char *        str;
4693{
4694  skip_whitespace (str);
4695
4696  if (co_proc_number (& str) == FAIL)
4697    {
4698      if (!inst.error)
4699	inst.error = BAD_ARGS;
4700    }
4701  else if (skip_past_comma (& str) == FAIL
4702	   || cp_reg_required_here (& str, 12) == FAIL)
4703    {
4704      if (!inst.error)
4705	inst.error = BAD_ARGS;
4706    }
4707  else if (skip_past_comma (& str) == FAIL
4708	   || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4709    {
4710      if (! inst.error)
4711	inst.error = BAD_ARGS;
4712    }
4713  else
4714    end_of_line (str);
4715}
4716
4717/* ARM V5 (argument parse)
4718     CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4719     Instruction is not conditional, and has 0xf in the condition field.
4720     Otherwise, it's the same as CDP.  */
4721
4722static void
4723do_cdp2 (str)
4724     char *        str;
4725{
4726  skip_whitespace (str);
4727
4728  if (co_proc_number (& str) == FAIL)
4729    {
4730      if (!inst.error)
4731	inst.error = BAD_ARGS;
4732      return;
4733    }
4734
4735  if (skip_past_comma (& str) == FAIL
4736      || cp_opc_expr (& str, 20,4) == FAIL)
4737    {
4738      if (!inst.error)
4739	inst.error = BAD_ARGS;
4740      return;
4741    }
4742
4743  if (skip_past_comma (& str) == FAIL
4744      || cp_reg_required_here (& str, 12) == FAIL)
4745    {
4746      if (!inst.error)
4747	inst.error = BAD_ARGS;
4748      return;
4749    }
4750
4751  if (skip_past_comma (& str) == FAIL
4752      || cp_reg_required_here (& str, 16) == FAIL)
4753    {
4754      if (!inst.error)
4755	inst.error = BAD_ARGS;
4756      return;
4757    }
4758
4759  if (skip_past_comma (& str) == FAIL
4760      || cp_reg_required_here (& str, 0) == FAIL)
4761    {
4762      if (!inst.error)
4763	inst.error = BAD_ARGS;
4764      return;
4765    }
4766
4767  if (skip_past_comma (& str) == SUCCESS)
4768    {
4769      if (cp_opc_expr (& str, 5, 3) == FAIL)
4770	{
4771	  if (!inst.error)
4772	    inst.error = BAD_ARGS;
4773	  return;
4774	}
4775    }
4776
4777  end_of_line (str);
4778}
4779
4780/* ARM V5 (argument parse)
4781     MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4782     MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4783     Instruction is not conditional, and has 0xf in the condition field.
4784     Otherwise, it's the same as MCR/MRC.  */
4785
4786static void
4787do_co_reg2 (str)
4788     char *        str;
4789{
4790  skip_whitespace (str);
4791
4792  if (co_proc_number (& str) == FAIL)
4793    {
4794      if (!inst.error)
4795	inst.error = BAD_ARGS;
4796      return;
4797    }
4798
4799  if (skip_past_comma (& str) == FAIL
4800      || cp_opc_expr (& str, 21, 3) == FAIL)
4801    {
4802      if (!inst.error)
4803	inst.error = BAD_ARGS;
4804      return;
4805    }
4806
4807  if (skip_past_comma (& str) == FAIL
4808      || reg_required_here (& str, 12) == FAIL)
4809    {
4810      if (!inst.error)
4811	inst.error = BAD_ARGS;
4812      return;
4813    }
4814
4815  if (skip_past_comma (& str) == FAIL
4816      || cp_reg_required_here (& str, 16) == FAIL)
4817    {
4818      if (!inst.error)
4819	inst.error = BAD_ARGS;
4820      return;
4821    }
4822
4823  if (skip_past_comma (& str) == FAIL
4824      || cp_reg_required_here (& str, 0) == FAIL)
4825    {
4826      if (!inst.error)
4827	inst.error = BAD_ARGS;
4828      return;
4829    }
4830
4831  if (skip_past_comma (& str) == SUCCESS)
4832    {
4833      if (cp_opc_expr (& str, 5, 3) == FAIL)
4834	{
4835	  if (!inst.error)
4836	    inst.error = BAD_ARGS;
4837	  return;
4838	}
4839    }
4840
4841  end_of_line (str);
4842}
4843
4844/* ARM v5TEJ.  Jump to Jazelle code.  */
4845static void
4846do_bxj (str)
4847     char * str;
4848{
4849  int reg;
4850
4851  skip_whitespace (str);
4852
4853  if ((reg = reg_required_here (&str, 0)) == FAIL)
4854    {
4855      inst.error = BAD_ARGS;
4856      return;
4857    }
4858
4859  /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
4860  if (reg == REG_PC)
4861    as_tsktsk (_("use of r15 in bxj is not really useful"));
4862
4863  end_of_line (str);
4864}
4865
4866/* ARM V6 umaal (argument parse). */
4867
4868static void
4869do_umaal (str)
4870     char *str;
4871{
4872
4873  int rdlo, rdhi, rm, rs;
4874
4875  skip_whitespace (str);
4876  if ((rdlo = reg_required_here (& str, 12)) == FAIL
4877      || skip_past_comma (& str) == FAIL
4878      || (rdhi = reg_required_here (& str, 16)) == FAIL
4879      || skip_past_comma (& str) == FAIL
4880      || (rm = reg_required_here (& str, 0)) == FAIL
4881      || skip_past_comma (& str) == FAIL
4882      || (rs = reg_required_here (& str, 8)) == FAIL)
4883    {
4884      inst.error = BAD_ARGS;
4885      return;
4886    }
4887
4888  if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4889    {
4890      inst.error = BAD_PC;
4891      return;
4892    }
4893
4894  end_of_line (str);
4895}
4896
4897/* ARM V6 strex (argument parse). */
4898
4899static void
4900do_strex (str)
4901     char *str;
4902{
4903  int rd, rm, rn;
4904
4905  /* Parse Rd, Rm,. */
4906  skip_whitespace (str);
4907  if ((rd = reg_required_here (& str, 12)) == FAIL
4908      || skip_past_comma (& str) == FAIL
4909      || (rm = reg_required_here (& str, 0)) == FAIL
4910      || skip_past_comma (& str) == FAIL)
4911    {
4912      inst.error = BAD_ARGS;
4913      return;
4914    }
4915  if (rd == REG_PC || rm == REG_PC)
4916    {
4917      inst.error = BAD_PC;
4918      return;
4919    }
4920  if (rd == rm)
4921    {
4922      inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4923      return;
4924    }
4925
4926  /* Skip past '['. */
4927  if ((strlen (str) >= 1)
4928      && strncmp (str, "[", 1) == 0)
4929    str+=1;
4930  skip_whitespace (str);
4931
4932  /* Parse Rn. */
4933  if ((rn = reg_required_here (& str, 16)) == FAIL)
4934    {
4935      inst.error = BAD_ARGS;
4936      return;
4937    }
4938  else if (rn == REG_PC)
4939    {
4940      inst.error = BAD_PC;
4941      return;
4942    }
4943  if (rd == rn)
4944    {
4945      inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4946      return;
4947    }
4948  skip_whitespace (str);
4949
4950  /* Skip past ']'. */
4951  if ((strlen (str) >= 1)
4952      && strncmp (str, "]", 1) == 0)
4953    str+=1;
4954
4955  end_of_line (str);
4956}
4957
4958/* ARM V6 ssat (argument parse). */
4959
4960static void
4961do_ssat (str)
4962     char* str;
4963{
4964  do_sat (&str, /*bias=*/-1);
4965  end_of_line (str);
4966}
4967
4968/* ARM V6 usat (argument parse). */
4969
4970static void
4971do_usat (str)
4972     char* str;
4973{
4974  do_sat (&str, /*bias=*/0);
4975  end_of_line (str);
4976}
4977
4978static void
4979do_sat (str, bias)
4980     char **str;
4981     int    bias;
4982{
4983  int rd, rm;
4984  expressionS expr;
4985
4986  skip_whitespace (*str);
4987
4988  /* Parse <Rd>, field. */
4989  if ((rd = reg_required_here (str, 12)) == FAIL
4990      || skip_past_comma (str) == FAIL)
4991    {
4992      inst.error = BAD_ARGS;
4993      return;
4994    }
4995  if (rd == REG_PC)
4996    {
4997      inst.error = BAD_PC;
4998      return;
4999    }
5000
5001  /* Parse #<immed>,  field. */
5002  if (is_immediate_prefix (**str))
5003    (*str)++;
5004  else
5005    {
5006      inst.error = _("immediate expression expected");
5007      return;
5008    }
5009  if (my_get_expression (&expr, str))
5010    {
5011      inst.error = _("bad expression");
5012      return;
5013    }
5014  if (expr.X_op != O_constant)
5015    {
5016      inst.error = _("constant expression expected");
5017      return;
5018    }
5019  if (expr.X_add_number + bias < 0
5020      || expr.X_add_number + bias > 31)
5021    {
5022      inst.error = _("immediate value out of range");
5023      return;
5024    }
5025  inst.instruction |= (expr.X_add_number + bias) << 16;
5026  if (skip_past_comma (str) == FAIL)
5027    {
5028      inst.error = BAD_ARGS;
5029      return;
5030    }
5031
5032  /* Parse <Rm> field. */
5033  if ((rm = reg_required_here (str, 0)) == FAIL)
5034    {
5035      inst.error = BAD_ARGS;
5036      return;
5037    }
5038  if (rm == REG_PC)
5039    {
5040      inst.error = BAD_PC;
5041      return;
5042    }
5043
5044  if (skip_past_comma (str) == SUCCESS)
5045    decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5046}
5047
5048/* ARM V6 ssat16 (argument parse). */
5049
5050static void
5051do_ssat16 (str)
5052     char *str;
5053{
5054  do_sat16 (&str, /*bias=*/-1);
5055  end_of_line (str);
5056}
5057
5058static void
5059do_usat16 (str)
5060     char *str;
5061{
5062  do_sat16 (&str, /*bias=*/0);
5063  end_of_line (str);
5064}
5065
5066static void
5067do_sat16 (str, bias)
5068     char **str;
5069     int bias;
5070{
5071  int rd, rm;
5072  expressionS expr;
5073
5074  skip_whitespace (*str);
5075
5076  /* Parse the <Rd> field. */
5077  if ((rd = reg_required_here (str, 12)) == FAIL
5078      || skip_past_comma (str) == FAIL)
5079    {
5080      inst.error = BAD_ARGS;
5081      return;
5082    }
5083  if (rd == REG_PC)
5084    {
5085      inst.error = BAD_PC;
5086      return;
5087    }
5088
5089  /* Parse #<immed>, field. */
5090  if (is_immediate_prefix (**str))
5091    (*str)++;
5092  else
5093    {
5094      inst.error = _("immediate expression expected");
5095      return;
5096    }
5097  if (my_get_expression (&expr, str))
5098    {
5099      inst.error = _("bad expression");
5100      return;
5101    }
5102  if (expr.X_op != O_constant)
5103    {
5104      inst.error = _("constant expression expected");
5105      return;
5106    }
5107  if (expr.X_add_number + bias < 0
5108      || expr.X_add_number + bias > 15)
5109    {
5110      inst.error = _("immediate value out of range");
5111      return;
5112    }
5113  inst.instruction |= (expr.X_add_number + bias) << 16;
5114  if (skip_past_comma (str) == FAIL)
5115    {
5116      inst.error = BAD_ARGS;
5117      return;
5118    }
5119
5120  /* Parse <Rm> field. */
5121  if ((rm = reg_required_here (str, 0)) == FAIL)
5122    {
5123      inst.error = BAD_ARGS;
5124      return;
5125    }
5126  if (rm == REG_PC)
5127    {
5128      inst.error = BAD_PC;
5129      return;
5130    }
5131}
5132
5133/* ARM V6 srs (argument parse). */
5134
5135static void
5136do_srs (str)
5137     char* str;
5138{
5139  char *exclam;
5140  skip_whitespace (str);
5141  exclam = strchr (str, '!');
5142  if (exclam)
5143    *exclam = '\0';
5144  do_cps_mode (&str);
5145  if (exclam)
5146    *exclam = '!';
5147  if (*str == '!')
5148    {
5149      inst.instruction |= WRITE_BACK;
5150      str++;
5151    }
5152  end_of_line (str);
5153}
5154
5155/* ARM V6 SMMUL (argument parse). */
5156
5157static void
5158do_smmul (str)
5159     char* str;
5160{
5161  int rd, rm, rs;
5162
5163  skip_whitespace (str);
5164  if ((rd = reg_required_here (&str, 16)) == FAIL
5165      || skip_past_comma (&str) == FAIL
5166      || (rm = reg_required_here (&str, 0)) == FAIL
5167      || skip_past_comma (&str) == FAIL
5168      || (rs = reg_required_here (&str, 8)) == FAIL)
5169    {
5170      inst.error = BAD_ARGS;
5171      return;
5172    }
5173
5174  if (rd == REG_PC
5175      || rm == REG_PC
5176      || rs == REG_PC)
5177    {
5178      inst.error = BAD_PC;
5179      return;
5180    }
5181
5182  end_of_line (str);
5183
5184}
5185
5186/* ARM V6 SMLALD (argument parse). */
5187
5188static void
5189do_smlald (str)
5190    char* str;
5191{
5192  int rdlo, rdhi, rm, rs;
5193  skip_whitespace (str);
5194  if ((rdlo = reg_required_here (&str, 12)) == FAIL
5195      || skip_past_comma (&str) == FAIL
5196      || (rdhi = reg_required_here (&str, 16)) == FAIL
5197      || skip_past_comma (&str) == FAIL
5198      || (rm = reg_required_here (&str, 0)) == FAIL
5199      || skip_past_comma (&str) == FAIL
5200      || (rs = reg_required_here (&str, 8)) == FAIL)
5201    {
5202      inst.error = BAD_ARGS;
5203      return;
5204    }
5205
5206  if (rdlo == REG_PC
5207      || rdhi == REG_PC
5208      || rm == REG_PC
5209      || rs == REG_PC)
5210    {
5211      inst.error = BAD_PC;
5212      return;
5213    }
5214
5215  end_of_line (str);
5216}
5217
5218/* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
5219   smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5220
5221static void
5222do_smlad (str)
5223     char *str;
5224{
5225  int rd, rm, rs, rn;
5226
5227  skip_whitespace (str);
5228  if ((rd = reg_required_here (&str, 16)) == FAIL
5229      || skip_past_comma (&str) == FAIL
5230      || (rm = reg_required_here (&str, 0)) == FAIL
5231      || skip_past_comma (&str) == FAIL
5232      || (rs = reg_required_here (&str, 8)) == FAIL
5233      || skip_past_comma (&str) == FAIL
5234      || (rn = reg_required_here (&str, 12)) == FAIL)
5235    {
5236      inst.error = BAD_ARGS;
5237      return;
5238    }
5239
5240  if (rd == REG_PC
5241      || rn == REG_PC
5242      || rs == REG_PC
5243      || rm == REG_PC)
5244    {
5245      inst.error = BAD_PC;
5246      return;
5247    }
5248
5249  end_of_line (str);
5250}
5251
5252/* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
5253   preserving the other bits.
5254
5255   setend <endian_specifier>, where <endian_specifier> is either
5256   BE or LE. */
5257
5258static void
5259do_setend (str)
5260     char *str;
5261{
5262  if (do_endian_specifier (str))
5263    inst.instruction |= 0x200;
5264}
5265
5266/* Returns true if the endian-specifier indicates big-endianness.  */
5267
5268static int
5269do_endian_specifier (str)
5270     char *str;
5271{
5272  int big_endian = 0;
5273
5274  skip_whitespace (str);
5275  if (strlen (str) < 2)
5276    inst.error = _("missing endian specifier");
5277  else if (strncasecmp (str, "BE", 2) == 0)
5278    {
5279      str += 2;
5280      big_endian = 1;
5281    }
5282  else if (strncasecmp (str, "LE", 2) == 0)
5283    str += 2;
5284  else
5285    inst.error = _("valid endian specifiers are be or le");
5286
5287  end_of_line (str);
5288
5289  return big_endian;
5290}
5291
5292/* ARM V6 SXTH.
5293
5294   SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5295   Condition defaults to COND_ALWAYS.
5296   Error if any register uses R15. */
5297
5298static void
5299do_sxth (str)
5300     char *str;
5301{
5302  int rd, rm;
5303  expressionS expr;
5304  int rotation_clear_mask = 0xfffff3ff;
5305  int rotation_eight_mask = 0x00000400;
5306  int rotation_sixteen_mask = 0x00000800;
5307  int rotation_twenty_four_mask = 0x00000c00;
5308
5309  skip_whitespace (str);
5310  if ((rd = reg_required_here (&str, 12)) == FAIL
5311      || skip_past_comma (&str) == FAIL
5312      || (rm = reg_required_here (&str, 0)) == FAIL)
5313    {
5314      inst.error = BAD_ARGS;
5315      return;
5316    }
5317
5318  else if (rd == REG_PC || rm == REG_PC)
5319    {
5320      inst.error = BAD_PC;
5321      return;
5322    }
5323
5324  /* Zero out the rotation field. */
5325  inst.instruction &= rotation_clear_mask;
5326
5327  /* Check for lack of optional rotation field. */
5328  if (skip_past_comma (&str) == FAIL)
5329    {
5330      end_of_line (str);
5331      return;
5332    }
5333
5334  /* Move past 'ROR'. */
5335  skip_whitespace (str);
5336  if (strncasecmp (str, "ROR", 3) == 0)
5337    str+=3;
5338  else
5339    {
5340      inst.error = _("missing rotation field after comma");
5341      return;
5342    }
5343
5344  /* Get the immediate constant. */
5345  skip_whitespace (str);
5346  if (is_immediate_prefix (* str))
5347    str++;
5348  else
5349    {
5350      inst.error = _("immediate expression expected");
5351      return;
5352    }
5353
5354  if (my_get_expression (&expr, &str))
5355    {
5356      inst.error = _("bad expression");
5357      return;
5358    }
5359
5360  if (expr.X_op != O_constant)
5361    {
5362      inst.error = _("constant expression expected");
5363      return;
5364    }
5365
5366  switch (expr.X_add_number)
5367    {
5368    case 0:
5369      /* Rotation field has already been zeroed. */
5370      break;
5371    case 8:
5372      inst.instruction |= rotation_eight_mask;
5373      break;
5374
5375    case 16:
5376      inst.instruction |= rotation_sixteen_mask;
5377      break;
5378
5379    case 24:
5380      inst.instruction |= rotation_twenty_four_mask;
5381      break;
5382
5383    default:
5384      inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5385      break;
5386    }
5387
5388  end_of_line (str);
5389
5390}
5391
5392/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5393   extends it to 32-bits, and adds the result to a value in another
5394   register.  You can specify a rotation by 0, 8, 16, or 24 bits
5395   before extracting the 16-bit value.
5396   SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5397   Condition defaults to COND_ALWAYS.
5398   Error if any register uses R15. */
5399
5400static void
5401do_sxtah (str)
5402     char *str;
5403{
5404  int rd, rn, rm;
5405  expressionS expr;
5406  int rotation_clear_mask = 0xfffff3ff;
5407  int rotation_eight_mask = 0x00000400;
5408  int rotation_sixteen_mask = 0x00000800;
5409  int rotation_twenty_four_mask = 0x00000c00;
5410
5411  skip_whitespace (str);
5412  if ((rd = reg_required_here (&str, 12)) == FAIL
5413      || skip_past_comma (&str) == FAIL
5414      || (rn = reg_required_here (&str, 16)) == FAIL
5415      || skip_past_comma (&str) == FAIL
5416      || (rm = reg_required_here (&str, 0)) == FAIL)
5417    {
5418      inst.error = BAD_ARGS;
5419      return;
5420    }
5421
5422  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5423    {
5424      inst.error = BAD_PC;
5425      return;
5426    }
5427
5428  /* Zero out the rotation field. */
5429  inst.instruction &= rotation_clear_mask;
5430
5431  /* Check for lack of optional rotation field. */
5432  if (skip_past_comma (&str) == FAIL)
5433    {
5434      end_of_line (str);
5435      return;
5436    }
5437
5438  /* Move past 'ROR'. */
5439  skip_whitespace (str);
5440  if (strncasecmp (str, "ROR", 3) == 0)
5441    str+=3;
5442  else
5443    {
5444      inst.error = _("missing rotation field after comma");
5445      return;
5446    }
5447
5448  /* Get the immediate constant. */
5449  skip_whitespace (str);
5450  if (is_immediate_prefix (* str))
5451    str++;
5452  else
5453    {
5454      inst.error = _("immediate expression expected");
5455      return;
5456    }
5457
5458  if (my_get_expression (&expr, &str))
5459    {
5460      inst.error = _("bad expression");
5461      return;
5462    }
5463
5464  if (expr.X_op != O_constant)
5465    {
5466      inst.error = _("constant expression expected");
5467      return;
5468    }
5469
5470  switch (expr.X_add_number)
5471    {
5472    case 0:
5473      /* Rotation field has already been zeroed. */
5474      break;
5475
5476    case 8:
5477      inst.instruction |= rotation_eight_mask;
5478      break;
5479
5480    case 16:
5481      inst.instruction |= rotation_sixteen_mask;
5482      break;
5483
5484    case 24:
5485      inst.instruction |= rotation_twenty_four_mask;
5486      break;
5487
5488    default:
5489      inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5490      break;
5491    }
5492
5493  end_of_line (str);
5494
5495}
5496
5497
5498/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5499   word at the specified address and the following word
5500   respectively.
5501   Unconditionally executed.
5502   Error if Rn is R15.
5503*/
5504
5505static void
5506do_rfe (str)
5507     char *str;
5508{
5509  int rn;
5510
5511  skip_whitespace (str);
5512
5513  if ((rn = reg_required_here (&str, 16)) == FAIL)
5514    return;
5515
5516  if (rn == REG_PC)
5517    {
5518      inst.error = BAD_PC;
5519      return;
5520    }
5521
5522  skip_whitespace (str);
5523
5524  if (*str == '!')
5525    {
5526      inst.instruction |= WRITE_BACK;
5527      str++;
5528    }
5529  end_of_line (str);
5530}
5531
5532/* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5533   register (argument parse).
5534   REV{<cond>} Rd, Rm.
5535   Condition defaults to COND_ALWAYS.
5536   Error if Rd or Rm are R15. */
5537
5538static void
5539do_rev (str)
5540     char* str;
5541{
5542  int rd, rm;
5543
5544  skip_whitespace (str);
5545
5546  if ((rd = reg_required_here (&str, 12)) == FAIL
5547      || skip_past_comma (&str) == FAIL
5548      || (rm = reg_required_here (&str, 0)) == FAIL)
5549    inst.error = BAD_ARGS;
5550
5551  else if (rd == REG_PC || rm == REG_PC)
5552    inst.error = BAD_PC;
5553
5554  else
5555    end_of_line (str);
5556}
5557
5558/* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5559   QADD16{<cond>} <Rd>, <Rn>, <Rm>
5560   Condition defaults to COND_ALWAYS.
5561   Error if Rd, Rn or Rm are R15.  */
5562
5563static void
5564do_qadd16 (str)
5565     char* str;
5566{
5567  int rd, rm, rn;
5568
5569  skip_whitespace (str);
5570
5571  if ((rd = reg_required_here (&str, 12)) == FAIL
5572      || skip_past_comma (&str) == FAIL
5573      || (rn = reg_required_here (&str, 16)) == FAIL
5574      || skip_past_comma (&str) == FAIL
5575      || (rm = reg_required_here (&str, 0)) == FAIL)
5576    inst.error = BAD_ARGS;
5577
5578  else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5579    inst.error = BAD_PC;
5580
5581  else
5582    end_of_line (str);
5583}
5584
5585/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5586   PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
5587   Condition defaults to COND_ALWAYS.
5588   Error if Rd, Rn or Rm are R15.  */
5589
5590static void
5591do_pkhbt (str)
5592     char* str;
5593{
5594  do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5595}
5596
5597/* ARM V6 PKHTB (Argument Parse). */
5598
5599static void
5600do_pkhtb (str)
5601     char* str;
5602{
5603  do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5604}
5605
5606static void
5607do_pkh_core (str, shift)
5608     char* str;
5609     int shift;
5610{
5611  int rd, rn, rm;
5612
5613  skip_whitespace (str);
5614  if (((rd = reg_required_here (&str, 12)) == FAIL)
5615      || (skip_past_comma (&str) == FAIL)
5616      || ((rn = reg_required_here (&str, 16)) == FAIL)
5617      || (skip_past_comma (&str) == FAIL)
5618      || ((rm = reg_required_here (&str, 0)) == FAIL))
5619    {
5620      inst.error = BAD_ARGS;
5621      return;
5622    }
5623
5624  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5625    {
5626      inst.error = BAD_PC;
5627      return;
5628    }
5629
5630  /* Check for optional shift immediate constant. */
5631  if (skip_past_comma (&str) == FAIL)
5632    {
5633      if (shift == SHIFT_ASR_IMMEDIATE)
5634	{
5635	  /* If the shift specifier is ommited, turn the instruction
5636	     into pkhbt rd, rm, rn.  First, switch the instruction
5637	     code, and clear the rn and rm fields.  */
5638	  inst.instruction &= 0xfff0f010;
5639	  /* Now, re-encode the registers.  */
5640	  inst.instruction |= (rm << 16) | rn;
5641	}
5642      return;
5643    }
5644
5645  decode_shift (&str, shift);
5646}
5647
5648/* ARM V6 Load Register Exclusive instruction (argument parse).
5649   LDREX{<cond>} <Rd, [<Rn>]
5650   Condition defaults to COND_ALWAYS.
5651   Error if Rd or Rn are R15.
5652   See ARMARMv6 A4.1.27: LDREX. */
5653
5654
5655static void
5656do_ldrex (str)
5657     char * str;
5658{
5659  int rd, rn;
5660
5661  skip_whitespace (str);
5662
5663  /* Parse Rd. */
5664  if (((rd = reg_required_here (&str, 12)) == FAIL)
5665      || (skip_past_comma (&str) == FAIL))
5666    {
5667      inst.error = BAD_ARGS;
5668      return;
5669    }
5670  else if (rd == REG_PC)
5671    {
5672      inst.error = BAD_PC;
5673      return;
5674    }
5675  skip_whitespace (str);
5676
5677  /* Skip past '['. */
5678  if ((strlen (str) >= 1)
5679      &&strncmp (str, "[", 1) == 0)
5680    str+=1;
5681  skip_whitespace (str);
5682
5683  /* Parse Rn. */
5684  if ((rn = reg_required_here (&str, 16)) == FAIL)
5685    {
5686      inst.error = BAD_ARGS;
5687      return;
5688    }
5689  else if (rn == REG_PC)
5690    {
5691      inst.error = BAD_PC;
5692      return;
5693    }
5694  skip_whitespace (str);
5695
5696  /* Skip past ']'. */
5697  if ((strlen (str) >= 1)
5698      && strncmp (str, "]", 1) == 0)
5699    str+=1;
5700
5701  end_of_line (str);
5702}
5703
5704/* ARM V6 change processor state instruction (argument parse)
5705      CPS, CPSIE, CSPID . */
5706
5707static void
5708do_cps (str)
5709     char * str;
5710{
5711  do_cps_mode (&str);
5712  end_of_line (str);
5713}
5714
5715static void
5716do_cpsi (str)
5717     char * str;
5718{
5719  do_cps_flags (&str, /*thumb_p=*/0);
5720
5721  if (skip_past_comma (&str) == SUCCESS)
5722    {
5723      skip_whitespace (str);
5724      do_cps_mode (&str);
5725    }
5726  end_of_line (str);
5727}
5728
5729static void
5730do_cps_mode (str)
5731     char **str;
5732{
5733  expressionS expr;
5734
5735  skip_whitespace (*str);
5736
5737  if (! is_immediate_prefix (**str))
5738    {
5739      inst.error = _("immediate expression expected");
5740      return;
5741    }
5742
5743  (*str)++; /* Strip off the immediate signifier. */
5744  if (my_get_expression (&expr, str))
5745    {
5746      inst.error = _("bad expression");
5747      return;
5748    }
5749
5750  if (expr.X_op != O_constant)
5751    {
5752      inst.error = _("constant expression expected");
5753      return;
5754    }
5755
5756  /* The mode is a 5 bit field.  Valid values are 0-31. */
5757  if (((unsigned) expr.X_add_number) > 31
5758      || (inst.reloc.exp.X_add_number) < 0)
5759    {
5760      inst.error = _("invalid constant");
5761      return;
5762    }
5763
5764  inst.instruction |= expr.X_add_number;
5765}
5766
5767static void
5768do_cps_flags (str, thumb_p)
5769     char **str;
5770     int    thumb_p;
5771{
5772  struct cps_flag {
5773    char character;
5774    unsigned long arm_value;
5775    unsigned long thumb_value;
5776  };
5777  static struct cps_flag flag_table[] = {
5778    {'a', 0x100, 0x4 },
5779    {'i', 0x080, 0x2 },
5780    {'f', 0x040, 0x1 }
5781  };
5782
5783  int saw_a_flag = 0;
5784
5785  skip_whitespace (*str);
5786
5787  /* Get the a, f and i flags. */
5788  while (**str && **str != ',')
5789    {
5790      struct cps_flag *p;
5791      struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5792      for (p = flag_table; p < q; ++p)
5793	if (strncasecmp (*str, &p->character, 1) == 0)
5794	  {
5795	    inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5796	    saw_a_flag = 1;
5797	    break;
5798	  }
5799      if (p == q)
5800	{
5801	  inst.error = _("unrecognized flag");
5802	  return;
5803	}
5804      (*str)++;
5805    }
5806  if (!saw_a_flag)
5807    inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5808}
5809
5810/* THUMB V5 breakpoint instruction (argument parse)
5811	BKPT <immed_8>.  */
5812
5813static void
5814do_t_bkpt (str)
5815     char * str;
5816{
5817  expressionS expr;
5818  unsigned long number;
5819
5820  skip_whitespace (str);
5821
5822  /* Allow optional leading '#'.  */
5823  if (is_immediate_prefix (*str))
5824    str ++;
5825
5826  memset (& expr, '\0', sizeof (expr));
5827  if (my_get_expression (& expr, & str)
5828      || (expr.X_op != O_constant
5829	  /* As a convenience we allow 'bkpt' without an operand.  */
5830	  && expr.X_op != O_absent))
5831    {
5832      inst.error = _("bad expression");
5833      return;
5834    }
5835
5836  number = expr.X_add_number;
5837
5838  /* Check it fits an 8 bit unsigned.  */
5839  if (number != (number & 0xff))
5840    {
5841      inst.error = _("immediate value out of range");
5842      return;
5843    }
5844
5845  inst.instruction |= number;
5846
5847  end_of_line (str);
5848}
5849
5850/* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5851   Expects inst.instruction is set for BLX(1).
5852   Note: this is cloned from do_branch, and the reloc changed to be a
5853	new one that can cope with setting one extra bit (the H bit).  */
5854
5855static void
5856do_branch25 (str)
5857     char *        str;
5858{
5859  if (my_get_expression (& inst.reloc.exp, & str))
5860    return;
5861
5862#ifdef OBJ_ELF
5863  {
5864    char * save_in;
5865
5866    /* ScottB: February 5, 1998 */
5867    /* Check to see of PLT32 reloc required for the instruction.  */
5868
5869    /* arm_parse_reloc() works on input_line_pointer.
5870       We actually want to parse the operands to the branch instruction
5871       passed in 'str'.  Save the input pointer and restore it later.  */
5872    save_in = input_line_pointer;
5873    input_line_pointer = str;
5874
5875    if (inst.reloc.exp.X_op == O_symbol
5876	&& *str == '('
5877	&& arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5878      {
5879	inst.reloc.type   = BFD_RELOC_ARM_PLT32;
5880	inst.reloc.pc_rel = 0;
5881	/* Modify str to point to after parsed operands, otherwise
5882	   end_of_line() will complain about the (PLT) left in str.  */
5883	str = input_line_pointer;
5884      }
5885    else
5886      {
5887	inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5888	inst.reloc.pc_rel = 1;
5889      }
5890
5891    input_line_pointer = save_in;
5892  }
5893#else
5894  inst.reloc.type   = BFD_RELOC_ARM_PCREL_BLX;
5895  inst.reloc.pc_rel = 1;
5896#endif /* OBJ_ELF */
5897
5898  end_of_line (str);
5899}
5900
5901/* ARM V5 branch-link-exchange instruction (argument parse)
5902     BLX <target_addr>		ie BLX(1)
5903     BLX{<condition>} <Rm>	ie BLX(2)
5904   Unfortunately, there are two different opcodes for this mnemonic.
5905   So, the insns[].value is not used, and the code here zaps values
5906	into inst.instruction.
5907   Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
5908
5909static void
5910do_blx (str)
5911     char *        str;
5912{
5913  char * mystr = str;
5914  int rm;
5915
5916  skip_whitespace (mystr);
5917  rm = reg_required_here (& mystr, 0);
5918
5919  /* The above may set inst.error.  Ignore his opinion.  */
5920  inst.error = 0;
5921
5922  if (rm != FAIL)
5923    {
5924      /* Arg is a register.
5925	 Use the condition code our caller put in inst.instruction.
5926	 Pass ourselves off as a BX with a funny opcode.  */
5927      inst.instruction |= 0x012fff30;
5928      do_bx (str);
5929    }
5930  else
5931    {
5932      /* This must be is BLX <target address>, no condition allowed.  */
5933      if (inst.instruction != COND_ALWAYS)
5934	{
5935	  inst.error = BAD_COND;
5936	  return;
5937	}
5938
5939      inst.instruction = 0xfafffffe;
5940
5941      /* Process like a B/BL, but with a different reloc.
5942	 Note that B/BL expecte fffffe, not 0, offset in the opcode table.  */
5943      do_branch25 (str);
5944    }
5945}
5946
5947/* ARM V5 Thumb BLX (argument parse)
5948	BLX <target_addr>	which is BLX(1)
5949	BLX <Rm>		which is BLX(2)
5950   Unfortunately, there are two different opcodes for this mnemonic.
5951   So, the tinsns[].value is not used, and the code here zaps values
5952	into inst.instruction.	*/
5953
5954static void
5955do_t_blx (str)
5956     char * str;
5957{
5958  char * mystr = str;
5959  int rm;
5960
5961  skip_whitespace (mystr);
5962  inst.instruction = 0x4780;
5963
5964  /* Note that this call is to the ARM register recognizer.  BLX(2)
5965     uses the ARM register space, not the Thumb one, so a call to
5966     thumb_reg() would be wrong.  */
5967  rm = reg_required_here (& mystr, 3);
5968  inst.error = 0;
5969
5970  if (rm != FAIL)
5971    {
5972      /* It's BLX(2).  The .instruction was zapped with rm & is final.  */
5973      inst.size = 2;
5974    }
5975  else
5976    {
5977      /* No ARM register.  This must be BLX(1).  Change the .instruction.  */
5978      inst.instruction = 0xf7ffeffe;
5979      inst.size = 4;
5980
5981      if (my_get_expression (& inst.reloc.exp, & mystr))
5982	return;
5983
5984      inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
5985      inst.reloc.pc_rel = 1;
5986    }
5987
5988  end_of_line (mystr);
5989}
5990
5991/* ARM V5 breakpoint instruction (argument parse)
5992     BKPT <16 bit unsigned immediate>
5993     Instruction is not conditional.
5994	The bit pattern given in insns[] has the COND_ALWAYS condition,
5995	and it is an error if the caller tried to override that.  */
5996
5997static void
5998do_bkpt (str)
5999     char *        str;
6000{
6001  expressionS expr;
6002  unsigned long number;
6003
6004  skip_whitespace (str);
6005
6006  /* Allow optional leading '#'.  */
6007  if (is_immediate_prefix (* str))
6008    str++;
6009
6010  memset (& expr, '\0', sizeof (expr));
6011
6012  if (my_get_expression (& expr, & str)
6013      || (expr.X_op != O_constant
6014	  /* As a convenience we allow 'bkpt' without an operand.  */
6015	  && expr.X_op != O_absent))
6016    {
6017      inst.error = _("bad expression");
6018      return;
6019    }
6020
6021  number = expr.X_add_number;
6022
6023  /* Check it fits a 16 bit unsigned.  */
6024  if (number != (number & 0xffff))
6025    {
6026      inst.error = _("immediate value out of range");
6027      return;
6028    }
6029
6030  /* Top 12 of 16 bits to bits 19:8.  */
6031  inst.instruction |= (number & 0xfff0) << 4;
6032
6033  /* Bottom 4 of 16 bits to bits 3:0.  */
6034  inst.instruction |= number & 0xf;
6035
6036  end_of_line (str);
6037}
6038
6039/* THUMB CPS instruction (argument parse).  */
6040
6041static void
6042do_t_cps (str)
6043     char *str;
6044{
6045  do_cps_flags (&str, /*thumb_p=*/1);
6046  end_of_line (str);
6047}
6048
6049/* THUMB CPY instruction (argument parse).  */
6050
6051static void
6052do_t_cpy (str)
6053     char *str;
6054{
6055  thumb_mov_compare (str, THUMB_CPY);
6056}
6057
6058/* THUMB SETEND instruction (argument parse).  */
6059
6060static void
6061do_t_setend (str)
6062     char *str;
6063{
6064  if (do_endian_specifier (str))
6065    inst.instruction |= 0x8;
6066}
6067
6068static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6069
6070/* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
6071
6072static unsigned long
6073check_iwmmxt_insn (str, insn_type, immediate_size)
6074     char * str;
6075     enum iwmmxt_insn_type insn_type;
6076     int immediate_size;
6077{
6078  int reg = 0;
6079  const char *  inst_error;
6080  expressionS expr;
6081  unsigned long number;
6082
6083  inst_error = inst.error;
6084  if (!inst.error)
6085    inst.error = BAD_ARGS;
6086  skip_whitespace (str);
6087
6088  switch (insn_type)
6089    {
6090    case check_rd:
6091      if ((reg = reg_required_here (&str, 12)) == FAIL)
6092	return FAIL;
6093      break;
6094
6095    case check_wr:
6096       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6097	 return FAIL;
6098       break;
6099
6100    case check_wrwr:
6101      if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6102	   || skip_past_comma (&str) == FAIL
6103	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6104	return FAIL;
6105      break;
6106
6107    case check_wrwrwr:
6108      if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6109	   || skip_past_comma (&str) == FAIL
6110	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6111	   || skip_past_comma (&str) == FAIL
6112	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6113	return FAIL;
6114      break;
6115
6116    case check_wrwrwcg:
6117      if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6118	   || skip_past_comma (&str) == FAIL
6119	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6120	   || skip_past_comma (&str) == FAIL
6121	   || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6122	return FAIL;
6123      break;
6124
6125    case check_tbcst:
6126      if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6127	   || skip_past_comma (&str) == FAIL
6128	   || reg_required_here (&str, 12) == FAIL))
6129	return FAIL;
6130      break;
6131
6132    case check_tmovmsk:
6133      if ((reg_required_here (&str, 12) == FAIL
6134	   || skip_past_comma (&str) == FAIL
6135	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6136	return FAIL;
6137      break;
6138
6139    case check_tmia:
6140      if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6141	   || skip_past_comma (&str) == FAIL
6142	   || reg_required_here (&str, 0) == FAIL
6143	   || skip_past_comma (&str) == FAIL
6144	   || reg_required_here (&str, 12) == FAIL))
6145	return FAIL;
6146      break;
6147
6148    case check_tmcrr:
6149      if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6150	   || skip_past_comma (&str) == FAIL
6151	   || reg_required_here (&str, 12) == FAIL
6152	   || skip_past_comma (&str) == FAIL
6153	   || reg_required_here (&str, 16) == FAIL))
6154	return FAIL;
6155      break;
6156
6157    case check_tmrrc:
6158      if ((reg_required_here (&str, 12) == FAIL
6159	   || skip_past_comma (&str) == FAIL
6160	   || reg_required_here (&str, 16) == FAIL
6161	   || skip_past_comma (&str) == FAIL
6162	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6163	return FAIL;
6164      break;
6165
6166    case check_tmcr:
6167      if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6168	   || skip_past_comma (&str) == FAIL
6169	   || reg_required_here (&str, 12) == FAIL))
6170	return FAIL;
6171      break;
6172
6173    case check_tmrc:
6174      if ((reg_required_here (&str, 12) == FAIL
6175	   || skip_past_comma (&str) == FAIL
6176	   || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6177	return FAIL;
6178      break;
6179
6180    case check_tinsr:
6181      if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6182	   || skip_past_comma (&str) == FAIL
6183	   || reg_required_here (&str, 12) == FAIL
6184	   || skip_past_comma (&str) == FAIL))
6185	return FAIL;
6186      break;
6187
6188    case check_textrc:
6189      if ((reg_required_here (&str, 12) == FAIL
6190	   || skip_past_comma (&str) == FAIL))
6191	return FAIL;
6192      break;
6193
6194    case check_waligni:
6195      if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6196	   || skip_past_comma (&str) == FAIL
6197	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6198	   || skip_past_comma (&str) == FAIL
6199	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6200	   || skip_past_comma (&str) == FAIL))
6201	return FAIL;
6202      break;
6203
6204    case check_textrm:
6205      if ((reg_required_here (&str, 12) == FAIL
6206	   || skip_past_comma (&str) == FAIL
6207	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6208	   || skip_past_comma (&str) == FAIL))
6209	return FAIL;
6210      break;
6211
6212    case check_wshufh:
6213      if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6214	   || skip_past_comma (&str) == FAIL
6215	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6216	   || skip_past_comma (&str) == FAIL))
6217	return FAIL;
6218      break;
6219    }
6220
6221  if (immediate_size == 0)
6222    {
6223      end_of_line (str);
6224      inst.error = inst_error;
6225      return reg;
6226    }
6227  else
6228    {
6229      skip_whitespace (str);
6230
6231      /* Allow optional leading '#'. */
6232      if (is_immediate_prefix (* str))
6233        str++;
6234
6235      memset (& expr, '\0', sizeof (expr));
6236
6237      if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6238        {
6239          inst.error = _("bad or missing expression");
6240          return FAIL;
6241        }
6242
6243      number = expr.X_add_number;
6244
6245      if (number != (number & immediate_size))
6246        {
6247          inst.error = _("immediate value out of range");
6248          return FAIL;
6249        }
6250      end_of_line (str);
6251      inst.error = inst_error;
6252      return number;
6253    }
6254}
6255
6256static void
6257do_iwmmxt_byte_addr (str)
6258     char * str;
6259{
6260  int op = (inst.instruction & 0x300) >> 8;
6261  int reg;
6262
6263  inst.instruction &= ~0x300;
6264  inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
6265
6266  skip_whitespace (str);
6267
6268  if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6269      || skip_past_comma (& str) == FAIL
6270      || cp_byte_address_required_here (&str) == FAIL)
6271    {
6272      if (! inst.error)
6273        inst.error = BAD_ARGS;
6274    }
6275  else
6276    end_of_line (str);
6277
6278  if (wc_register (reg))
6279    {
6280      as_bad (_("non-word size not supported with control register"));
6281      inst.instruction |=  0xf0000100;
6282      inst.instruction &= ~0x00400000;
6283    }
6284}
6285
6286static void
6287do_iwmmxt_tandc (str)
6288     char * str;
6289{
6290  int reg;
6291
6292  reg = check_iwmmxt_insn (str, check_rd, 0);
6293
6294  if (reg != REG_PC && !inst.error)
6295    inst.error = _("only r15 allowed here");
6296}
6297
6298static void
6299do_iwmmxt_tbcst (str)
6300     char * str;
6301{
6302  check_iwmmxt_insn (str, check_tbcst, 0);
6303}
6304
6305static void
6306do_iwmmxt_textrc (str)
6307     char * str;
6308{
6309  unsigned long number;
6310
6311  if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6312    return;
6313
6314  inst.instruction |= number & 0x7;
6315}
6316
6317static void
6318do_iwmmxt_textrm (str)
6319     char * str;
6320{
6321  unsigned long number;
6322
6323  if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6324    return;
6325
6326  inst.instruction |= number & 0x7;
6327}
6328
6329static void
6330do_iwmmxt_tinsr (str)
6331     char * str;
6332{
6333  unsigned long number;
6334
6335  if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6336    return;
6337
6338  inst.instruction |= number & 0x7;
6339}
6340
6341static void
6342do_iwmmxt_tmcr (str)
6343     char * str;
6344{
6345  check_iwmmxt_insn (str, check_tmcr, 0);
6346}
6347
6348static void
6349do_iwmmxt_tmcrr (str)
6350     char * str;
6351{
6352  check_iwmmxt_insn (str, check_tmcrr, 0);
6353}
6354
6355static void
6356do_iwmmxt_tmia (str)
6357     char * str;
6358{
6359  check_iwmmxt_insn (str, check_tmia, 0);
6360}
6361
6362static void
6363do_iwmmxt_tmovmsk (str)
6364     char * str;
6365{
6366  check_iwmmxt_insn (str, check_tmovmsk, 0);
6367}
6368
6369static void
6370do_iwmmxt_tmrc (str)
6371     char * str;
6372{
6373  check_iwmmxt_insn (str, check_tmrc, 0);
6374}
6375
6376static void
6377do_iwmmxt_tmrrc (str)
6378     char * str;
6379{
6380  check_iwmmxt_insn (str, check_tmrrc, 0);
6381}
6382
6383static void
6384do_iwmmxt_torc (str)
6385     char * str;
6386{
6387  check_iwmmxt_insn (str, check_rd, 0);
6388}
6389
6390static void
6391do_iwmmxt_waligni (str)
6392     char * str;
6393{
6394  unsigned long number;
6395
6396  if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6397    return;
6398
6399  inst.instruction |= ((number & 0x7) << 20);
6400}
6401
6402static void
6403do_iwmmxt_wmov (str)
6404     char * str;
6405{
6406  if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6407    return;
6408
6409  inst.instruction |= ((inst.instruction >> 16) & 0xf);
6410}
6411
6412static void
6413do_iwmmxt_word_addr (str)
6414     char * str;
6415{
6416  int op = (inst.instruction & 0x300) >> 8;
6417  int reg;
6418
6419  inst.instruction &= ~0x300;
6420  inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
6421
6422  skip_whitespace (str);
6423
6424  if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6425      || skip_past_comma (& str) == FAIL
6426      || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6427    {
6428      if (! inst.error)
6429        inst.error = BAD_ARGS;
6430    }
6431  else
6432    end_of_line (str);
6433
6434  if (wc_register (reg))
6435    {
6436      if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6437	as_bad (_("conditional execution not supported with control register"));
6438      if (op != 2)
6439	as_bad (_("non-word size not supported with control register"));
6440      inst.instruction |=  0xf0000100;
6441      inst.instruction &= ~0x00400000;
6442    }
6443}
6444
6445static void
6446do_iwmmxt_wrwr (str)
6447     char * str;
6448{
6449  check_iwmmxt_insn (str, check_wrwr, 0);
6450}
6451
6452static void
6453do_iwmmxt_wrwrwcg (str)
6454     char * str;
6455{
6456  check_iwmmxt_insn (str, check_wrwrwcg, 0);
6457}
6458
6459static void
6460do_iwmmxt_wrwrwr (str)
6461     char * str;
6462{
6463  check_iwmmxt_insn (str, check_wrwrwr, 0);
6464}
6465
6466static void
6467do_iwmmxt_wshufh (str)
6468     char * str;
6469{
6470  unsigned long number;
6471
6472  if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6473    return;
6474
6475  inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6476}
6477
6478static void
6479do_iwmmxt_wzero (str)
6480     char * str;
6481{
6482  if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6483    return;
6484
6485  inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6486}
6487
6488/* Xscale multiply-accumulate (argument parse)
6489     MIAcc   acc0,Rm,Rs
6490     MIAPHcc acc0,Rm,Rs
6491     MIAxycc acc0,Rm,Rs.  */
6492
6493static void
6494do_xsc_mia (str)
6495     char * str;
6496{
6497  int rs;
6498  int rm;
6499
6500  if (accum0_required_here (& str) == FAIL)
6501    inst.error = ERR_NO_ACCUM;
6502
6503  else if (skip_past_comma (& str) == FAIL
6504	   || (rm = reg_required_here (& str, 0)) == FAIL)
6505    inst.error = BAD_ARGS;
6506
6507  else if (skip_past_comma (& str) == FAIL
6508	   || (rs = reg_required_here (& str, 12)) == FAIL)
6509    inst.error = BAD_ARGS;
6510
6511  /* inst.instruction has now been zapped with both rm and rs.  */
6512  else if (rm == REG_PC || rs == REG_PC)
6513    inst.error = BAD_PC;	/* Undefined result if rm or rs is R15.  */
6514
6515  else
6516    end_of_line (str);
6517}
6518
6519/* Xscale move-accumulator-register (argument parse)
6520
6521     MARcc   acc0,RdLo,RdHi.  */
6522
6523static void
6524do_xsc_mar (str)
6525     char * str;
6526{
6527  int rdlo, rdhi;
6528
6529  if (accum0_required_here (& str) == FAIL)
6530    inst.error = ERR_NO_ACCUM;
6531
6532  else if (skip_past_comma (& str) == FAIL
6533	   || (rdlo = reg_required_here (& str, 12)) == FAIL)
6534    inst.error = BAD_ARGS;
6535
6536  else if (skip_past_comma (& str) == FAIL
6537	   || (rdhi = reg_required_here (& str, 16)) == FAIL)
6538    inst.error = BAD_ARGS;
6539
6540  /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6541  else if (rdlo == REG_PC || rdhi == REG_PC)
6542    inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
6543
6544  else
6545    end_of_line (str);
6546}
6547
6548/* Xscale move-register-accumulator (argument parse)
6549
6550     MRAcc   RdLo,RdHi,acc0.  */
6551
6552static void
6553do_xsc_mra (str)
6554     char * str;
6555{
6556  int rdlo;
6557  int rdhi;
6558
6559  skip_whitespace (str);
6560
6561  if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6562    inst.error = BAD_ARGS;
6563
6564  else if (skip_past_comma (& str) == FAIL
6565	   || (rdhi = reg_required_here (& str, 16)) == FAIL)
6566    inst.error = BAD_ARGS;
6567
6568  else if  (skip_past_comma (& str) == FAIL
6569	    || accum0_required_here (& str) == FAIL)
6570    inst.error = ERR_NO_ACCUM;
6571
6572  /* inst.instruction has now been zapped with both rdlo and rdhi.  */
6573  else if (rdlo == rdhi)
6574    inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
6575
6576  else if (rdlo == REG_PC || rdhi == REG_PC)
6577    inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
6578  else
6579    end_of_line (str);
6580}
6581
6582/* ARMv5TE: Preload-Cache
6583
6584    PLD <addr_mode>
6585
6586  Syntactically, like LDR with B=1, W=0, L=1.  */
6587
6588static void
6589do_pld (str)
6590     char * str;
6591{
6592  int rd;
6593
6594  skip_whitespace (str);
6595
6596  if (* str != '[')
6597    {
6598      inst.error = _("'[' expected after PLD mnemonic");
6599      return;
6600    }
6601
6602  ++str;
6603  skip_whitespace (str);
6604
6605  if ((rd = reg_required_here (& str, 16)) == FAIL)
6606    return;
6607
6608  skip_whitespace (str);
6609
6610  if (*str == ']')
6611    {
6612      /* [Rn], ... ?  */
6613      ++str;
6614      skip_whitespace (str);
6615
6616      /* Post-indexed addressing is not allowed with PLD.  */
6617      if (skip_past_comma (&str) == SUCCESS)
6618	{
6619	  inst.error
6620	    = _("post-indexed expression used in preload instruction");
6621	  return;
6622	}
6623      else if (*str == '!') /* [Rn]! */
6624	{
6625	  inst.error = _("writeback used in preload instruction");
6626	  ++str;
6627	}
6628      else /* [Rn] */
6629	inst.instruction |= INDEX_UP | PRE_INDEX;
6630    }
6631  else /* [Rn, ...] */
6632    {
6633      if (skip_past_comma (& str) == FAIL)
6634	{
6635	  inst.error = _("pre-indexed expression expected");
6636	  return;
6637	}
6638
6639      if (ldst_extend (&str) == FAIL)
6640	return;
6641
6642      skip_whitespace (str);
6643
6644      if (* str != ']')
6645	{
6646	  inst.error = _("missing ]");
6647	  return;
6648	}
6649
6650      ++ str;
6651      skip_whitespace (str);
6652
6653      if (* str == '!') /* [Rn]! */
6654	{
6655	  inst.error = _("writeback used in preload instruction");
6656	  ++ str;
6657	}
6658
6659      inst.instruction |= PRE_INDEX;
6660    }
6661
6662  end_of_line (str);
6663}
6664
6665/* ARMv5TE load-consecutive (argument parse)
6666   Mode is like LDRH.
6667
6668     LDRccD R, mode
6669     STRccD R, mode.  */
6670
6671static void
6672do_ldrd (str)
6673     char * str;
6674{
6675  int rd;
6676  int rn;
6677
6678  skip_whitespace (str);
6679
6680  if ((rd = reg_required_here (& str, 12)) == FAIL)
6681    {
6682      inst.error = BAD_ARGS;
6683      return;
6684    }
6685
6686  if (skip_past_comma (& str) == FAIL
6687      || (rn = ld_mode_required_here (& str)) == FAIL)
6688    {
6689      if (!inst.error)
6690	inst.error = BAD_ARGS;
6691      return;
6692    }
6693
6694  /* inst.instruction has now been zapped with Rd and the addressing mode.  */
6695  if (rd & 1)		/* Unpredictable result if Rd is odd.  */
6696    {
6697      inst.error = _("destination register must be even");
6698      return;
6699    }
6700
6701  if (rd == REG_LR)
6702    {
6703      inst.error = _("r14 not allowed here");
6704      return;
6705    }
6706
6707  if (((rd == rn) || (rd + 1 == rn))
6708      && ((inst.instruction & WRITE_BACK)
6709	  || (!(inst.instruction & PRE_INDEX))))
6710    as_warn (_("pre/post-indexing used when modified address register is destination"));
6711
6712  /* For an index-register load, the index register must not overlap the
6713     destination (even if not write-back).  */
6714  if ((inst.instruction & V4_STR_BIT) == 0
6715      && (inst.instruction & HWOFFSET_IMM) == 0)
6716    {
6717      int rm = inst.instruction & 0x0000000f;
6718
6719      if (rm == rd || (rm == rd + 1))
6720	as_warn (_("ldrd destination registers must not overlap index register"));
6721    }
6722
6723  end_of_line (str);
6724}
6725
6726/* Returns the index into fp_values of a floating point number,
6727   or -1 if not in the table.  */
6728
6729static int
6730my_get_float_expression (str)
6731     char ** str;
6732{
6733  LITTLENUM_TYPE words[MAX_LITTLENUMS];
6734  char *         save_in;
6735  expressionS    exp;
6736  int            i;
6737  int            j;
6738
6739  memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6740
6741  /* Look for a raw floating point number.  */
6742  if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6743      && is_end_of_line[(unsigned char) *save_in])
6744    {
6745      for (i = 0; i < NUM_FLOAT_VALS; i++)
6746	{
6747	  for (j = 0; j < MAX_LITTLENUMS; j++)
6748	    {
6749	      if (words[j] != fp_values[i][j])
6750		break;
6751	    }
6752
6753	  if (j == MAX_LITTLENUMS)
6754	    {
6755	      *str = save_in;
6756	      return i;
6757	    }
6758	}
6759    }
6760
6761  /* Try and parse a more complex expression, this will probably fail
6762     unless the code uses a floating point prefix (eg "0f").  */
6763  save_in = input_line_pointer;
6764  input_line_pointer = *str;
6765  if (expression (&exp) == absolute_section
6766      && exp.X_op == O_big
6767      && exp.X_add_number < 0)
6768    {
6769      /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6770	 Ditto for 15.  */
6771      if (gen_to_words (words, 5, (long) 15) == 0)
6772	{
6773	  for (i = 0; i < NUM_FLOAT_VALS; i++)
6774	    {
6775	      for (j = 0; j < MAX_LITTLENUMS; j++)
6776		{
6777		  if (words[j] != fp_values[i][j])
6778		    break;
6779		}
6780
6781	      if (j == MAX_LITTLENUMS)
6782		{
6783		  *str = input_line_pointer;
6784		  input_line_pointer = save_in;
6785		  return i;
6786		}
6787	    }
6788	}
6789    }
6790
6791  *str = input_line_pointer;
6792  input_line_pointer = save_in;
6793  return -1;
6794}
6795
6796/* Return TRUE if anything in the expression is a bignum.  */
6797
6798static int
6799walk_no_bignums (sp)
6800     symbolS * sp;
6801{
6802  if (symbol_get_value_expression (sp)->X_op == O_big)
6803    return 1;
6804
6805  if (symbol_get_value_expression (sp)->X_add_symbol)
6806    {
6807      return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6808	      || (symbol_get_value_expression (sp)->X_op_symbol
6809		  && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6810    }
6811
6812  return 0;
6813}
6814
6815static int in_my_get_expression = 0;
6816
6817static int
6818my_get_expression (ep, str)
6819     expressionS * ep;
6820     char ** str;
6821{
6822  char * save_in;
6823  segT   seg;
6824
6825  save_in = input_line_pointer;
6826  input_line_pointer = *str;
6827  in_my_get_expression = 1;
6828  seg = expression (ep);
6829  in_my_get_expression = 0;
6830
6831  if (ep->X_op == O_illegal)
6832    {
6833      /* We found a bad expression in md_operand().  */
6834      *str = input_line_pointer;
6835      input_line_pointer = save_in;
6836      return 1;
6837    }
6838
6839#ifdef OBJ_AOUT
6840  if (seg != absolute_section
6841      && seg != text_section
6842      && seg != data_section
6843      && seg != bss_section
6844      && seg != undefined_section)
6845    {
6846      inst.error = _("bad_segment");
6847      *str = input_line_pointer;
6848      input_line_pointer = save_in;
6849      return 1;
6850    }
6851#endif
6852
6853  /* Get rid of any bignums now, so that we don't generate an error for which
6854     we can't establish a line number later on.  Big numbers are never valid
6855     in instructions, which is where this routine is always called.  */
6856  if (ep->X_op == O_big
6857      || (ep->X_add_symbol
6858	  && (walk_no_bignums (ep->X_add_symbol)
6859	      || (ep->X_op_symbol
6860		  && walk_no_bignums (ep->X_op_symbol)))))
6861    {
6862      inst.error = _("invalid constant");
6863      *str = input_line_pointer;
6864      input_line_pointer = save_in;
6865      return 1;
6866    }
6867
6868  *str = input_line_pointer;
6869  input_line_pointer = save_in;
6870  return 0;
6871}
6872
6873/* We handle all bad expressions here, so that we can report the faulty
6874   instruction in the error message.  */
6875void
6876md_operand (expr)
6877     expressionS *expr;
6878{
6879  if (in_my_get_expression)
6880    {
6881      expr->X_op = O_illegal;
6882      if (inst.error == NULL)
6883	inst.error = _("bad expression");
6884    }
6885}
6886
6887/* KIND indicates what kind of shifts are accepted.  */
6888
6889static int
6890decode_shift (str, kind)
6891     char ** str;
6892     int     kind;
6893{
6894  const struct asm_shift_name * shift;
6895  char * p;
6896  char   c;
6897
6898  skip_whitespace (* str);
6899
6900  for (p = * str; ISALPHA (* p); p ++)
6901    ;
6902
6903  if (p == * str)
6904    {
6905      inst.error = _("shift expression expected");
6906      return FAIL;
6907    }
6908
6909  c = * p;
6910  * p = '\0';
6911  shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6912  * p = c;
6913
6914  if (shift == NULL)
6915    {
6916      inst.error = _("shift expression expected");
6917      return FAIL;
6918    }
6919
6920  assert (shift->properties->index == shift_properties[shift->properties->index].index);
6921
6922  if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6923      && shift->properties->index != SHIFT_LSL
6924      && shift->properties->index != SHIFT_ASR)
6925    {
6926      inst.error = _("'LSL' or 'ASR' required");
6927      return FAIL;
6928    }
6929  else if (kind == SHIFT_LSL_IMMEDIATE
6930	   && shift->properties->index != SHIFT_LSL)
6931    {
6932      inst.error = _("'LSL' required");
6933      return FAIL;
6934    }
6935  else if (kind == SHIFT_ASR_IMMEDIATE
6936	   && shift->properties->index != SHIFT_ASR)
6937    {
6938      inst.error = _("'ASR' required");
6939      return FAIL;
6940    }
6941
6942  if (shift->properties->index == SHIFT_RRX)
6943    {
6944      * str = p;
6945      inst.instruction |= shift->properties->bit_field;
6946      return SUCCESS;
6947    }
6948
6949  skip_whitespace (p);
6950
6951  if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6952    {
6953      inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6954      * str = p;
6955      return SUCCESS;
6956    }
6957  else if (! is_immediate_prefix (* p))
6958    {
6959      inst.error = (NO_SHIFT_RESTRICT
6960		    ? _("shift requires register or #expression")
6961		    : _("shift requires #expression"));
6962      * str = p;
6963      return FAIL;
6964    }
6965
6966  inst.error = NULL;
6967  p ++;
6968
6969  if (my_get_expression (& inst.reloc.exp, & p))
6970    return FAIL;
6971
6972  /* Validate some simple #expressions.  */
6973  if (inst.reloc.exp.X_op == O_constant)
6974    {
6975      unsigned num = inst.reloc.exp.X_add_number;
6976
6977      /* Reject operations greater than 32.  */
6978      if (num > 32
6979	  /* Reject a shift of 0 unless the mode allows it.  */
6980	  || (num == 0 && shift->properties->allows_0 == 0)
6981	  /* Reject a shift of 32 unless the mode allows it.  */
6982	  || (num == 32 && shift->properties->allows_32 == 0)
6983	  )
6984	{
6985	  /* As a special case we allow a shift of zero for
6986	     modes that do not support it to be recoded as an
6987	     logical shift left of zero (ie nothing).  We warn
6988	     about this though.  */
6989	  if (num == 0)
6990	    {
6991	      as_warn (_("shift of 0 ignored."));
6992	      shift = & shift_names[0];
6993	      assert (shift->properties->index == SHIFT_LSL);
6994	    }
6995	  else
6996	    {
6997	      inst.error = _("invalid immediate shift");
6998	      return FAIL;
6999	    }
7000	}
7001
7002      /* Shifts of 32 are encoded as 0, for those shifts that
7003	 support it.  */
7004      if (num == 32)
7005	num = 0;
7006
7007      inst.instruction |= (num << 7) | shift->properties->bit_field;
7008    }
7009  else
7010    {
7011      inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
7012      inst.reloc.pc_rel = 0;
7013      inst.instruction |= shift->properties->bit_field;
7014    }
7015
7016  * str = p;
7017  return SUCCESS;
7018}
7019
7020/* Do those data_ops which can take a negative immediate constant
7021   by altering the instruction.  A bit of a hack really.
7022        MOV <-> MVN
7023        AND <-> BIC
7024        ADC <-> SBC
7025        by inverting the second operand, and
7026        ADD <-> SUB
7027        CMP <-> CMN
7028        by negating the second operand.  */
7029
7030static int
7031negate_data_op (instruction, value)
7032     unsigned long * instruction;
7033     unsigned long   value;
7034{
7035  int op, new_inst;
7036  unsigned long negated, inverted;
7037
7038  negated = validate_immediate (-value);
7039  inverted = validate_immediate (~value);
7040
7041  op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7042  switch (op)
7043    {
7044      /* First negates.  */
7045    case OPCODE_SUB:             /* ADD <-> SUB  */
7046      new_inst = OPCODE_ADD;
7047      value = negated;
7048      break;
7049
7050    case OPCODE_ADD:
7051      new_inst = OPCODE_SUB;
7052      value = negated;
7053      break;
7054
7055    case OPCODE_CMP:             /* CMP <-> CMN  */
7056      new_inst = OPCODE_CMN;
7057      value = negated;
7058      break;
7059
7060    case OPCODE_CMN:
7061      new_inst = OPCODE_CMP;
7062      value = negated;
7063      break;
7064
7065      /* Now Inverted ops.  */
7066    case OPCODE_MOV:             /* MOV <-> MVN  */
7067      new_inst = OPCODE_MVN;
7068      value = inverted;
7069      break;
7070
7071    case OPCODE_MVN:
7072      new_inst = OPCODE_MOV;
7073      value = inverted;
7074      break;
7075
7076    case OPCODE_AND:             /* AND <-> BIC  */
7077      new_inst = OPCODE_BIC;
7078      value = inverted;
7079      break;
7080
7081    case OPCODE_BIC:
7082      new_inst = OPCODE_AND;
7083      value = inverted;
7084      break;
7085
7086    case OPCODE_ADC:              /* ADC <-> SBC  */
7087      new_inst = OPCODE_SBC;
7088      value = inverted;
7089      break;
7090
7091    case OPCODE_SBC:
7092      new_inst = OPCODE_ADC;
7093      value = inverted;
7094      break;
7095
7096      /* We cannot do anything.  */
7097    default:
7098      return FAIL;
7099    }
7100
7101  if (value == (unsigned) FAIL)
7102    return FAIL;
7103
7104  *instruction &= OPCODE_MASK;
7105  *instruction |= new_inst << DATA_OP_SHIFT;
7106  return value;
7107}
7108
7109static int
7110data_op2 (str)
7111     char ** str;
7112{
7113  int value;
7114  expressionS expr;
7115
7116  skip_whitespace (* str);
7117
7118  if (reg_required_here (str, 0) != FAIL)
7119    {
7120      if (skip_past_comma (str) == SUCCESS)
7121	/* Shift operation on register.  */
7122	return decode_shift (str, NO_SHIFT_RESTRICT);
7123
7124      return SUCCESS;
7125    }
7126  else
7127    {
7128      /* Immediate expression.  */
7129      if (is_immediate_prefix (**str))
7130	{
7131	  (*str)++;
7132	  inst.error = NULL;
7133
7134	  if (my_get_expression (&inst.reloc.exp, str))
7135	    return FAIL;
7136
7137	  if (inst.reloc.exp.X_add_symbol)
7138	    {
7139	      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7140	      inst.reloc.pc_rel = 0;
7141	    }
7142	  else
7143	    {
7144	      if (skip_past_comma (str) == SUCCESS)
7145		{
7146		  /* #x, y -- ie explicit rotation by Y.  */
7147		  if (my_get_expression (&expr, str))
7148		    return FAIL;
7149
7150		  if (expr.X_op != O_constant)
7151		    {
7152		      inst.error = _("constant expression expected");
7153		      return FAIL;
7154		    }
7155
7156		  /* Rotate must be a multiple of 2.  */
7157		  if (((unsigned) expr.X_add_number) > 30
7158		      || (expr.X_add_number & 1) != 0
7159		      || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7160		    {
7161		      inst.error = _("invalid constant");
7162		      return FAIL;
7163		    }
7164		  inst.instruction |= INST_IMMEDIATE;
7165		  inst.instruction |= inst.reloc.exp.X_add_number;
7166		  inst.instruction |= expr.X_add_number << 7;
7167		  return SUCCESS;
7168		}
7169
7170	      /* Implicit rotation, select a suitable one.  */
7171	      value = validate_immediate (inst.reloc.exp.X_add_number);
7172
7173	      if (value == FAIL)
7174		{
7175		  /* Can't be done.  Perhaps the code reads something like
7176		     "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
7177		  if ((value = negate_data_op (&inst.instruction,
7178					       inst.reloc.exp.X_add_number))
7179		      == FAIL)
7180		    {
7181		      inst.error = _("invalid constant");
7182		      return FAIL;
7183		    }
7184		}
7185
7186	      inst.instruction |= value;
7187	    }
7188
7189	  inst.instruction |= INST_IMMEDIATE;
7190	  return SUCCESS;
7191	}
7192
7193      (*str)++;
7194      inst.error = _("register or shift expression expected");
7195      return FAIL;
7196    }
7197}
7198
7199static int
7200fp_op2 (str)
7201     char ** str;
7202{
7203  skip_whitespace (* str);
7204
7205  if (fp_reg_required_here (str, 0) != FAIL)
7206    return SUCCESS;
7207  else
7208    {
7209      /* Immediate expression.  */
7210      if (*((*str)++) == '#')
7211	{
7212	  int i;
7213
7214	  inst.error = NULL;
7215
7216	  skip_whitespace (* str);
7217
7218	  /* First try and match exact strings, this is to guarantee
7219	     that some formats will work even for cross assembly.  */
7220
7221	  for (i = 0; fp_const[i]; i++)
7222	    {
7223	      if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7224		{
7225		  char *start = *str;
7226
7227		  *str += strlen (fp_const[i]);
7228		  if (is_end_of_line[(unsigned char) **str])
7229		    {
7230		      inst.instruction |= i + 8;
7231		      return SUCCESS;
7232		    }
7233		  *str = start;
7234		}
7235	    }
7236
7237	  /* Just because we didn't get a match doesn't mean that the
7238	     constant isn't valid, just that it is in a format that we
7239	     don't automatically recognize.  Try parsing it with
7240	     the standard expression routines.  */
7241	  if ((i = my_get_float_expression (str)) >= 0)
7242	    {
7243	      inst.instruction |= i + 8;
7244	      return SUCCESS;
7245	    }
7246
7247	  inst.error = _("invalid floating point immediate expression");
7248	  return FAIL;
7249	}
7250      inst.error =
7251	_("floating point register or immediate expression expected");
7252      return FAIL;
7253    }
7254}
7255
7256static void
7257do_arit (str)
7258     char * str;
7259{
7260  skip_whitespace (str);
7261
7262  if (reg_required_here (&str, 12) == FAIL
7263      || skip_past_comma (&str) == FAIL
7264      || reg_required_here (&str, 16) == FAIL
7265      || skip_past_comma (&str) == FAIL
7266      || data_op2 (&str) == FAIL)
7267    {
7268      if (!inst.error)
7269	inst.error = BAD_ARGS;
7270      return;
7271    }
7272
7273  end_of_line (str);
7274}
7275
7276static void
7277do_adr (str)
7278     char * str;
7279{
7280  /* This is a pseudo-op of the form "adr rd, label" to be converted
7281     into a relative address of the form "add rd, pc, #label-.-8".  */
7282  skip_whitespace (str);
7283
7284  if (reg_required_here (&str, 12) == FAIL
7285      || skip_past_comma (&str) == FAIL
7286      || my_get_expression (&inst.reloc.exp, &str))
7287    {
7288      if (!inst.error)
7289	inst.error = BAD_ARGS;
7290      return;
7291    }
7292
7293  /* Frag hacking will turn this into a sub instruction if the offset turns
7294     out to be negative.  */
7295  inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7296#ifndef TE_WINCE
7297  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
7298#endif
7299  inst.reloc.pc_rel = 1;
7300
7301  end_of_line (str);
7302}
7303
7304static void
7305do_adrl (str)
7306     char * str;
7307{
7308  /* This is a pseudo-op of the form "adrl rd, label" to be converted
7309     into a relative address of the form:
7310     add rd, pc, #low(label-.-8)"
7311     add rd, rd, #high(label-.-8)"  */
7312
7313  skip_whitespace (str);
7314
7315  if (reg_required_here (&str, 12) == FAIL
7316      || skip_past_comma (&str) == FAIL
7317      || my_get_expression (&inst.reloc.exp, &str))
7318    {
7319      if (!inst.error)
7320	inst.error = BAD_ARGS;
7321
7322      return;
7323    }
7324
7325  end_of_line (str);
7326  /* Frag hacking will turn this into a sub instruction if the offset turns
7327     out to be negative.  */
7328  inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7329#ifndef TE_WINCE
7330  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
7331#endif
7332  inst.reloc.pc_rel            = 1;
7333  inst.size                    = INSN_SIZE * 2;
7334}
7335
7336static void
7337do_cmp (str)
7338     char * str;
7339{
7340  skip_whitespace (str);
7341
7342  if (reg_required_here (&str, 16) == FAIL)
7343    {
7344      if (!inst.error)
7345	inst.error = BAD_ARGS;
7346      return;
7347    }
7348
7349  if (skip_past_comma (&str) == FAIL
7350      || data_op2 (&str) == FAIL)
7351    {
7352      if (!inst.error)
7353	inst.error = BAD_ARGS;
7354      return;
7355    }
7356
7357  end_of_line (str);
7358}
7359
7360static void
7361do_mov (str)
7362     char * str;
7363{
7364  skip_whitespace (str);
7365
7366  if (reg_required_here (&str, 12) == FAIL)
7367    {
7368      if (!inst.error)
7369	inst.error = BAD_ARGS;
7370      return;
7371    }
7372
7373  if (skip_past_comma (&str) == FAIL
7374      || data_op2 (&str) == FAIL)
7375    {
7376      if (!inst.error)
7377	inst.error = BAD_ARGS;
7378      return;
7379    }
7380
7381  end_of_line (str);
7382}
7383
7384static int
7385ldst_extend (str)
7386     char ** str;
7387{
7388  int add = INDEX_UP;
7389
7390  switch (**str)
7391    {
7392    case '#':
7393    case '$':
7394      (*str)++;
7395      if (my_get_expression (& inst.reloc.exp, str))
7396	return FAIL;
7397
7398      if (inst.reloc.exp.X_op == O_constant)
7399	{
7400	  int value = inst.reloc.exp.X_add_number;
7401
7402	  if (value < -4095 || value > 4095)
7403	    {
7404	      inst.error = _("address offset too large");
7405	      return FAIL;
7406	    }
7407
7408	  if (value < 0)
7409	    {
7410	      value = -value;
7411	      add = 0;
7412	    }
7413
7414	  inst.instruction |= add | value;
7415	}
7416      else
7417	{
7418	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7419	  inst.reloc.pc_rel = 0;
7420	}
7421      return SUCCESS;
7422
7423    case '-':
7424      add = 0;
7425      /* Fall through.  */
7426
7427    case '+':
7428      (*str)++;
7429      /* Fall through.  */
7430
7431    default:
7432      if (reg_required_here (str, 0) == FAIL)
7433	return FAIL;
7434
7435      inst.instruction |= add | OFFSET_REG;
7436      if (skip_past_comma (str) == SUCCESS)
7437	return decode_shift (str, SHIFT_IMMEDIATE);
7438
7439      return SUCCESS;
7440    }
7441}
7442
7443static void
7444do_ldst (str)
7445     char *        str;
7446{
7447  int pre_inc = 0;
7448  int conflict_reg;
7449  int value;
7450
7451  skip_whitespace (str);
7452
7453  if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7454    {
7455      if (!inst.error)
7456	inst.error = BAD_ARGS;
7457      return;
7458    }
7459
7460  if (skip_past_comma (&str) == FAIL)
7461    {
7462      inst.error = _("address expected");
7463      return;
7464    }
7465
7466  if (*str == '[')
7467    {
7468      int reg;
7469
7470      str++;
7471
7472      skip_whitespace (str);
7473
7474      if ((reg = reg_required_here (&str, 16)) == FAIL)
7475	return;
7476
7477      /* Conflicts can occur on stores as well as loads.  */
7478      conflict_reg = (conflict_reg == reg);
7479
7480      skip_whitespace (str);
7481
7482      if (*str == ']')
7483	{
7484	  str ++;
7485
7486	  if (skip_past_comma (&str) == SUCCESS)
7487	    {
7488	      /* [Rn],... (post inc)  */
7489	      if (ldst_extend (&str) == FAIL)
7490		return;
7491	      if (conflict_reg)
7492		as_warn (_("%s register same as write-back base"),
7493			 ((inst.instruction & LOAD_BIT)
7494			  ? _("destination") : _("source")));
7495	    }
7496	  else
7497	    {
7498	      /* [Rn]  */
7499	      skip_whitespace (str);
7500
7501	      if (*str == '!')
7502		{
7503		  if (conflict_reg)
7504		    as_warn (_("%s register same as write-back base"),
7505			     ((inst.instruction & LOAD_BIT)
7506			      ? _("destination") : _("source")));
7507		  str++;
7508		  inst.instruction |= WRITE_BACK;
7509		}
7510
7511	      inst.instruction |= INDEX_UP;
7512	      pre_inc = 1;
7513	    }
7514	}
7515      else
7516	{
7517	  /* [Rn,...]  */
7518	  if (skip_past_comma (&str) == FAIL)
7519	    {
7520	      inst.error = _("pre-indexed expression expected");
7521	      return;
7522	    }
7523
7524	  pre_inc = 1;
7525	  if (ldst_extend (&str) == FAIL)
7526	    return;
7527
7528	  skip_whitespace (str);
7529
7530	  if (*str++ != ']')
7531	    {
7532	      inst.error = _("missing ]");
7533	      return;
7534	    }
7535
7536	  skip_whitespace (str);
7537
7538	  if (*str == '!')
7539	    {
7540	      if (conflict_reg)
7541		as_warn (_("%s register same as write-back base"),
7542			 ((inst.instruction & LOAD_BIT)
7543			  ? _("destination") : _("source")));
7544	      str++;
7545	      inst.instruction |= WRITE_BACK;
7546	    }
7547	}
7548    }
7549  else if (*str == '=')
7550    {
7551      if ((inst.instruction & LOAD_BIT) == 0)
7552	{
7553	  inst.error = _("invalid pseudo operation");
7554	  return;
7555	}
7556
7557      /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7558      str++;
7559
7560      skip_whitespace (str);
7561
7562      if (my_get_expression (&inst.reloc.exp, &str))
7563	return;
7564
7565      if (inst.reloc.exp.X_op != O_constant
7566	  && inst.reloc.exp.X_op != O_symbol)
7567	{
7568	  inst.error = _("constant expression expected");
7569	  return;
7570	}
7571
7572      if (inst.reloc.exp.X_op == O_constant)
7573	{
7574	  value = validate_immediate (inst.reloc.exp.X_add_number);
7575
7576	  if (value != FAIL)
7577	    {
7578	      /* This can be done with a mov instruction.  */
7579	      inst.instruction &= LITERAL_MASK;
7580	      inst.instruction |= (INST_IMMEDIATE
7581				   | (OPCODE_MOV << DATA_OP_SHIFT));
7582	      inst.instruction |= value & 0xfff;
7583	      end_of_line (str);
7584	      return;
7585	    }
7586
7587	  value = validate_immediate (~inst.reloc.exp.X_add_number);
7588
7589	  if (value != FAIL)
7590	    {
7591	      /* This can be done with a mvn instruction.  */
7592	      inst.instruction &= LITERAL_MASK;
7593	      inst.instruction |= (INST_IMMEDIATE
7594				   | (OPCODE_MVN << DATA_OP_SHIFT));
7595	      inst.instruction |= value & 0xfff;
7596	      end_of_line (str);
7597	      return;
7598	    }
7599	}
7600
7601      /* Insert into literal pool.  */
7602      if (add_to_lit_pool () == FAIL)
7603	{
7604	  if (!inst.error)
7605	    inst.error = _("literal pool insertion failed");
7606	  return;
7607	}
7608
7609      /* Change the instruction exp to point to the pool.  */
7610      inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7611      inst.reloc.pc_rel = 1;
7612      inst.instruction |= (REG_PC << 16);
7613      pre_inc = 1;
7614    }
7615  else
7616    {
7617      if (my_get_expression (&inst.reloc.exp, &str))
7618	return;
7619
7620      inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7621#ifndef TE_WINCE
7622      /* PC rel adjust.  */
7623      inst.reloc.exp.X_add_number -= 8;
7624#endif
7625      inst.reloc.pc_rel = 1;
7626      inst.instruction |= (REG_PC << 16);
7627      pre_inc = 1;
7628    }
7629
7630  inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7631  end_of_line (str);
7632}
7633
7634static void
7635do_ldstt (str)
7636     char *        str;
7637{
7638  int conflict_reg;
7639
7640  skip_whitespace (str);
7641
7642  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7643    {
7644      if (!inst.error)
7645	inst.error = BAD_ARGS;
7646      return;
7647    }
7648
7649  if (skip_past_comma (& str) == FAIL)
7650    {
7651      inst.error = _("address expected");
7652      return;
7653    }
7654
7655  if (*str == '[')
7656    {
7657      int reg;
7658
7659      str++;
7660
7661      skip_whitespace (str);
7662
7663      if ((reg = reg_required_here (&str, 16)) == FAIL)
7664	return;
7665
7666      /* ldrt/strt always use post-indexed addressing, so if the base is
7667	 the same as Rd, we warn.  */
7668      if (conflict_reg == reg)
7669	as_warn (_("%s register same as write-back base"),
7670		 ((inst.instruction & LOAD_BIT)
7671		  ? _("destination") : _("source")));
7672
7673      skip_whitespace (str);
7674
7675      if (*str == ']')
7676	{
7677	  str ++;
7678
7679	  if (skip_past_comma (&str) == SUCCESS)
7680	    {
7681	      /* [Rn],... (post inc)  */
7682	      if (ldst_extend (&str) == FAIL)
7683		return;
7684	    }
7685	  else
7686	    {
7687	      /* [Rn]  */
7688	      skip_whitespace (str);
7689
7690	      /* Skip a write-back '!'.  */
7691	      if (*str == '!')
7692		str++;
7693
7694	      inst.instruction |= INDEX_UP;
7695	    }
7696	}
7697      else
7698	{
7699	  inst.error = _("post-indexed expression expected");
7700	  return;
7701	}
7702    }
7703  else
7704    {
7705      inst.error = _("post-indexed expression expected");
7706      return;
7707    }
7708
7709  end_of_line (str);
7710}
7711
7712static int
7713ldst_extend_v4 (str)
7714     char ** str;
7715{
7716  int add = INDEX_UP;
7717
7718  switch (**str)
7719    {
7720    case '#':
7721    case '$':
7722      (*str)++;
7723      if (my_get_expression (& inst.reloc.exp, str))
7724	return FAIL;
7725
7726      if (inst.reloc.exp.X_op == O_constant)
7727	{
7728	  int value = inst.reloc.exp.X_add_number;
7729
7730	  if (value < -255 || value > 255)
7731	    {
7732	      inst.error = _("address offset too large");
7733	      return FAIL;
7734	    }
7735
7736	  if (value < 0)
7737	    {
7738	      value = -value;
7739	      add = 0;
7740	    }
7741
7742	  /* Halfword and signextension instructions have the
7743             immediate value split across bits 11..8 and bits 3..0.  */
7744	  inst.instruction |= (add | HWOFFSET_IMM
7745			       | ((value >> 4) << 8) | (value & 0xF));
7746	}
7747      else
7748	{
7749	  inst.instruction |= HWOFFSET_IMM;
7750	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7751	  inst.reloc.pc_rel = 0;
7752	}
7753      return SUCCESS;
7754
7755    case '-':
7756      add = 0;
7757      /* Fall through.  */
7758
7759    case '+':
7760      (*str)++;
7761      /* Fall through.  */
7762
7763    default:
7764      if (reg_required_here (str, 0) == FAIL)
7765	return FAIL;
7766
7767      inst.instruction |= add;
7768      return SUCCESS;
7769    }
7770}
7771
7772/* Halfword and signed-byte load/store operations.  */
7773static void
7774do_ldstv4 (str)
7775     char *        str;
7776{
7777  int pre_inc = 0;
7778  int conflict_reg;
7779  int value;
7780
7781  skip_whitespace (str);
7782
7783  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7784    {
7785      if (!inst.error)
7786	inst.error = BAD_ARGS;
7787      return;
7788    }
7789
7790  if (skip_past_comma (& str) == FAIL)
7791    {
7792      inst.error = _("address expected");
7793      return;
7794    }
7795
7796  if (*str == '[')
7797    {
7798      int reg;
7799
7800      str++;
7801
7802      skip_whitespace (str);
7803
7804      if ((reg = reg_required_here (&str, 16)) == FAIL)
7805	return;
7806
7807      /* Conflicts can occur on stores as well as loads.  */
7808      conflict_reg = (conflict_reg == reg);
7809
7810      skip_whitespace (str);
7811
7812      if (*str == ']')
7813	{
7814	  str ++;
7815
7816	  if (skip_past_comma (&str) == SUCCESS)
7817	    {
7818	      /* [Rn],... (post inc)  */
7819	      if (ldst_extend_v4 (&str) == FAIL)
7820		return;
7821	      if (conflict_reg)
7822		as_warn (_("%s register same as write-back base"),
7823			 ((inst.instruction & LOAD_BIT)
7824			  ? _("destination") : _("source")));
7825	    }
7826	  else
7827	    {
7828	      /* [Rn]  */
7829	      inst.instruction |= HWOFFSET_IMM;
7830
7831	      skip_whitespace (str);
7832
7833	      if (*str == '!')
7834		{
7835		  if (conflict_reg)
7836		    as_warn (_("%s register same as write-back base"),
7837			     ((inst.instruction & LOAD_BIT)
7838			      ? _("destination") : _("source")));
7839		  str++;
7840		  inst.instruction |= WRITE_BACK;
7841		}
7842
7843	      inst.instruction |= INDEX_UP;
7844	      pre_inc = 1;
7845	    }
7846	}
7847      else
7848	{
7849	  /* [Rn,...]  */
7850	  if (skip_past_comma (&str) == FAIL)
7851	    {
7852	      inst.error = _("pre-indexed expression expected");
7853	      return;
7854	    }
7855
7856	  pre_inc = 1;
7857	  if (ldst_extend_v4 (&str) == FAIL)
7858	    return;
7859
7860	  skip_whitespace (str);
7861
7862	  if (*str++ != ']')
7863	    {
7864	      inst.error = _("missing ]");
7865	      return;
7866	    }
7867
7868	  skip_whitespace (str);
7869
7870	  if (*str == '!')
7871	    {
7872	      if (conflict_reg)
7873		as_warn (_("%s register same as write-back base"),
7874			 ((inst.instruction & LOAD_BIT)
7875			  ? _("destination") : _("source")));
7876	      str++;
7877	      inst.instruction |= WRITE_BACK;
7878	    }
7879	}
7880    }
7881  else if (*str == '=')
7882    {
7883      if ((inst.instruction & LOAD_BIT) == 0)
7884	{
7885	  inst.error = _("invalid pseudo operation");
7886	  return;
7887	}
7888
7889      /* XXX Does this work correctly for half-word/byte ops?  */
7890      /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
7891      str++;
7892
7893      skip_whitespace (str);
7894
7895      if (my_get_expression (&inst.reloc.exp, &str))
7896	return;
7897
7898      if (inst.reloc.exp.X_op != O_constant
7899	  && inst.reloc.exp.X_op != O_symbol)
7900	{
7901	  inst.error = _("constant expression expected");
7902	  return;
7903	}
7904
7905      if (inst.reloc.exp.X_op == O_constant)
7906	{
7907	  value = validate_immediate (inst.reloc.exp.X_add_number);
7908
7909	  if (value != FAIL)
7910	    {
7911	      /* This can be done with a mov instruction.  */
7912	      inst.instruction &= LITERAL_MASK;
7913	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7914	      inst.instruction |= value & 0xfff;
7915	      end_of_line (str);
7916	      return;
7917	    }
7918
7919	  value = validate_immediate (~ inst.reloc.exp.X_add_number);
7920
7921	  if (value != FAIL)
7922	    {
7923	      /* This can be done with a mvn instruction.  */
7924	      inst.instruction &= LITERAL_MASK;
7925	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7926	      inst.instruction |= value & 0xfff;
7927	      end_of_line (str);
7928	      return;
7929	    }
7930	}
7931
7932      /* Insert into literal pool.  */
7933      if (add_to_lit_pool () == FAIL)
7934	{
7935	  if (!inst.error)
7936	    inst.error = _("literal pool insertion failed");
7937	  return;
7938	}
7939
7940      /* Change the instruction exp to point to the pool.  */
7941      inst.instruction |= HWOFFSET_IMM;
7942      inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7943      inst.reloc.pc_rel = 1;
7944      inst.instruction |= (REG_PC << 16);
7945      pre_inc = 1;
7946    }
7947  else
7948    {
7949      if (my_get_expression (&inst.reloc.exp, &str))
7950	return;
7951
7952      inst.instruction |= HWOFFSET_IMM;
7953      inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7954#ifndef TE_WINCE
7955      /* PC rel adjust.  */
7956      inst.reloc.exp.X_add_number -= 8;
7957#endif
7958      inst.reloc.pc_rel = 1;
7959      inst.instruction |= (REG_PC << 16);
7960      pre_inc = 1;
7961    }
7962
7963  inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7964  end_of_line (str);
7965}
7966
7967static long
7968reg_list (strp)
7969     char ** strp;
7970{
7971  char * str = * strp;
7972  long   range = 0;
7973  int    another_range;
7974
7975  /* We come back here if we get ranges concatenated by '+' or '|'.  */
7976  do
7977    {
7978      another_range = 0;
7979
7980      if (*str == '{')
7981	{
7982	  int in_range = 0;
7983	  int cur_reg = -1;
7984
7985	  str++;
7986	  do
7987	    {
7988	      int reg;
7989
7990	      skip_whitespace (str);
7991
7992	      if ((reg = reg_required_here (& str, -1)) == FAIL)
7993		return FAIL;
7994
7995	      if (in_range)
7996		{
7997		  int i;
7998
7999		  if (reg <= cur_reg)
8000		    {
8001		      inst.error = _("bad range in register list");
8002		      return FAIL;
8003		    }
8004
8005		  for (i = cur_reg + 1; i < reg; i++)
8006		    {
8007		      if (range & (1 << i))
8008			as_tsktsk
8009			  (_("Warning: duplicated register (r%d) in register list"),
8010			   i);
8011		      else
8012			range |= 1 << i;
8013		    }
8014		  in_range = 0;
8015		}
8016
8017	      if (range & (1 << reg))
8018		as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8019			   reg);
8020	      else if (reg <= cur_reg)
8021		as_tsktsk (_("Warning: register range not in ascending order"));
8022
8023	      range |= 1 << reg;
8024	      cur_reg = reg;
8025	    }
8026	  while (skip_past_comma (&str) != FAIL
8027		 || (in_range = 1, *str++ == '-'));
8028	  str--;
8029	  skip_whitespace (str);
8030
8031	  if (*str++ != '}')
8032	    {
8033	      inst.error = _("missing `}'");
8034	      return FAIL;
8035	    }
8036	}
8037      else
8038	{
8039	  expressionS expr;
8040
8041	  if (my_get_expression (&expr, &str))
8042	    return FAIL;
8043
8044	  if (expr.X_op == O_constant)
8045	    {
8046	      if (expr.X_add_number
8047		  != (expr.X_add_number & 0x0000ffff))
8048		{
8049		  inst.error = _("invalid register mask");
8050		  return FAIL;
8051		}
8052
8053	      if ((range & expr.X_add_number) != 0)
8054		{
8055		  int regno = range & expr.X_add_number;
8056
8057		  regno &= -regno;
8058		  regno = (1 << regno) - 1;
8059		  as_tsktsk
8060		    (_("Warning: duplicated register (r%d) in register list"),
8061		     regno);
8062		}
8063
8064	      range |= expr.X_add_number;
8065	    }
8066	  else
8067	    {
8068	      if (inst.reloc.type != 0)
8069		{
8070		  inst.error = _("expression too complex");
8071		  return FAIL;
8072		}
8073
8074	      memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8075	      inst.reloc.type = BFD_RELOC_ARM_MULTI;
8076	      inst.reloc.pc_rel = 0;
8077	    }
8078	}
8079
8080      skip_whitespace (str);
8081
8082      if (*str == '|' || *str == '+')
8083	{
8084	  str++;
8085	  another_range = 1;
8086	}
8087    }
8088  while (another_range);
8089
8090  *strp = str;
8091  return range;
8092}
8093
8094static void
8095do_ldmstm (str)
8096     char * str;
8097{
8098  int base_reg;
8099  long range;
8100
8101  skip_whitespace (str);
8102
8103  if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8104    return;
8105
8106  if (base_reg == REG_PC)
8107    {
8108      inst.error = _("r15 not allowed as base register");
8109      return;
8110    }
8111
8112  skip_whitespace (str);
8113
8114  if (*str == '!')
8115    {
8116      inst.instruction |= WRITE_BACK;
8117      str++;
8118    }
8119
8120  if (skip_past_comma (&str) == FAIL
8121      || (range = reg_list (&str)) == FAIL)
8122    {
8123      if (! inst.error)
8124	inst.error = BAD_ARGS;
8125      return;
8126    }
8127
8128  if (*str == '^')
8129    {
8130      str++;
8131      inst.instruction |= LDM_TYPE_2_OR_3;
8132    }
8133
8134  if (inst.instruction & WRITE_BACK)
8135    {
8136      /* Check for unpredictable uses of writeback.  */
8137      if (inst.instruction & LOAD_BIT)
8138	{
8139	  /* Not allowed in LDM type 2.  */
8140	  if ((inst.instruction & LDM_TYPE_2_OR_3)
8141	      && ((range & (1 << REG_PC)) == 0))
8142	    as_warn (_("writeback of base register is UNPREDICTABLE"));
8143	  /* Only allowed if base reg not in list for other types.  */
8144	  else if (range & (1 << base_reg))
8145	    as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8146	}
8147      else /* STM.  */
8148	{
8149	  /* Not allowed for type 2.  */
8150	  if (inst.instruction & LDM_TYPE_2_OR_3)
8151	    as_warn (_("writeback of base register is UNPREDICTABLE"));
8152	  /* Only allowed if base reg not in list, or first in list.  */
8153	  else if ((range & (1 << base_reg))
8154		   && (range & ((1 << base_reg) - 1)))
8155	    as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8156	}
8157    }
8158
8159  inst.instruction |= range;
8160  end_of_line (str);
8161}
8162
8163static void
8164do_swi (str)
8165     char * str;
8166{
8167  skip_whitespace (str);
8168
8169  /* Allow optional leading '#'.  */
8170  if (is_immediate_prefix (*str))
8171    str++;
8172
8173  if (my_get_expression (& inst.reloc.exp, & str))
8174    return;
8175
8176  inst.reloc.type = BFD_RELOC_ARM_SWI;
8177  inst.reloc.pc_rel = 0;
8178  end_of_line (str);
8179}
8180
8181static void
8182do_swap (str)
8183     char * str;
8184{
8185  int reg;
8186
8187  skip_whitespace (str);
8188
8189  if ((reg = reg_required_here (&str, 12)) == FAIL)
8190    return;
8191
8192  if (reg == REG_PC)
8193    {
8194      inst.error = _("r15 not allowed in swap");
8195      return;
8196    }
8197
8198  if (skip_past_comma (&str) == FAIL
8199      || (reg = reg_required_here (&str, 0)) == FAIL)
8200    {
8201      if (!inst.error)
8202	inst.error = BAD_ARGS;
8203      return;
8204    }
8205
8206  if (reg == REG_PC)
8207    {
8208      inst.error = _("r15 not allowed in swap");
8209      return;
8210    }
8211
8212  if (skip_past_comma (&str) == FAIL
8213      || *str++ != '[')
8214    {
8215      inst.error = BAD_ARGS;
8216      return;
8217    }
8218
8219  skip_whitespace (str);
8220
8221  if ((reg = reg_required_here (&str, 16)) == FAIL)
8222    return;
8223
8224  if (reg == REG_PC)
8225    {
8226      inst.error = BAD_PC;
8227      return;
8228    }
8229
8230  skip_whitespace (str);
8231
8232  if (*str++ != ']')
8233    {
8234      inst.error = _("missing ]");
8235      return;
8236    }
8237
8238  end_of_line (str);
8239}
8240
8241static void
8242do_branch (str)
8243     char * str;
8244{
8245  if (my_get_expression (&inst.reloc.exp, &str))
8246    return;
8247
8248#ifdef OBJ_ELF
8249  {
8250    char * save_in;
8251
8252    /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8253       required for the instruction.  */
8254
8255    /* arm_parse_reloc () works on input_line_pointer.
8256       We actually want to parse the operands to the branch instruction
8257       passed in 'str'.  Save the input pointer and restore it later.  */
8258    save_in = input_line_pointer;
8259    input_line_pointer = str;
8260    if (inst.reloc.exp.X_op == O_symbol
8261	&& *str == '('
8262	&& arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8263      {
8264	inst.reloc.type   = BFD_RELOC_ARM_PLT32;
8265	inst.reloc.pc_rel = 0;
8266	/* Modify str to point to after parsed operands, otherwise
8267	   end_of_line() will complain about the (PLT) left in str.  */
8268	str = input_line_pointer;
8269      }
8270    else
8271      {
8272	inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8273	inst.reloc.pc_rel = 1;
8274      }
8275    input_line_pointer = save_in;
8276  }
8277#else
8278  inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
8279  inst.reloc.pc_rel = 1;
8280#endif /* OBJ_ELF  */
8281
8282  end_of_line (str);
8283}
8284
8285static void
8286do_bx (str)
8287     char * str;
8288{
8289  int reg;
8290
8291  skip_whitespace (str);
8292
8293  if ((reg = reg_required_here (&str, 0)) == FAIL)
8294    {
8295      inst.error = BAD_ARGS;
8296      return;
8297    }
8298
8299  /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
8300  if (reg == REG_PC)
8301    as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8302
8303  end_of_line (str);
8304}
8305
8306static void
8307do_cdp (str)
8308     char * str;
8309{
8310  /* Co-processor data operation.
8311     Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
8312  skip_whitespace (str);
8313
8314  if (co_proc_number (&str) == FAIL)
8315    {
8316      if (!inst.error)
8317	inst.error = BAD_ARGS;
8318      return;
8319    }
8320
8321  if (skip_past_comma (&str) == FAIL
8322      || cp_opc_expr (&str, 20,4) == FAIL)
8323    {
8324      if (!inst.error)
8325	inst.error = BAD_ARGS;
8326      return;
8327    }
8328
8329  if (skip_past_comma (&str) == FAIL
8330      || cp_reg_required_here (&str, 12) == FAIL)
8331    {
8332      if (!inst.error)
8333	inst.error = BAD_ARGS;
8334      return;
8335    }
8336
8337  if (skip_past_comma (&str) == FAIL
8338      || cp_reg_required_here (&str, 16) == FAIL)
8339    {
8340      if (!inst.error)
8341	inst.error = BAD_ARGS;
8342      return;
8343    }
8344
8345  if (skip_past_comma (&str) == FAIL
8346      || cp_reg_required_here (&str, 0) == FAIL)
8347    {
8348      if (!inst.error)
8349	inst.error = BAD_ARGS;
8350      return;
8351    }
8352
8353  if (skip_past_comma (&str) == SUCCESS)
8354    {
8355      if (cp_opc_expr (&str, 5, 3) == FAIL)
8356	{
8357	  if (!inst.error)
8358	    inst.error = BAD_ARGS;
8359	  return;
8360	}
8361    }
8362
8363  end_of_line (str);
8364}
8365
8366static void
8367do_lstc (str)
8368     char * str;
8369{
8370  /* Co-processor register load/store.
8371     Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
8372
8373  skip_whitespace (str);
8374
8375  if (co_proc_number (&str) == FAIL)
8376    {
8377      if (!inst.error)
8378	inst.error = BAD_ARGS;
8379      return;
8380    }
8381
8382  if (skip_past_comma (&str) == FAIL
8383      || cp_reg_required_here (&str, 12) == FAIL)
8384    {
8385      if (!inst.error)
8386	inst.error = BAD_ARGS;
8387      return;
8388    }
8389
8390  if (skip_past_comma (&str) == FAIL
8391      || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8392    {
8393      if (! inst.error)
8394	inst.error = BAD_ARGS;
8395      return;
8396    }
8397
8398  end_of_line (str);
8399}
8400
8401static void
8402do_co_reg (str)
8403     char * str;
8404{
8405  /* Co-processor register transfer.
8406     Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
8407
8408  skip_whitespace (str);
8409
8410  if (co_proc_number (&str) == FAIL)
8411    {
8412      if (!inst.error)
8413	inst.error = BAD_ARGS;
8414      return;
8415    }
8416
8417  if (skip_past_comma (&str) == FAIL
8418      || cp_opc_expr (&str, 21, 3) == FAIL)
8419    {
8420      if (!inst.error)
8421	inst.error = BAD_ARGS;
8422      return;
8423    }
8424
8425  if (skip_past_comma (&str) == FAIL
8426      || reg_required_here (&str, 12) == FAIL)
8427    {
8428      if (!inst.error)
8429	inst.error = BAD_ARGS;
8430      return;
8431    }
8432
8433  if (skip_past_comma (&str) == FAIL
8434      || cp_reg_required_here (&str, 16) == FAIL)
8435    {
8436      if (!inst.error)
8437	inst.error = BAD_ARGS;
8438      return;
8439    }
8440
8441  if (skip_past_comma (&str) == FAIL
8442      || cp_reg_required_here (&str, 0) == FAIL)
8443    {
8444      if (!inst.error)
8445	inst.error = BAD_ARGS;
8446      return;
8447    }
8448
8449  if (skip_past_comma (&str) == SUCCESS)
8450    {
8451      if (cp_opc_expr (&str, 5, 3) == FAIL)
8452	{
8453	  if (!inst.error)
8454	    inst.error = BAD_ARGS;
8455	  return;
8456	}
8457    }
8458
8459  end_of_line (str);
8460}
8461
8462static void
8463do_fpa_ctrl (str)
8464     char * str;
8465{
8466  /* FP control registers.
8467     Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
8468
8469  skip_whitespace (str);
8470
8471  if (reg_required_here (&str, 12) == FAIL)
8472    {
8473      if (!inst.error)
8474	inst.error = BAD_ARGS;
8475      return;
8476    }
8477
8478  end_of_line (str);
8479}
8480
8481static void
8482do_fpa_ldst (str)
8483     char * str;
8484{
8485  skip_whitespace (str);
8486
8487  if (fp_reg_required_here (&str, 12) == FAIL)
8488    {
8489      if (!inst.error)
8490	inst.error = BAD_ARGS;
8491      return;
8492    }
8493
8494  if (skip_past_comma (&str) == FAIL
8495      || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8496    {
8497      if (!inst.error)
8498	inst.error = BAD_ARGS;
8499      return;
8500    }
8501
8502  end_of_line (str);
8503}
8504
8505static void
8506do_fpa_ldmstm (str)
8507     char * str;
8508{
8509  int num_regs;
8510
8511  skip_whitespace (str);
8512
8513  if (fp_reg_required_here (&str, 12) == FAIL)
8514    {
8515      if (! inst.error)
8516	inst.error = BAD_ARGS;
8517      return;
8518    }
8519
8520  /* Get Number of registers to transfer.  */
8521  if (skip_past_comma (&str) == FAIL
8522      || my_get_expression (&inst.reloc.exp, &str))
8523    {
8524      if (! inst.error)
8525	inst.error = _("constant expression expected");
8526      return;
8527    }
8528
8529  if (inst.reloc.exp.X_op != O_constant)
8530    {
8531      inst.error = _("constant value required for number of registers");
8532      return;
8533    }
8534
8535  num_regs = inst.reloc.exp.X_add_number;
8536
8537  if (num_regs < 1 || num_regs > 4)
8538    {
8539      inst.error = _("number of registers must be in the range [1:4]");
8540      return;
8541    }
8542
8543  switch (num_regs)
8544    {
8545    case 1:
8546      inst.instruction |= CP_T_X;
8547      break;
8548    case 2:
8549      inst.instruction |= CP_T_Y;
8550      break;
8551    case 3:
8552      inst.instruction |= CP_T_Y | CP_T_X;
8553      break;
8554    case 4:
8555      break;
8556    default:
8557      abort ();
8558    }
8559
8560  if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
8561    {
8562      int reg;
8563      int write_back;
8564      int offset;
8565
8566      /* The instruction specified "ea" or "fd", so we can only accept
8567	 [Rn]{!}.  The instruction does not really support stacking or
8568	 unstacking, so we have to emulate these by setting appropriate
8569	 bits and offsets.  */
8570      if (skip_past_comma (&str) == FAIL
8571	  || *str != '[')
8572	{
8573	  if (! inst.error)
8574	    inst.error = BAD_ARGS;
8575	  return;
8576	}
8577
8578      str++;
8579      skip_whitespace (str);
8580
8581      if ((reg = reg_required_here (&str, 16)) == FAIL)
8582	return;
8583
8584      skip_whitespace (str);
8585
8586      if (*str != ']')
8587	{
8588	  inst.error = BAD_ARGS;
8589	  return;
8590	}
8591
8592      str++;
8593      if (*str == '!')
8594	{
8595	  write_back = 1;
8596	  str++;
8597	  if (reg == REG_PC)
8598	    {
8599	      inst.error =
8600		_("r15 not allowed as base register with write-back");
8601	      return;
8602	    }
8603	}
8604      else
8605	write_back = 0;
8606
8607      if (inst.instruction & CP_T_Pre)
8608	{
8609	  /* Pre-decrement.  */
8610	  offset = 3 * num_regs;
8611	  if (write_back)
8612	    inst.instruction |= CP_T_WB;
8613	}
8614      else
8615	{
8616	  /* Post-increment.  */
8617	  if (write_back)
8618	    {
8619	      inst.instruction |= CP_T_WB;
8620	      offset = 3 * num_regs;
8621	    }
8622	  else
8623	    {
8624	      /* No write-back, so convert this into a standard pre-increment
8625		 instruction -- aesthetically more pleasing.  */
8626	      inst.instruction |= CP_T_Pre | CP_T_UD;
8627	      offset = 0;
8628	    }
8629	}
8630
8631      inst.instruction |= offset;
8632    }
8633  else if (skip_past_comma (&str) == FAIL
8634	   || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8635    {
8636      if (! inst.error)
8637	inst.error = BAD_ARGS;
8638      return;
8639    }
8640
8641  end_of_line (str);
8642}
8643
8644static void
8645do_fpa_dyadic (str)
8646     char * str;
8647{
8648  skip_whitespace (str);
8649
8650  if (fp_reg_required_here (&str, 12) == FAIL)
8651    {
8652      if (! inst.error)
8653	inst.error = BAD_ARGS;
8654      return;
8655    }
8656
8657  if (skip_past_comma (&str) == FAIL
8658      || fp_reg_required_here (&str, 16) == FAIL)
8659    {
8660      if (! inst.error)
8661	inst.error = BAD_ARGS;
8662      return;
8663    }
8664
8665  if (skip_past_comma (&str) == FAIL
8666      || fp_op2 (&str) == FAIL)
8667    {
8668      if (! inst.error)
8669	inst.error = BAD_ARGS;
8670      return;
8671    }
8672
8673  end_of_line (str);
8674}
8675
8676static void
8677do_fpa_monadic (str)
8678     char * str;
8679{
8680  skip_whitespace (str);
8681
8682  if (fp_reg_required_here (&str, 12) == FAIL)
8683    {
8684      if (! inst.error)
8685	inst.error = BAD_ARGS;
8686      return;
8687    }
8688
8689  if (skip_past_comma (&str) == FAIL
8690      || fp_op2 (&str) == FAIL)
8691    {
8692      if (! inst.error)
8693	inst.error = BAD_ARGS;
8694      return;
8695    }
8696
8697  end_of_line (str);
8698}
8699
8700static void
8701do_fpa_cmp (str)
8702     char * str;
8703{
8704  skip_whitespace (str);
8705
8706  if (fp_reg_required_here (&str, 16) == FAIL)
8707    {
8708      if (! inst.error)
8709	inst.error = BAD_ARGS;
8710      return;
8711    }
8712
8713  if (skip_past_comma (&str) == FAIL
8714      || fp_op2 (&str) == FAIL)
8715    {
8716      if (! inst.error)
8717	inst.error = BAD_ARGS;
8718      return;
8719    }
8720
8721  end_of_line (str);
8722}
8723
8724static void
8725do_fpa_from_reg (str)
8726     char * str;
8727{
8728  skip_whitespace (str);
8729
8730  if (fp_reg_required_here (&str, 16) == FAIL)
8731    {
8732      if (! inst.error)
8733	inst.error = BAD_ARGS;
8734      return;
8735    }
8736
8737  if (skip_past_comma (&str) == FAIL
8738      || reg_required_here (&str, 12) == FAIL)
8739    {
8740      if (! inst.error)
8741	inst.error = BAD_ARGS;
8742      return;
8743    }
8744
8745  end_of_line (str);
8746}
8747
8748static void
8749do_fpa_to_reg (str)
8750     char * str;
8751{
8752  skip_whitespace (str);
8753
8754  if (reg_required_here (&str, 12) == FAIL)
8755    return;
8756
8757  if (skip_past_comma (&str) == FAIL
8758      || fp_reg_required_here (&str, 0) == FAIL)
8759    {
8760      if (! inst.error)
8761	inst.error = BAD_ARGS;
8762      return;
8763    }
8764
8765  end_of_line (str);
8766}
8767
8768static int
8769vfp_sp_reg_required_here (str, pos)
8770     char **str;
8771     enum vfp_sp_reg_pos pos;
8772{
8773  int    reg;
8774  char *start = *str;
8775
8776  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8777    {
8778      switch (pos)
8779	{
8780	case VFP_REG_Sd:
8781	  inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8782	  break;
8783
8784	case VFP_REG_Sn:
8785	  inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8786	  break;
8787
8788	case VFP_REG_Sm:
8789	  inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8790	  break;
8791
8792	default:
8793	  abort ();
8794	}
8795      return reg;
8796    }
8797
8798  /* In the few cases where we might be able to accept something else
8799     this error can be overridden.  */
8800  inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8801
8802  /* Restore the start point.  */
8803  *str = start;
8804  return FAIL;
8805}
8806
8807static int
8808vfp_dp_reg_required_here (str, pos)
8809     char **str;
8810     enum vfp_dp_reg_pos pos;
8811{
8812  int   reg;
8813  char *start = *str;
8814
8815  if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8816    {
8817      switch (pos)
8818	{
8819	case VFP_REG_Dd:
8820	  inst.instruction |= reg << 12;
8821	  break;
8822
8823	case VFP_REG_Dn:
8824	  inst.instruction |= reg << 16;
8825	  break;
8826
8827	case VFP_REG_Dm:
8828	  inst.instruction |= reg << 0;
8829	  break;
8830
8831	default:
8832	  abort ();
8833	}
8834      return reg;
8835    }
8836
8837  /* In the few cases where we might be able to accept something else
8838     this error can be overridden.  */
8839  inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8840
8841  /* Restore the start point.  */
8842  *str = start;
8843  return FAIL;
8844}
8845
8846static void
8847do_vfp_sp_monadic (str)
8848     char *str;
8849{
8850  skip_whitespace (str);
8851
8852  if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8853    return;
8854
8855  if (skip_past_comma (&str) == FAIL
8856      || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8857    {
8858      if (! inst.error)
8859	inst.error = BAD_ARGS;
8860      return;
8861    }
8862
8863  end_of_line (str);
8864}
8865
8866static void
8867do_vfp_dp_monadic (str)
8868     char *str;
8869{
8870  skip_whitespace (str);
8871
8872  if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8873    return;
8874
8875  if (skip_past_comma (&str) == FAIL
8876      || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8877    {
8878      if (! inst.error)
8879	inst.error = BAD_ARGS;
8880      return;
8881    }
8882
8883  end_of_line (str);
8884}
8885
8886static void
8887do_vfp_sp_dyadic (str)
8888     char *str;
8889{
8890  skip_whitespace (str);
8891
8892  if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8893    return;
8894
8895  if (skip_past_comma (&str) == FAIL
8896      || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8897      || skip_past_comma (&str) == FAIL
8898      || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8899    {
8900      if (! inst.error)
8901	inst.error = BAD_ARGS;
8902      return;
8903    }
8904
8905  end_of_line (str);
8906}
8907
8908static void
8909do_vfp_dp_dyadic (str)
8910     char *str;
8911{
8912  skip_whitespace (str);
8913
8914  if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8915    return;
8916
8917  if (skip_past_comma (&str) == FAIL
8918      || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8919      || skip_past_comma (&str) == FAIL
8920      || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8921    {
8922      if (! inst.error)
8923	inst.error = BAD_ARGS;
8924      return;
8925    }
8926
8927  end_of_line (str);
8928}
8929
8930static void
8931do_vfp_reg_from_sp (str)
8932     char *str;
8933{
8934  skip_whitespace (str);
8935
8936  if (reg_required_here (&str, 12) == FAIL)
8937    return;
8938
8939  if (skip_past_comma (&str) == FAIL
8940      || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8941    {
8942      if (! inst.error)
8943	inst.error = BAD_ARGS;
8944      return;
8945    }
8946
8947  end_of_line (str);
8948}
8949
8950static void
8951do_vfp_reg2_from_sp2 (str)
8952     char *str;
8953{
8954  skip_whitespace (str);
8955
8956  if (reg_required_here (&str, 12) == FAIL
8957      || skip_past_comma (&str) == FAIL
8958      || reg_required_here (&str, 16) == FAIL
8959      || skip_past_comma (&str) == FAIL)
8960    {
8961      if (! inst.error)
8962	inst.error = BAD_ARGS;
8963      return;
8964    }
8965
8966  /* We require exactly two consecutive SP registers.  */
8967  if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8968    {
8969      if (! inst.error)
8970	inst.error = _("only two consecutive VFP SP registers allowed here");
8971    }
8972
8973  end_of_line (str);
8974}
8975
8976static void
8977do_vfp_sp_from_reg (str)
8978     char *str;
8979{
8980  skip_whitespace (str);
8981
8982  if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8983    return;
8984
8985  if (skip_past_comma (&str) == FAIL
8986      || reg_required_here (&str, 12) == FAIL)
8987    {
8988      if (! inst.error)
8989	inst.error = BAD_ARGS;
8990      return;
8991    }
8992
8993  end_of_line (str);
8994}
8995
8996static void
8997do_vfp_sp2_from_reg2 (str)
8998     char *str;
8999{
9000  skip_whitespace (str);
9001
9002  /* We require exactly two consecutive SP registers.  */
9003  if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
9004    {
9005      if (! inst.error)
9006	inst.error = _("only two consecutive VFP SP registers allowed here");
9007    }
9008
9009  if (skip_past_comma (&str) == FAIL
9010      || reg_required_here (&str, 12) == FAIL
9011      || skip_past_comma (&str) == FAIL
9012      || reg_required_here (&str, 16) == FAIL)
9013    {
9014      if (! inst.error)
9015	inst.error = BAD_ARGS;
9016      return;
9017    }
9018
9019  end_of_line (str);
9020}
9021
9022static void
9023do_vfp_reg_from_dp (str)
9024     char *str;
9025{
9026  skip_whitespace (str);
9027
9028  if (reg_required_here (&str, 12) == FAIL)
9029    return;
9030
9031  if (skip_past_comma (&str) == FAIL
9032      || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9033    {
9034      if (! inst.error)
9035	inst.error = BAD_ARGS;
9036      return;
9037    }
9038
9039  end_of_line (str);
9040}
9041
9042static void
9043do_vfp_reg2_from_dp (str)
9044     char *str;
9045{
9046  skip_whitespace (str);
9047
9048  if (reg_required_here (&str, 12) == FAIL)
9049    return;
9050
9051  if (skip_past_comma (&str) == FAIL
9052      || reg_required_here (&str, 16) == FAIL
9053      || skip_past_comma (&str) == FAIL
9054      || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9055    {
9056      if (! inst.error)
9057	inst.error = BAD_ARGS;
9058      return;
9059    }
9060
9061  end_of_line (str);
9062}
9063
9064static void
9065do_vfp_dp_from_reg (str)
9066     char *str;
9067{
9068  skip_whitespace (str);
9069
9070  if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9071    return;
9072
9073  if (skip_past_comma (&str) == FAIL
9074      || reg_required_here (&str, 12) == FAIL)
9075    {
9076      if (! inst.error)
9077	inst.error = BAD_ARGS;
9078      return;
9079    }
9080
9081  end_of_line (str);
9082}
9083
9084static void
9085do_vfp_dp_from_reg2 (str)
9086     char *str;
9087{
9088  skip_whitespace (str);
9089
9090  if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9091    return;
9092
9093  if (skip_past_comma (&str) == FAIL
9094      || reg_required_here (&str, 12) == FAIL
9095      || skip_past_comma (&str) == FAIL
9096      || reg_required_here (&str, 16) == FAIL)
9097    {
9098      if (! inst.error)
9099	inst.error = BAD_ARGS;
9100      return;
9101    }
9102
9103  end_of_line (str);
9104}
9105
9106static const struct vfp_reg *
9107vfp_psr_parse (str)
9108     char **str;
9109{
9110  char *start = *str;
9111  char  c;
9112  char *p;
9113  const struct vfp_reg *vreg;
9114
9115  p = start;
9116
9117  /* Find the end of the current token.  */
9118  do
9119    {
9120      c = *p++;
9121    }
9122  while (ISALPHA (c));
9123
9124  /* Mark it.  */
9125  *--p = 0;
9126
9127  for (vreg = vfp_regs + 0;
9128       vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9129       vreg++)
9130    {
9131      if (strcmp (start, vreg->name) == 0)
9132	{
9133	  *p = c;
9134	  *str = p;
9135	  return vreg;
9136	}
9137    }
9138
9139  *p = c;
9140  return NULL;
9141}
9142
9143static int
9144vfp_psr_required_here (str)
9145     char **str;
9146{
9147  char *start = *str;
9148  const struct vfp_reg *vreg;
9149
9150  vreg = vfp_psr_parse (str);
9151
9152  if (vreg)
9153    {
9154      inst.instruction |= vreg->regno;
9155      return SUCCESS;
9156    }
9157
9158  inst.error = _("VFP system register expected");
9159
9160  *str = start;
9161  return FAIL;
9162}
9163
9164static void
9165do_vfp_reg_from_ctrl (str)
9166     char *str;
9167{
9168  skip_whitespace (str);
9169
9170  if (reg_required_here (&str, 12) == FAIL)
9171    return;
9172
9173  if (skip_past_comma (&str) == FAIL
9174      || vfp_psr_required_here (&str) == FAIL)
9175    {
9176      if (! inst.error)
9177	inst.error = BAD_ARGS;
9178      return;
9179    }
9180
9181  end_of_line (str);
9182}
9183
9184static void
9185do_vfp_ctrl_from_reg (str)
9186     char *str;
9187{
9188  skip_whitespace (str);
9189
9190  if (vfp_psr_required_here (&str) == FAIL)
9191    return;
9192
9193  if (skip_past_comma (&str) == FAIL
9194      || reg_required_here (&str, 12) == FAIL)
9195    {
9196      if (! inst.error)
9197	inst.error = BAD_ARGS;
9198      return;
9199    }
9200
9201  end_of_line (str);
9202}
9203
9204static void
9205do_vfp_sp_ldst (str)
9206     char *str;
9207{
9208  skip_whitespace (str);
9209
9210  if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9211    {
9212      if (!inst.error)
9213	inst.error = BAD_ARGS;
9214      return;
9215    }
9216
9217  if (skip_past_comma (&str) == FAIL
9218      || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9219    {
9220      if (!inst.error)
9221	inst.error = BAD_ARGS;
9222      return;
9223    }
9224
9225  end_of_line (str);
9226}
9227
9228static void
9229do_vfp_dp_ldst (str)
9230     char *str;
9231{
9232  skip_whitespace (str);
9233
9234  if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9235    {
9236      if (!inst.error)
9237	inst.error = BAD_ARGS;
9238      return;
9239    }
9240
9241  if (skip_past_comma (&str) == FAIL
9242      || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9243    {
9244      if (!inst.error)
9245	inst.error = BAD_ARGS;
9246      return;
9247    }
9248
9249  end_of_line (str);
9250}
9251
9252/* Parse and encode a VFP SP register list, storing the initial
9253   register in position POS and returning the range as the result.  If
9254   the string is invalid return FAIL (an invalid range).  */
9255static long
9256vfp_sp_reg_list (str, pos)
9257     char **str;
9258     enum vfp_sp_reg_pos pos;
9259{
9260  long range = 0;
9261  int base_reg = 0;
9262  int new_base;
9263  long base_bits = 0;
9264  int count = 0;
9265  long tempinst;
9266  unsigned long mask = 0;
9267  int warned = 0;
9268
9269  if (**str != '{')
9270    return FAIL;
9271
9272  (*str)++;
9273  skip_whitespace (*str);
9274
9275  tempinst = inst.instruction;
9276
9277  do
9278    {
9279      inst.instruction = 0;
9280
9281      if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9282	return FAIL;
9283
9284      if (count == 0 || base_reg > new_base)
9285	{
9286	  base_reg = new_base;
9287	  base_bits = inst.instruction;
9288	}
9289
9290      if (mask & (1 << new_base))
9291	{
9292	  inst.error = _("invalid register list");
9293	  return FAIL;
9294	}
9295
9296      if ((mask >> new_base) != 0 && ! warned)
9297	{
9298	  as_tsktsk (_("register list not in ascending order"));
9299	  warned = 1;
9300	}
9301
9302      mask |= 1 << new_base;
9303      count++;
9304
9305      skip_whitespace (*str);
9306
9307      if (**str == '-') /* We have the start of a range expression */
9308	{
9309	  int high_range;
9310
9311	  (*str)++;
9312
9313	  if ((high_range
9314	       = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9315	      == FAIL)
9316	    {
9317	      inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9318	      return FAIL;
9319	    }
9320
9321	  if (high_range <= new_base)
9322	    {
9323	      inst.error = _("register range not in ascending order");
9324	      return FAIL;
9325	    }
9326
9327	  for (new_base++; new_base <= high_range; new_base++)
9328	    {
9329	      if (mask & (1 << new_base))
9330		{
9331		  inst.error = _("invalid register list");
9332		  return FAIL;
9333		}
9334
9335	      mask |= 1 << new_base;
9336	      count++;
9337	    }
9338	}
9339    }
9340  while (skip_past_comma (str) != FAIL);
9341
9342  if (**str != '}')
9343    {
9344      inst.error = _("invalid register list");
9345      return FAIL;
9346    }
9347
9348  (*str)++;
9349
9350  range = count;
9351
9352  /* Sanity check -- should have raised a parse error above.  */
9353  if (count == 0 || count > 32)
9354    abort ();
9355
9356  /* Final test -- the registers must be consecutive.  */
9357  while (count--)
9358    {
9359      if ((mask & (1 << base_reg++)) == 0)
9360	{
9361	  inst.error = _("non-contiguous register range");
9362	  return FAIL;
9363	}
9364    }
9365
9366  inst.instruction = tempinst | base_bits;
9367  return range;
9368}
9369
9370static long
9371vfp_dp_reg_list (str)
9372     char **str;
9373{
9374  long range = 0;
9375  int base_reg = 0;
9376  int new_base;
9377  int count = 0;
9378  long tempinst;
9379  unsigned long mask = 0;
9380  int warned = 0;
9381
9382  if (**str != '{')
9383    return FAIL;
9384
9385  (*str)++;
9386  skip_whitespace (*str);
9387
9388  tempinst = inst.instruction;
9389
9390  do
9391    {
9392      inst.instruction = 0;
9393
9394      if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9395	return FAIL;
9396
9397      if (count == 0 || base_reg > new_base)
9398	{
9399	  base_reg = new_base;
9400	  range = inst.instruction;
9401	}
9402
9403      if (mask & (1 << new_base))
9404	{
9405	  inst.error = _("invalid register list");
9406	  return FAIL;
9407	}
9408
9409      if ((mask >> new_base) != 0 && ! warned)
9410	{
9411	  as_tsktsk (_("register list not in ascending order"));
9412	  warned = 1;
9413	}
9414
9415      mask |= 1 << new_base;
9416      count++;
9417
9418      skip_whitespace (*str);
9419
9420      if (**str == '-') /* We have the start of a range expression */
9421	{
9422	  int high_range;
9423
9424	  (*str)++;
9425
9426	  if ((high_range
9427	       = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9428	      == FAIL)
9429	    {
9430	      inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9431	      return FAIL;
9432	    }
9433
9434	  if (high_range <= new_base)
9435	    {
9436	      inst.error = _("register range not in ascending order");
9437	      return FAIL;
9438	    }
9439
9440	  for (new_base++; new_base <= high_range; new_base++)
9441	    {
9442	      if (mask & (1 << new_base))
9443		{
9444		  inst.error = _("invalid register list");
9445		  return FAIL;
9446		}
9447
9448	      mask |= 1 << new_base;
9449	      count++;
9450	    }
9451	}
9452    }
9453  while (skip_past_comma (str) != FAIL);
9454
9455  if (**str != '}')
9456    {
9457      inst.error = _("invalid register list");
9458      return FAIL;
9459    }
9460
9461  (*str)++;
9462
9463  range |= 2 * count;
9464
9465  /* Sanity check -- should have raised a parse error above.  */
9466  if (count == 0 || count > 16)
9467    abort ();
9468
9469  /* Final test -- the registers must be consecutive.  */
9470  while (count--)
9471    {
9472      if ((mask & (1 << base_reg++)) == 0)
9473	{
9474	  inst.error = _("non-contiguous register range");
9475	  return FAIL;
9476	}
9477    }
9478
9479  inst.instruction = tempinst;
9480  return range;
9481}
9482
9483static void
9484vfp_sp_ldstm (str, ldstm_type)
9485     char *str;
9486     enum vfp_ldstm_type ldstm_type;
9487{
9488  long range;
9489
9490  skip_whitespace (str);
9491
9492  if (reg_required_here (&str, 16) == FAIL)
9493    return;
9494
9495  skip_whitespace (str);
9496
9497  if (*str == '!')
9498    {
9499      inst.instruction |= WRITE_BACK;
9500      str++;
9501    }
9502  else if (ldstm_type != VFP_LDSTMIA)
9503    {
9504      inst.error = _("this addressing mode requires base-register writeback");
9505      return;
9506    }
9507
9508  if (skip_past_comma (&str) == FAIL
9509      || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9510    {
9511      if (!inst.error)
9512	inst.error = BAD_ARGS;
9513      return;
9514    }
9515
9516  inst.instruction |= range;
9517  end_of_line (str);
9518}
9519
9520static void
9521vfp_dp_ldstm (str, ldstm_type)
9522     char *str;
9523     enum vfp_ldstm_type ldstm_type;
9524{
9525  long range;
9526
9527  skip_whitespace (str);
9528
9529  if (reg_required_here (&str, 16) == FAIL)
9530    return;
9531
9532  skip_whitespace (str);
9533
9534  if (*str == '!')
9535    {
9536      inst.instruction |= WRITE_BACK;
9537      str++;
9538    }
9539  else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9540    {
9541      inst.error = _("this addressing mode requires base-register writeback");
9542      return;
9543    }
9544
9545  if (skip_past_comma (&str) == FAIL
9546      || (range = vfp_dp_reg_list (&str)) == FAIL)
9547    {
9548      if (!inst.error)
9549	inst.error = BAD_ARGS;
9550      return;
9551    }
9552
9553  if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9554    range += 1;
9555
9556  inst.instruction |= range;
9557  end_of_line (str);
9558}
9559
9560static void
9561do_vfp_sp_ldstmia (str)
9562     char *str;
9563{
9564  vfp_sp_ldstm (str, VFP_LDSTMIA);
9565}
9566
9567static void
9568do_vfp_sp_ldstmdb (str)
9569     char *str;
9570{
9571  vfp_sp_ldstm (str, VFP_LDSTMDB);
9572}
9573
9574static void
9575do_vfp_dp_ldstmia (str)
9576     char *str;
9577{
9578  vfp_dp_ldstm (str, VFP_LDSTMIA);
9579}
9580
9581static void
9582do_vfp_dp_ldstmdb (str)
9583     char *str;
9584{
9585  vfp_dp_ldstm (str, VFP_LDSTMDB);
9586}
9587
9588static void
9589do_vfp_xp_ldstmia (str)
9590     char *str;
9591{
9592  vfp_dp_ldstm (str, VFP_LDSTMIAX);
9593}
9594
9595static void
9596do_vfp_xp_ldstmdb (str)
9597     char *str;
9598{
9599  vfp_dp_ldstm (str, VFP_LDSTMDBX);
9600}
9601
9602static void
9603do_vfp_sp_compare_z (str)
9604     char *str;
9605{
9606  skip_whitespace (str);
9607
9608  if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9609    {
9610      if (!inst.error)
9611	inst.error = BAD_ARGS;
9612      return;
9613    }
9614
9615  end_of_line (str);
9616}
9617
9618static void
9619do_vfp_dp_compare_z (str)
9620     char *str;
9621{
9622  skip_whitespace (str);
9623
9624  if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9625    {
9626      if (!inst.error)
9627	inst.error = BAD_ARGS;
9628      return;
9629    }
9630
9631  end_of_line (str);
9632}
9633
9634static void
9635do_vfp_dp_sp_cvt (str)
9636     char *str;
9637{
9638  skip_whitespace (str);
9639
9640  if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9641    return;
9642
9643  if (skip_past_comma (&str) == FAIL
9644      || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9645    {
9646      if (! inst.error)
9647	inst.error = BAD_ARGS;
9648      return;
9649    }
9650
9651  end_of_line (str);
9652}
9653
9654static void
9655do_vfp_sp_dp_cvt (str)
9656     char *str;
9657{
9658  skip_whitespace (str);
9659
9660  if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9661    return;
9662
9663  if (skip_past_comma (&str) == FAIL
9664      || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9665    {
9666      if (! inst.error)
9667	inst.error = BAD_ARGS;
9668      return;
9669    }
9670
9671  end_of_line (str);
9672}
9673
9674/* Thumb specific routines.  */
9675
9676/* Parse and validate that a register is of the right form, this saves
9677   repeated checking of this information in many similar cases.
9678   Unlike the 32-bit case we do not insert the register into the opcode
9679   here, since the position is often unknown until the full instruction
9680   has been parsed.  */
9681
9682static int
9683thumb_reg (strp, hi_lo)
9684     char ** strp;
9685     int     hi_lo;
9686{
9687  int reg;
9688
9689  if ((reg = reg_required_here (strp, -1)) == FAIL)
9690    return FAIL;
9691
9692  switch (hi_lo)
9693    {
9694    case THUMB_REG_LO:
9695      if (reg > 7)
9696	{
9697	  inst.error = _("lo register required");
9698	  return FAIL;
9699	}
9700      break;
9701
9702    case THUMB_REG_HI:
9703      if (reg < 8)
9704	{
9705	  inst.error = _("hi register required");
9706	  return FAIL;
9707	}
9708      break;
9709
9710    default:
9711      break;
9712    }
9713
9714  return reg;
9715}
9716
9717/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9718   was SUB.  */
9719
9720static void
9721thumb_add_sub (str, subtract)
9722     char * str;
9723     int    subtract;
9724{
9725  int Rd, Rs, Rn = FAIL;
9726
9727  skip_whitespace (str);
9728
9729  if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9730      || skip_past_comma (&str) == FAIL)
9731    {
9732      if (! inst.error)
9733	inst.error = BAD_ARGS;
9734      return;
9735    }
9736
9737  if (is_immediate_prefix (*str))
9738    {
9739      Rs = Rd;
9740      str++;
9741      if (my_get_expression (&inst.reloc.exp, &str))
9742	return;
9743    }
9744  else
9745    {
9746      if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9747	return;
9748
9749      if (skip_past_comma (&str) == FAIL)
9750	{
9751	  /* Two operand format, shuffle the registers
9752	     and pretend there are 3.  */
9753	  Rn = Rs;
9754	  Rs = Rd;
9755	}
9756      else if (is_immediate_prefix (*str))
9757	{
9758	  str++;
9759	  if (my_get_expression (&inst.reloc.exp, &str))
9760	    return;
9761	}
9762      else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9763	return;
9764    }
9765
9766  /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9767     for the latter case, EXPR contains the immediate that was found.  */
9768  if (Rn != FAIL)
9769    {
9770      /* All register format.  */
9771      if (Rd > 7 || Rs > 7 || Rn > 7)
9772	{
9773	  if (Rs != Rd)
9774	    {
9775	      inst.error = _("dest and source1 must be the same register");
9776	      return;
9777	    }
9778
9779	  /* Can't do this for SUB.  */
9780	  if (subtract)
9781	    {
9782	      inst.error = _("subtract valid only on lo regs");
9783	      return;
9784	    }
9785
9786	  inst.instruction = (T_OPCODE_ADD_HI
9787			      | (Rd > 7 ? THUMB_H1 : 0)
9788			      | (Rn > 7 ? THUMB_H2 : 0));
9789	  inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9790	}
9791      else
9792	{
9793	  inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9794	  inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9795	}
9796    }
9797  else
9798    {
9799      /* Immediate expression, now things start to get nasty.  */
9800
9801      /* First deal with HI regs, only very restricted cases allowed:
9802	 Adjusting SP, and using PC or SP to get an address.  */
9803      if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9804	  || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9805	{
9806	  inst.error = _("invalid Hi register with immediate");
9807	  return;
9808	}
9809
9810      if (inst.reloc.exp.X_op != O_constant)
9811	{
9812	  /* Value isn't known yet, all we can do is store all the fragments
9813	     we know about in the instruction and let the reloc hacking
9814	     work it all out.  */
9815	  inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9816	  inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9817	}
9818      else
9819	{
9820	  int offset = inst.reloc.exp.X_add_number;
9821
9822	  if (subtract)
9823	    offset = - offset;
9824
9825	  if (offset < 0)
9826	    {
9827	      offset = - offset;
9828	      subtract = 1;
9829
9830	      /* Quick check, in case offset is MIN_INT.  */
9831	      if (offset < 0)
9832		{
9833		  inst.error = _("immediate value out of range");
9834		  return;
9835		}
9836	    }
9837	  /* Note - you cannot convert a subtract of 0 into an
9838	     add of 0 because the carry flag is set differently.  */
9839	  else if (offset > 0)
9840	    subtract = 0;
9841
9842	  if (Rd == REG_SP)
9843	    {
9844	      if (offset & ~0x1fc)
9845		{
9846		  inst.error = _("invalid immediate value for stack adjust");
9847		  return;
9848		}
9849	      inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9850	      inst.instruction |= offset >> 2;
9851	    }
9852	  else if (Rs == REG_PC || Rs == REG_SP)
9853	    {
9854	      if (subtract
9855		  || (offset & ~0x3fc))
9856		{
9857		  inst.error = _("invalid immediate for address calculation");
9858		  return;
9859		}
9860	      inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9861				  : T_OPCODE_ADD_SP);
9862	      inst.instruction |= (Rd << 8) | (offset >> 2);
9863	    }
9864	  else if (Rs == Rd)
9865	    {
9866	      if (offset & ~0xff)
9867		{
9868		  inst.error = _("immediate value out of range");
9869		  return;
9870		}
9871	      inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9872	      inst.instruction |= (Rd << 8) | offset;
9873	    }
9874	  else
9875	    {
9876	      if (offset & ~0x7)
9877		{
9878		  inst.error = _("immediate value out of range");
9879		  return;
9880		}
9881	      inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9882	      inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9883	    }
9884	}
9885    }
9886
9887  end_of_line (str);
9888}
9889
9890static void
9891thumb_shift (str, shift)
9892     char * str;
9893     int    shift;
9894{
9895  int Rd, Rs, Rn = FAIL;
9896
9897  skip_whitespace (str);
9898
9899  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9900      || skip_past_comma (&str) == FAIL)
9901    {
9902      if (! inst.error)
9903	inst.error = BAD_ARGS;
9904      return;
9905    }
9906
9907  if (is_immediate_prefix (*str))
9908    {
9909      /* Two operand immediate format, set Rs to Rd.  */
9910      Rs = Rd;
9911      str ++;
9912      if (my_get_expression (&inst.reloc.exp, &str))
9913	return;
9914    }
9915  else
9916    {
9917      if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9918	return;
9919
9920      if (skip_past_comma (&str) == FAIL)
9921	{
9922	  /* Two operand format, shuffle the registers
9923	     and pretend there are 3.  */
9924	  Rn = Rs;
9925	  Rs = Rd;
9926	}
9927      else if (is_immediate_prefix (*str))
9928	{
9929	  str++;
9930	  if (my_get_expression (&inst.reloc.exp, &str))
9931	    return;
9932	}
9933      else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9934	return;
9935    }
9936
9937  /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9938     for the latter case, EXPR contains the immediate that was found.  */
9939
9940  if (Rn != FAIL)
9941    {
9942      if (Rs != Rd)
9943	{
9944	  inst.error = _("source1 and dest must be same register");
9945	  return;
9946	}
9947
9948      switch (shift)
9949	{
9950	case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9951	case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9952	case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9953	}
9954
9955      inst.instruction |= Rd | (Rn << 3);
9956    }
9957  else
9958    {
9959      switch (shift)
9960	{
9961	case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9962	case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9963	case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9964	}
9965
9966      if (inst.reloc.exp.X_op != O_constant)
9967	{
9968	  /* Value isn't known yet, create a dummy reloc and let reloc
9969	     hacking fix it up.  */
9970	  inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9971	}
9972      else
9973	{
9974	  unsigned shift_value = inst.reloc.exp.X_add_number;
9975
9976	  if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9977	    {
9978	      inst.error = _("invalid immediate for shift");
9979	      return;
9980	    }
9981
9982	  /* Shifts of zero are handled by converting to LSL.  */
9983	  if (shift_value == 0)
9984	    inst.instruction = T_OPCODE_LSL_I;
9985
9986	  /* Shifts of 32 are encoded as a shift of zero.  */
9987	  if (shift_value == 32)
9988	    shift_value = 0;
9989
9990	  inst.instruction |= shift_value << 6;
9991	}
9992
9993      inst.instruction |= Rd | (Rs << 3);
9994    }
9995
9996  end_of_line (str);
9997}
9998
9999static void
10000thumb_mov_compare (str, move)
10001     char * str;
10002     int    move;
10003{
10004  int Rd, Rs = FAIL;
10005
10006  skip_whitespace (str);
10007
10008  if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
10009      || skip_past_comma (&str) == FAIL)
10010    {
10011      if (! inst.error)
10012	inst.error = BAD_ARGS;
10013      return;
10014    }
10015
10016  if (move != THUMB_CPY && is_immediate_prefix (*str))
10017    {
10018      str++;
10019      if (my_get_expression (&inst.reloc.exp, &str))
10020	return;
10021    }
10022  else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10023    return;
10024
10025  if (Rs != FAIL)
10026    {
10027      if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10028	{
10029	  if (move == THUMB_MOVE)
10030	    /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10031	       since a MOV instruction produces unpredictable results.  */
10032	    inst.instruction = T_OPCODE_ADD_I3;
10033	  else
10034	    inst.instruction = T_OPCODE_CMP_LR;
10035	  inst.instruction |= Rd | (Rs << 3);
10036	}
10037      else
10038	{
10039	  if (move == THUMB_MOVE)
10040	    inst.instruction = T_OPCODE_MOV_HR;
10041	  else if (move != THUMB_CPY)
10042	    inst.instruction = T_OPCODE_CMP_HR;
10043
10044	  if (Rd > 7)
10045	    inst.instruction |= THUMB_H1;
10046
10047	  if (Rs > 7)
10048	    inst.instruction |= THUMB_H2;
10049
10050	  inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10051	}
10052    }
10053  else
10054    {
10055      if (Rd > 7)
10056	{
10057	  inst.error = _("only lo regs allowed with immediate");
10058	  return;
10059	}
10060
10061      if (move == THUMB_MOVE)
10062	inst.instruction = T_OPCODE_MOV_I8;
10063      else
10064	inst.instruction = T_OPCODE_CMP_I8;
10065
10066      inst.instruction |= Rd << 8;
10067
10068      if (inst.reloc.exp.X_op != O_constant)
10069	inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10070      else
10071	{
10072	  unsigned value = inst.reloc.exp.X_add_number;
10073
10074	  if (value > 255)
10075	    {
10076	      inst.error = _("invalid immediate");
10077	      return;
10078	    }
10079
10080	  inst.instruction |= value;
10081	}
10082    }
10083
10084  end_of_line (str);
10085}
10086
10087static void
10088thumb_load_store (str, load_store, size)
10089     char * str;
10090     int    load_store;
10091     int    size;
10092{
10093  int Rd, Rb, Ro = FAIL;
10094
10095  skip_whitespace (str);
10096
10097  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10098      || skip_past_comma (&str) == FAIL)
10099    {
10100      if (! inst.error)
10101	inst.error = BAD_ARGS;
10102      return;
10103    }
10104
10105  if (*str == '[')
10106    {
10107      str++;
10108      if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10109	return;
10110
10111      if (skip_past_comma (&str) != FAIL)
10112	{
10113	  if (is_immediate_prefix (*str))
10114	    {
10115	      str++;
10116	      if (my_get_expression (&inst.reloc.exp, &str))
10117		return;
10118	    }
10119	  else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10120	    return;
10121	}
10122      else
10123	{
10124	  inst.reloc.exp.X_op = O_constant;
10125	  inst.reloc.exp.X_add_number = 0;
10126	}
10127
10128      if (*str != ']')
10129	{
10130	  inst.error = _("expected ']'");
10131	  return;
10132	}
10133      str++;
10134    }
10135  else if (*str == '=')
10136    {
10137      if (load_store != THUMB_LOAD)
10138	{
10139	  inst.error = _("invalid pseudo operation");
10140	  return;
10141	}
10142
10143      /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
10144      str++;
10145
10146      skip_whitespace (str);
10147
10148      if (my_get_expression (& inst.reloc.exp, & str))
10149	return;
10150
10151      end_of_line (str);
10152
10153      if (   inst.reloc.exp.X_op != O_constant
10154	  && inst.reloc.exp.X_op != O_symbol)
10155	{
10156	  inst.error = "Constant expression expected";
10157	  return;
10158	}
10159
10160      if (inst.reloc.exp.X_op == O_constant
10161	  && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10162	{
10163	  /* This can be done with a mov instruction.  */
10164
10165	  inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
10166	  inst.instruction |= inst.reloc.exp.X_add_number;
10167	  return;
10168	}
10169
10170      /* Insert into literal pool.  */
10171      if (add_to_lit_pool () == FAIL)
10172	{
10173	  if (!inst.error)
10174	    inst.error = "literal pool insertion failed";
10175	  return;
10176	}
10177
10178      inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
10179      inst.reloc.pc_rel = 1;
10180      inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
10181      /* Adjust ARM pipeline offset to Thumb.  */
10182      inst.reloc.exp.X_add_number += 4;
10183
10184      return;
10185    }
10186  else
10187    {
10188      if (my_get_expression (&inst.reloc.exp, &str))
10189	return;
10190
10191      inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10192      inst.reloc.pc_rel = 1;
10193      inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
10194      inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10195      end_of_line (str);
10196      return;
10197    }
10198
10199  if (Rb == REG_PC || Rb == REG_SP)
10200    {
10201      if (size != THUMB_WORD)
10202	{
10203	  inst.error = _("byte or halfword not valid for base register");
10204	  return;
10205	}
10206      else if (Rb == REG_PC && load_store != THUMB_LOAD)
10207	{
10208	  inst.error = _("r15 based store not allowed");
10209	  return;
10210	}
10211      else if (Ro != FAIL)
10212	{
10213	  inst.error = _("invalid base register for register offset");
10214	  return;
10215	}
10216
10217      if (Rb == REG_PC)
10218	inst.instruction = T_OPCODE_LDR_PC;
10219      else if (load_store == THUMB_LOAD)
10220	inst.instruction = T_OPCODE_LDR_SP;
10221      else
10222	inst.instruction = T_OPCODE_STR_SP;
10223
10224      inst.instruction |= Rd << 8;
10225      if (inst.reloc.exp.X_op == O_constant)
10226	{
10227	  unsigned offset = inst.reloc.exp.X_add_number;
10228
10229	  if (offset & ~0x3fc)
10230	    {
10231	      inst.error = _("invalid offset");
10232	      return;
10233	    }
10234
10235	  inst.instruction |= offset >> 2;
10236	}
10237      else
10238	inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10239    }
10240  else if (Rb > 7)
10241    {
10242      inst.error = _("invalid base register in load/store");
10243      return;
10244    }
10245  else if (Ro == FAIL)
10246    {
10247      /* Immediate offset.  */
10248      if (size == THUMB_WORD)
10249	inst.instruction = (load_store == THUMB_LOAD
10250			    ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10251      else if (size == THUMB_HALFWORD)
10252	inst.instruction = (load_store == THUMB_LOAD
10253			    ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10254      else
10255	inst.instruction = (load_store == THUMB_LOAD
10256			    ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10257
10258      inst.instruction |= Rd | (Rb << 3);
10259
10260      if (inst.reloc.exp.X_op == O_constant)
10261	{
10262	  unsigned offset = inst.reloc.exp.X_add_number;
10263
10264	  if (offset & ~(0x1f << size))
10265	    {
10266	      inst.error = _("invalid offset");
10267	      return;
10268	    }
10269	  inst.instruction |= (offset >> size) << 6;
10270	}
10271      else
10272	inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10273    }
10274  else
10275    {
10276      /* Register offset.  */
10277      if (size == THUMB_WORD)
10278	inst.instruction = (load_store == THUMB_LOAD
10279			    ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10280      else if (size == THUMB_HALFWORD)
10281	inst.instruction = (load_store == THUMB_LOAD
10282			    ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10283      else
10284	inst.instruction = (load_store == THUMB_LOAD
10285			    ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10286
10287      inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10288    }
10289
10290  end_of_line (str);
10291}
10292
10293/* A register must be given at this point.
10294
10295   Shift is the place to put it in inst.instruction.
10296
10297   Restores input start point on err.
10298   Returns the reg#, or FAIL.  */
10299
10300static int
10301mav_reg_required_here (str, shift, regtype)
10302     char ** str;
10303     int shift;
10304     enum arm_reg_type regtype;
10305{
10306  int   reg;
10307  char *start = *str;
10308
10309  if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10310    {
10311      if (shift >= 0)
10312	inst.instruction |= reg << shift;
10313
10314      return reg;
10315    }
10316
10317  /* Restore the start point.  */
10318  *str = start;
10319
10320  /* In the few cases where we might be able to accept something else
10321     this error can be overridden.  */
10322  inst.error = _(all_reg_maps[regtype].expected);
10323
10324  return FAIL;
10325}
10326
10327/* Cirrus Maverick Instructions.  */
10328
10329/* Wrapper functions.  */
10330
10331static void
10332do_mav_binops_1a (str)
10333     char * str;
10334{
10335  do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10336}
10337
10338static void
10339do_mav_binops_1b (str)
10340     char * str;
10341{
10342  do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10343}
10344
10345static void
10346do_mav_binops_1c (str)
10347     char * str;
10348{
10349  do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10350}
10351
10352static void
10353do_mav_binops_1d (str)
10354     char * str;
10355{
10356  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10357}
10358
10359static void
10360do_mav_binops_1e (str)
10361     char * str;
10362{
10363  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10364}
10365
10366static void
10367do_mav_binops_1f (str)
10368     char * str;
10369{
10370  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10371}
10372
10373static void
10374do_mav_binops_1g (str)
10375     char * str;
10376{
10377  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10378}
10379
10380static void
10381do_mav_binops_1h (str)
10382     char * str;
10383{
10384  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10385}
10386
10387static void
10388do_mav_binops_1i (str)
10389     char * str;
10390{
10391  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10392}
10393
10394static void
10395do_mav_binops_1j (str)
10396     char * str;
10397{
10398  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10399}
10400
10401static void
10402do_mav_binops_1k (str)
10403     char * str;
10404{
10405  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10406}
10407
10408static void
10409do_mav_binops_1l (str)
10410     char * str;
10411{
10412  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10413}
10414
10415static void
10416do_mav_binops_1m (str)
10417     char * str;
10418{
10419  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10420}
10421
10422static void
10423do_mav_binops_1n (str)
10424     char * str;
10425{
10426  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10427}
10428
10429static void
10430do_mav_binops_1o (str)
10431     char * str;
10432{
10433  do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10434}
10435
10436static void
10437do_mav_binops_2a (str)
10438     char * str;
10439{
10440  do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10441}
10442
10443static void
10444do_mav_binops_2b (str)
10445     char * str;
10446{
10447  do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10448}
10449
10450static void
10451do_mav_binops_2c (str)
10452     char * str;
10453{
10454  do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10455}
10456
10457static void
10458do_mav_binops_3a (str)
10459     char * str;
10460{
10461  do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10462}
10463
10464static void
10465do_mav_binops_3b (str)
10466     char * str;
10467{
10468  do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10469}
10470
10471static void
10472do_mav_binops_3c (str)
10473     char * str;
10474{
10475  do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10476}
10477
10478static void
10479do_mav_binops_3d (str)
10480     char * str;
10481{
10482  do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10483}
10484
10485static void
10486do_mav_triple_4a (str)
10487     char * str;
10488{
10489  do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10490}
10491
10492static void
10493do_mav_triple_4b (str)
10494     char * str;
10495{
10496  do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10497}
10498
10499static void
10500do_mav_triple_5a (str)
10501     char * str;
10502{
10503  do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10504}
10505
10506static void
10507do_mav_triple_5b (str)
10508     char * str;
10509{
10510  do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10511}
10512
10513static void
10514do_mav_triple_5c (str)
10515     char * str;
10516{
10517  do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10518}
10519
10520static void
10521do_mav_triple_5d (str)
10522     char * str;
10523{
10524  do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10525}
10526
10527static void
10528do_mav_triple_5e (str)
10529     char * str;
10530{
10531  do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10532}
10533
10534static void
10535do_mav_triple_5f (str)
10536     char * str;
10537{
10538  do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10539}
10540
10541static void
10542do_mav_triple_5g (str)
10543     char * str;
10544{
10545  do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10546}
10547
10548static void
10549do_mav_triple_5h (str)
10550     char * str;
10551{
10552  do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10553}
10554
10555static void
10556do_mav_quad_6a (str)
10557     char * str;
10558{
10559  do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10560	     REG_TYPE_MVFX);
10561}
10562
10563static void
10564do_mav_quad_6b (str)
10565     char * str;
10566{
10567  do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10568	     REG_TYPE_MVFX);
10569}
10570
10571/* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
10572static void
10573do_mav_dspsc_1 (str)
10574     char * str;
10575{
10576  skip_whitespace (str);
10577
10578  /* cfmvsc32.  */
10579  if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10580      || skip_past_comma (&str) == FAIL
10581      || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10582    {
10583      if (!inst.error)
10584	inst.error = BAD_ARGS;
10585
10586      return;
10587    }
10588
10589  end_of_line (str);
10590}
10591
10592/* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
10593static void
10594do_mav_dspsc_2 (str)
10595     char * str;
10596{
10597  skip_whitespace (str);
10598
10599  /* cfmv32sc.  */
10600  if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10601      || skip_past_comma (&str) == FAIL
10602      || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10603    {
10604      if (!inst.error)
10605	inst.error = BAD_ARGS;
10606
10607      return;
10608    }
10609
10610  end_of_line (str);
10611}
10612
10613static void
10614do_mav_shift_1 (str)
10615     char * str;
10616{
10617  do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10618}
10619
10620static void
10621do_mav_shift_2 (str)
10622     char * str;
10623{
10624  do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10625}
10626
10627static void
10628do_mav_ldst_1 (str)
10629     char * str;
10630{
10631  do_mav_ldst (str, REG_TYPE_MVF);
10632}
10633
10634static void
10635do_mav_ldst_2 (str)
10636     char * str;
10637{
10638  do_mav_ldst (str, REG_TYPE_MVD);
10639}
10640
10641static void
10642do_mav_ldst_3 (str)
10643     char * str;
10644{
10645  do_mav_ldst (str, REG_TYPE_MVFX);
10646}
10647
10648static void
10649do_mav_ldst_4 (str)
10650     char * str;
10651{
10652  do_mav_ldst (str, REG_TYPE_MVDX);
10653}
10654
10655/* Isnsn like "foo X,Y".  */
10656
10657static void
10658do_mav_binops (str, mode, reg0, reg1)
10659     char * str;
10660     int mode;
10661     enum arm_reg_type reg0;
10662     enum arm_reg_type reg1;
10663{
10664  int shift0, shift1;
10665
10666  shift0 = mode & 0xff;
10667  shift1 = (mode >> 8) & 0xff;
10668
10669  skip_whitespace (str);
10670
10671  if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10672      || skip_past_comma (&str) == FAIL
10673      || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10674    {
10675      if (!inst.error)
10676	inst.error = BAD_ARGS;
10677    }
10678  else
10679    end_of_line (str);
10680}
10681
10682/* Isnsn like "foo X,Y,Z".  */
10683
10684static void
10685do_mav_triple (str, mode, reg0, reg1, reg2)
10686     char * str;
10687     int mode;
10688     enum arm_reg_type reg0;
10689     enum arm_reg_type reg1;
10690     enum arm_reg_type reg2;
10691{
10692  int shift0, shift1, shift2;
10693
10694  shift0 = mode & 0xff;
10695  shift1 = (mode >> 8) & 0xff;
10696  shift2 = (mode >> 16) & 0xff;
10697
10698  skip_whitespace (str);
10699
10700  if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10701      || skip_past_comma (&str) == FAIL
10702      || mav_reg_required_here (&str, shift1, reg1) == FAIL
10703      || skip_past_comma (&str) == FAIL
10704      || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10705    {
10706      if (!inst.error)
10707	inst.error = BAD_ARGS;
10708    }
10709  else
10710    end_of_line (str);
10711}
10712
10713/* Isnsn like "foo W,X,Y,Z".
10714    where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
10715
10716static void
10717do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10718     char * str;
10719     int mode;
10720     enum arm_reg_type reg0;
10721     enum arm_reg_type reg1;
10722     enum arm_reg_type reg2;
10723     enum arm_reg_type reg3;
10724{
10725  int shift0, shift1, shift2, shift3;
10726
10727  shift0= mode & 0xff;
10728  shift1 = (mode >> 8) & 0xff;
10729  shift2 = (mode >> 16) & 0xff;
10730  shift3 = (mode >> 24) & 0xff;
10731
10732  skip_whitespace (str);
10733
10734  if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10735      || skip_past_comma (&str) == FAIL
10736      || mav_reg_required_here (&str, shift1, reg1) == FAIL
10737      || skip_past_comma (&str) == FAIL
10738      || mav_reg_required_here (&str, shift2, reg2) == FAIL
10739      || skip_past_comma (&str) == FAIL
10740      || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10741    {
10742      if (!inst.error)
10743	inst.error = BAD_ARGS;
10744    }
10745  else
10746    end_of_line (str);
10747}
10748
10749/* Maverick shift immediate instructions.
10750   cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10751   cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
10752
10753static void
10754do_mav_shift (str, reg0, reg1)
10755     char * str;
10756     enum arm_reg_type reg0;
10757     enum arm_reg_type reg1;
10758{
10759  int error;
10760  int imm, neg = 0;
10761
10762  skip_whitespace (str);
10763
10764  error = 0;
10765
10766  if (mav_reg_required_here (&str, 12, reg0) == FAIL
10767      || skip_past_comma (&str) == FAIL
10768      || mav_reg_required_here (&str, 16, reg1) == FAIL
10769      || skip_past_comma  (&str) == FAIL)
10770    {
10771      if (!inst.error)
10772	inst.error = BAD_ARGS;
10773      return;
10774    }
10775
10776  /* Calculate the immediate operand.
10777     The operand is a 7bit signed number.  */
10778  skip_whitespace (str);
10779
10780  if (*str == '#')
10781    ++str;
10782
10783  if (!ISDIGIT (*str) && *str != '-')
10784    {
10785      inst.error = _("expecting immediate, 7bit operand");
10786      return;
10787    }
10788
10789  if (*str == '-')
10790    {
10791      neg = 1;
10792      ++str;
10793    }
10794
10795  for (imm = 0; *str && ISDIGIT (*str); ++str)
10796    imm = imm * 10 + *str - '0';
10797
10798  if (imm > 64)
10799    {
10800      inst.error = _("immediate out of range");
10801      return;
10802    }
10803
10804  /* Make negative imm's into 7bit signed numbers.  */
10805  if (neg)
10806    {
10807      imm = -imm;
10808      imm &= 0x0000007f;
10809    }
10810
10811  /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10812     Bits 5-7 of the insn should have bits 4-6 of the immediate.
10813     Bit 4 should be 0.  */
10814  imm = (imm & 0xf) | ((imm & 0x70) << 1);
10815
10816  inst.instruction |= imm;
10817  end_of_line (str);
10818}
10819
10820static int
10821mav_parse_offset (str, negative)
10822     char ** str;
10823     int *negative;
10824{
10825  char * p = *str;
10826  int offset;
10827
10828  *negative = 0;
10829
10830  skip_whitespace (p);
10831
10832  if (*p == '#')
10833    ++p;
10834
10835  if (*p == '-')
10836    {
10837      *negative = 1;
10838      ++p;
10839    }
10840
10841  if (!ISDIGIT (*p))
10842    {
10843      inst.error = _("offset expected");
10844      return 0;
10845    }
10846
10847  for (offset = 0; *p && ISDIGIT (*p); ++p)
10848    offset = offset * 10 + *p - '0';
10849
10850  if (offset > 0xff)
10851    {
10852      inst.error = _("offset out of range");
10853      return 0;
10854    }
10855
10856  *str = p;
10857
10858  return *negative ? -offset : offset;
10859}
10860
10861/* Maverick load/store instructions.
10862  <insn><cond> CRd,[Rn,<offset>]{!}.
10863  <insn><cond> CRd,[Rn],<offset>.  */
10864
10865static void
10866do_mav_ldst (str, reg0)
10867     char * str;
10868     enum arm_reg_type reg0;
10869{
10870  int offset, negative;
10871
10872  skip_whitespace (str);
10873
10874  if (mav_reg_required_here (&str, 12, reg0) == FAIL
10875      || skip_past_comma (&str) == FAIL
10876      || *str++ != '['
10877      || reg_required_here (&str, 16) == FAIL)
10878    goto fail_ldst;
10879
10880  if (skip_past_comma (&str) == SUCCESS)
10881    {
10882      /* You are here: "<offset>]{!}".  */
10883      inst.instruction |= PRE_INDEX;
10884
10885      offset = mav_parse_offset (&str, &negative);
10886
10887      if (inst.error)
10888	return;
10889
10890      if (*str++ != ']')
10891	{
10892	  inst.error = _("missing ]");
10893	  return;
10894	}
10895
10896      if (*str == '!')
10897	{
10898	  inst.instruction |= WRITE_BACK;
10899	  ++str;
10900	}
10901    }
10902  else
10903    {
10904      /* You are here: "], <offset>".  */
10905      if (*str++ != ']')
10906	{
10907	  inst.error = _("missing ]");
10908	  return;
10909	}
10910
10911      if (skip_past_comma (&str) == FAIL
10912	  || (offset = mav_parse_offset (&str, &negative), inst.error))
10913	goto fail_ldst;
10914
10915      inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
10916    }
10917
10918  if (negative)
10919    offset = -offset;
10920  else
10921    inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
10922
10923  inst.instruction |= offset >> 2;
10924  end_of_line (str);
10925  return;
10926
10927fail_ldst:
10928  if (!inst.error)
10929     inst.error = BAD_ARGS;
10930}
10931
10932static void
10933do_t_nop (str)
10934     char * str;
10935{
10936  /* Do nothing.  */
10937  end_of_line (str);
10938}
10939
10940/* Handle the Format 4 instructions that do not have equivalents in other
10941   formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10942   BIC and MVN.  */
10943
10944static void
10945do_t_arit (str)
10946     char * str;
10947{
10948  int Rd, Rs, Rn;
10949
10950  skip_whitespace (str);
10951
10952  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10953      || skip_past_comma (&str) == FAIL
10954      || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10955    {
10956      inst.error = BAD_ARGS;
10957      return;
10958    }
10959
10960  if (skip_past_comma (&str) != FAIL)
10961    {
10962      /* Three operand format not allowed for TST, CMN, NEG and MVN.
10963	 (It isn't allowed for CMP either, but that isn't handled by this
10964	 function.)  */
10965      if (inst.instruction == T_OPCODE_TST
10966	  || inst.instruction == T_OPCODE_CMN
10967	  || inst.instruction == T_OPCODE_NEG
10968	  || inst.instruction == T_OPCODE_MVN)
10969	{
10970	  inst.error = BAD_ARGS;
10971	  return;
10972	}
10973
10974      if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10975	return;
10976
10977      if (Rs != Rd)
10978	{
10979	  inst.error = _("dest and source1 must be the same register");
10980	  return;
10981	}
10982      Rs = Rn;
10983    }
10984
10985  if (inst.instruction == T_OPCODE_MUL
10986      && Rs == Rd)
10987    as_tsktsk (_("Rs and Rd must be different in MUL"));
10988
10989  inst.instruction |= Rd | (Rs << 3);
10990  end_of_line (str);
10991}
10992
10993static void
10994do_t_add (str)
10995     char * str;
10996{
10997  thumb_add_sub (str, 0);
10998}
10999
11000static void
11001do_t_asr (str)
11002     char * str;
11003{
11004  thumb_shift (str, THUMB_ASR);
11005}
11006
11007static void
11008do_t_branch9 (str)
11009     char * str;
11010{
11011  if (my_get_expression (&inst.reloc.exp, &str))
11012    return;
11013  inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
11014  inst.reloc.pc_rel = 1;
11015  end_of_line (str);
11016}
11017
11018static void
11019do_t_branch12 (str)
11020     char * str;
11021{
11022  if (my_get_expression (&inst.reloc.exp, &str))
11023    return;
11024  inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11025  inst.reloc.pc_rel = 1;
11026  end_of_line (str);
11027}
11028
11029/* Find the real, Thumb encoded start of a Thumb function.  */
11030
11031static symbolS *
11032find_real_start (symbolP)
11033     symbolS * symbolP;
11034{
11035  char *       real_start;
11036  const char * name = S_GET_NAME (symbolP);
11037  symbolS *    new_target;
11038
11039  /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
11040#define STUB_NAME ".real_start_of"
11041
11042  if (name == NULL)
11043    abort ();
11044
11045  /* Names that start with '.' are local labels, not function entry points.
11046     The compiler may generate BL instructions to these labels because it
11047     needs to perform a branch to a far away location.  */
11048  if (name[0] == '.')
11049    return symbolP;
11050
11051  real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11052  sprintf (real_start, "%s%s", STUB_NAME, name);
11053
11054  new_target = symbol_find (real_start);
11055
11056  if (new_target == NULL)
11057    {
11058      as_warn ("Failed to find real start of function: %s\n", name);
11059      new_target = symbolP;
11060    }
11061
11062  free (real_start);
11063
11064  return new_target;
11065}
11066
11067static void
11068do_t_branch23 (str)
11069     char * str;
11070{
11071  if (my_get_expression (& inst.reloc.exp, & str))
11072    return;
11073
11074  inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
11075  inst.reloc.pc_rel = 1;
11076  end_of_line (str);
11077
11078  /* If the destination of the branch is a defined symbol which does not have
11079     the THUMB_FUNC attribute, then we must be calling a function which has
11080     the (interfacearm) attribute.  We look for the Thumb entry point to that
11081     function and change the branch to refer to that function instead.  */
11082  if (   inst.reloc.exp.X_op == O_symbol
11083      && inst.reloc.exp.X_add_symbol != NULL
11084      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11085      && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11086    inst.reloc.exp.X_add_symbol =
11087      find_real_start (inst.reloc.exp.X_add_symbol);
11088}
11089
11090static void
11091do_t_bx (str)
11092     char * str;
11093{
11094  int reg;
11095
11096  skip_whitespace (str);
11097
11098  if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11099    return;
11100
11101  /* This sets THUMB_H2 from the top bit of reg.  */
11102  inst.instruction |= reg << 3;
11103
11104  /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
11105     should cause the alignment to be checked once it is known.  This is
11106     because BX PC only works if the instruction is word aligned.  */
11107
11108  end_of_line (str);
11109}
11110
11111static void
11112do_t_compare (str)
11113     char * str;
11114{
11115  thumb_mov_compare (str, THUMB_COMPARE);
11116}
11117
11118static void
11119do_t_ldmstm (str)
11120     char * str;
11121{
11122  int Rb;
11123  long range;
11124
11125  skip_whitespace (str);
11126
11127  if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11128    return;
11129
11130  if (*str != '!')
11131    as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11132  else
11133    str++;
11134
11135  if (skip_past_comma (&str) == FAIL
11136      || (range = reg_list (&str)) == FAIL)
11137    {
11138      if (! inst.error)
11139	inst.error = BAD_ARGS;
11140      return;
11141    }
11142
11143  if (inst.reloc.type != BFD_RELOC_NONE)
11144    {
11145      /* This really doesn't seem worth it.  */
11146      inst.reloc.type = BFD_RELOC_NONE;
11147      inst.error = _("expression too complex");
11148      return;
11149    }
11150
11151  if (range & ~0xff)
11152    {
11153      inst.error = _("only lo-regs valid in load/store multiple");
11154      return;
11155    }
11156
11157  inst.instruction |= (Rb << 8) | range;
11158  end_of_line (str);
11159}
11160
11161static void
11162do_t_ldr (str)
11163     char * str;
11164{
11165  thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11166}
11167
11168static void
11169do_t_ldrb (str)
11170     char * str;
11171{
11172  thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11173}
11174
11175static void
11176do_t_ldrh (str)
11177     char * str;
11178{
11179  thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11180}
11181
11182static void
11183do_t_lds (str)
11184     char * str;
11185{
11186  int Rd, Rb, Ro;
11187
11188  skip_whitespace (str);
11189
11190  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11191      || skip_past_comma (&str) == FAIL
11192      || *str++ != '['
11193      || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11194      || skip_past_comma (&str) == FAIL
11195      || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11196      || *str++ != ']')
11197    {
11198      if (! inst.error)
11199	inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11200      return;
11201    }
11202
11203  inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11204  end_of_line (str);
11205}
11206
11207static void
11208do_t_lsl (str)
11209     char * str;
11210{
11211  thumb_shift (str, THUMB_LSL);
11212}
11213
11214static void
11215do_t_lsr (str)
11216     char * str;
11217{
11218  thumb_shift (str, THUMB_LSR);
11219}
11220
11221static void
11222do_t_mov (str)
11223     char * str;
11224{
11225  thumb_mov_compare (str, THUMB_MOVE);
11226}
11227
11228static void
11229do_t_push_pop (str)
11230     char * str;
11231{
11232  long range;
11233
11234  skip_whitespace (str);
11235
11236  if ((range = reg_list (&str)) == FAIL)
11237    {
11238      if (! inst.error)
11239	inst.error = BAD_ARGS;
11240      return;
11241    }
11242
11243  if (inst.reloc.type != BFD_RELOC_NONE)
11244    {
11245      /* This really doesn't seem worth it.  */
11246      inst.reloc.type = BFD_RELOC_NONE;
11247      inst.error = _("expression too complex");
11248      return;
11249    }
11250
11251  if (range & ~0xff)
11252    {
11253      if ((inst.instruction == T_OPCODE_PUSH
11254	   && (range & ~0xff) == 1 << REG_LR)
11255	  || (inst.instruction == T_OPCODE_POP
11256	      && (range & ~0xff) == 1 << REG_PC))
11257	{
11258	  inst.instruction |= THUMB_PP_PC_LR;
11259	  range &= 0xff;
11260	}
11261      else
11262	{
11263	  inst.error = _("invalid register list to push/pop instruction");
11264	  return;
11265	}
11266    }
11267
11268  inst.instruction |= range;
11269  end_of_line (str);
11270}
11271
11272static void
11273do_t_str (str)
11274     char * str;
11275{
11276  thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11277}
11278
11279static void
11280do_t_strb (str)
11281     char * str;
11282{
11283  thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11284}
11285
11286static void
11287do_t_strh (str)
11288     char * str;
11289{
11290  thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11291}
11292
11293static void
11294do_t_sub (str)
11295     char * str;
11296{
11297  thumb_add_sub (str, 1);
11298}
11299
11300static void
11301do_t_swi (str)
11302     char * str;
11303{
11304  skip_whitespace (str);
11305
11306  if (my_get_expression (&inst.reloc.exp, &str))
11307    return;
11308
11309  inst.reloc.type = BFD_RELOC_ARM_SWI;
11310  end_of_line (str);
11311}
11312
11313static void
11314do_t_adr (str)
11315     char * str;
11316{
11317  int reg;
11318
11319  /* This is a pseudo-op of the form "adr rd, label" to be converted
11320     into a relative address of the form "add rd, pc, #label-.-4".  */
11321  skip_whitespace (str);
11322
11323  /* Store Rd in temporary location inside instruction.  */
11324  if ((reg = reg_required_here (&str, 4)) == FAIL
11325      || (reg > 7)  /* For Thumb reg must be r0..r7.  */
11326      || skip_past_comma (&str) == FAIL
11327      || my_get_expression (&inst.reloc.exp, &str))
11328    {
11329      if (!inst.error)
11330	inst.error = BAD_ARGS;
11331      return;
11332    }
11333
11334  inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11335  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
11336  inst.reloc.pc_rel = 1;
11337  inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
11338
11339  end_of_line (str);
11340}
11341
11342static void
11343insert_reg (r, htab)
11344     const struct reg_entry *r;
11345     struct hash_control *htab;
11346{
11347  int    len  = strlen (r->name) + 2;
11348  char * buf  = (char *) xmalloc (len);
11349  char * buf2 = (char *) xmalloc (len);
11350  int    i    = 0;
11351
11352#ifdef REGISTER_PREFIX
11353  buf[i++] = REGISTER_PREFIX;
11354#endif
11355
11356  strcpy (buf + i, r->name);
11357
11358  for (i = 0; buf[i]; i++)
11359    buf2[i] = TOUPPER (buf[i]);
11360
11361  buf2[i] = '\0';
11362
11363  hash_insert (htab, buf,  (PTR) r);
11364  hash_insert (htab, buf2, (PTR) r);
11365}
11366
11367static void
11368build_reg_hsh (map)
11369     struct reg_map *map;
11370{
11371  const struct reg_entry *r;
11372
11373  if ((map->htab = hash_new ()) == NULL)
11374    as_fatal (_("virtual memory exhausted"));
11375
11376  for (r = map->names; r->name != NULL; r++)
11377    insert_reg (r, map->htab);
11378}
11379
11380static void
11381insert_reg_alias (str, regnum, htab)
11382     char *str;
11383     int regnum;
11384     struct hash_control *htab;
11385{
11386  const char *error;
11387  struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11388  const char *name = xmalloc (strlen (str) + 1);
11389
11390  strcpy ((char *) name, str);
11391
11392  new->name = name;
11393  new->number = regnum;
11394  new->builtin = FALSE;
11395
11396  error = hash_insert (htab, name, (PTR) new);
11397  if (error)
11398    {
11399      as_bad (_("failed to create an alias for %s, reason: %s"),
11400	    str, error);
11401      free ((char *) name);
11402      free (new);
11403    }
11404}
11405
11406/* Look for the .req directive.  This is of the form:
11407
11408   	new_register_name .req existing_register_name
11409
11410   If we find one, or if it looks sufficiently like one that we want to
11411   handle any error here, return non-zero.  Otherwise return zero.  */
11412static int
11413create_register_alias (newname, p)
11414     char *newname;
11415     char *p;
11416{
11417  char *q;
11418  char c;
11419
11420  q = p;
11421  skip_whitespace (q);
11422
11423  c = *p;
11424  *p = '\0';
11425
11426  if (*q && !strncmp (q, ".req ", 5))
11427    {
11428      char *copy_of_str;
11429      char *r;
11430
11431#ifdef IGNORE_OPCODE_CASE
11432      newname = original_case_string;
11433#endif
11434      copy_of_str = newname;
11435
11436      q += 4;
11437      skip_whitespace (q);
11438
11439      for (r = q; *r != '\0'; r++)
11440	if (*r == ' ')
11441	  break;
11442
11443      if (r != q)
11444	{
11445	  enum arm_reg_type new_type, old_type;
11446	  int old_regno;
11447	  char d = *r;
11448
11449	  *r = '\0';
11450	  old_type = arm_reg_parse_any (q);
11451	  *r = d;
11452
11453	  new_type = arm_reg_parse_any (newname);
11454
11455	  if (new_type == REG_TYPE_MAX)
11456	    {
11457	      if (old_type != REG_TYPE_MAX)
11458		{
11459		  old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11460		  insert_reg_alias (newname, old_regno,
11461				    all_reg_maps[old_type].htab);
11462		}
11463	      else
11464		as_warn (_("register '%s' does not exist\n"), q);
11465	    }
11466	  else if (old_type == REG_TYPE_MAX)
11467	    {
11468	      as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11469		       copy_of_str, q);
11470	    }
11471	  else
11472	    {
11473	      /* Do not warn about redefinitions to the same alias.  */
11474	      if (new_type != old_type
11475		  || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11476		      != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11477		as_warn (_("ignoring redefinition of register alias '%s'"),
11478			 copy_of_str);
11479
11480	    }
11481	}
11482      else
11483	as_warn (_("ignoring incomplete .req pseuso op"));
11484
11485      *p = c;
11486      return 1;
11487    }
11488
11489  *p = c;
11490  return 0;
11491}
11492
11493static void
11494set_constant_flonums ()
11495{
11496  int i;
11497
11498  for (i = 0; i < NUM_FLOAT_VALS; i++)
11499    if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11500      abort ();
11501}
11502
11503/* Iterate over the base tables to create the instruction patterns.  */
11504static void
11505build_arm_ops_hsh ()
11506{
11507  unsigned int i;
11508  unsigned int j;
11509  static struct obstack insn_obstack;
11510
11511  obstack_begin (&insn_obstack, 4000);
11512
11513  for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11514    {
11515      const struct asm_opcode *insn = insns + i;
11516
11517      if (insn->cond_offset != 0)
11518	{
11519	  /* Insn supports conditional execution.  Build the varaints
11520	     and insert them in the hash table.  */
11521	  for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11522	    {
11523	      unsigned len = strlen (insn->template);
11524	      struct asm_opcode *new;
11525	      char *template;
11526
11527	      new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11528	      /* All condition codes are two characters.  */
11529	      template = obstack_alloc (&insn_obstack, len + 3);
11530
11531	      strncpy (template, insn->template, insn->cond_offset);
11532	      strcpy (template + insn->cond_offset, conds[j].template);
11533	      if (len > insn->cond_offset)
11534		strcpy (template + insn->cond_offset + 2,
11535			insn->template + insn->cond_offset);
11536	      new->template = template;
11537	      new->cond_offset = 0;
11538	      new->variant = insn->variant;
11539	      new->parms = insn->parms;
11540	      new->value = (insn->value & ~COND_MASK) | conds[j].value;
11541
11542	      hash_insert (arm_ops_hsh, new->template, (PTR) new);
11543	    }
11544	}
11545      /* Finally, insert the unconditional insn in the table directly;
11546	 no need to build a copy.  */
11547      hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11548    }
11549}
11550
11551#if 0 /* Suppressed - for now.  */
11552#if defined OBJ_ELF || defined OBJ_COFF
11553
11554#ifdef OBJ_ELF
11555#define arm_Note Elf_External_Note
11556#else
11557typedef struct
11558{
11559  unsigned char	namesz[4];	/* Size of entry's owner string.  */
11560  unsigned char	descsz[4];	/* Size of the note descriptor.  */
11561  unsigned char	type[4];	/* Interpretation of the descriptor.  */
11562  char		name[1];	/* Start of the name+desc data.  */
11563} arm_Note;
11564#endif
11565
11566/* The description is kept to a fix sized in order to make updating
11567   it and merging it easier.  */
11568#define ARM_NOTE_DESCRIPTION_LENGTH	8
11569
11570static void
11571arm_add_note (name, description, type)
11572     const char * name;
11573     const char * description;
11574     unsigned int type;
11575{
11576  arm_Note     note ATTRIBUTE_UNUSED;
11577  char *       p;
11578  unsigned int name_len;
11579
11580  name_len = (strlen (name) + 1 + 3) & ~3;
11581
11582  p = frag_more (sizeof (note.namesz));
11583  md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11584
11585  p = frag_more (sizeof (note.descsz));
11586  md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11587
11588  p = frag_more (sizeof (note.type));
11589  md_number_to_chars (p, (valueT) type, sizeof (note.type));
11590
11591  p = frag_more (name_len);
11592  strcpy (p, name);
11593
11594  p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11595  strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11596  frag_align (2, 0, 0);
11597}
11598#endif
11599#endif
11600
11601void
11602md_begin ()
11603{
11604  unsigned mach;
11605  unsigned int i;
11606
11607  if (   (arm_ops_hsh = hash_new ()) == NULL
11608      || (arm_tops_hsh = hash_new ()) == NULL
11609      || (arm_cond_hsh = hash_new ()) == NULL
11610      || (arm_shift_hsh = hash_new ()) == NULL
11611      || (arm_psr_hsh = hash_new ()) == NULL)
11612    as_fatal (_("virtual memory exhausted"));
11613
11614  build_arm_ops_hsh ();
11615  for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11616    hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11617  for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11618    hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11619  for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11620    hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11621  for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11622    hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11623
11624  for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11625    build_reg_hsh (all_reg_maps + i);
11626
11627  set_constant_flonums ();
11628
11629  /* Set the cpu variant based on the command-line options.  We prefer
11630     -mcpu= over -march= if both are set (as for GCC); and we prefer
11631     -mfpu= over any other way of setting the floating point unit.
11632     Use of legacy options with new options are faulted.  */
11633  if (legacy_cpu != -1)
11634    {
11635      if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11636	as_bad (_("use of old and new-style options to set CPU type"));
11637
11638      mcpu_cpu_opt = legacy_cpu;
11639    }
11640  else if (mcpu_cpu_opt == -1)
11641    mcpu_cpu_opt = march_cpu_opt;
11642
11643  if (legacy_fpu != -1)
11644    {
11645      if (mfpu_opt != -1)
11646	as_bad (_("use of old and new-style options to set FPU type"));
11647
11648      mfpu_opt = legacy_fpu;
11649    }
11650  else if (mfpu_opt == -1)
11651    {
11652#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined(TE_OpenBSD))
11653      /* Some environments specify a default FPU.  If they don't, infer it
11654	 from the processor.  */
11655      if (mcpu_fpu_opt != -1)
11656	mfpu_opt = mcpu_fpu_opt;
11657      else
11658	mfpu_opt = march_fpu_opt;
11659#else
11660      mfpu_opt = FPU_DEFAULT;
11661#endif
11662    }
11663
11664  if (mfpu_opt == -1)
11665    {
11666      if (mcpu_cpu_opt == -1)
11667	mfpu_opt = FPU_DEFAULT;
11668      else if (mcpu_cpu_opt & ARM_EXT_V5)
11669	mfpu_opt = FPU_ARCH_VFP_V2;
11670      else
11671	mfpu_opt = FPU_ARCH_FPA;
11672    }
11673
11674  if (mcpu_cpu_opt == -1)
11675    mcpu_cpu_opt = CPU_DEFAULT;
11676
11677  cpu_variant = mcpu_cpu_opt | mfpu_opt;
11678
11679#if defined OBJ_COFF || defined OBJ_ELF
11680  {
11681    unsigned int flags = 0;
11682
11683    /* Set the flags in the private structure.  */
11684    if (uses_apcs_26)      flags |= F_APCS26;
11685    if (support_interwork) flags |= F_INTERWORK;
11686    if (uses_apcs_float)   flags |= F_APCS_FLOAT;
11687    if (pic_code)          flags |= F_PIC;
11688    if ((cpu_variant & FPU_ANY) == FPU_NONE
11689	 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only.  */
11690      {
11691	flags |= F_SOFT_FLOAT;
11692      }
11693    switch (mfloat_abi_opt)
11694      {
11695      case ARM_FLOAT_ABI_SOFT:
11696      case ARM_FLOAT_ABI_SOFTFP:
11697	flags |= F_SOFT_FLOAT;
11698	break;
11699
11700      case ARM_FLOAT_ABI_HARD:
11701	if (flags & F_SOFT_FLOAT)
11702	  as_bad (_("hard-float conflicts with specified fpu"));
11703	break;
11704      }
11705    /* Using VFP conventions (even if soft-float).  */
11706    if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
11707
11708#if defined OBJ_ELF
11709    if (cpu_variant & FPU_ARCH_MAVERICK)
11710	flags |= EF_ARM_MAVERICK_FLOAT;
11711#endif
11712
11713    bfd_set_private_flags (stdoutput, flags);
11714
11715    /* We have run out flags in the COFF header to encode the
11716       status of ATPCS support, so instead we create a dummy,
11717       empty, debug section called .arm.atpcs.  */
11718    if (atpcs)
11719      {
11720	asection * sec;
11721
11722	sec = bfd_make_section (stdoutput, ".arm.atpcs");
11723
11724	if (sec != NULL)
11725	  {
11726	    bfd_set_section_flags
11727	      (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11728	    bfd_set_section_size (stdoutput, sec, 0);
11729	    bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11730	  }
11731      }
11732  }
11733#endif
11734
11735  /* Record the CPU type as well.  */
11736  switch (cpu_variant & ARM_CPU_MASK)
11737    {
11738    case ARM_2:
11739      mach = bfd_mach_arm_2;
11740      break;
11741
11742    case ARM_3: 		/* Also ARM_250.  */
11743      mach = bfd_mach_arm_2a;
11744      break;
11745
11746    case ARM_6:			/* Also ARM_7.  */
11747      mach = bfd_mach_arm_3;
11748      break;
11749
11750    default:
11751      mach = bfd_mach_arm_unknown;
11752      break;
11753    }
11754
11755  /* Catch special cases.  */
11756  if (cpu_variant & ARM_CEXT_IWMMXT)
11757    mach = bfd_mach_arm_iWMMXt;
11758  else if (cpu_variant & ARM_CEXT_XSCALE)
11759    mach = bfd_mach_arm_XScale;
11760  else if (cpu_variant & ARM_CEXT_MAVERICK)
11761    mach = bfd_mach_arm_ep9312;
11762  else if (cpu_variant & ARM_EXT_V5E)
11763    mach = bfd_mach_arm_5TE;
11764  else if (cpu_variant & ARM_EXT_V5)
11765    {
11766      if (cpu_variant & ARM_EXT_V4T)
11767	mach = bfd_mach_arm_5T;
11768      else
11769	mach = bfd_mach_arm_5;
11770    }
11771  else if (cpu_variant & ARM_EXT_V4)
11772    {
11773      if (cpu_variant & ARM_EXT_V4T)
11774	mach = bfd_mach_arm_4T;
11775      else
11776	mach = bfd_mach_arm_4;
11777    }
11778  else if (cpu_variant & ARM_EXT_V3M)
11779    mach = bfd_mach_arm_3M;
11780
11781#if 0 /* Suppressed - for now.  */
11782#if defined (OBJ_ELF) || defined (OBJ_COFF)
11783
11784  /* Create a .note section to fully identify this arm binary.  */
11785
11786#define NOTE_ARCH_STRING 	"arch: "
11787
11788#if defined OBJ_COFF && ! defined NT_VERSION
11789#define NT_VERSION  1
11790#define NT_ARCH     2
11791#endif
11792
11793  {
11794    segT current_seg = now_seg;
11795    subsegT current_subseg = now_subseg;
11796    asection * arm_arch;
11797    const char * arch_string;
11798
11799    arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11800
11801#ifdef OBJ_COFF
11802    bfd_set_section_flags (stdoutput, arm_arch,
11803			   SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11804			   | SEC_HAS_CONTENTS);
11805#else
11806    bfd_set_section_flags (stdoutput, arm_arch,
11807			   SEC_READONLY | SEC_HAS_CONTENTS);
11808#endif
11809    arm_arch->output_section = arm_arch;
11810    subseg_set (arm_arch, 0);
11811
11812    switch (mach)
11813      {
11814      default:
11815      case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11816      case bfd_mach_arm_2:       arch_string = "armv2"; break;
11817      case bfd_mach_arm_2a:      arch_string = "armv2a"; break;
11818      case bfd_mach_arm_3:       arch_string = "armv3"; break;
11819      case bfd_mach_arm_3M:      arch_string = "armv3M"; break;
11820      case bfd_mach_arm_4:       arch_string = "armv4"; break;
11821      case bfd_mach_arm_4T:      arch_string = "armv4t"; break;
11822      case bfd_mach_arm_5:       arch_string = "armv5"; break;
11823      case bfd_mach_arm_5T:      arch_string = "armv5t"; break;
11824      case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
11825      case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
11826      case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
11827      case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break;
11828      }
11829
11830    arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11831
11832    subseg_set (current_seg, current_subseg);
11833  }
11834#endif
11835#endif /* Suppressed code.  */
11836
11837  bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11838}
11839
11840/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11841   for use in the a.out file, and stores them in the array pointed to by buf.
11842   This knows about the endian-ness of the target machine and does
11843   THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
11844   2 (short) and 4 (long)  Floating numbers are put out as a series of
11845   LITTLENUMS (shorts, here at least).  */
11846
11847void
11848md_number_to_chars (buf, val, n)
11849     char * buf;
11850     valueT val;
11851     int    n;
11852{
11853  if (target_big_endian)
11854    number_to_chars_bigendian (buf, val, n);
11855  else
11856    number_to_chars_littleendian (buf, val, n);
11857}
11858
11859static valueT
11860md_chars_to_number (buf, n)
11861     char * buf;
11862     int    n;
11863{
11864  valueT result = 0;
11865  unsigned char * where = (unsigned char *) buf;
11866
11867  if (target_big_endian)
11868    {
11869      while (n--)
11870	{
11871	  result <<= 8;
11872	  result |= (*where++ & 255);
11873	}
11874    }
11875  else
11876    {
11877      while (n--)
11878	{
11879	  result <<= 8;
11880	  result |= (where[n] & 255);
11881	}
11882    }
11883
11884  return result;
11885}
11886
11887/* Turn a string in input_line_pointer into a floating point constant
11888   of type TYPE, and store the appropriate bytes in *LITP.  The number
11889   of LITTLENUMS emitted is stored in *SIZEP.  An error message is
11890   returned, or NULL on OK.
11891
11892   Note that fp constants aren't represent in the normal way on the ARM.
11893   In big endian mode, things are as expected.  However, in little endian
11894   mode fp constants are big-endian word-wise, and little-endian byte-wise
11895   within the words.  For example, (double) 1.1 in big endian mode is
11896   the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11897   the byte sequence 99 99 f1 3f 9a 99 99 99.
11898
11899   ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
11900
11901char *
11902md_atof (type, litP, sizeP)
11903     char   type;
11904     char * litP;
11905     int *  sizeP;
11906{
11907  int prec;
11908  LITTLENUM_TYPE words[MAX_LITTLENUMS];
11909  char *t;
11910  int i;
11911
11912  switch (type)
11913    {
11914    case 'f':
11915    case 'F':
11916    case 's':
11917    case 'S':
11918      prec = 2;
11919      break;
11920
11921    case 'd':
11922    case 'D':
11923    case 'r':
11924    case 'R':
11925      prec = 4;
11926      break;
11927
11928    case 'x':
11929    case 'X':
11930      prec = 6;
11931      break;
11932
11933    case 'p':
11934    case 'P':
11935      prec = 6;
11936      break;
11937
11938    default:
11939      *sizeP = 0;
11940      return _("bad call to MD_ATOF()");
11941    }
11942
11943  t = atof_ieee (input_line_pointer, type, words);
11944  if (t)
11945    input_line_pointer = t;
11946  *sizeP = prec * 2;
11947
11948  if (target_big_endian)
11949    {
11950      for (i = 0; i < prec; i++)
11951	{
11952	  md_number_to_chars (litP, (valueT) words[i], 2);
11953	  litP += 2;
11954	}
11955    }
11956  else
11957    {
11958      if (cpu_variant & FPU_ARCH_VFP)
11959	for (i = prec - 1; i >= 0; i--)
11960	  {
11961	    md_number_to_chars (litP, (valueT) words[i], 2);
11962	    litP += 2;
11963	  }
11964      else
11965	/* For a 4 byte float the order of elements in `words' is 1 0.
11966	   For an 8 byte float the order is 1 0 3 2.  */
11967	for (i = 0; i < prec; i += 2)
11968	  {
11969	    md_number_to_chars (litP, (valueT) words[i + 1], 2);
11970	    md_number_to_chars (litP + 2, (valueT) words[i], 2);
11971	    litP += 4;
11972	  }
11973    }
11974
11975  return 0;
11976}
11977
11978/* The knowledge of the PC's pipeline offset is built into the insns
11979   themselves.  */
11980
11981long
11982md_pcrel_from (fixP)
11983     fixS * fixP;
11984{
11985  if (fixP->fx_addsy
11986      && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
11987      && fixP->fx_subsy == NULL)
11988    return 0;
11989
11990  if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
11991    {
11992      /* PC relative addressing on the Thumb is slightly odd
11993	 as the bottom two bits of the PC are forced to zero
11994	 for the calculation.  */
11995      return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
11996    }
11997
11998#ifdef TE_WINCE
11999  /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12000     so we un-adjust here to compensate for the accommodation.  */
12001  return fixP->fx_where + fixP->fx_frag->fr_address + 8;
12002#else
12003  return fixP->fx_where + fixP->fx_frag->fr_address;
12004#endif
12005}
12006
12007/* Round up a section size to the appropriate boundary.  */
12008
12009valueT
12010md_section_align (segment, size)
12011     segT   segment ATTRIBUTE_UNUSED;
12012     valueT size;
12013{
12014#ifdef OBJ_ELF
12015  return size;
12016#else
12017  /* Round all sects to multiple of 4.  */
12018  return (size + 3) & ~3;
12019#endif
12020}
12021
12022/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12023   Otherwise we have no need to default values of symbols.  */
12024
12025symbolS *
12026md_undefined_symbol (name)
12027     char * name ATTRIBUTE_UNUSED;
12028{
12029#ifdef OBJ_ELF
12030  if (name[0] == '_' && name[1] == 'G'
12031      && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12032    {
12033      if (!GOT_symbol)
12034	{
12035	  if (symbol_find (name))
12036	    as_bad ("GOT already in the symbol table");
12037
12038	  GOT_symbol = symbol_new (name, undefined_section,
12039				   (valueT) 0, & zero_address_frag);
12040	}
12041
12042      return GOT_symbol;
12043    }
12044#endif
12045
12046  return 0;
12047}
12048
12049/* arm_reg_parse () := if it looks like a register, return its token and
12050   advance the pointer.  */
12051
12052static int
12053arm_reg_parse (ccp, htab)
12054     register char ** ccp;
12055     struct hash_control *htab;
12056{
12057  char * start = * ccp;
12058  char   c;
12059  char * p;
12060  struct reg_entry * reg;
12061
12062#ifdef REGISTER_PREFIX
12063  if (*start != REGISTER_PREFIX)
12064    return FAIL;
12065  p = start + 1;
12066#else
12067  p = start;
12068#ifdef OPTIONAL_REGISTER_PREFIX
12069  if (*p == OPTIONAL_REGISTER_PREFIX)
12070    p++, start++;
12071#endif
12072#endif
12073  if (!ISALPHA (*p) || !is_name_beginner (*p))
12074    return FAIL;
12075
12076  c = *p++;
12077  while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12078    c = *p++;
12079
12080  *--p = 0;
12081  reg = (struct reg_entry *) hash_find (htab, start);
12082  *p = c;
12083
12084  if (reg)
12085    {
12086      *ccp = p;
12087      return reg->number;
12088    }
12089
12090  return FAIL;
12091}
12092
12093/* Search for the following register name in each of the possible reg name
12094   tables.  Return the classification if found, or REG_TYPE_MAX if not
12095   present.  */
12096static enum arm_reg_type
12097arm_reg_parse_any (cp)
12098     char *cp;
12099{
12100  int i;
12101
12102  for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12103    if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12104      return (enum arm_reg_type) i;
12105
12106  return REG_TYPE_MAX;
12107}
12108
12109void
12110md_apply_fix3 (fixP, valP, seg)
12111     fixS *   fixP;
12112     valueT * valP;
12113     segT     seg;
12114{
12115  offsetT        value = * valP;
12116  offsetT        newval;
12117  unsigned int   newimm;
12118  unsigned long  temp;
12119  int            sign;
12120  char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12121  arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12122
12123  assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12124
12125  /* Note whether this will delete the relocation.  */
12126#if 0
12127  /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12128     doesn't work fully.)  */
12129  if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12130      && !fixP->fx_pcrel)
12131#else
12132  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12133#endif
12134    fixP->fx_done = 1;
12135
12136  /* If this symbol is in a different section then we need to leave it for
12137     the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
12138     so we have to undo it's effects here.  */
12139  if (fixP->fx_pcrel)
12140    {
12141      if (fixP->fx_addsy != NULL
12142	  && S_IS_DEFINED (fixP->fx_addsy)
12143	  && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12144	{
12145	  if (target_oabi
12146	      && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12147		  || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12148		  ))
12149	    value = 0;
12150	  else
12151	    value += md_pcrel_from (fixP);
12152	}
12153    }
12154
12155  /* Remember value for emit_reloc.  */
12156  fixP->fx_addnumber = value;
12157
12158  switch (fixP->fx_r_type)
12159    {
12160    case BFD_RELOC_ARM_IMMEDIATE:
12161      newimm = validate_immediate (value);
12162      temp = md_chars_to_number (buf, INSN_SIZE);
12163
12164      /* If the instruction will fail, see if we can fix things up by
12165	 changing the opcode.  */
12166      if (newimm == (unsigned int) FAIL
12167	  && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12168	{
12169	  as_bad_where (fixP->fx_file, fixP->fx_line,
12170			_("invalid constant (%lx) after fixup"),
12171			(unsigned long) value);
12172	  break;
12173	}
12174
12175      newimm |= (temp & 0xfffff000);
12176      md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12177      fixP->fx_done = 1;
12178      break;
12179
12180    case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12181      {
12182	unsigned int highpart = 0;
12183	unsigned int newinsn  = 0xe1a00000; /* nop.  */
12184
12185	newimm = validate_immediate (value);
12186	temp = md_chars_to_number (buf, INSN_SIZE);
12187
12188	/* If the instruction will fail, see if we can fix things up by
12189	   changing the opcode.  */
12190	if (newimm == (unsigned int) FAIL
12191	    && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12192	  {
12193	    /* No ?  OK - try using two ADD instructions to generate
12194               the value.  */
12195	    newimm = validate_immediate_twopart (value, & highpart);
12196
12197	    /* Yes - then make sure that the second instruction is
12198               also an add.  */
12199	    if (newimm != (unsigned int) FAIL)
12200	      newinsn = temp;
12201	    /* Still No ?  Try using a negated value.  */
12202	    else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12203	      temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12204	    /* Otherwise - give up.  */
12205	    else
12206	      {
12207		as_bad_where (fixP->fx_file, fixP->fx_line,
12208			      _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12209			      (long) value);
12210		break;
12211	      }
12212
12213	    /* Replace the first operand in the 2nd instruction (which
12214	       is the PC) with the destination register.  We have
12215	       already added in the PC in the first instruction and we
12216	       do not want to do it again.  */
12217	    newinsn &= ~ 0xf0000;
12218	    newinsn |= ((newinsn & 0x0f000) << 4);
12219	  }
12220
12221	newimm |= (temp & 0xfffff000);
12222	md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12223
12224	highpart |= (newinsn & 0xfffff000);
12225	md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12226      }
12227      break;
12228
12229    case BFD_RELOC_ARM_OFFSET_IMM:
12230      sign = value >= 0;
12231
12232      if (value < 0)
12233	value = - value;
12234
12235      if (validate_offset_imm (value, 0) == FAIL)
12236	{
12237	  as_bad_where (fixP->fx_file, fixP->fx_line,
12238			_("bad immediate value for offset (%ld)"),
12239			(long) value);
12240	  break;
12241	}
12242
12243      newval = md_chars_to_number (buf, INSN_SIZE);
12244      newval &= 0xff7ff000;
12245      newval |= value | (sign ? INDEX_UP : 0);
12246      md_number_to_chars (buf, newval, INSN_SIZE);
12247      break;
12248
12249    case BFD_RELOC_ARM_OFFSET_IMM8:
12250    case BFD_RELOC_ARM_HWLITERAL:
12251      sign = value >= 0;
12252
12253      if (value < 0)
12254	value = - value;
12255
12256      if (validate_offset_imm (value, 1) == FAIL)
12257	{
12258	  if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12259	    as_bad_where (fixP->fx_file, fixP->fx_line,
12260			  _("invalid literal constant: pool needs to be closer"));
12261	  else
12262	    as_bad (_("bad immediate value for half-word offset (%ld)"),
12263		    (long) value);
12264	  break;
12265	}
12266
12267      newval = md_chars_to_number (buf, INSN_SIZE);
12268      newval &= 0xff7ff0f0;
12269      newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12270      md_number_to_chars (buf, newval, INSN_SIZE);
12271      break;
12272
12273    case BFD_RELOC_ARM_LITERAL:
12274      sign = value >= 0;
12275
12276      if (value < 0)
12277	value = - value;
12278
12279      if (validate_offset_imm (value, 0) == FAIL)
12280	{
12281	  as_bad_where (fixP->fx_file, fixP->fx_line,
12282			_("invalid literal constant: pool needs to be closer"));
12283	  break;
12284	}
12285
12286      newval = md_chars_to_number (buf, INSN_SIZE);
12287      newval &= 0xff7ff000;
12288      newval |= value | (sign ? INDEX_UP : 0);
12289      md_number_to_chars (buf, newval, INSN_SIZE);
12290      break;
12291
12292    case BFD_RELOC_ARM_SHIFT_IMM:
12293      newval = md_chars_to_number (buf, INSN_SIZE);
12294      if (((unsigned long) value) > 32
12295	  || (value == 32
12296	      && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12297	{
12298	  as_bad_where (fixP->fx_file, fixP->fx_line,
12299			_("shift expression is too large"));
12300	  break;
12301	}
12302
12303      if (value == 0)
12304	/* Shifts of zero must be done as lsl.  */
12305	newval &= ~0x60;
12306      else if (value == 32)
12307	value = 0;
12308      newval &= 0xfffff07f;
12309      newval |= (value & 0x1f) << 7;
12310      md_number_to_chars (buf, newval, INSN_SIZE);
12311      break;
12312
12313    case BFD_RELOC_ARM_SWI:
12314      if (arm_data->thumb_mode)
12315	{
12316	  if (((unsigned long) value) > 0xff)
12317	    as_bad_where (fixP->fx_file, fixP->fx_line,
12318			  _("invalid swi expression"));
12319	  newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12320	  newval |= value;
12321	  md_number_to_chars (buf, newval, THUMB_SIZE);
12322	}
12323      else
12324	{
12325	  if (((unsigned long) value) > 0x00ffffff)
12326	    as_bad_where (fixP->fx_file, fixP->fx_line,
12327			  _("invalid swi expression"));
12328	  newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12329	  newval |= value;
12330	  md_number_to_chars (buf, newval, INSN_SIZE);
12331	}
12332      break;
12333
12334    case BFD_RELOC_ARM_MULTI:
12335      if (((unsigned long) value) > 0xffff)
12336	as_bad_where (fixP->fx_file, fixP->fx_line,
12337		      _("invalid expression in load/store multiple"));
12338      newval = value | md_chars_to_number (buf, INSN_SIZE);
12339      md_number_to_chars (buf, newval, INSN_SIZE);
12340      break;
12341
12342    case BFD_RELOC_ARM_PCREL_BRANCH:
12343      newval = md_chars_to_number (buf, INSN_SIZE);
12344
12345      /* Sign-extend a 24-bit number.  */
12346#define SEXT24(x)	((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12347
12348#ifdef OBJ_ELF
12349      if (! target_oabi)
12350	value = fixP->fx_offset;
12351#endif
12352
12353      /* We are going to store value (shifted right by two) in the
12354	 instruction, in a 24 bit, signed field.  Thus we need to check
12355	 that none of the top 8 bits of the shifted value (top 7 bits of
12356         the unshifted, unsigned value) are set, or that they are all set.  */
12357      if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12358	  && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12359	{
12360#ifdef OBJ_ELF
12361	  /* Normally we would be stuck at this point, since we cannot store
12362	     the absolute address that is the destination of the branch in the
12363	     24 bits of the branch instruction.  If however, we happen to know
12364	     that the destination of the branch is in the same section as the
12365	     branch instruction itself, then we can compute the relocation for
12366	     ourselves and not have to bother the linker with it.
12367
12368	     FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12369	     because I have not worked out how to do this for OBJ_COFF or
12370	     target_oabi.  */
12371	  if (! target_oabi
12372	      && fixP->fx_addsy != NULL
12373	      && S_IS_DEFINED (fixP->fx_addsy)
12374	      && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12375	    {
12376	      /* Get pc relative value to go into the branch.  */
12377	      value = * valP;
12378
12379	      /* Permit a backward branch provided that enough bits
12380		 are set.  Allow a forwards branch, provided that
12381		 enough bits are clear.  */
12382	      if (   (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12383		  || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12384		fixP->fx_done = 1;
12385	    }
12386
12387	  if (! fixP->fx_done)
12388#endif
12389	    as_bad_where (fixP->fx_file, fixP->fx_line,
12390			  _("GAS can't handle same-section branch dest >= 0x04000000"));
12391	}
12392
12393      value >>= 2;
12394      value += SEXT24 (newval);
12395
12396      if (    (value & ~ ((offsetT) 0xffffff)) != 0
12397	  && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12398	as_bad_where (fixP->fx_file, fixP->fx_line,
12399		      _("out of range branch"));
12400
12401      newval = (value & 0x00ffffff) | (newval & 0xff000000);
12402      md_number_to_chars (buf, newval, INSN_SIZE);
12403      break;
12404
12405    case BFD_RELOC_ARM_PCREL_BLX:
12406      {
12407	offsetT hbit;
12408	newval = md_chars_to_number (buf, INSN_SIZE);
12409
12410#ifdef OBJ_ELF
12411	if (! target_oabi)
12412	  value = fixP->fx_offset;
12413#endif
12414	hbit   = (value >> 1) & 1;
12415	value  = (value >> 2) & 0x00ffffff;
12416	value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12417	newval = value | (newval & 0xfe000000) | (hbit << 24);
12418	md_number_to_chars (buf, newval, INSN_SIZE);
12419      }
12420      break;
12421
12422    case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.  */
12423      newval = md_chars_to_number (buf, THUMB_SIZE);
12424      {
12425	addressT diff = (newval & 0xff) << 1;
12426	if (diff & 0x100)
12427	  diff |= ~0xff;
12428
12429	value += diff;
12430	if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12431	  as_bad_where (fixP->fx_file, fixP->fx_line,
12432			_("branch out of range"));
12433	newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12434      }
12435      md_number_to_chars (buf, newval, THUMB_SIZE);
12436      break;
12437
12438    case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
12439      newval = md_chars_to_number (buf, THUMB_SIZE);
12440      {
12441	addressT diff = (newval & 0x7ff) << 1;
12442	if (diff & 0x800)
12443	  diff |= ~0x7ff;
12444
12445	value += diff;
12446	if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12447	  as_bad_where (fixP->fx_file, fixP->fx_line,
12448			_("branch out of range"));
12449	newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12450      }
12451      md_number_to_chars (buf, newval, THUMB_SIZE);
12452      break;
12453
12454    case BFD_RELOC_THUMB_PCREL_BLX:
12455    case BFD_RELOC_THUMB_PCREL_BRANCH23:
12456      {
12457	offsetT newval2;
12458	addressT diff;
12459
12460	newval  = md_chars_to_number (buf, THUMB_SIZE);
12461	newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12462	diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12463	if (diff & 0x400000)
12464	  diff |= ~0x3fffff;
12465#ifdef OBJ_ELF
12466	value = fixP->fx_offset;
12467#endif
12468	value += diff;
12469
12470	if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12471	  as_bad_where (fixP->fx_file, fixP->fx_line,
12472			_("branch with link out of range"));
12473
12474	newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
12475	newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12476	if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12477	  /* For a BLX instruction, make sure that the relocation is rounded up
12478	     to a word boundary.  This follows the semantics of the instruction
12479	     which specifies that bit 1 of the target address will come from bit
12480	     1 of the base address.  */
12481	  newval2 = (newval2 + 1) & ~ 1;
12482	md_number_to_chars (buf, newval, THUMB_SIZE);
12483	md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12484      }
12485      break;
12486
12487    case BFD_RELOC_8:
12488      if (fixP->fx_done || fixP->fx_pcrel)
12489	md_number_to_chars (buf, value, 1);
12490#ifdef OBJ_ELF
12491      else if (!target_oabi)
12492	{
12493	  value = fixP->fx_offset;
12494	  md_number_to_chars (buf, value, 1);
12495	}
12496#endif
12497      break;
12498
12499    case BFD_RELOC_16:
12500      if (fixP->fx_done || fixP->fx_pcrel)
12501	md_number_to_chars (buf, value, 2);
12502#ifdef OBJ_ELF
12503      else if (!target_oabi)
12504	{
12505	  value = fixP->fx_offset;
12506	  md_number_to_chars (buf, value, 2);
12507	}
12508#endif
12509      break;
12510
12511#ifdef OBJ_ELF
12512    case BFD_RELOC_ARM_GOT32:
12513    case BFD_RELOC_ARM_GOTOFF:
12514      md_number_to_chars (buf, 0, 4);
12515      break;
12516#endif
12517
12518    case BFD_RELOC_RVA:
12519    case BFD_RELOC_32:
12520      if (fixP->fx_done || fixP->fx_pcrel)
12521	md_number_to_chars (buf, value, 4);
12522#ifdef OBJ_ELF
12523      else if (!target_oabi)
12524	{
12525	  value = fixP->fx_offset;
12526	  md_number_to_chars (buf, value, 4);
12527	}
12528#endif
12529      break;
12530
12531#ifdef OBJ_ELF
12532    case BFD_RELOC_ARM_PLT32:
12533      /* It appears the instruction is fully prepared at this point.  */
12534      break;
12535#endif
12536
12537    case BFD_RELOC_ARM_CP_OFF_IMM:
12538      sign = value >= 0;
12539      if (value < -1023 || value > 1023 || (value & 3))
12540	as_bad_where (fixP->fx_file, fixP->fx_line,
12541		      _("illegal value for co-processor offset"));
12542      if (value < 0)
12543	value = -value;
12544      newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12545      newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12546      md_number_to_chars (buf, newval, INSN_SIZE);
12547      break;
12548
12549    case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12550      sign = value >= 0;
12551      if (value < -255 || value > 255)
12552        as_bad_where (fixP->fx_file, fixP->fx_line,
12553                      _("Illegal value for co-processor offset"));
12554      if (value < 0)
12555        value = -value;
12556      newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12557      newval |= value | (sign ?  INDEX_UP : 0);
12558      md_number_to_chars (buf, newval , INSN_SIZE);
12559      break;
12560
12561    case BFD_RELOC_ARM_THUMB_OFFSET:
12562      newval = md_chars_to_number (buf, THUMB_SIZE);
12563      /* Exactly what ranges, and where the offset is inserted depends
12564	 on the type of instruction, we can establish this from the
12565	 top 4 bits.  */
12566      switch (newval >> 12)
12567	{
12568	case 4: /* PC load.  */
12569	  /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12570	     forced to zero for these loads, so we will need to round
12571	     up the offset if the instruction address is not word
12572	     aligned (since the final address produced must be, and
12573	     we can only describe word-aligned immediate offsets).  */
12574
12575	  if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12576	    as_bad_where (fixP->fx_file, fixP->fx_line,
12577			  _("invalid offset, target not word aligned (0x%08X)"),
12578			  (unsigned int) (fixP->fx_frag->fr_address
12579					  + fixP->fx_where + value));
12580
12581	  if ((value + 2) & ~0x3fe)
12582	    as_bad_where (fixP->fx_file, fixP->fx_line,
12583			  _("invalid offset, value too big (0x%08lX)"),
12584			  (long) value);
12585
12586	  /* Round up, since pc will be rounded down.  */
12587	  newval |= (value + 2) >> 2;
12588	  break;
12589
12590	case 9: /* SP load/store.  */
12591	  if (value & ~0x3fc)
12592	    as_bad_where (fixP->fx_file, fixP->fx_line,
12593			  _("invalid offset, value too big (0x%08lX)"),
12594			  (long) value);
12595	  newval |= value >> 2;
12596	  break;
12597
12598	case 6: /* Word load/store.  */
12599	  if (value & ~0x7c)
12600	    as_bad_where (fixP->fx_file, fixP->fx_line,
12601			  _("invalid offset, value too big (0x%08lX)"),
12602			  (long) value);
12603	  newval |= value << 4; /* 6 - 2.  */
12604	  break;
12605
12606	case 7: /* Byte load/store.  */
12607	  if (value & ~0x1f)
12608	    as_bad_where (fixP->fx_file, fixP->fx_line,
12609			  _("invalid offset, value too big (0x%08lX)"),
12610			  (long) value);
12611	  newval |= value << 6;
12612	  break;
12613
12614	case 8: /* Halfword load/store.  */
12615	  if (value & ~0x3e)
12616	    as_bad_where (fixP->fx_file, fixP->fx_line,
12617			  _("invalid offset, value too big (0x%08lX)"),
12618			  (long) value);
12619	  newval |= value << 5; /* 6 - 1.  */
12620	  break;
12621
12622	default:
12623	  as_bad_where (fixP->fx_file, fixP->fx_line,
12624			"Unable to process relocation for thumb opcode: %lx",
12625			(unsigned long) newval);
12626	  break;
12627	}
12628      md_number_to_chars (buf, newval, THUMB_SIZE);
12629      break;
12630
12631    case BFD_RELOC_ARM_THUMB_ADD:
12632      /* This is a complicated relocation, since we use it for all of
12633         the following immediate relocations:
12634
12635	    3bit ADD/SUB
12636	    8bit ADD/SUB
12637	    9bit ADD/SUB SP word-aligned
12638	   10bit ADD PC/SP word-aligned
12639
12640         The type of instruction being processed is encoded in the
12641         instruction field:
12642
12643	   0x8000  SUB
12644	   0x00F0  Rd
12645	   0x000F  Rs
12646      */
12647      newval = md_chars_to_number (buf, THUMB_SIZE);
12648      {
12649	int rd = (newval >> 4) & 0xf;
12650	int rs = newval & 0xf;
12651	int subtract = newval & 0x8000;
12652
12653	if (rd == REG_SP)
12654	  {
12655	    if (value & ~0x1fc)
12656	      as_bad_where (fixP->fx_file, fixP->fx_line,
12657			    _("invalid immediate for stack address calculation"));
12658	    newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12659	    newval |= value >> 2;
12660	  }
12661	else if (rs == REG_PC || rs == REG_SP)
12662	  {
12663	    if (subtract ||
12664		value & ~0x3fc)
12665	      as_bad_where (fixP->fx_file, fixP->fx_line,
12666			    _("invalid immediate for address calculation (value = 0x%08lX)"),
12667			    (unsigned long) value);
12668	    newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12669	    newval |= rd << 8;
12670	    newval |= value >> 2;
12671	  }
12672	else if (rs == rd)
12673	  {
12674	    if (value & ~0xff)
12675	      as_bad_where (fixP->fx_file, fixP->fx_line,
12676			    _("invalid 8bit immediate"));
12677	    newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12678	    newval |= (rd << 8) | value;
12679	  }
12680	else
12681	  {
12682	    if (value & ~0x7)
12683	      as_bad_where (fixP->fx_file, fixP->fx_line,
12684			    _("invalid 3bit immediate"));
12685	    newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12686	    newval |= rd | (rs << 3) | (value << 6);
12687	  }
12688      }
12689      md_number_to_chars (buf, newval, THUMB_SIZE);
12690      break;
12691
12692    case BFD_RELOC_ARM_THUMB_IMM:
12693      newval = md_chars_to_number (buf, THUMB_SIZE);
12694      switch (newval >> 11)
12695	{
12696	case 0x04: /* 8bit immediate MOV.  */
12697	case 0x05: /* 8bit immediate CMP.  */
12698	  if (value < 0 || value > 255)
12699	    as_bad_where (fixP->fx_file, fixP->fx_line,
12700			  _("invalid immediate: %ld is too large"),
12701			  (long) value);
12702	  newval |= value;
12703	  break;
12704
12705	default:
12706	  abort ();
12707	}
12708      md_number_to_chars (buf, newval, THUMB_SIZE);
12709      break;
12710
12711    case BFD_RELOC_ARM_THUMB_SHIFT:
12712      /* 5bit shift value (0..31).  */
12713      if (value < 0 || value > 31)
12714	as_bad_where (fixP->fx_file, fixP->fx_line,
12715		      _("illegal Thumb shift value: %ld"), (long) value);
12716      newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12717      newval |= value << 6;
12718      md_number_to_chars (buf, newval, THUMB_SIZE);
12719      break;
12720
12721    case BFD_RELOC_VTABLE_INHERIT:
12722    case BFD_RELOC_VTABLE_ENTRY:
12723      fixP->fx_done = 0;
12724      return;
12725
12726    case BFD_RELOC_NONE:
12727    default:
12728      as_bad_where (fixP->fx_file, fixP->fx_line,
12729		    _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12730    }
12731}
12732
12733/* Translate internal representation of relocation info to BFD target
12734   format.  */
12735
12736arelent *
12737tc_gen_reloc (section, fixp)
12738     asection * section ATTRIBUTE_UNUSED;
12739     fixS * fixp;
12740{
12741  arelent * reloc;
12742  bfd_reloc_code_real_type code;
12743
12744  reloc = (arelent *) xmalloc (sizeof (arelent));
12745
12746  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12747  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12748  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12749
12750  /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
12751#ifndef OBJ_ELF
12752  if (fixp->fx_pcrel == 0)
12753    reloc->addend = fixp->fx_offset;
12754  else
12755    reloc->addend = fixp->fx_offset = reloc->address;
12756#else  /* OBJ_ELF */
12757  reloc->addend = fixp->fx_offset;
12758#endif
12759
12760  switch (fixp->fx_r_type)
12761    {
12762    case BFD_RELOC_8:
12763      if (fixp->fx_pcrel)
12764	{
12765	  code = BFD_RELOC_8_PCREL;
12766	  break;
12767	}
12768
12769    case BFD_RELOC_16:
12770      if (fixp->fx_pcrel)
12771	{
12772	  code = BFD_RELOC_16_PCREL;
12773	  break;
12774	}
12775
12776    case BFD_RELOC_32:
12777      if (fixp->fx_pcrel)
12778	{
12779	  code = BFD_RELOC_32_PCREL;
12780	  break;
12781	}
12782
12783    case BFD_RELOC_ARM_PCREL_BRANCH:
12784    case BFD_RELOC_ARM_PCREL_BLX:
12785    case BFD_RELOC_RVA:
12786    case BFD_RELOC_THUMB_PCREL_BRANCH9:
12787    case BFD_RELOC_THUMB_PCREL_BRANCH12:
12788    case BFD_RELOC_THUMB_PCREL_BRANCH23:
12789    case BFD_RELOC_THUMB_PCREL_BLX:
12790    case BFD_RELOC_VTABLE_ENTRY:
12791    case BFD_RELOC_VTABLE_INHERIT:
12792      code = fixp->fx_r_type;
12793      break;
12794
12795    case BFD_RELOC_ARM_LITERAL:
12796    case BFD_RELOC_ARM_HWLITERAL:
12797      /* If this is called then the a literal has
12798	 been referenced across a section boundary.  */
12799      as_bad_where (fixp->fx_file, fixp->fx_line,
12800		    _("literal referenced across section boundary"));
12801      return NULL;
12802
12803#ifdef OBJ_ELF
12804    case BFD_RELOC_ARM_GOT32:
12805    case BFD_RELOC_ARM_GOTOFF:
12806    case BFD_RELOC_ARM_PLT32:
12807      code = fixp->fx_r_type;
12808      break;
12809#endif
12810
12811    case BFD_RELOC_ARM_IMMEDIATE:
12812      as_bad_where (fixp->fx_file, fixp->fx_line,
12813		    _("internal relocation (type: IMMEDIATE) not fixed up"));
12814      return NULL;
12815
12816    case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12817      as_bad_where (fixp->fx_file, fixp->fx_line,
12818		    _("ADRL used for a symbol not defined in the same file"));
12819      return NULL;
12820
12821    case BFD_RELOC_ARM_OFFSET_IMM:
12822      if (fixp->fx_addsy != NULL
12823	  && !S_IS_DEFINED (fixp->fx_addsy)
12824	  && S_IS_LOCAL (fixp->fx_addsy))
12825	{
12826	  as_bad_where (fixp->fx_file, fixp->fx_line,
12827			_("undefined local label `%s'"),
12828			S_GET_NAME (fixp->fx_addsy));
12829	  return NULL;
12830	}
12831
12832      as_bad_where (fixp->fx_file, fixp->fx_line,
12833		    _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12834      return NULL;
12835
12836    default:
12837      {
12838	char * type;
12839
12840	switch (fixp->fx_r_type)
12841	  {
12842	  case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
12843	  case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
12844	  case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
12845	  case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
12846	  case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
12847	  case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
12848	  case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
12849	  case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
12850	  case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12851	  default:                         type = _("<unknown>"); break;
12852	  }
12853	as_bad_where (fixp->fx_file, fixp->fx_line,
12854		      _("cannot represent %s relocation in this object file format"),
12855		      type);
12856	return NULL;
12857      }
12858    }
12859
12860#ifdef OBJ_ELF
12861  if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12862      && GOT_symbol
12863      && fixp->fx_addsy == GOT_symbol)
12864    {
12865      code = BFD_RELOC_ARM_GOTPC;
12866      reloc->addend = fixp->fx_offset = reloc->address;
12867    }
12868#endif
12869
12870  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12871
12872  if (reloc->howto == NULL)
12873    {
12874      as_bad_where (fixp->fx_file, fixp->fx_line,
12875		    _("cannot represent %s relocation in this object file format"),
12876		    bfd_get_reloc_code_name (code));
12877      return NULL;
12878    }
12879
12880  /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12881     vtable entry to be used in the relocation's section offset.  */
12882  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12883    reloc->address = fixp->fx_offset;
12884
12885  return reloc;
12886}
12887
12888int
12889md_estimate_size_before_relax (fragP, segtype)
12890     fragS * fragP ATTRIBUTE_UNUSED;
12891     segT    segtype ATTRIBUTE_UNUSED;
12892{
12893  as_fatal (_("md_estimate_size_before_relax\n"));
12894  return 1;
12895}
12896
12897static void
12898output_inst (str)
12899     const char *str;
12900{
12901  char * to = NULL;
12902
12903  if (inst.error)
12904    {
12905      as_bad ("%s -- `%s'", inst.error, str);
12906      return;
12907    }
12908
12909  to = frag_more (inst.size);
12910
12911  if (thumb_mode && (inst.size > THUMB_SIZE))
12912    {
12913      assert (inst.size == (2 * THUMB_SIZE));
12914      md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12915      md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12916    }
12917  else if (inst.size > INSN_SIZE)
12918    {
12919      assert (inst.size == (2 * INSN_SIZE));
12920      md_number_to_chars (to, inst.instruction, INSN_SIZE);
12921      md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12922    }
12923  else
12924    md_number_to_chars (to, inst.instruction, inst.size);
12925
12926  if (inst.reloc.type != BFD_RELOC_NONE)
12927    fix_new_arm (frag_now, to - frag_now->fr_literal,
12928		 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12929		 inst.reloc.type);
12930
12931#ifdef OBJ_ELF
12932  dwarf2_emit_insn (inst.size);
12933#endif
12934}
12935
12936void
12937md_assemble (str)
12938     char * str;
12939{
12940  char  c;
12941  char *p;
12942  char *start;
12943
12944  /* Align the instruction.
12945     This may not be the right thing to do but ...  */
12946#if 0
12947  arm_align (2, 0);
12948#endif
12949
12950  /* Align the previous label if needed.  */
12951  if (last_label_seen != NULL)
12952    {
12953      symbol_set_frag (last_label_seen, frag_now);
12954      S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12955      S_SET_SEGMENT (last_label_seen, now_seg);
12956    }
12957
12958  memset (&inst, '\0', sizeof (inst));
12959  inst.reloc.type = BFD_RELOC_NONE;
12960
12961  skip_whitespace (str);
12962
12963  /* Scan up to the end of the op-code, which must end in white space or
12964     end of string.  */
12965  for (start = p = str; *p != '\0'; p++)
12966    if (*p == ' ')
12967      break;
12968
12969  if (p == str)
12970    {
12971      as_bad (_("no operator -- statement `%s'\n"), str);
12972      return;
12973    }
12974
12975  if (thumb_mode)
12976    {
12977      const struct thumb_opcode * opcode;
12978
12979      c = *p;
12980      *p = '\0';
12981      opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
12982      *p = c;
12983
12984      if (opcode)
12985	{
12986	  /* Check that this instruction is supported for this CPU.  */
12987	  if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
12988	    {
12989	      as_bad (_("selected processor does not support `%s'"), str);
12990	      return;
12991	    }
12992
12993	  mapping_state (MAP_THUMB);
12994	  inst.instruction = opcode->value;
12995	  inst.size = opcode->size;
12996	  (*opcode->parms) (p);
12997	  output_inst (str);
12998	  return;
12999	}
13000    }
13001  else
13002    {
13003      const struct asm_opcode * opcode;
13004
13005      c = *p;
13006      *p = '\0';
13007      opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13008      *p = c;
13009
13010      if (opcode)
13011	{
13012	  /* Check that this instruction is supported for this CPU.  */
13013	  if ((opcode->variant & cpu_variant) == 0)
13014	    {
13015	      as_bad (_("selected processor does not support `%s'"), str);
13016	      return;
13017	    }
13018
13019          mapping_state (MAP_ARM);
13020	  inst.instruction = opcode->value;
13021	  inst.size = INSN_SIZE;
13022	  (*opcode->parms) (p);
13023	  output_inst (str);
13024	  return;
13025	}
13026    }
13027
13028  /* It wasn't an instruction, but it might be a register alias of the form
13029     alias .req reg.  */
13030  if (create_register_alias (str, p))
13031    return;
13032
13033  as_bad (_("bad instruction `%s'"), start);
13034}
13035
13036/* md_parse_option
13037      Invocation line includes a switch not recognized by the base assembler.
13038      See if it's a processor-specific option.
13039
13040      This routine is somewhat complicated by the need for backwards
13041      compatibility (since older releases of gcc can't be changed).
13042      The new options try to make the interface as compatible as
13043      possible with GCC.
13044
13045      New options (supported) are:
13046
13047	      -mcpu=<cpu name>		 Assemble for selected processor
13048	      -march=<architecture name> Assemble for selected architecture
13049	      -mfpu=<fpu architecture>	 Assemble for selected FPU.
13050	      -EB/-mbig-endian		 Big-endian
13051	      -EL/-mlittle-endian	 Little-endian
13052	      -k			 Generate PIC code
13053	      -mthumb			 Start in Thumb mode
13054	      -mthumb-interwork		 Code supports ARM/Thumb interworking
13055
13056      For now we will also provide support for:
13057
13058	      -mapcs-32			 32-bit Program counter
13059	      -mapcs-26			 26-bit Program counter
13060	      -macps-float		 Floats passed in FP registers
13061	      -mapcs-reentrant		 Reentrant code
13062	      -matpcs
13063      (sometime these will probably be replaced with -mapcs=<list of options>
13064      and -matpcs=<list of options>)
13065
13066      The remaining options are only supported for back-wards compatibility.
13067      Cpu variants, the arm part is optional:
13068              -m[arm]1                Currently not supported.
13069              -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
13070              -m[arm]3                Arm 3 processor
13071              -m[arm]6[xx],           Arm 6 processors
13072              -m[arm]7[xx][t][[d]m]   Arm 7 processors
13073              -m[arm]8[10]            Arm 8 processors
13074              -m[arm]9[20][tdmi]      Arm 9 processors
13075              -mstrongarm[110[0]]     StrongARM processors
13076              -mxscale                XScale processors
13077              -m[arm]v[2345[t[e]]]    Arm architectures
13078              -mall                   All (except the ARM1)
13079      FP variants:
13080              -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
13081              -mfpe-old               (No float load/store multiples)
13082	      -mvfpxd		      VFP Single precision
13083	      -mvfp		      All VFP
13084              -mno-fpu                Disable all floating point instructions
13085
13086      The following CPU names are recognized:
13087	      arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13088	      arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13089	      arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13090	      arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13091	      arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13092	      arm10t arm10e, arm1020t, arm1020e, arm10200e,
13093	      strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13094
13095      */
13096
13097const char * md_shortopts = "m:k";
13098
13099#ifdef ARM_BI_ENDIAN
13100#define OPTION_EB (OPTION_MD_BASE + 0)
13101#define OPTION_EL (OPTION_MD_BASE + 1)
13102#else
13103#if TARGET_BYTES_BIG_ENDIAN
13104#define OPTION_EB (OPTION_MD_BASE + 0)
13105#else
13106#define OPTION_EL (OPTION_MD_BASE + 1)
13107#endif
13108#endif
13109
13110struct option md_longopts[] =
13111{
13112#ifdef OPTION_EB
13113  {"EB", no_argument, NULL, OPTION_EB},
13114#endif
13115#ifdef OPTION_EL
13116  {"EL", no_argument, NULL, OPTION_EL},
13117#endif
13118  {NULL, no_argument, NULL, 0}
13119};
13120
13121size_t md_longopts_size = sizeof (md_longopts);
13122
13123struct arm_option_table
13124{
13125  char *option;		/* Option name to match.  */
13126  char *help;		/* Help information.  */
13127  int  *var;		/* Variable to change.  */
13128  int   value;		/* What to change it to.  */
13129  char *deprecated;	/* If non-null, print this message.  */
13130};
13131
13132struct arm_option_table arm_opts[] =
13133{
13134  {"k",      N_("generate PIC code"),      &pic_code,    1, NULL},
13135  {"mthumb", N_("assemble Thumb code"),    &thumb_mode,  1, NULL},
13136  {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13137   &support_interwork, 1, NULL},
13138  {"moabi",  N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13139  {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13140  {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13141  {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13142   1, NULL},
13143  {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13144  {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13145  {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13146  {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13147   NULL},
13148
13149  /* These are recognized by the assembler, but have no affect on code.  */
13150  {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13151  {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13152
13153  /* DON'T add any new processors to this list -- we want the whole list
13154     to go away...  Add them to the processors table instead.  */
13155  {"marm1",	 NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13156  {"m1",	 NULL, &legacy_cpu, ARM_ARCH_V1,  N_("use -mcpu=arm1")},
13157  {"marm2",	 NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13158  {"m2",	 NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -mcpu=arm2")},
13159  {"marm250",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13160  {"m250",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13161  {"marm3",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13162  {"m3",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13163  {"marm6",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13164  {"m6",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm6")},
13165  {"marm600",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13166  {"m600",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm600")},
13167  {"marm610",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13168  {"m610",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm610")},
13169  {"marm620",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13170  {"m620",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm620")},
13171  {"marm7",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13172  {"m7",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7")},
13173  {"marm70",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13174  {"m70",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm70")},
13175  {"marm700",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13176  {"m700",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700")},
13177  {"marm700i",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13178  {"m700i",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm700i")},
13179  {"marm710",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13180  {"m710",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710")},
13181  {"marm710c",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13182  {"m710c",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm710c")},
13183  {"marm720",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13184  {"m720",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm720")},
13185  {"marm7d",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13186  {"m7d",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7d")},
13187  {"marm7di",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13188  {"m7di",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7di")},
13189  {"marm7m",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13190  {"m7m",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13191  {"marm7dm",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13192  {"m7dm",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13193  {"marm7dmi",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13194  {"m7dmi",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13195  {"marm7100",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13196  {"m7100",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7100")},
13197  {"marm7500",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13198  {"m7500",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500")},
13199  {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13200  {"m7500fe",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -mcpu=arm7500fe")},
13201  {"marm7t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13202  {"m7t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13203  {"marm7tdmi",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13204  {"m7tdmi",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13205  {"marm710t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13206  {"m710t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13207  {"marm720t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13208  {"m720t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13209  {"marm740t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13210  {"m740t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13211  {"marm8",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13212  {"m8",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm8")},
13213  {"marm810",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13214  {"m810",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=arm810")},
13215  {"marm9",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13216  {"m9",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13217  {"marm9tdmi",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13218  {"m9tdmi",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13219  {"marm920",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13220  {"m920",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13221  {"marm940",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13222  {"m940",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13223  {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -mcpu=strongarm")},
13224  {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13225   N_("use -mcpu=strongarm110")},
13226  {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13227   N_("use -mcpu=strongarm1100")},
13228  {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13229   N_("use -mcpu=strongarm1110")},
13230  {"mxscale",	 NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13231  {"miwmmxt",	 NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13232  {"mall",	 NULL, &legacy_cpu, ARM_ANY,      N_("use -mcpu=all")},
13233
13234  /* Architecture variants -- don't add any more to this list either.  */
13235  {"mv2",	 NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13236  {"marmv2",	 NULL, &legacy_cpu, ARM_ARCH_V2,  N_("use -march=armv2")},
13237  {"mv2a",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13238  {"marmv2a",	 NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13239  {"mv3",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13240  {"marmv3",	 NULL, &legacy_cpu, ARM_ARCH_V3,  N_("use -march=armv3")},
13241  {"mv3m",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13242  {"marmv3m",	 NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13243  {"mv4",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13244  {"marmv4",	 NULL, &legacy_cpu, ARM_ARCH_V4,  N_("use -march=armv4")},
13245  {"mv4t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13246  {"marmv4t",	 NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13247  {"mv5",	 NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13248  {"marmv5",	 NULL, &legacy_cpu, ARM_ARCH_V5,  N_("use -march=armv5")},
13249  {"mv5t",	 NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13250  {"marmv5t",	 NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13251  {"mv5e",	 NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13252  {"marmv5e",	 NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13253
13254  /* Floating point variants -- don't add any more to this list either.  */
13255  {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13256  {"mfpa10",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13257  {"mfpa11",   NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13258  {"mno-fpu",  NULL, &legacy_fpu, 0,
13259   N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13260
13261  {NULL, NULL, NULL, 0, NULL}
13262};
13263
13264struct arm_cpu_option_table
13265{
13266  char *name;
13267  int   value;
13268  /* For some CPUs we assume an FPU unless the user explicitly sets
13269     -mfpu=...  */
13270  int   default_fpu;
13271};
13272
13273/* This list should, at a minimum, contain all the cpu names
13274   recognized by GCC.  */
13275static struct arm_cpu_option_table arm_cpus[] =
13276{
13277  {"all",		ARM_ANY,	 FPU_ARCH_FPA},
13278  {"arm1",		ARM_ARCH_V1,	 FPU_ARCH_FPA},
13279  {"arm2",		ARM_ARCH_V2,	 FPU_ARCH_FPA},
13280  {"arm250",		ARM_ARCH_V2S,	 FPU_ARCH_FPA},
13281  {"arm3",		ARM_ARCH_V2S,	 FPU_ARCH_FPA},
13282  {"arm6",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13283  {"arm60",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13284  {"arm600",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13285  {"arm610",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13286  {"arm620",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13287  {"arm7",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13288  {"arm7m",		ARM_ARCH_V3M,	 FPU_ARCH_FPA},
13289  {"arm7d",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13290  {"arm7dm",		ARM_ARCH_V3M,	 FPU_ARCH_FPA},
13291  {"arm7di",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13292  {"arm7dmi",		ARM_ARCH_V3M,	 FPU_ARCH_FPA},
13293  {"arm70",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13294  {"arm700",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13295  {"arm700i",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13296  {"arm710",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13297  {"arm710t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13298  {"arm720",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13299  {"arm720t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13300  {"arm740t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13301  {"arm710c",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13302  {"arm7100",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13303  {"arm7500",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13304  {"arm7500fe",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13305  {"arm7t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13306  {"arm7tdmi",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13307  {"arm8",		ARM_ARCH_V4,	 FPU_ARCH_FPA},
13308  {"arm810",		ARM_ARCH_V4,	 FPU_ARCH_FPA},
13309  {"strongarm",		ARM_ARCH_V4,	 FPU_ARCH_FPA},
13310  {"strongarm1",	ARM_ARCH_V4,	 FPU_ARCH_FPA},
13311  {"strongarm110",	ARM_ARCH_V4,	 FPU_ARCH_FPA},
13312  {"strongarm1100",	ARM_ARCH_V4,	 FPU_ARCH_FPA},
13313  {"strongarm1110",	ARM_ARCH_V4,	 FPU_ARCH_FPA},
13314  {"arm9",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13315  {"arm920",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13316  {"arm920t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13317  {"arm922t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13318  {"arm940t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13319  {"arm9tdmi",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13320  /* For V5 or later processors we default to using VFP; but the user
13321     should really set the FPU type explicitly.  */
13322  {"arm9e-r0",		ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13323  {"arm9e",		ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13324  {"arm926ej",		ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2},
13325  {"arm926ejs",		ARM_ARCH_V5TEJ,	 FPU_ARCH_VFP_V2},
13326  {"arm946e-r0",	ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13327  {"arm946e",		ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2},
13328  {"arm966e-r0",	ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13329  {"arm966e",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2},
13330  {"arm10t",		ARM_ARCH_V5T,	 FPU_ARCH_VFP_V1},
13331  {"arm10e",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2},
13332  {"arm1020",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2},
13333  {"arm1020t",		ARM_ARCH_V5T,	 FPU_ARCH_VFP_V1},
13334  {"arm1020e",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2},
13335  {"arm1026ejs",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP_V2},
13336  {"arm1136js",		ARM_ARCH_V6,     FPU_NONE},
13337  {"arm1136jfs",	ARM_ARCH_V6,     FPU_ARCH_VFP_V2},
13338  /* ??? XSCALE is really an architecture.  */
13339  {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13340  /* ??? iwmmxt is not a processor.  */
13341  {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13342  {"i80200",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13343  /* Maverick */
13344  {"ep9312",		ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13345  {NULL, 0, 0}
13346};
13347
13348struct arm_arch_option_table
13349{
13350  char *name;
13351  int   value;
13352  int   default_fpu;
13353};
13354
13355/* This list should, at a minimum, contain all the architecture names
13356   recognized by GCC.  */
13357static struct arm_arch_option_table arm_archs[] =
13358{
13359  {"all",		ARM_ANY,	 FPU_ARCH_FPA},
13360  {"armv1",		ARM_ARCH_V1,	 FPU_ARCH_FPA},
13361  {"armv2",		ARM_ARCH_V2,	 FPU_ARCH_FPA},
13362  {"armv2a",		ARM_ARCH_V2S,	 FPU_ARCH_FPA},
13363  {"armv2s",		ARM_ARCH_V2S,	 FPU_ARCH_FPA},
13364  {"armv3",		ARM_ARCH_V3,	 FPU_ARCH_FPA},
13365  {"armv3m",		ARM_ARCH_V3M,	 FPU_ARCH_FPA},
13366  {"armv4",		ARM_ARCH_V4,	 FPU_ARCH_FPA},
13367  {"armv4xm",		ARM_ARCH_V4xM,	 FPU_ARCH_FPA},
13368  {"armv4t",		ARM_ARCH_V4T,	 FPU_ARCH_FPA},
13369  {"armv4txm",		ARM_ARCH_V4TxM,	 FPU_ARCH_FPA},
13370  {"armv5",		ARM_ARCH_V5,	 FPU_ARCH_VFP},
13371  {"armv5t",		ARM_ARCH_V5T,	 FPU_ARCH_VFP},
13372  {"armv5txm",		ARM_ARCH_V5TxM,	 FPU_ARCH_VFP},
13373  {"armv5te",		ARM_ARCH_V5TE,	 FPU_ARCH_VFP},
13374  {"armv5texp",		ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13375  {"armv5tej",		ARM_ARCH_V5TEJ,  FPU_ARCH_VFP},
13376  {"armv6",             ARM_ARCH_V6,     FPU_ARCH_VFP},
13377  {"armv6j",            ARM_ARCH_V6,     FPU_ARCH_VFP},
13378  {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13379  {"iwmmxt",		ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13380  {NULL, 0, 0}
13381};
13382
13383/* ISA extensions in the co-processor space.  */
13384struct arm_arch_extension_table
13385{
13386  char *name;
13387  int value;
13388};
13389
13390static struct arm_arch_extension_table arm_extensions[] =
13391{
13392  {"maverick",		ARM_CEXT_MAVERICK},
13393  {"xscale",		ARM_CEXT_XSCALE},
13394  {"iwmmxt",		ARM_CEXT_IWMMXT},
13395  {NULL,		0}
13396};
13397
13398struct arm_fpu_option_table
13399{
13400  char *name;
13401  int   value;
13402};
13403
13404/* This list should, at a minimum, contain all the fpu names
13405   recognized by GCC.  */
13406static struct arm_fpu_option_table arm_fpus[] =
13407{
13408  {"softfpa",		FPU_NONE},
13409  {"fpe",		FPU_ARCH_FPE},
13410  {"fpe2",		FPU_ARCH_FPE},
13411  {"fpe3",		FPU_ARCH_FPA},	/* Third release supports LFM/SFM.  */
13412  {"fpa",		FPU_ARCH_FPA},
13413  {"fpa10",		FPU_ARCH_FPA},
13414  {"fpa11",		FPU_ARCH_FPA},
13415  {"arm7500fe",		FPU_ARCH_FPA},
13416  {"softvfp",		FPU_ARCH_VFP},
13417  {"softvfp+vfp",	FPU_ARCH_VFP_V2},
13418  {"vfp",		FPU_ARCH_VFP_V2},
13419  {"vfp9",		FPU_ARCH_VFP_V2},
13420  {"vfp10",		FPU_ARCH_VFP_V2},
13421  {"vfp10-r0",		FPU_ARCH_VFP_V1},
13422  {"vfpxd",		FPU_ARCH_VFP_V1xD},
13423  {"arm1020t",		FPU_ARCH_VFP_V1},
13424  {"arm1020e",		FPU_ARCH_VFP_V2},
13425  {"arm1136jfs",	FPU_ARCH_VFP_V2},
13426  {"maverick",		FPU_ARCH_MAVERICK},
13427  {NULL, 0}
13428};
13429
13430struct arm_float_abi_option_table
13431{
13432  char *name;
13433  int value;
13434};
13435
13436static struct arm_float_abi_option_table arm_float_abis[] =
13437{
13438  {"hard",	ARM_FLOAT_ABI_HARD},
13439  {"softfp",	ARM_FLOAT_ABI_SOFTFP},
13440  {"soft",	ARM_FLOAT_ABI_SOFT},
13441  {NULL, 0}
13442};
13443
13444struct arm_long_option_table
13445{
13446  char *option;		/* Substring to match.  */
13447  char *help;		/* Help information.  */
13448  int (*func) PARAMS ((char *subopt));	/* Function to decode sub-option.  */
13449  char *deprecated;	/* If non-null, print this message.  */
13450};
13451
13452static int
13453arm_parse_extension (str, opt_p)
13454     char *str;
13455     int *opt_p;
13456{
13457  while (str != NULL && *str != 0)
13458    {
13459      struct arm_arch_extension_table *opt;
13460      char *ext;
13461      int optlen;
13462
13463      if (*str != '+')
13464	{
13465	  as_bad (_("invalid architectural extension"));
13466	  return 0;
13467	}
13468
13469      str++;
13470      ext = strchr (str, '+');
13471
13472      if (ext != NULL)
13473	optlen = ext - str;
13474      else
13475	optlen = strlen (str);
13476
13477      if (optlen == 0)
13478	{
13479	  as_bad (_("missing architectural extension"));
13480	  return 0;
13481	}
13482
13483      for (opt = arm_extensions; opt->name != NULL; opt++)
13484	if (strncmp (opt->name, str, optlen) == 0)
13485	  {
13486	    *opt_p |= opt->value;
13487	    break;
13488	  }
13489
13490      if (opt->name == NULL)
13491	{
13492	  as_bad (_("unknown architectural extnsion `%s'"), str);
13493	  return 0;
13494	}
13495
13496      str = ext;
13497    };
13498
13499  return 1;
13500}
13501
13502static int
13503arm_parse_cpu (str)
13504     char *str;
13505{
13506  struct arm_cpu_option_table *opt;
13507  char *ext = strchr (str, '+');
13508  int optlen;
13509
13510  if (ext != NULL)
13511    optlen = ext - str;
13512  else
13513    optlen = strlen (str);
13514
13515  if (optlen == 0)
13516    {
13517      as_bad (_("missing cpu name `%s'"), str);
13518      return 0;
13519    }
13520
13521  for (opt = arm_cpus; opt->name != NULL; opt++)
13522    if (strncmp (opt->name, str, optlen) == 0)
13523      {
13524	mcpu_cpu_opt = opt->value;
13525	mcpu_fpu_opt = opt->default_fpu;
13526
13527	if (ext != NULL)
13528	  return arm_parse_extension (ext, &mcpu_cpu_opt);
13529
13530	return 1;
13531      }
13532
13533  as_bad (_("unknown cpu `%s'"), str);
13534  return 0;
13535}
13536
13537static int
13538arm_parse_arch (str)
13539     char *str;
13540{
13541  struct arm_arch_option_table *opt;
13542  char *ext = strchr (str, '+');
13543  int optlen;
13544
13545  if (ext != NULL)
13546    optlen = ext - str;
13547  else
13548    optlen = strlen (str);
13549
13550  if (optlen == 0)
13551    {
13552      as_bad (_("missing architecture name `%s'"), str);
13553      return 0;
13554    }
13555
13556
13557  for (opt = arm_archs; opt->name != NULL; opt++)
13558    if (strcmp (opt->name, str) == 0)
13559      {
13560	march_cpu_opt = opt->value;
13561	march_fpu_opt = opt->default_fpu;
13562
13563	if (ext != NULL)
13564	  return arm_parse_extension (ext, &march_cpu_opt);
13565
13566	return 1;
13567      }
13568
13569  as_bad (_("unknown architecture `%s'\n"), str);
13570  return 0;
13571}
13572
13573static int
13574arm_parse_fpu (str)
13575     char *str;
13576{
13577  struct arm_fpu_option_table *opt;
13578
13579  for (opt = arm_fpus; opt->name != NULL; opt++)
13580    if (strcmp (opt->name, str) == 0)
13581      {
13582	mfpu_opt = opt->value;
13583	return 1;
13584      }
13585
13586  as_bad (_("unknown floating point format `%s'\n"), str);
13587  return 0;
13588}
13589
13590static int
13591arm_parse_float_abi (str)
13592     char * str;
13593{
13594  struct arm_float_abi_option_table *opt;
13595
13596  for (opt = arm_float_abis; opt->name != NULL; opt++)
13597    if (strcmp (opt->name, str) == 0)
13598      {
13599	mfloat_abi_opt = opt->value;
13600	return 1;
13601      }
13602
13603  as_bad (_("unknown floating point abi `%s'\n"), str);
13604  return 0;
13605}
13606
13607struct arm_long_option_table arm_long_opts[] =
13608{
13609  {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
13610   arm_parse_cpu, NULL},
13611  {"march=", N_("<arch name>\t  assemble for architecture <arch name>"),
13612   arm_parse_arch, NULL},
13613  {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
13614   arm_parse_fpu, NULL},
13615  {"mfloat-abi=", N_("<abi>\t  assemble for floating point ABI <abi>"),
13616   arm_parse_float_abi, NULL},
13617  {NULL, NULL, 0, NULL}
13618};
13619
13620int
13621md_parse_option (c, arg)
13622     int    c;
13623     char * arg;
13624{
13625  struct arm_option_table *opt;
13626  struct arm_long_option_table *lopt;
13627
13628  switch (c)
13629    {
13630#ifdef OPTION_EB
13631    case OPTION_EB:
13632      target_big_endian = 1;
13633      break;
13634#endif
13635
13636#ifdef OPTION_EL
13637    case OPTION_EL:
13638      target_big_endian = 0;
13639      break;
13640#endif
13641
13642    case 'a':
13643      /* Listing option.  Just ignore these, we don't support additional
13644	 ones.  */
13645      return 0;
13646
13647    default:
13648      for (opt = arm_opts; opt->option != NULL; opt++)
13649	{
13650	  if (c == opt->option[0]
13651	      && ((arg == NULL && opt->option[1] == 0)
13652		  || strcmp (arg, opt->option + 1) == 0))
13653	    {
13654#if WARN_DEPRECATED
13655	      /* If the option is deprecated, tell the user.  */
13656	      if (opt->deprecated != NULL)
13657		as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13658			   arg ? arg : "", _(opt->deprecated));
13659#endif
13660
13661	      if (opt->var != NULL)
13662		*opt->var = opt->value;
13663
13664	      return 1;
13665	    }
13666	}
13667
13668      for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13669	{
13670	  /* These options are expected to have an argument.  */
13671	  if (c == lopt->option[0]
13672	      && arg != NULL
13673	      && strncmp (arg, lopt->option + 1,
13674			  strlen (lopt->option + 1)) == 0)
13675	    {
13676#if WARN_DEPRECATED
13677	      /* If the option is deprecated, tell the user.  */
13678	      if (lopt->deprecated != NULL)
13679		as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13680			   _(lopt->deprecated));
13681#endif
13682
13683	      /* Call the sup-option parser.  */
13684	      return (*lopt->func)(arg + strlen (lopt->option) - 1);
13685	    }
13686	}
13687
13688      as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13689      return 0;
13690    }
13691
13692  return 1;
13693}
13694
13695void
13696md_show_usage (fp)
13697     FILE * fp;
13698{
13699  struct arm_option_table *opt;
13700  struct arm_long_option_table *lopt;
13701
13702  fprintf (fp, _(" ARM-specific assembler options:\n"));
13703
13704  for (opt = arm_opts; opt->option != NULL; opt++)
13705    if (opt->help != NULL)
13706      fprintf (fp, "  -%-23s%s\n", opt->option, _(opt->help));
13707
13708  for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13709    if (lopt->help != NULL)
13710      fprintf (fp, "  -%s%s\n", lopt->option, _(lopt->help));
13711
13712#ifdef OPTION_EB
13713  fprintf (fp, _("\
13714  -EB                     assemble code for a big-endian cpu\n"));
13715#endif
13716
13717#ifdef OPTION_EL
13718  fprintf (fp, _("\
13719  -EL                     assemble code for a little-endian cpu\n"));
13720#endif
13721}
13722
13723/* We need to be able to fix up arbitrary expressions in some statements.
13724   This is so that we can handle symbols that are an arbitrary distance from
13725   the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13726   which returns part of an address in a form which will be valid for
13727   a data instruction.  We do this by pushing the expression into a symbol
13728   in the expr_section, and creating a fix for that.  */
13729
13730static void
13731fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13732     fragS *       frag;
13733     int           where;
13734     short int     size;
13735     expressionS * exp;
13736     int           pc_rel;
13737     int           reloc;
13738{
13739  fixS *           new_fix;
13740  arm_fix_data *   arm_data;
13741
13742  switch (exp->X_op)
13743    {
13744    case O_constant:
13745    case O_symbol:
13746    case O_add:
13747    case O_subtract:
13748      new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13749      break;
13750
13751    default:
13752      new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13753			 pc_rel, reloc);
13754      break;
13755    }
13756
13757  /* Mark whether the fix is to a THUMB instruction, or an ARM
13758     instruction.  */
13759  arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13760  new_fix->tc_fix_data = (PTR) arm_data;
13761  arm_data->thumb_mode = thumb_mode;
13762}
13763
13764/* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
13765
13766void
13767cons_fix_new_arm (frag, where, size, exp)
13768     fragS *       frag;
13769     int           where;
13770     int           size;
13771     expressionS * exp;
13772{
13773  bfd_reloc_code_real_type type;
13774  int pcrel = 0;
13775
13776  /* Pick a reloc.
13777     FIXME: @@ Should look at CPU word size.  */
13778  switch (size)
13779    {
13780    case 1:
13781      type = BFD_RELOC_8;
13782      break;
13783    case 2:
13784      type = BFD_RELOC_16;
13785      break;
13786    case 4:
13787    default:
13788      type = BFD_RELOC_32;
13789      break;
13790    case 8:
13791      type = BFD_RELOC_64;
13792      break;
13793    }
13794
13795  fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13796}
13797
13798/* A good place to do this, although this was probably not intended
13799   for this kind of use.  We need to dump the literal pool before
13800   references are made to a null symbol pointer.  */
13801
13802void
13803arm_cleanup ()
13804{
13805  literal_pool * pool;
13806
13807  for (pool = list_of_pools; pool; pool = pool->next)
13808    {
13809      /* Put it at the end of the relevent section.  */
13810      subseg_set (pool->section, pool->sub_section);
13811#ifdef OBJ_ELF
13812      arm_elf_change_section ();
13813#endif
13814      s_ltorg (0);
13815    }
13816}
13817
13818void
13819arm_start_line_hook ()
13820{
13821  last_label_seen = NULL;
13822}
13823
13824void
13825arm_frob_label (sym)
13826     symbolS * sym;
13827{
13828  last_label_seen = sym;
13829
13830  ARM_SET_THUMB (sym, thumb_mode);
13831
13832#if defined OBJ_COFF || defined OBJ_ELF
13833  ARM_SET_INTERWORK (sym, support_interwork);
13834#endif
13835
13836  /* Note - do not allow local symbols (.Lxxx) to be labeled
13837     as Thumb functions.  This is because these labels, whilst
13838     they exist inside Thumb code, are not the entry points for
13839     possible ARM->Thumb calls.  Also, these labels can be used
13840     as part of a computed goto or switch statement.  eg gcc
13841     can generate code that looks like this:
13842
13843                ldr  r2, [pc, .Laaa]
13844                lsl  r3, r3, #2
13845                ldr  r2, [r3, r2]
13846                mov  pc, r2
13847
13848       .Lbbb:  .word .Lxxx
13849       .Lccc:  .word .Lyyy
13850       ..etc...
13851       .Laaa:   .word Lbbb
13852
13853     The first instruction loads the address of the jump table.
13854     The second instruction converts a table index into a byte offset.
13855     The third instruction gets the jump address out of the table.
13856     The fourth instruction performs the jump.
13857
13858     If the address stored at .Laaa is that of a symbol which has the
13859     Thumb_Func bit set, then the linker will arrange for this address
13860     to have the bottom bit set, which in turn would mean that the
13861     address computation performed by the third instruction would end
13862     up with the bottom bit set.  Since the ARM is capable of unaligned
13863     word loads, the instruction would then load the incorrect address
13864     out of the jump table, and chaos would ensue.  */
13865  if (label_is_thumb_function_name
13866      && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13867      && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13868    {
13869      /* When the address of a Thumb function is taken the bottom
13870	 bit of that address should be set.  This will allow
13871	 interworking between Arm and Thumb functions to work
13872	 correctly.  */
13873
13874      THUMB_SET_FUNC (sym, 1);
13875
13876      label_is_thumb_function_name = FALSE;
13877    }
13878}
13879
13880/* Adjust the symbol table.  This marks Thumb symbols as distinct from
13881   ARM ones.  */
13882
13883void
13884arm_adjust_symtab ()
13885{
13886#ifdef OBJ_COFF
13887  symbolS * sym;
13888
13889  for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13890    {
13891      if (ARM_IS_THUMB (sym))
13892	{
13893	  if (THUMB_IS_FUNC (sym))
13894	    {
13895	      /* Mark the symbol as a Thumb function.  */
13896	      if (   S_GET_STORAGE_CLASS (sym) == C_STAT
13897		  || S_GET_STORAGE_CLASS (sym) == C_LABEL)  /* This can happen!  */
13898		S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13899
13900	      else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13901		S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13902	      else
13903		as_bad (_("%s: unexpected function type: %d"),
13904			S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13905	    }
13906	  else switch (S_GET_STORAGE_CLASS (sym))
13907	    {
13908	    case C_EXT:
13909	      S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13910	      break;
13911	    case C_STAT:
13912	      S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13913	      break;
13914	    case C_LABEL:
13915	      S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13916	      break;
13917	    default:
13918	      /* Do nothing.  */
13919	      break;
13920	    }
13921	}
13922
13923      if (ARM_IS_INTERWORK (sym))
13924	coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13925    }
13926#endif
13927#ifdef OBJ_ELF
13928  symbolS * sym;
13929  char      bind;
13930
13931  for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13932    {
13933      if (ARM_IS_THUMB (sym))
13934	{
13935	  elf_symbol_type * elf_sym;
13936
13937	  elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13938	  bind = ELF_ST_BIND (elf_sym);
13939
13940	  /* If it's a .thumb_func, declare it as so,
13941	     otherwise tag label as .code 16.  */
13942	  if (THUMB_IS_FUNC (sym))
13943	    elf_sym->internal_elf_sym.st_info =
13944	      ELF_ST_INFO (bind, STT_ARM_TFUNC);
13945	  else
13946	    elf_sym->internal_elf_sym.st_info =
13947	      ELF_ST_INFO (bind, STT_ARM_16BIT);
13948	}
13949    }
13950#endif
13951}
13952
13953int
13954arm_data_in_code ()
13955{
13956  if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
13957    {
13958      *input_line_pointer = '/';
13959      input_line_pointer += 5;
13960      *input_line_pointer = 0;
13961      return 1;
13962    }
13963
13964  return 0;
13965}
13966
13967char *
13968arm_canonicalize_symbol_name (name)
13969     char * name;
13970{
13971  int len;
13972
13973  if (thumb_mode && (len = strlen (name)) > 5
13974      && streq (name + len - 5, "/data"))
13975    *(name + len - 5) = 0;
13976
13977  return name;
13978}
13979
13980#if defined OBJ_COFF || defined OBJ_ELF
13981void
13982arm_validate_fix (fixP)
13983     fixS * fixP;
13984{
13985  /* If the destination of the branch is a defined symbol which does not have
13986     the THUMB_FUNC attribute, then we must be calling a function which has
13987     the (interfacearm) attribute.  We look for the Thumb entry point to that
13988     function and change the branch to refer to that function instead.  */
13989  if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
13990      && fixP->fx_addsy != NULL
13991      && S_IS_DEFINED (fixP->fx_addsy)
13992      && ! THUMB_IS_FUNC (fixP->fx_addsy))
13993    {
13994      fixP->fx_addsy = find_real_start (fixP->fx_addsy);
13995    }
13996}
13997#endif
13998
13999int
14000arm_force_relocation (fixp)
14001     struct fix * fixp;
14002{
14003#if defined (OBJ_COFF) && defined (TE_PE)
14004  if (fixp->fx_r_type == BFD_RELOC_RVA)
14005    return 1;
14006#endif
14007#ifdef OBJ_ELF
14008  if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14009      || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14010      || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14011      || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14012    return 1;
14013#endif
14014
14015  /* Resolve these relocations even if the symbol is extern or weak.  */
14016  if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14017      || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14018      || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14019    return 0;
14020
14021  return generic_force_reloc (fixp);
14022}
14023
14024#ifdef OBJ_COFF
14025/* This is a little hack to help the gas/arm/adrl.s test.  It prevents
14026   local labels from being added to the output symbol table when they
14027   are used with the ADRL pseudo op.  The ADRL relocation should always
14028   be resolved before the binbary is emitted, so it is safe to say that
14029   it is adjustable.  */
14030
14031bfd_boolean
14032arm_fix_adjustable (fixP)
14033   fixS * fixP;
14034{
14035  if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14036    return 1;
14037  return 0;
14038}
14039#endif
14040
14041#ifdef OBJ_ELF
14042/* Relocations against Thumb function names must be left unadjusted,
14043   so that the linker can use this information to correctly set the
14044   bottom bit of their addresses.  The MIPS version of this function
14045   also prevents relocations that are mips-16 specific, but I do not
14046   know why it does this.
14047
14048   FIXME:
14049   There is one other problem that ought to be addressed here, but
14050   which currently is not:  Taking the address of a label (rather
14051   than a function) and then later jumping to that address.  Such
14052   addresses also ought to have their bottom bit set (assuming that
14053   they reside in Thumb code), but at the moment they will not.  */
14054
14055bfd_boolean
14056arm_fix_adjustable (fixP)
14057   fixS * fixP;
14058{
14059  if (fixP->fx_addsy == NULL)
14060    return 1;
14061
14062  if (THUMB_IS_FUNC (fixP->fx_addsy)
14063      && fixP->fx_subsy == NULL)
14064    return 0;
14065
14066  /* We need the symbol name for the VTABLE entries.  */
14067  if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14068      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14069    return 0;
14070
14071  /* Don't allow symbols to be discarded on GOT related relocs.  */
14072  if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14073      || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14074      || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14075    return 0;
14076
14077  return 1;
14078}
14079
14080const char *
14081elf32_arm_target_format ()
14082{
14083  if (target_big_endian)
14084    {
14085      if (target_oabi)
14086	return "elf32-bigarm-oabi";
14087      else
14088	return "elf32-bigarm";
14089    }
14090  else
14091    {
14092      if (target_oabi)
14093	return "elf32-littlearm-oabi";
14094      else
14095	return "elf32-littlearm";
14096    }
14097}
14098
14099void
14100armelf_frob_symbol (symp, puntp)
14101     symbolS * symp;
14102     int *     puntp;
14103{
14104  elf_frob_symbol (symp, puntp);
14105}
14106
14107static bfd_reloc_code_real_type
14108arm_parse_reloc ()
14109{
14110  char         id [16];
14111  char *       ip;
14112  unsigned int i;
14113  static struct
14114  {
14115    char * str;
14116    int    len;
14117    bfd_reloc_code_real_type reloc;
14118  }
14119  reloc_map[] =
14120  {
14121#define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14122    MAP ("(got)",    BFD_RELOC_ARM_GOT32),
14123    MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14124    /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14125       branch instructions generated by GCC for PLT relocs.  */
14126    MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
14127    { NULL, 0,         BFD_RELOC_UNUSED }
14128#undef MAP
14129  };
14130
14131  for (i = 0, ip = input_line_pointer;
14132       i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14133       i++, ip++)
14134    id[i] = TOLOWER (*ip);
14135
14136  for (i = 0; reloc_map[i].str; i++)
14137    if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14138      break;
14139
14140  input_line_pointer += reloc_map[i].len;
14141
14142  return reloc_map[i].reloc;
14143}
14144
14145static void
14146s_arm_elf_cons (nbytes)
14147     int nbytes;
14148{
14149  expressionS exp;
14150
14151#ifdef md_flush_pending_output
14152  md_flush_pending_output ();
14153#endif
14154
14155  if (is_it_end_of_statement ())
14156    {
14157      demand_empty_rest_of_line ();
14158      return;
14159    }
14160
14161#ifdef md_cons_align
14162  md_cons_align (nbytes);
14163#endif
14164
14165  mapping_state (MAP_DATA);
14166  do
14167    {
14168      bfd_reloc_code_real_type reloc;
14169
14170      expression (& exp);
14171
14172      if (exp.X_op == O_symbol
14173	  && * input_line_pointer == '('
14174	  && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14175	{
14176	  reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14177	  int size = bfd_get_reloc_size (howto);
14178
14179	  if (size > nbytes)
14180	    as_bad ("%s relocations do not fit in %d bytes",
14181		    howto->name, nbytes);
14182	  else
14183	    {
14184	      register char *p = frag_more ((int) nbytes);
14185	      int offset = nbytes - size;
14186
14187	      fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14188			   &exp, 0, reloc);
14189	    }
14190	}
14191      else
14192	emit_expr (&exp, (unsigned int) nbytes);
14193    }
14194  while (*input_line_pointer++ == ',');
14195
14196  /* Put terminator back into stream.  */
14197  input_line_pointer --;
14198  demand_empty_rest_of_line ();
14199}
14200
14201#endif /* OBJ_ELF */
14202
14203/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
14204   of an rs_align_code fragment.  */
14205
14206void
14207arm_handle_align (fragP)
14208     fragS *fragP;
14209{
14210  static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14211  static char const thumb_noop[2] = { 0xc0, 0x46 };
14212  static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14213  static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14214
14215  int bytes, fix, noop_size;
14216  char * p;
14217  const char * noop;
14218
14219  if (fragP->fr_type != rs_align_code)
14220    return;
14221
14222  bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14223  p = fragP->fr_literal + fragP->fr_fix;
14224  fix = 0;
14225
14226  if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14227    bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14228
14229  if (fragP->tc_frag_data)
14230    {
14231      if (target_big_endian)
14232	noop = thumb_bigend_noop;
14233      else
14234	noop = thumb_noop;
14235      noop_size = sizeof (thumb_noop);
14236    }
14237  else
14238    {
14239      if (target_big_endian)
14240	noop = arm_bigend_noop;
14241      else
14242	noop = arm_noop;
14243      noop_size = sizeof (arm_noop);
14244    }
14245
14246  if (bytes & (noop_size - 1))
14247    {
14248      fix = bytes & (noop_size - 1);
14249      memset (p, 0, fix);
14250      p += fix;
14251      bytes -= fix;
14252    }
14253
14254  while (bytes >= noop_size)
14255    {
14256      memcpy (p, noop, noop_size);
14257      p += noop_size;
14258      bytes -= noop_size;
14259      fix += noop_size;
14260    }
14261
14262  fragP->fr_fix += fix;
14263  fragP->fr_var = noop_size;
14264}
14265
14266/* Called from md_do_align.  Used to create an alignment
14267   frag in a code section.  */
14268
14269void
14270arm_frag_align_code (n, max)
14271     int n;
14272     int max;
14273{
14274  char * p;
14275
14276  /* We assume that there will never be a requirement
14277     to support alignments greater than 32 bytes.  */
14278  if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14279    as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14280
14281  p = frag_var (rs_align_code,
14282		MAX_MEM_FOR_RS_ALIGN_CODE,
14283		1,
14284		(relax_substateT) max,
14285		(symbolS *) NULL,
14286		(offsetT) n,
14287		(char *) NULL);
14288  *p = 0;
14289
14290}
14291
14292/* Perform target specific initialisation of a frag.  */
14293
14294void
14295arm_init_frag (fragP)
14296     fragS *fragP;
14297{
14298  /* Record whether this frag is in an ARM or a THUMB area.  */
14299  fragP->tc_frag_data = thumb_mode;
14300}
14301