* config/tc-arm.c (psrs): Accept combinations of flags.
[external/binutils.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2    Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
3    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4         Modified by David Taylor (dtaylor@armltd.co.uk)
5
6    This file is part of GAS, the GNU Assembler.
7
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 #include <ctype.h>
24 #include <string.h>
25 #define  NO_RELOC 0
26 #include "as.h"
27
28 /* need TARGET_CPU */
29 #include "config.h"
30 #include "subsegs.h"
31 #include "obstack.h"
32 #include "symbols.h"
33 #include "listing.h"
34
35 #ifdef OBJ_ELF
36 #include "elf/arm.h"
37 #endif
38
39 /* Types of processor to assemble for.  */
40 #define ARM_1           0x00000001
41 #define ARM_2           0x00000002
42 #define ARM_3           0x00000004
43 #define ARM_250         ARM_3
44 #define ARM_6           0x00000008
45 #define ARM_7           ARM_6           /* same core instruction set */
46 #define ARM_8           ARM_6           /* same core instruction set */
47 #define ARM_9           ARM_6           /* same core instruction set */
48 #define ARM_CPU_MASK    0x0000000f
49
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL     0x00000010      /* allow long multiplies */
52 #define ARM_HALFWORD    0x00000020      /* allow half word loads */
53 #define ARM_THUMB       0x00000040      /* allow BX instruction  */
54 #define ARM_EXT_V5      0x00000080      /* allow CLZ etc         */
55
56 /* Architectures are the sum of the base and extensions.  */
57 #define ARM_ARCH_V4     (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 #define ARM_ARCH_V4T    (ARM_ARCH_V4 | ARM_THUMB)
59 #define ARM_ARCH_V5     (ARM_ARCH_V4 | ARM_EXT_V5)
60 #define ARM_ARCH_V5T    (ARM_ARCH_V5 | ARM_THUMB)
61
62 /* Some useful combinations:  */
63 #define ARM_ANY         0x00ffffff
64 #define ARM_2UP         (ARM_ANY - ARM_1)
65 #define ARM_ALL         ARM_2UP         /* Not arm1 only */
66 #define ARM_3UP         0x00fffffc
67 #define ARM_6UP         0x00fffff8      /* Includes ARM7 */
68
69 #define FPU_CORE        0x80000000
70 #define FPU_FPA10       0x40000000
71 #define FPU_FPA11       0x40000000
72 #define FPU_NONE        0
73
74 /* Some useful combinations  */
75 #define FPU_ALL         0xff000000      /* Note this is ~ARM_ANY */
76 #define FPU_MEMMULTI    0x7f000000      /* Not fpu_core */
77
78      
79 #ifndef CPU_DEFAULT
80 #if defined __thumb__
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
82 #else
83 #define CPU_DEFAULT ARM_ALL
84 #endif
85 #endif
86
87 #ifndef FPU_DEFAULT
88 #define FPU_DEFAULT FPU_ALL
89 #endif
90
91 #define streq(a, b)           (strcmp (a, b) == 0)
92 #define skip_whitespace(str)  while (* (str) == ' ') ++ (str)
93
94 static unsigned long    cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
95 static int target_oabi = 0;
96
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure */
99 static boolean          uses_apcs_26 = false;
100 static boolean          support_interwork = false;
101 static boolean          uses_apcs_float = false;
102 static boolean          pic_code = false;
103 #endif
104
105 /* This array holds the chars that always start a comment.  If the
106    pre-processor is disabled, these aren't very useful.  */
107 CONST char comment_chars[] = "@";
108
109 /* This array holds the chars that only start a comment at the beginning of
110    a line.  If the line seems to have the form '# 123 filename'
111    .line and .file directives will appear in the pre-processed output.  */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113    first line of the input file.  This is because the compiler outputs
114    #NO_APP at the beginning of its output.  */
115 /* Also note that comments like this one will always work.  */
116 CONST char line_comment_chars[] = "#";
117
118 CONST char line_separator_chars[] = ";";
119
120 /* Chars that can be used to separate mant
121    from exp in floating point numbers.  */
122 CONST char EXP_CHARS[] = "eE";
123
124 /* Chars that mean this number is a floating point constant */
125 /* As in 0f12.456 */
126 /* or    0d1.2345e12 */
127
128 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
129
130 /* Prefix characters that indicate the start of an immediate
131    value.  */
132 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
133
134 #ifdef OBJ_ELF
135 symbolS * GOT_symbol;           /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
136 #endif
137
138 CONST int md_reloc_size = 8;    /* Size of relocation record */
139
140 static int thumb_mode = 0;      /* 0: assemble for ARM, 1: assemble for Thumb,
141                                    2: assemble for Thumb even though target cpu
142                                    does not support thumb instructions.  */
143 typedef struct arm_fix
144 {
145   int thumb_mode;
146 } arm_fix_data;
147
148 struct arm_it
149 {
150   CONST char *  error;
151   unsigned long instruction;
152   int           suffix;
153   int           size;
154   struct
155     {
156       bfd_reloc_code_real_type type;
157       expressionS              exp;
158       int                      pc_rel;
159     } reloc;
160 };
161
162 struct arm_it inst;
163
164 struct asm_shift
165 {
166   CONST char *  template;
167   unsigned long value;
168 };
169
170 static CONST struct asm_shift shift[] =
171 {
172   {"asl", 0},
173   {"lsl", 0},
174   {"lsr", 0x00000020},
175   {"asr", 0x00000040},
176   {"ror", 0x00000060},
177   {"rrx", 0x00000060},
178   {"ASL", 0},
179   {"LSL", 0},
180   {"LSR", 0x00000020},
181   {"ASR", 0x00000040},
182   {"ROR", 0x00000060},
183   {"RRX", 0x00000060}
184 };
185
186 #define NO_SHIFT_RESTRICT 1
187 #define SHIFT_RESTRICT    0
188
189 #define NUM_FLOAT_VALS 8
190
191 CONST char * fp_const[] = 
192 {
193   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
194 };
195
196 /* Number of littlenums required to hold an extended precision number.  */
197 #define MAX_LITTLENUMS 6
198
199 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
200
201 #define FAIL    (-1)
202 #define SUCCESS (0)
203
204 #define SUFF_S 1
205 #define SUFF_D 2
206 #define SUFF_E 3
207 #define SUFF_P 4
208
209 #define CP_T_X   0x00008000
210 #define CP_T_Y   0x00400000
211 #define CP_T_Pre 0x01000000
212 #define CP_T_UD  0x00800000
213 #define CP_T_WB  0x00200000
214
215 #define CONDS_BIT       (0x00100000)
216 #define LOAD_BIT        (0x00100000)
217 #define TRANS_BIT       (0x00200000)
218
219 struct asm_cond
220 {
221   CONST char *  template;
222   unsigned long value;
223 };
224
225 /* This is to save a hash look-up in the common case.  */
226 #define COND_ALWAYS 0xe0000000
227
228 static CONST struct asm_cond conds[] = 
229 {
230   {"eq", 0x00000000},
231   {"ne", 0x10000000},
232   {"cs", 0x20000000}, {"hs", 0x20000000},
233   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
234   {"mi", 0x40000000},
235   {"pl", 0x50000000},
236   {"vs", 0x60000000},
237   {"vc", 0x70000000},
238   {"hi", 0x80000000},
239   {"ls", 0x90000000},
240   {"ge", 0xa0000000},
241   {"lt", 0xb0000000},
242   {"gt", 0xc0000000},
243   {"le", 0xd0000000},
244   {"al", 0xe0000000},
245   {"nv", 0xf0000000}
246 };
247
248 /* Warning: If the top bit of the set_bits is set, then the standard
249    instruction bitmask is ignored, and the new bitmask is taken from
250    the set_bits:  */
251 struct asm_flg
252 {
253   CONST char *  template;       /* Basic flag string */
254   unsigned long set_bits;       /* Bits to set */
255 };
256
257 static CONST struct asm_flg s_flag[] =
258 {
259   {"s", CONDS_BIT},
260   {NULL, 0}
261 };
262
263 static CONST struct asm_flg ldr_flags[] =
264 {
265   {"b",  0x00400000},
266   {"t",  TRANS_BIT},
267   {"bt", 0x00400000 | TRANS_BIT},
268   {"h",  0x801000b0},
269   {"sh", 0x801000f0},
270   {"sb", 0x801000d0},
271   {NULL, 0}
272 };
273
274 static CONST struct asm_flg str_flags[] =
275 {
276   {"b",  0x00400000},
277   {"t",  TRANS_BIT},
278   {"bt", 0x00400000 | TRANS_BIT},
279   {"h",  0x800000b0},
280   {NULL, 0}
281 };
282
283 static CONST struct asm_flg byte_flag[] =
284 {
285   {"b", 0x00400000},
286   {NULL, 0}
287 };
288
289 static CONST struct asm_flg cmp_flags[] =
290 {
291   {"s", CONDS_BIT},
292   {"p", 0x0010f000},
293   {NULL, 0}
294 };
295
296 static CONST struct asm_flg ldm_flags[] =
297 {
298   {"ed", 0x01800000},
299   {"fd", 0x00800000},
300   {"ea", 0x01000000},
301   {"fa", 0x08000000},
302   {"ib", 0x01800000},
303   {"ia", 0x00800000},
304   {"db", 0x01000000},
305   {"da", 0x08000000},
306   {NULL, 0}
307 };
308
309 static CONST struct asm_flg stm_flags[] =
310 {
311   {"ed", 0x08000000},
312   {"fd", 0x01000000},
313   {"ea", 0x00800000},
314   {"fa", 0x01800000},
315   {"ib", 0x01800000},
316   {"ia", 0x00800000},
317   {"db", 0x01000000},
318   {"da", 0x08000000},
319   {NULL, 0}
320 };
321
322 static CONST struct asm_flg lfm_flags[] =
323 {
324   {"fd", 0x00800000},
325   {"ea", 0x01000000},
326   {NULL, 0}
327 };
328
329 static CONST struct asm_flg sfm_flags[] =
330 {
331   {"fd", 0x01000000},
332   {"ea", 0x00800000},
333   {NULL, 0}
334 };
335
336 static CONST struct asm_flg round_flags[] =
337 {
338   {"p", 0x00000020},
339   {"m", 0x00000040},
340   {"z", 0x00000060},
341   {NULL, 0}
342 };
343
344 /* The implementation of the FIX instruction is broken on some assemblers,
345    in that it accepts a precision specifier as well as a rounding specifier,
346    despite the fact that this is meaningless.  To be more compatible, we
347    accept it as well, though of course it does not set any bits.  */
348 static CONST struct asm_flg fix_flags[] =
349 {
350   {"p", 0x00000020},
351   {"m", 0x00000040},
352   {"z", 0x00000060},
353   {"sp", 0x00000020},
354   {"sm", 0x00000040},
355   {"sz", 0x00000060},
356   {"dp", 0x00000020},
357   {"dm", 0x00000040},
358   {"dz", 0x00000060},
359   {"ep", 0x00000020},
360   {"em", 0x00000040},
361   {"ez", 0x00000060},
362   {NULL, 0}
363 };
364
365 static CONST struct asm_flg except_flag[] =
366 {
367   {"e", 0x00400000},
368   {NULL, 0}
369 };
370
371 static CONST struct asm_flg cplong_flag[] =
372 {
373   {"l", 0x00400000},
374   {NULL, 0}
375 };
376
377 struct asm_psr
378 {
379   CONST char *  template;
380   boolean       cpsr;
381   unsigned long field;
382 };
383
384 #define SPSR_BIT   (1 << 22)  /* The bit that distnguishes CPSR and SPSR.  */
385 #define PSR_SHIFT  16  /* How many bits to shift the PSR_xxx bits up by.  */
386
387 #define PSR_c   (1 << 0)
388 #define PSR_x   (1 << 1)
389 #define PSR_s   (1 << 2)
390 #define PSR_f   (1 << 3)
391
392 static CONST struct asm_psr psrs[] =
393 {
394   {"CPSR",      true,  PSR_c | PSR_f},
395   {"CPSR_all",  true,  PSR_c | PSR_f},
396   {"SPSR",      false, PSR_c | PSR_f},
397   {"SPSR_all",  false, PSR_c | PSR_f},
398   {"CPSR_flg",  true,  PSR_f},
399   {"CPSR_f",    true,  PSR_f},
400   {"SPSR_flg",  false, PSR_f},
401   {"SPSR_f",    false, PSR_f}, 
402   {"CPSR_c",    true,  PSR_c},
403   {"CPSR_ctl",  true,  PSR_c},
404   {"SPSR_c",    false, PSR_c},
405   {"SPSR_ctl",  false, PSR_c},
406   {"CPSR_x",    true,  PSR_x},
407   {"CPSR_s",    true,  PSR_s},
408   {"SPSR_x",    false, PSR_x},
409   {"SPSR_s",    false, PSR_s},
410   /* Combinations of flags.  */
411   {"CPSR_fs",   true, PSR_f | PSR_s},
412   {"CPSR_fx",   true, PSR_f | PSR_x},
413   {"CPSR_fc",   true, PSR_f | PSR_c},
414   {"CPSR_sf",   true, PSR_s | PSR_f},
415   {"CPSR_sx",   true, PSR_s | PSR_x},
416   {"CPSR_sc",   true, PSR_s | PSR_c},
417   {"CPSR_xf",   true, PSR_x | PSR_f},
418   {"CPSR_xs",   true, PSR_x | PSR_s},
419   {"CPSR_xc",   true, PSR_x | PSR_c},
420   {"CPSR_cf",   true, PSR_c | PSR_f},
421   {"CPSR_cs",   true, PSR_c | PSR_s},
422   {"CPSR_cx",   true, PSR_c | PSR_x},
423   {"CPSR_fsx",  true, PSR_f | PSR_s | PSR_x},
424   {"CPSR_fsc",  true, PSR_f | PSR_s | PSR_c},
425   {"CPSR_fxs",  true, PSR_f | PSR_x | PSR_s},
426   {"CPSR_fxc",  true, PSR_f | PSR_x | PSR_c},
427   {"CPSR_fcs",  true, PSR_f | PSR_c | PSR_s},
428   {"CPSR_fcx",  true, PSR_f | PSR_c | PSR_x},
429   {"CPSR_sfx",  true, PSR_s | PSR_f | PSR_x},
430   {"CPSR_sfc",  true, PSR_s | PSR_f | PSR_c},
431   {"CPSR_sxf",  true, PSR_s | PSR_x | PSR_f},
432   {"CPSR_sxc",  true, PSR_s | PSR_x | PSR_c},
433   {"CPSR_scf",  true, PSR_s | PSR_c | PSR_f},
434   {"CPSR_scx",  true, PSR_s | PSR_c | PSR_x},
435   {"CPSR_xfs",  true, PSR_x | PSR_f | PSR_s},
436   {"CPSR_xfc",  true, PSR_x | PSR_f | PSR_c},
437   {"CPSR_xsf",  true, PSR_x | PSR_s | PSR_f},
438   {"CPSR_xsc",  true, PSR_x | PSR_s | PSR_c},
439   {"CPSR_xcf",  true, PSR_x | PSR_c | PSR_f},
440   {"CPSR_xcs",  true, PSR_x | PSR_c | PSR_s},
441   {"CPSR_cfs",  true, PSR_c | PSR_f | PSR_s},
442   {"CPSR_cfx",  true, PSR_c | PSR_f | PSR_x},
443   {"CPSR_csf",  true, PSR_c | PSR_s | PSR_f},
444   {"CPSR_csx",  true, PSR_c | PSR_s | PSR_x},
445   {"CPSR_cxf",  true, PSR_c | PSR_x | PSR_f},
446   {"CPSR_cxs",  true, PSR_c | PSR_x | PSR_s},
447   {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c},
448   {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x},
449   {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c},
450   {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s},
451   {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x},
452   {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s},
453   {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c},
454   {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x},
455   {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c},
456   {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f},
457   {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x},
458   {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f},
459   {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c},
460   {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s},
461   {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c},
462   {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f},
463   {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s},
464   {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f},
465   {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x},
466   {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s},
467   {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x},
468   {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f},
469   {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s},
470   {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f},
471   {"SPSR_fs",   false, PSR_f | PSR_s},
472   {"SPSR_fx",   false, PSR_f | PSR_x},
473   {"SPSR_fc",   false, PSR_f | PSR_c},
474   {"SPSR_sf",   false, PSR_s | PSR_f},
475   {"SPSR_sx",   false, PSR_s | PSR_x},
476   {"SPSR_sc",   false, PSR_s | PSR_c},
477   {"SPSR_xf",   false, PSR_x | PSR_f},
478   {"SPSR_xs",   false, PSR_x | PSR_s},
479   {"SPSR_xc",   false, PSR_x | PSR_c},
480   {"SPSR_cf",   false, PSR_c | PSR_f},
481   {"SPSR_cs",   false, PSR_c | PSR_s},
482   {"SPSR_cx",   false, PSR_c | PSR_x},
483   {"SPSR_fsx",  false, PSR_f | PSR_s | PSR_x},
484   {"SPSR_fsc",  false, PSR_f | PSR_s | PSR_c},
485   {"SPSR_fxs",  false, PSR_f | PSR_x | PSR_s},
486   {"SPSR_fxc",  false, PSR_f | PSR_x | PSR_c},
487   {"SPSR_fcs",  false, PSR_f | PSR_c | PSR_s},
488   {"SPSR_fcx",  false, PSR_f | PSR_c | PSR_x},
489   {"SPSR_sfx",  false, PSR_s | PSR_f | PSR_x},
490   {"SPSR_sfc",  false, PSR_s | PSR_f | PSR_c},
491   {"SPSR_sxf",  false, PSR_s | PSR_x | PSR_f},
492   {"SPSR_sxc",  false, PSR_s | PSR_x | PSR_c},
493   {"SPSR_scf",  false, PSR_s | PSR_c | PSR_f},
494   {"SPSR_scx",  false, PSR_s | PSR_c | PSR_x},
495   {"SPSR_xfs",  false, PSR_x | PSR_f | PSR_s},
496   {"SPSR_xfc",  false, PSR_x | PSR_f | PSR_c},
497   {"SPSR_xsf",  false, PSR_x | PSR_s | PSR_f},
498   {"SPSR_xsc",  false, PSR_x | PSR_s | PSR_c},
499   {"SPSR_xcf",  false, PSR_x | PSR_c | PSR_f},
500   {"SPSR_xcs",  false, PSR_x | PSR_c | PSR_s},
501   {"SPSR_cfs",  false, PSR_c | PSR_f | PSR_s},
502   {"SPSR_cfx",  false, PSR_c | PSR_f | PSR_x},
503   {"SPSR_csf",  false, PSR_c | PSR_s | PSR_f},
504   {"SPSR_csx",  false, PSR_c | PSR_s | PSR_x},
505   {"SPSR_cxf",  false, PSR_c | PSR_x | PSR_f},
506   {"SPSR_cxs",  false, PSR_c | PSR_x | PSR_s},
507   {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c},
508   {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x},
509   {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c},
510   {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s},
511   {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x},
512   {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s},
513   {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c},
514   {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x},
515   {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c},
516   {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f},
517   {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x},
518   {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f},
519   {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c},
520   {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s},
521   {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c},
522   {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f},
523   {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s},
524   {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f},
525   {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x},
526   {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s},
527   {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x},
528   {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f},
529   {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s},
530   {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
531   /* For backwards compatability with older toolchain we also
532      support lower case versions of some of these flags.  */
533   {"cpsr",      true,  PSR_c | PSR_f},
534   {"cpsr_all",  true,  PSR_c | PSR_f},
535   {"spsr",      false, PSR_c | PSR_f},
536   {"spsr_all",  false, PSR_c | PSR_f},
537   {"cpsr_flg",  true,  PSR_f},
538   {"cpsr_f",    true,  PSR_f},
539   {"spsr_flg",  false, PSR_f},
540   {"spsr_f",    false, PSR_f}, 
541   {"cpsr_c",    true,  PSR_c},
542   {"cpsr_ctl",  true,  PSR_c},
543   {"spsr_c",    false, PSR_c},
544   {"spsr_ctl",  false, PSR_c}
545 };
546
547 /* Functions called by parser.  */
548 /* ARM instructions */
549 static void do_arit             PARAMS ((char *, unsigned long));
550 static void do_cmp              PARAMS ((char *, unsigned long));
551 static void do_mov              PARAMS ((char *, unsigned long));
552 static void do_ldst             PARAMS ((char *, unsigned long));
553 static void do_ldmstm           PARAMS ((char *, unsigned long));
554 static void do_branch           PARAMS ((char *, unsigned long));
555 static void do_swi              PARAMS ((char *, unsigned long));
556 /* Pseudo Op codes */                                         
557 static void do_adr              PARAMS ((char *, unsigned long));
558 static void do_adrl             PARAMS ((char *, unsigned long));
559 static void do_nop              PARAMS ((char *, unsigned long));
560 /* ARM 2 */                                                   
561 static void do_mul              PARAMS ((char *, unsigned long));
562 static void do_mla              PARAMS ((char *, unsigned long));
563 /* ARM 3 */                                                   
564 static void do_swap             PARAMS ((char *, unsigned long));
565 /* ARM 6 */                                                   
566 static void do_msr              PARAMS ((char *, unsigned long));
567 static void do_mrs              PARAMS ((char *, unsigned long));
568 /* ARM 7M */                                                  
569 static void do_mull             PARAMS ((char *, unsigned long));
570 /* ARM THUMB */                                               
571 static void do_bx               PARAMS ((char *, unsigned long));
572
573                                                               
574 /* Coprocessor Instructions */                                
575 static void do_cdp              PARAMS ((char *, unsigned long));
576 static void do_lstc             PARAMS ((char *, unsigned long));
577 static void do_co_reg           PARAMS ((char *, unsigned long));
578 static void do_fp_ctrl          PARAMS ((char *, unsigned long));
579 static void do_fp_ldst          PARAMS ((char *, unsigned long));
580 static void do_fp_ldmstm        PARAMS ((char *, unsigned long));
581 static void do_fp_dyadic        PARAMS ((char *, unsigned long));
582 static void do_fp_monadic       PARAMS ((char *, unsigned long));
583 static void do_fp_cmp           PARAMS ((char *, unsigned long));
584 static void do_fp_from_reg      PARAMS ((char *, unsigned long));
585 static void do_fp_to_reg        PARAMS ((char *, unsigned long));
586
587 static void fix_new_arm         PARAMS ((fragS *, int, short, expressionS *, int, int));
588 static int arm_reg_parse        PARAMS ((char **));
589 static CONST struct asm_psr * arm_psr_parse PARAMS ((char **));
590 static void symbol_locate       PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
591 static int add_to_lit_pool      PARAMS ((void));
592 static unsigned validate_immediate PARAMS ((unsigned));
593 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
594 static int validate_offset_imm  PARAMS ((unsigned int, int));
595 static void opcode_select       PARAMS ((int));
596 static void end_of_line         PARAMS ((char *));
597 static int reg_required_here    PARAMS ((char **, int));
598 static int psr_required_here    PARAMS ((char **));
599 static int co_proc_number       PARAMS ((char **));
600 static int cp_opc_expr          PARAMS ((char **, int, int));
601 static int cp_reg_required_here PARAMS ((char **, int));
602 static int fp_reg_required_here PARAMS ((char **, int));
603 static int cp_address_offset    PARAMS ((char **));
604 static int cp_address_required_here     PARAMS ((char **));
605 static int my_get_float_expression      PARAMS ((char **));
606 static int skip_past_comma      PARAMS ((char **));
607 static int walk_no_bignums      PARAMS ((symbolS *));
608 static int negate_data_op       PARAMS ((unsigned long *, unsigned long));
609 static int data_op2             PARAMS ((char **));
610 static int fp_op2               PARAMS ((char **));
611 static long reg_list            PARAMS ((char **));
612 static void thumb_load_store    PARAMS ((char *, int, int));
613 static int decode_shift         PARAMS ((char **, int));
614 static int ldst_extend          PARAMS ((char **, int));
615 static void thumb_add_sub       PARAMS ((char *, int));
616 static void insert_reg          PARAMS ((int));
617 static void thumb_shift         PARAMS ((char *, int));
618 static void thumb_mov_compare   PARAMS ((char *, int));
619 static void set_constant_flonums        PARAMS ((void));
620 static valueT md_chars_to_number        PARAMS ((char *, int));
621 static void insert_reg_alias    PARAMS ((char *, int));
622 static void output_inst         PARAMS ((void));
623 #ifdef OBJ_ELF
624 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
625 #endif
626
627 /* ARM instructions take 4bytes in the object file, Thumb instructions
628    take 2:  */
629 #define INSN_SIZE       4
630
631 /* LONGEST_INST is the longest basic instruction name without conditions or 
632    flags.  ARM7M has 4 of length 5.  */
633
634 #define LONGEST_INST 5
635
636
637 struct asm_opcode 
638 {
639   CONST char *           template;      /* Basic string to match */
640   unsigned long          value;         /* Basic instruction code */
641
642   /* Compulsory suffix that must follow conds. If "", then the
643      instruction is not conditional and must have no suffix. */
644   CONST char *           comp_suffix;   
645
646   CONST struct asm_flg * flags;         /* Bits to toggle if flag 'n' set */
647   unsigned long          variants;      /* Which CPU variants this exists for */
648   /* Function to call to parse args */
649   void (*                parms) PARAMS ((char *, unsigned long));
650 };
651
652 static CONST struct asm_opcode insns[] = 
653 {
654 /* ARM Instructions */
655   {"and",   0x00000000, NULL,   s_flag,      ARM_ANY,      do_arit},
656   {"eor",   0x00200000, NULL,   s_flag,      ARM_ANY,      do_arit},
657   {"sub",   0x00400000, NULL,   s_flag,      ARM_ANY,      do_arit},
658   {"rsb",   0x00600000, NULL,   s_flag,      ARM_ANY,      do_arit},
659   {"add",   0x00800000, NULL,   s_flag,      ARM_ANY,      do_arit},
660   {"adc",   0x00a00000, NULL,   s_flag,      ARM_ANY,      do_arit},
661   {"sbc",   0x00c00000, NULL,   s_flag,      ARM_ANY,      do_arit},
662   {"rsc",   0x00e00000, NULL,   s_flag,      ARM_ANY,      do_arit},
663   {"orr",   0x01800000, NULL,   s_flag,      ARM_ANY,      do_arit},
664   {"bic",   0x01c00000, NULL,   s_flag,      ARM_ANY,      do_arit},
665   {"tst",   0x01000000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
666   {"teq",   0x01200000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
667   {"cmp",   0x01400000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
668   {"cmn",   0x01600000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
669   {"mov",   0x01a00000, NULL,   s_flag,      ARM_ANY,      do_mov},
670   {"mvn",   0x01e00000, NULL,   s_flag,      ARM_ANY,      do_mov},
671   {"str",   0x04000000, NULL,   str_flags,   ARM_ANY,      do_ldst},
672   {"ldr",   0x04100000, NULL,   ldr_flags,   ARM_ANY,      do_ldst},
673   {"stm",   0x08000000, NULL,   stm_flags,   ARM_ANY,      do_ldmstm},
674   {"ldm",   0x08100000, NULL,   ldm_flags,   ARM_ANY,      do_ldmstm},
675   {"swi",   0x0f000000, NULL,   NULL,        ARM_ANY,      do_swi},
676 #ifdef TE_WINCE
677   {"bl",    0x0b000000, NULL,   NULL,        ARM_ANY,      do_branch},
678   {"b",     0x0a000000, NULL,   NULL,        ARM_ANY,      do_branch},
679 #else
680   {"bl",    0x0bfffffe, NULL,   NULL,        ARM_ANY,      do_branch},
681   {"b",     0x0afffffe, NULL,   NULL,        ARM_ANY,      do_branch},
682 #endif
683   
684 /* Pseudo ops */
685   {"adr",   0x028f0000, NULL,   NULL,        ARM_ANY,      do_adr},
686   {"adrl",  0x028f0000, NULL,   NULL,        ARM_ANY,      do_adrl},
687   {"nop",   0x01a00000, NULL,   NULL,        ARM_ANY,      do_nop},
688
689 /* ARM 2 multiplies */
690   {"mul",   0x00000090, NULL,   s_flag,      ARM_2UP,      do_mul},
691   {"mla",   0x00200090, NULL,   s_flag,      ARM_2UP,      do_mla},
692
693 /* ARM 3 - swp instructions */
694   {"swp",   0x01000090, NULL,   byte_flag,   ARM_3UP,      do_swap},
695
696 /* ARM 6 Coprocessor instructions */
697   {"mrs",   0x010f0000, NULL,   NULL,        ARM_6UP,      do_mrs},
698   {"msr",   0x0120f000, NULL,   NULL,        ARM_6UP,      do_msr},
699 /* ScottB: our code uses 0x0128f000 for msr.
700    NickC:  but this is wrong because the bits 16 through 19 are
701            handled by the PSR_xxx defines above.  */
702
703 /* ARM 7M long multiplies - need signed/unsigned flags! */
704   {"smull", 0x00c00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
705   {"umull", 0x00800090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
706   {"smlal", 0x00e00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
707   {"umlal", 0x00a00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
708
709 /* ARM THUMB interworking */
710   {"bx",    0x012fff10, NULL,   NULL,        ARM_THUMB,    do_bx},
711
712 /* Floating point instructions */
713   {"wfs",   0x0e200110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
714   {"rfs",   0x0e300110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
715   {"wfc",   0x0e400110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
716   {"rfc",   0x0e500110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
717   {"ldf",   0x0c100100, "sdep", NULL,        FPU_ALL,      do_fp_ldst},
718   {"stf",   0x0c000100, "sdep", NULL,        FPU_ALL,      do_fp_ldst},
719   {"lfm",   0x0c100200, NULL,   lfm_flags,   FPU_MEMMULTI, do_fp_ldmstm},
720   {"sfm",   0x0c000200, NULL,   sfm_flags,   FPU_MEMMULTI, do_fp_ldmstm},
721   {"mvf",   0x0e008100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
722   {"mnf",   0x0e108100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
723   {"abs",   0x0e208100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
724   {"rnd",   0x0e308100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
725   {"sqt",   0x0e408100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
726   {"log",   0x0e508100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
727   {"lgn",   0x0e608100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
728   {"exp",   0x0e708100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
729   {"sin",   0x0e808100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
730   {"cos",   0x0e908100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
731   {"tan",   0x0ea08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
732   {"asn",   0x0eb08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
733   {"acs",   0x0ec08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
734   {"atn",   0x0ed08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
735   {"urd",   0x0ee08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
736   {"nrm",   0x0ef08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
737   {"adf",   0x0e000100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
738   {"suf",   0x0e200100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
739   {"rsf",   0x0e300100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
740   {"muf",   0x0e100100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
741   {"dvf",   0x0e400100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
742   {"rdf",   0x0e500100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
743   {"pow",   0x0e600100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
744   {"rpw",   0x0e700100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
745   {"rmf",   0x0e800100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
746   {"fml",   0x0e900100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
747   {"fdv",   0x0ea00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
748   {"frd",   0x0eb00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
749   {"pol",   0x0ec00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
750   {"cmf",   0x0e90f110, NULL,   except_flag, FPU_ALL,      do_fp_cmp},
751   {"cnf",   0x0eb0f110, NULL,   except_flag, FPU_ALL,      do_fp_cmp},
752 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
753    be an optional suffix, but part of the instruction.  To be compatible,
754    we accept either.  */
755   {"cmfe",  0x0ed0f110, NULL,   NULL,        FPU_ALL,      do_fp_cmp},
756   {"cnfe",  0x0ef0f110, NULL,   NULL,        FPU_ALL,      do_fp_cmp},
757   {"flt",   0x0e000110, "sde",  round_flags, FPU_ALL,      do_fp_from_reg},
758   {"fix",   0x0e100110, NULL,   fix_flags,   FPU_ALL,      do_fp_to_reg},
759
760 /* Generic copressor instructions.  */
761   {"cdp",   0x0e000000, NULL,  NULL,         ARM_2UP,      do_cdp},
762   {"ldc",   0x0c100000, NULL,  cplong_flag,  ARM_2UP,      do_lstc},
763   {"stc",   0x0c000000, NULL,  cplong_flag,  ARM_2UP,      do_lstc},
764   {"mcr",   0x0e000010, NULL,  NULL,         ARM_2UP,      do_co_reg},
765   {"mrc",   0x0e100010, NULL,  NULL,         ARM_2UP,      do_co_reg},
766 };
767
768 /* Defines for various bits that we will want to toggle.  */
769 #define INST_IMMEDIATE  0x02000000
770 #define OFFSET_REG      0x02000000
771 #define HWOFFSET_IMM    0x00400000
772 #define SHIFT_BY_REG    0x00000010
773 #define PRE_INDEX       0x01000000
774 #define INDEX_UP        0x00800000
775 #define WRITE_BACK      0x00200000
776 #define LDM_TYPE_2_OR_3 0x00400000
777
778 #define LITERAL_MASK    0xf000f000
779 #define COND_MASK       0xf0000000
780 #define OPCODE_MASK     0xfe1fffff
781 #define DATA_OP_SHIFT   21
782
783 /* Codes to distinguish the arithmetic instructions.  */
784 #define OPCODE_AND      0
785 #define OPCODE_EOR      1
786 #define OPCODE_SUB      2
787 #define OPCODE_RSB      3
788 #define OPCODE_ADD      4
789 #define OPCODE_ADC      5
790 #define OPCODE_SBC      6
791 #define OPCODE_RSC      7
792 #define OPCODE_TST      8
793 #define OPCODE_TEQ      9
794 #define OPCODE_CMP      10
795 #define OPCODE_CMN      11
796 #define OPCODE_ORR      12
797 #define OPCODE_MOV      13
798 #define OPCODE_BIC      14
799 #define OPCODE_MVN      15
800
801 static void do_t_nop            PARAMS ((char *));
802 static void do_t_arit           PARAMS ((char *));
803 static void do_t_add            PARAMS ((char *));
804 static void do_t_asr            PARAMS ((char *));
805 static void do_t_branch9        PARAMS ((char *));
806 static void do_t_branch12       PARAMS ((char *));
807 static void do_t_branch23       PARAMS ((char *));
808 static void do_t_bx             PARAMS ((char *));
809 static void do_t_compare        PARAMS ((char *));
810 static void do_t_ldmstm         PARAMS ((char *));
811 static void do_t_ldr            PARAMS ((char *));
812 static void do_t_ldrb           PARAMS ((char *));
813 static void do_t_ldrh           PARAMS ((char *));
814 static void do_t_lds            PARAMS ((char *));
815 static void do_t_lsl            PARAMS ((char *));
816 static void do_t_lsr            PARAMS ((char *));
817 static void do_t_mov            PARAMS ((char *));
818 static void do_t_push_pop       PARAMS ((char *));
819 static void do_t_str            PARAMS ((char *));
820 static void do_t_strb           PARAMS ((char *));
821 static void do_t_strh           PARAMS ((char *));
822 static void do_t_sub            PARAMS ((char *));
823 static void do_t_swi            PARAMS ((char *));
824 static void do_t_adr            PARAMS ((char *));
825
826 #define T_OPCODE_MUL 0x4340
827 #define T_OPCODE_TST 0x4200
828 #define T_OPCODE_CMN 0x42c0
829 #define T_OPCODE_NEG 0x4240
830 #define T_OPCODE_MVN 0x43c0
831
832 #define T_OPCODE_ADD_R3 0x1800
833 #define T_OPCODE_SUB_R3 0x1a00
834 #define T_OPCODE_ADD_HI 0x4400
835 #define T_OPCODE_ADD_ST 0xb000
836 #define T_OPCODE_SUB_ST 0xb080
837 #define T_OPCODE_ADD_SP 0xa800
838 #define T_OPCODE_ADD_PC 0xa000
839 #define T_OPCODE_ADD_I8 0x3000
840 #define T_OPCODE_SUB_I8 0x3800
841 #define T_OPCODE_ADD_I3 0x1c00
842 #define T_OPCODE_SUB_I3 0x1e00
843
844 #define T_OPCODE_ASR_R  0x4100
845 #define T_OPCODE_LSL_R  0x4080
846 #define T_OPCODE_LSR_R  0x40c0
847 #define T_OPCODE_ASR_I  0x1000
848 #define T_OPCODE_LSL_I  0x0000
849 #define T_OPCODE_LSR_I  0x0800
850
851 #define T_OPCODE_MOV_I8 0x2000
852 #define T_OPCODE_CMP_I8 0x2800
853 #define T_OPCODE_CMP_LR 0x4280
854 #define T_OPCODE_MOV_HR 0x4600
855 #define T_OPCODE_CMP_HR 0x4500
856
857 #define T_OPCODE_LDR_PC 0x4800
858 #define T_OPCODE_LDR_SP 0x9800
859 #define T_OPCODE_STR_SP 0x9000
860 #define T_OPCODE_LDR_IW 0x6800
861 #define T_OPCODE_STR_IW 0x6000
862 #define T_OPCODE_LDR_IH 0x8800
863 #define T_OPCODE_STR_IH 0x8000
864 #define T_OPCODE_LDR_IB 0x7800
865 #define T_OPCODE_STR_IB 0x7000
866 #define T_OPCODE_LDR_RW 0x5800
867 #define T_OPCODE_STR_RW 0x5000
868 #define T_OPCODE_LDR_RH 0x5a00
869 #define T_OPCODE_STR_RH 0x5200
870 #define T_OPCODE_LDR_RB 0x5c00
871 #define T_OPCODE_STR_RB 0x5400
872
873 #define T_OPCODE_PUSH   0xb400
874 #define T_OPCODE_POP    0xbc00
875
876 #define T_OPCODE_BRANCH 0xe7fe
877
878 static int thumb_reg            PARAMS ((char ** str, int hi_lo));
879
880 #define THUMB_SIZE      2       /* Size of thumb instruction.  */
881 #define THUMB_REG_LO    0x1
882 #define THUMB_REG_HI    0x2
883 #define THUMB_REG_ANY   0x3
884
885 #define THUMB_H1        0x0080
886 #define THUMB_H2        0x0040
887
888 #define THUMB_ASR 0
889 #define THUMB_LSL 1
890 #define THUMB_LSR 2
891
892 #define THUMB_MOVE 0
893 #define THUMB_COMPARE 1
894
895 #define THUMB_LOAD 0
896 #define THUMB_STORE 1
897
898 #define THUMB_PP_PC_LR 0x0100
899
900 /* These three are used for immediate shifts, do not alter.  */
901 #define THUMB_WORD 2
902 #define THUMB_HALFWORD 1
903 #define THUMB_BYTE 0
904
905 struct thumb_opcode 
906 {
907   CONST char *  template;       /* Basic string to match */
908   unsigned long value;          /* Basic instruction code */
909   int           size;
910   unsigned long          variants;    /* Which CPU variants this exists for */
911   void (*       parms) PARAMS ((char *));  /* Function to call to parse args */
912 };
913
914 static CONST struct thumb_opcode tinsns[] =
915 {
916   {"adc",       0x4140,         2,      ARM_THUMB, do_t_arit},
917   {"add",       0x0000,         2,      ARM_THUMB, do_t_add},
918   {"and",       0x4000,         2,      ARM_THUMB, do_t_arit},
919   {"asr",       0x0000,         2,      ARM_THUMB, do_t_asr},
920   {"b",         T_OPCODE_BRANCH, 2,     ARM_THUMB, do_t_branch12},
921   {"beq",       0xd0fe,         2,      ARM_THUMB, do_t_branch9},
922   {"bne",       0xd1fe,         2,      ARM_THUMB, do_t_branch9},
923   {"bcs",       0xd2fe,         2,      ARM_THUMB, do_t_branch9},
924   {"bhs",       0xd2fe,         2,      ARM_THUMB, do_t_branch9},
925   {"bcc",       0xd3fe,         2,      ARM_THUMB, do_t_branch9},
926   {"bul",       0xd3fe,         2,      ARM_THUMB, do_t_branch9},
927   {"blo",       0xd3fe,         2,      ARM_THUMB, do_t_branch9},
928   {"bmi",       0xd4fe,         2,      ARM_THUMB, do_t_branch9},
929   {"bpl",       0xd5fe,         2,      ARM_THUMB, do_t_branch9},
930   {"bvs",       0xd6fe,         2,      ARM_THUMB, do_t_branch9},
931   {"bvc",       0xd7fe,         2,      ARM_THUMB, do_t_branch9},
932   {"bhi",       0xd8fe,         2,      ARM_THUMB, do_t_branch9},
933   {"bls",       0xd9fe,         2,      ARM_THUMB, do_t_branch9},
934   {"bge",       0xdafe,         2,      ARM_THUMB, do_t_branch9},
935   {"blt",       0xdbfe,         2,      ARM_THUMB, do_t_branch9},
936   {"bgt",       0xdcfe,         2,      ARM_THUMB, do_t_branch9},
937   {"ble",       0xddfe,         2,      ARM_THUMB, do_t_branch9},
938   {"bal",       0xdefe,         2,      ARM_THUMB, do_t_branch9},
939   {"bic",       0x4380,         2,      ARM_THUMB, do_t_arit},
940   {"bl",        0xf7fffffe,     4,      ARM_THUMB, do_t_branch23},
941   {"bx",        0x4700,         2,      ARM_THUMB, do_t_bx},
942   {"cmn",       T_OPCODE_CMN,   2,      ARM_THUMB, do_t_arit},
943   {"cmp",       0x0000,         2,      ARM_THUMB, do_t_compare},
944   {"eor",       0x4040,         2,      ARM_THUMB, do_t_arit},
945   {"ldmia",     0xc800,         2,      ARM_THUMB, do_t_ldmstm},
946   {"ldr",       0x0000,         2,      ARM_THUMB, do_t_ldr},
947   {"ldrb",      0x0000,         2,      ARM_THUMB, do_t_ldrb},
948   {"ldrh",      0x0000,         2,      ARM_THUMB, do_t_ldrh},
949   {"ldrsb",     0x5600,         2,      ARM_THUMB, do_t_lds},
950   {"ldrsh",     0x5e00,         2,      ARM_THUMB, do_t_lds},
951   {"ldsb",      0x5600,         2,      ARM_THUMB, do_t_lds},
952   {"ldsh",      0x5e00,         2,      ARM_THUMB, do_t_lds},
953   {"lsl",       0x0000,         2,      ARM_THUMB, do_t_lsl},
954   {"lsr",       0x0000,         2,      ARM_THUMB, do_t_lsr},
955   {"mov",       0x0000,         2,      ARM_THUMB, do_t_mov},
956   {"mul",       T_OPCODE_MUL,   2,      ARM_THUMB, do_t_arit},
957   {"mvn",       T_OPCODE_MVN,   2,      ARM_THUMB, do_t_arit},
958   {"neg",       T_OPCODE_NEG,   2,      ARM_THUMB, do_t_arit},
959   {"orr",       0x4300,         2,      ARM_THUMB, do_t_arit},
960   {"pop",       0xbc00,         2,      ARM_THUMB, do_t_push_pop},
961   {"push",      0xb400,         2,      ARM_THUMB, do_t_push_pop},
962   {"ror",       0x41c0,         2,      ARM_THUMB, do_t_arit},
963   {"sbc",       0x4180,         2,      ARM_THUMB, do_t_arit},
964   {"stmia",     0xc000,         2,      ARM_THUMB, do_t_ldmstm},
965   {"str",       0x0000,         2,      ARM_THUMB, do_t_str},
966   {"strb",      0x0000,         2,      ARM_THUMB, do_t_strb},
967   {"strh",      0x0000,         2,      ARM_THUMB, do_t_strh},
968   {"swi",       0xdf00,         2,      ARM_THUMB, do_t_swi},
969   {"sub",       0x0000,         2,      ARM_THUMB, do_t_sub},
970   {"tst",       T_OPCODE_TST,   2,      ARM_THUMB, do_t_arit},
971   /* Pseudo ops: */
972   {"adr",       0x0000,         2,      ARM_THUMB, do_t_adr},
973   {"nop",       0x46C0,         2,      ARM_THUMB, do_t_nop},      /* mov r8,r8 */
974 };
975
976 struct reg_entry
977 {
978   CONST char * name;
979   int          number;
980 };
981
982 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
983 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
984 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
985
986 #define REG_PC  15
987 #define REG_LR  14
988 #define REG_SP  13
989
990 /* These are the standard names.  Users can add aliases with .req  */
991 static CONST struct reg_entry reg_table[] =
992 {
993   /* Processor Register Numbers.  */
994   {"r0", 0},    {"r1", 1},      {"r2", 2},      {"r3", 3},
995   {"r4", 4},    {"r5", 5},      {"r6", 6},      {"r7", 7},
996   {"r8", 8},    {"r9", 9},      {"r10", 10},    {"r11", 11},
997   {"r12", 12},  {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
998   /* APCS conventions.  */
999   {"a1", 0},    {"a2", 1},    {"a3", 2},     {"a4", 3},
1000   {"v1", 4},    {"v2", 5},    {"v3", 6},     {"v4", 7},     {"v5", 8},
1001   {"v6", 9},    {"sb", 9},    {"v7", 10},    {"sl", 10},
1002   {"fp", 11},   {"ip", 12},   {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
1003   /* ATPCS additions to APCS conventions.  */
1004   {"wr", 7},    {"v8", 11},
1005   /* FP Registers.  */
1006   {"f0", 16},   {"f1", 17},   {"f2", 18},   {"f3", 19},
1007   {"f4", 20},   {"f5", 21},   {"f6", 22},   {"f7", 23},
1008   {"c0", 32},   {"c1", 33},   {"c2", 34},   {"c3", 35},
1009   {"c4", 36},   {"c5", 37},   {"c6", 38},   {"c7", 39},
1010   {"c8", 40},   {"c9", 41},   {"c10", 42},  {"c11", 43},
1011   {"c12", 44},  {"c13", 45},  {"c14", 46},  {"c15", 47},
1012   {"cr0", 32},  {"cr1", 33},  {"cr2", 34},  {"cr3", 35},
1013   {"cr4", 36},  {"cr5", 37},  {"cr6", 38},  {"cr7", 39},
1014   {"cr8", 40},  {"cr9", 41},  {"cr10", 42}, {"cr11", 43},
1015   {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1016   /* ATPCS additions to float register names.  */
1017   {"s0",16},    {"s1",17},      {"s2",18},      {"s3",19},
1018   {"s4",20},    {"s5",21},      {"s6",22},      {"s7",23},
1019   {"d0",16},    {"d1",17},      {"d2",18},      {"d3",19},
1020   {"d4",20},    {"d5",21},      {"d6",22},      {"d7",23},
1021   /* FIXME: At some point we need to add VFP register names.  */
1022   /* Array terminator.  */
1023   {NULL, 0}
1024 };
1025
1026 #define BAD_ARGS        _("Bad arguments to instruction")
1027 #define BAD_PC          _("r15 not allowed here")
1028 #define BAD_FLAGS       _("Instruction should not have flags")
1029 #define BAD_COND        _("Instruction is not conditional")
1030
1031 static struct hash_control * arm_ops_hsh = NULL;
1032 static struct hash_control * arm_tops_hsh = NULL;
1033 static struct hash_control * arm_cond_hsh = NULL;
1034 static struct hash_control * arm_shift_hsh = NULL;
1035 static struct hash_control * arm_reg_hsh = NULL;
1036 static struct hash_control * arm_psr_hsh = NULL;
1037
1038 /* This table describes all the machine specific pseudo-ops the assembler
1039    has to support.  The fields are:
1040      pseudo-op name without dot
1041      function to call to execute this pseudo-op
1042      Integer arg to pass to the function.  */
1043
1044 static void s_req PARAMS ((int));
1045 static void s_align PARAMS ((int));
1046 static void s_bss PARAMS ((int));
1047 static void s_even PARAMS ((int));
1048 static void s_ltorg PARAMS ((int));
1049 static void s_arm PARAMS ((int));
1050 static void s_thumb PARAMS ((int));
1051 static void s_code PARAMS ((int));
1052 static void s_force_thumb PARAMS ((int));
1053 static void s_thumb_func PARAMS ((int));
1054 static void s_thumb_set PARAMS ((int));
1055 static void arm_s_text PARAMS ((int));
1056 static void arm_s_data PARAMS ((int));
1057 #ifdef OBJ_ELF
1058 static void arm_s_section PARAMS ((int));
1059 static void s_arm_elf_cons PARAMS ((int));
1060 #endif
1061
1062 static int my_get_expression PARAMS ((expressionS *, char **));
1063
1064 CONST pseudo_typeS md_pseudo_table[] =
1065 {
1066   { "req",         s_req,         0 },  /* Never called becasue '.req' does not start line */
1067   { "bss",         s_bss,         0 },
1068   { "align",       s_align,       0 },
1069   { "arm",         s_arm,         0 },
1070   { "thumb",       s_thumb,       0 },
1071   { "code",        s_code,        0 },
1072   { "force_thumb", s_force_thumb, 0 },
1073   { "thumb_func",  s_thumb_func,  0 },
1074   { "thumb_set",   s_thumb_set,   0 },
1075   { "even",        s_even,        0 },
1076   { "ltorg",       s_ltorg,       0 },
1077   { "pool",        s_ltorg,       0 },
1078   /* Allow for the effect of section changes.  */
1079   { "text",        arm_s_text,    0 },
1080   { "data",        arm_s_data,    0 },
1081 #ifdef OBJ_ELF  
1082   { "section",     arm_s_section, 0 },
1083   { "section.s",   arm_s_section, 0 },
1084   { "sect",        arm_s_section, 0 },
1085   { "sect.s",      arm_s_section, 0 },
1086   { "word",        s_arm_elf_cons, 4 },
1087   { "long",        s_arm_elf_cons, 4 },
1088 #else
1089   { "word",        cons, 4},
1090 #endif
1091   { "extend",      float_cons, 'x' },
1092   { "ldouble",     float_cons, 'x' },
1093   { "packed",      float_cons, 'p' },
1094   { 0, 0, 0 }
1095 };
1096
1097 /* Stuff needed to resolve the label ambiguity
1098    As:
1099      ...
1100      label:   <insn>
1101    may differ from:
1102      ...
1103      label:
1104               <insn>
1105 */
1106
1107 symbolS *  last_label_seen;
1108 static int label_is_thumb_function_name = false;
1109
1110 /* Literal stuff */
1111
1112 #define MAX_LITERAL_POOL_SIZE 1024
1113
1114 typedef struct literalS
1115 {
1116   struct expressionS  exp;
1117   struct arm_it *     inst;
1118 } literalT;
1119
1120 literalT  literals[MAX_LITERAL_POOL_SIZE];
1121 int       next_literal_pool_place = 0; /* Next free entry in the pool */
1122 int       lit_pool_num = 1; /* Next literal pool number */
1123 symbolS * current_poolP = NULL;
1124
1125 static int
1126 add_to_lit_pool ()
1127 {
1128   int lit_count = 0;
1129
1130   if (current_poolP == NULL)
1131     current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
1132                                    (valueT) 0, &zero_address_frag);
1133
1134   /* Check if this literal value is already in the pool:  */
1135   while (lit_count < next_literal_pool_place)
1136     {
1137       if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1138           && inst.reloc.exp.X_op == O_constant
1139           && literals[lit_count].exp.X_add_number
1140              == inst.reloc.exp.X_add_number
1141           && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1142         break;
1143       lit_count++;
1144     }
1145
1146   if (lit_count == next_literal_pool_place) /* new entry */
1147     {
1148       if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1149         {
1150           inst.error = _("Literal Pool Overflow");
1151           return FAIL;
1152         }
1153
1154       literals[next_literal_pool_place].exp = inst.reloc.exp;
1155       lit_count = next_literal_pool_place++;
1156     }
1157
1158   inst.reloc.exp.X_op = O_symbol;
1159   inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1160   inst.reloc.exp.X_add_symbol = current_poolP;
1161
1162   return SUCCESS;
1163 }
1164  
1165 /* Can't use symbol_new here, so have to create a symbol and then at
1166    a later date assign it a value. Thats what these functions do.  */
1167 static void
1168 symbol_locate (symbolP, name, segment, valu, frag)
1169      symbolS *    symbolP; 
1170      CONST char * name;         /* It is copied, the caller can modify */
1171      segT         segment;      /* Segment identifier (SEG_<something>) */
1172      valueT       valu;         /* Symbol value */
1173      fragS *      frag;         /* Associated fragment */
1174 {
1175   unsigned int name_length;
1176   char * preserved_copy_of_name;
1177
1178   name_length = strlen (name) + 1;      /* +1 for \0 */
1179   obstack_grow (&notes, name, name_length);
1180   preserved_copy_of_name = obstack_finish (&notes);
1181 #ifdef STRIP_UNDERSCORE
1182   if (preserved_copy_of_name[0] == '_')
1183     preserved_copy_of_name++;
1184 #endif
1185
1186 #ifdef tc_canonicalize_symbol_name
1187   preserved_copy_of_name =
1188     tc_canonicalize_symbol_name (preserved_copy_of_name);
1189 #endif
1190
1191   S_SET_NAME (symbolP, preserved_copy_of_name);
1192
1193   S_SET_SEGMENT (symbolP, segment);
1194   S_SET_VALUE (symbolP, valu);
1195   symbol_clear_list_pointers(symbolP);
1196
1197   symbol_set_frag (symbolP, frag);
1198
1199   /* Link to end of symbol chain.  */
1200   {
1201     extern int symbol_table_frozen;
1202     if (symbol_table_frozen)
1203       abort ();
1204   }
1205
1206   symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1207
1208   obj_symbol_new_hook (symbolP);
1209
1210 #ifdef tc_symbol_new_hook
1211   tc_symbol_new_hook (symbolP);
1212 #endif
1213  
1214 #ifdef DEBUG_SYMS
1215   verify_symbol_chain (symbol_rootP, symbol_lastP);
1216 #endif /* DEBUG_SYMS */
1217 }
1218
1219 /* Check that an immediate is valid, and if so,
1220    convert it to the right format.  */
1221 static unsigned int
1222 validate_immediate (val)
1223      unsigned int val;
1224 {
1225   unsigned int a;
1226   unsigned int i;
1227   
1228 #define rotate_left(v, n) (v << n | v >> (32 - n))
1229   
1230   for (i = 0; i < 32; i += 2)
1231     if ((a = rotate_left (val, i)) <= 0xff)
1232       return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1233   
1234   return FAIL;
1235 }
1236
1237 /* Check to see if an immediate can be computed as two seperate immediate
1238    values, added together.  We already know that this value cannot be
1239    computed by just one ARM instruction.  */
1240 static unsigned int
1241 validate_immediate_twopart (val, highpart)
1242      unsigned int val;
1243      unsigned int * highpart;
1244 {
1245   unsigned int a;
1246   unsigned int i;
1247   
1248   for (i = 0; i < 32; i += 2)
1249     if (((a = rotate_left (val, i)) & 0xff) != 0)
1250       {
1251         if (a & 0xff00)
1252           {
1253             if (a & ~ 0xffff)
1254               continue;
1255             * highpart = (a  >> 8) | ((i + 24) << 7);
1256           }
1257         else if (a & 0xff0000)
1258           {
1259             if (a & 0xff000000)
1260               continue;
1261
1262             * highpart = (a >> 16) | ((i + 16) << 7);
1263           }
1264         else
1265           {
1266             assert (a & 0xff000000);
1267
1268             * highpart = (a >> 24) | ((i + 8) << 7);
1269           }
1270
1271         return (a & 0xff) | (i << 7);
1272       }
1273   
1274   return FAIL;
1275 }
1276
1277 static int
1278 validate_offset_imm (val, hwse)
1279      unsigned int val;
1280      int hwse;
1281 {
1282   if ((hwse && val > 255) || val > 4095)
1283      return FAIL;
1284   return val;
1285 }
1286
1287     
1288 static void
1289 s_req (a)
1290      int a ATTRIBUTE_UNUSED;
1291 {
1292   as_bad (_("Invalid syntax for .req directive."));
1293 }
1294
1295 static void
1296 s_bss (ignore)
1297      int ignore ATTRIBUTE_UNUSED;
1298 {
1299   /* We don't support putting frags in the BSS segment, we fake it by
1300      marking in_bss, then looking at s_skip for clues?.. */
1301   subseg_set (bss_section, 0);
1302   demand_empty_rest_of_line ();
1303 }
1304
1305 static void
1306 s_even (ignore)
1307      int ignore ATTRIBUTE_UNUSED;
1308 {
1309   if (!need_pass_2)             /* Never make frag if expect extra pass. */
1310     frag_align (1, 0, 0);
1311   
1312   record_alignment (now_seg, 1);
1313   
1314   demand_empty_rest_of_line ();
1315 }
1316
1317 static void
1318 s_ltorg (ignored)
1319      int ignored ATTRIBUTE_UNUSED;
1320 {
1321   int lit_count = 0;
1322   char sym_name[20];
1323
1324   if (current_poolP == NULL)
1325     return;
1326
1327   /* Align pool as you have word accesses */
1328   /* Only make a frag if we have to ... */
1329   if (!need_pass_2)
1330     frag_align (2, 0, 0);
1331
1332   record_alignment (now_seg, 2);
1333
1334   sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1335
1336   symbol_locate (current_poolP, sym_name, now_seg,
1337                  (valueT) frag_now_fix (), frag_now);
1338   symbol_table_insert (current_poolP);
1339
1340   ARM_SET_THUMB (current_poolP, thumb_mode);
1341   
1342 #if defined OBJ_COFF || defined OBJ_ELF
1343   ARM_SET_INTERWORK (current_poolP, support_interwork);
1344 #endif
1345   
1346   while (lit_count < next_literal_pool_place)
1347     /* First output the expression in the instruction to the pool.  */
1348     emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1349
1350   next_literal_pool_place = 0;
1351   current_poolP = NULL;
1352 }
1353
1354 static void
1355 s_align (unused)        /* Same as s_align_ptwo but align 0 => align 2 */
1356      int unused ATTRIBUTE_UNUSED;
1357 {
1358   register int temp;
1359   register long temp_fill;
1360   long max_alignment = 15;
1361
1362   temp = get_absolute_expression ();
1363   if (temp > max_alignment)
1364     as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1365   else if (temp < 0)
1366     {
1367       as_bad (_("Alignment negative. 0 assumed."));
1368       temp = 0;
1369     }
1370
1371   if (*input_line_pointer == ',')
1372     {
1373       input_line_pointer++;
1374       temp_fill = get_absolute_expression ();
1375     }
1376   else
1377     temp_fill = 0;
1378
1379   if (!temp)
1380     temp = 2;
1381
1382   /* Only make a frag if we HAVE to. . . */
1383   if (temp && !need_pass_2)
1384     frag_align (temp, (int) temp_fill, 0);
1385   demand_empty_rest_of_line ();
1386
1387   record_alignment (now_seg, temp);
1388 }
1389
1390 static void
1391 s_force_thumb (ignore)
1392      int ignore ATTRIBUTE_UNUSED;
1393 {
1394   /* If we are not already in thumb mode go into it, EVEN if
1395      the target processor does not support thumb instructions.
1396      This is used by gcc/config/arm/lib1funcs.asm for example
1397      to compile interworking support functions even if the
1398      target processor should not support interworking.  */
1399      
1400   if (! thumb_mode)
1401     {
1402       thumb_mode = 2;
1403       
1404       record_alignment (now_seg, 1);
1405     }
1406   
1407   demand_empty_rest_of_line ();
1408 }
1409
1410 static void
1411 s_thumb_func (ignore)
1412      int ignore ATTRIBUTE_UNUSED;
1413 {
1414   if (! thumb_mode)
1415     opcode_select (16);
1416
1417   /* The following label is the name/address of the start of a Thumb function.
1418      We need to know this for the interworking support.  */
1419   label_is_thumb_function_name = true;
1420
1421   demand_empty_rest_of_line ();
1422 }
1423
1424 /* Perform a .set directive, but also mark the alias as
1425    being a thumb function.  */
1426
1427 static void
1428 s_thumb_set (equiv)
1429      int equiv;
1430 {
1431   /* XXX the following is a duplicate of the code for s_set() in read.c
1432      We cannot just call that code as we need to get at the symbol that
1433      is created.  */
1434   register char *    name;
1435   register char      delim;
1436   register char *    end_name;
1437   register symbolS * symbolP;
1438
1439   /*
1440    * Especial apologies for the random logic:
1441    * this just grew, and could be parsed much more simply!
1442    * Dean in haste.
1443    */
1444   name      = input_line_pointer;
1445   delim     = get_symbol_end ();
1446   end_name  = input_line_pointer;
1447   *end_name = delim;
1448   
1449   SKIP_WHITESPACE ();
1450
1451   if (*input_line_pointer != ',')
1452     {
1453       *end_name = 0;
1454       as_bad (_("Expected comma after name \"%s\""), name);
1455       *end_name = delim;
1456       ignore_rest_of_line ();
1457       return;
1458     }
1459
1460   input_line_pointer++;
1461   *end_name = 0;
1462
1463   if (name[0] == '.' && name[1] == '\0')
1464     {
1465       /* XXX - this should not happen to .thumb_set  */
1466       abort ();
1467     }
1468
1469   if ((symbolP = symbol_find (name)) == NULL
1470       && (symbolP = md_undefined_symbol (name)) == NULL)
1471     {
1472 #ifndef NO_LISTING
1473       /* When doing symbol listings, play games with dummy fragments living
1474          outside the normal fragment chain to record the file and line info
1475          for this symbol.  */
1476       if (listing & LISTING_SYMBOLS)
1477         {
1478           extern struct list_info_struct * listing_tail;
1479           fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
1480           memset (dummy_frag, 0, sizeof(fragS));
1481           dummy_frag->fr_type = rs_fill;
1482           dummy_frag->line = listing_tail;
1483           symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1484           dummy_frag->fr_symbol = symbolP;
1485         }
1486       else
1487 #endif
1488         symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1489                             
1490 #ifdef OBJ_COFF
1491       /* "set" symbols are local unless otherwise specified. */
1492       SF_SET_LOCAL (symbolP);
1493 #endif /* OBJ_COFF */
1494     }                           /* make a new symbol */
1495
1496   symbol_table_insert (symbolP);
1497
1498   * end_name = delim;
1499
1500   if (equiv
1501       && S_IS_DEFINED (symbolP)
1502       && S_GET_SEGMENT (symbolP) != reg_section)
1503     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1504
1505   pseudo_set (symbolP);
1506   
1507   demand_empty_rest_of_line ();
1508
1509   /* XXX Now we come to the Thumb specific bit of code.  */
1510   
1511   THUMB_SET_FUNC (symbolP, 1);
1512   ARM_SET_THUMB (symbolP, 1);
1513 #if defined OBJ_ELF || defined OBJ_COFF
1514   ARM_SET_INTERWORK (symbolP, support_interwork);
1515 #endif
1516 }
1517
1518 /* If we change section we must dump the literal pool first.  */
1519 static void
1520 arm_s_text (ignore)
1521      int ignore;
1522 {
1523   if (now_seg != text_section)
1524     s_ltorg (0);
1525   
1526 #ifdef OBJ_ELF
1527   obj_elf_text (ignore);
1528 #else
1529   s_text (ignore);
1530 #endif
1531 }
1532
1533 static void
1534 arm_s_data (ignore)
1535      int ignore;
1536 {
1537   if (flag_readonly_data_in_text)
1538     {
1539       if (now_seg != text_section)
1540         s_ltorg (0);
1541     }
1542   else if (now_seg != data_section)
1543     s_ltorg (0);
1544   
1545 #ifdef OBJ_ELF
1546   obj_elf_data (ignore);
1547 #else
1548   s_data (ignore);
1549 #endif
1550 }
1551
1552 #ifdef OBJ_ELF
1553 static void
1554 arm_s_section (ignore)
1555      int ignore;
1556 {
1557   s_ltorg (0);
1558
1559   obj_elf_section (ignore);
1560 }
1561 #endif
1562
1563 static void
1564 opcode_select (width)
1565      int width;
1566 {
1567   switch (width)
1568     {
1569     case 16:
1570       if (! thumb_mode)
1571         {
1572           if (! (cpu_variant & ARM_THUMB))
1573             as_bad (_("selected processor does not support THUMB opcodes"));
1574           thumb_mode = 1;
1575           /* No need to force the alignment, since we will have been
1576              coming from ARM mode, which is word-aligned. */
1577           record_alignment (now_seg, 1);
1578         }
1579       break;
1580
1581     case 32:
1582       if (thumb_mode)
1583         {
1584           if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1585             as_bad (_("selected processor does not support ARM opcodes"));
1586           thumb_mode = 0;
1587           if (!need_pass_2)
1588             frag_align (2, 0, 0);
1589           record_alignment (now_seg, 1);
1590         }
1591       break;
1592
1593     default:
1594       as_bad (_("invalid instruction size selected (%d)"), width);
1595     }
1596 }
1597
1598 static void
1599 s_arm (ignore)
1600      int ignore ATTRIBUTE_UNUSED;
1601 {
1602   opcode_select (32);
1603   demand_empty_rest_of_line ();
1604 }
1605
1606 static void
1607 s_thumb (ignore)
1608      int ignore ATTRIBUTE_UNUSED;
1609 {
1610   opcode_select (16);
1611   demand_empty_rest_of_line ();
1612 }
1613
1614 static void
1615 s_code (unused)
1616      int unused ATTRIBUTE_UNUSED;
1617 {
1618   register int temp;
1619
1620   temp = get_absolute_expression ();
1621   switch (temp)
1622     {
1623     case 16:
1624     case 32:
1625       opcode_select (temp);
1626       break;
1627
1628     default:
1629       as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1630     }
1631 }
1632
1633 static void
1634 end_of_line (str)
1635      char * str;
1636 {
1637   skip_whitespace (str);
1638
1639   if (* str != '\0')
1640     inst.error = _("Garbage following instruction");
1641 }
1642
1643 static int
1644 skip_past_comma (str)
1645      char ** str;
1646 {
1647   char *p = *str, c;
1648   int comma = 0;
1649     
1650   while ((c = *p) == ' ' || c == ',')
1651     {
1652       p++;
1653       if (c == ',' && comma++)
1654         return FAIL;
1655     }
1656
1657   if (c == '\0')
1658     return FAIL;
1659
1660   *str = p;
1661   return comma ? SUCCESS : FAIL;
1662 }
1663
1664 /* A standard register must be given at this point.
1665    Shift is the place to put it in inst.instruction.
1666    Restores input start point on err.
1667    Returns the reg#, or FAIL.  */
1668 static int
1669 reg_required_here (str, shift)
1670      char ** str;
1671      int     shift;
1672 {
1673   static char buff [128]; /* XXX */
1674   int    reg;
1675   char * start = *str;
1676
1677   if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1678     {
1679       if (shift >= 0)
1680         inst.instruction |= reg << shift;
1681       return reg;
1682     }
1683
1684   /* Restore the start point, we may have got a reg of the wrong class.  */
1685   *str = start;
1686   
1687   /* In the few cases where we might be able to accept something else
1688      this error can be overridden.  */
1689   sprintf (buff, _("Register expected, not '%.100s'"), start);
1690   inst.error = buff;
1691
1692   return FAIL;
1693 }
1694
1695 static CONST struct asm_psr *
1696 arm_psr_parse (ccp)
1697      register char ** ccp;
1698 {
1699   char * start = * ccp;
1700   char   c;
1701   char * p;
1702   CONST struct asm_psr * psr;
1703
1704   p = start;
1705
1706   /* Skip to the end of the next word in the input stream.  */
1707   do
1708     {
1709       c = *p++;
1710     }
1711   while (isalpha (c) || c == '_');
1712
1713   /* Terminate the word.  */
1714   *--p = 0;
1715
1716   /* Now locate the word in the psr hash table.  */
1717   psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
1718
1719   /* Restore the input stream.  */
1720   *p = c;
1721
1722   /* If we found a valid match, advance the
1723      stream pointer past the end of the word.  */
1724   *ccp = p;
1725
1726   return psr;
1727 }
1728
1729 /* Parse the input looking for a PSR flag.  */
1730 static int
1731 psr_required_here (str)
1732      char ** str;
1733 {
1734   char * start = *str;
1735   CONST struct asm_psr * psr;
1736   
1737   psr = arm_psr_parse (str);
1738
1739   if (psr)
1740     {
1741       /* If this is the SPSR that is being modified, set the R bit.  */
1742       if (! psr->cpsr)
1743         inst.instruction |= SPSR_BIT;
1744
1745       /* Set the psr flags in the MSR instruction.  */
1746       inst.instruction |= psr->field << PSR_SHIFT;
1747       
1748       return SUCCESS;
1749     }
1750
1751   /* In the few cases where we might be able to accept
1752      something else this error can be overridden.  */
1753   inst.error = _("flag for {c}psr instruction expected");
1754
1755   /* Restore the start point.  */
1756   *str = start;
1757   return FAIL;
1758 }
1759
1760 static int
1761 co_proc_number (str)
1762      char ** str;
1763 {
1764   int processor, pchar;
1765
1766   skip_whitespace (* str);
1767
1768   /* The data sheet seems to imply that just a number on its own is valid
1769      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
1770      accept either.  */
1771   if (**str == 'p' || **str == 'P')
1772     (*str)++;
1773
1774   pchar = *(*str)++;
1775   if (pchar >= '0' && pchar <= '9')
1776     {
1777       processor = pchar - '0';
1778       if (**str >= '0' && **str <= '9')
1779         {
1780           processor = processor * 10 + *(*str)++ - '0';
1781           if (processor > 15)
1782             {
1783               inst.error = _("Illegal co-processor number");
1784               return FAIL;
1785             }
1786         }
1787     }
1788   else
1789     {
1790       inst.error = _("Bad or missing co-processor number");
1791       return FAIL;
1792     }
1793
1794   inst.instruction |= processor << 8;
1795   return SUCCESS;
1796 }
1797
1798 static int
1799 cp_opc_expr (str, where, length)
1800      char ** str;
1801      int where;
1802      int length;
1803 {
1804   expressionS expr;
1805
1806   skip_whitespace (* str);
1807
1808   memset (&expr, '\0', sizeof (expr));
1809
1810   if (my_get_expression (&expr, str))
1811     return FAIL;
1812   if (expr.X_op != O_constant)
1813     {
1814       inst.error = _("bad or missing expression");
1815       return FAIL;
1816     }
1817
1818   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1819     {
1820       inst.error = _("immediate co-processor expression too large");
1821       return FAIL;
1822     }
1823
1824   inst.instruction |= expr.X_add_number << where;
1825   return SUCCESS;
1826 }
1827
1828 static int
1829 cp_reg_required_here (str, where)
1830      char ** str;
1831      int     where;
1832 {
1833   int    reg;
1834   char * start = *str;
1835
1836   if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1837     {
1838       reg &= 15;
1839       inst.instruction |= reg << where;
1840       return reg;
1841     }
1842
1843   /* In the few cases where we might be able to accept something else
1844      this error can be overridden.  */
1845   inst.error = _("Co-processor register expected");
1846
1847   /* Restore the start point.  */
1848   *str = start;
1849   return FAIL;
1850 }
1851
1852 static int
1853 fp_reg_required_here (str, where)
1854      char ** str;
1855      int     where;
1856 {
1857   int reg;
1858   char * start = *str;
1859
1860   if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1861     {
1862       reg &= 7;
1863       inst.instruction |= reg << where;
1864       return reg;
1865     }
1866
1867   /* In the few cases where we might be able to accept something else
1868      this error can be overridden.  */
1869   inst.error = _("Floating point register expected");
1870
1871   /* Restore the start point.  */
1872   *str = start;
1873   return FAIL;
1874 }
1875
1876 static int
1877 cp_address_offset (str)
1878      char ** str;
1879 {
1880   int offset;
1881
1882   skip_whitespace (* str);
1883
1884   if (! is_immediate_prefix (**str))
1885     {
1886       inst.error = _("immediate expression expected");
1887       return FAIL;
1888     }
1889
1890   (*str)++;
1891   
1892   if (my_get_expression (& inst.reloc.exp, str))
1893     return FAIL;
1894   
1895   if (inst.reloc.exp.X_op == O_constant)
1896     {
1897       offset = inst.reloc.exp.X_add_number;
1898       
1899       if (offset & 3)
1900         {
1901           inst.error = _("co-processor address must be word aligned");
1902           return FAIL;
1903         }
1904
1905       if (offset > 1023 || offset < -1023)
1906         {
1907           inst.error = _("offset too large");
1908           return FAIL;
1909         }
1910
1911       if (offset >= 0)
1912         inst.instruction |= INDEX_UP;
1913       else
1914         offset = -offset;
1915
1916       inst.instruction |= offset >> 2;
1917     }
1918   else
1919     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1920
1921   return SUCCESS;
1922 }
1923
1924 static int
1925 cp_address_required_here (str)
1926      char ** str;
1927 {
1928   char * p = * str;
1929   int    pre_inc = 0;
1930   int    write_back = 0;
1931
1932   if (*p == '[')
1933     {
1934       int reg;
1935
1936       p++;
1937       skip_whitespace (p);
1938
1939       if ((reg = reg_required_here (& p, 16)) == FAIL)
1940         return FAIL;
1941
1942       skip_whitespace (p);
1943
1944       if (*p == ']')
1945         {
1946           p++;
1947           
1948           if (skip_past_comma (& p) == SUCCESS)
1949             {
1950               /* [Rn], #expr */
1951               write_back = WRITE_BACK;
1952               
1953               if (reg == REG_PC)
1954                 {
1955                   inst.error = _("pc may not be used in post-increment");
1956                   return FAIL;
1957                 }
1958
1959               if (cp_address_offset (& p) == FAIL)
1960                 return FAIL;
1961             }
1962           else
1963             pre_inc = PRE_INDEX | INDEX_UP;
1964         }
1965       else
1966         {
1967           /* '['Rn, #expr']'[!] */
1968
1969           if (skip_past_comma (& p) == FAIL)
1970             {
1971               inst.error = _("pre-indexed expression expected");
1972               return FAIL;
1973             }
1974
1975           pre_inc = PRE_INDEX;
1976           
1977           if (cp_address_offset (& p) == FAIL)
1978             return FAIL;
1979
1980           skip_whitespace (p);
1981
1982           if (*p++ != ']')
1983             {
1984               inst.error = _("missing ]");
1985               return FAIL;
1986             }
1987
1988           skip_whitespace (p);
1989
1990           if (*p == '!')
1991             {
1992               if (reg == REG_PC)
1993                 {
1994                   inst.error = _("pc may not be used with write-back");
1995                   return FAIL;
1996                 }
1997
1998               p++;
1999               write_back = WRITE_BACK;
2000             }
2001         }
2002     }
2003   else
2004     {
2005       if (my_get_expression (&inst.reloc.exp, &p))
2006         return FAIL;
2007
2008       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2009       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust */
2010       inst.reloc.pc_rel = 1;
2011       inst.instruction |= (REG_PC << 16);
2012       pre_inc = PRE_INDEX;
2013     }
2014
2015   inst.instruction |= write_back | pre_inc;
2016   *str = p;
2017   return SUCCESS;
2018 }
2019
2020 static void
2021 do_nop (str, flags)
2022      char * str;
2023      unsigned long flags;
2024 {
2025   /* Do nothing really.  */
2026   inst.instruction |= flags; /* This is pointless.  */
2027   end_of_line (str);
2028   return;
2029 }
2030
2031 static void
2032 do_mrs (str, flags)
2033      char *str;
2034      unsigned long flags;
2035 {
2036   int skip = 0;
2037   
2038   /* Only one syntax.  */
2039   skip_whitespace (str);
2040
2041   if (reg_required_here (&str, 12) == FAIL)
2042     {
2043       inst.error = BAD_ARGS;
2044       return;
2045     }
2046
2047   if (skip_past_comma (&str) == FAIL)
2048     {
2049       inst.error = _("comma expected after register name");
2050       return;
2051     }
2052
2053   skip_whitespace (str);
2054
2055   if (   strcmp (str, "CPSR") == 0
2056       || strcmp (str, "SPSR") == 0
2057          /* Lower case versions for backwards compatability.  */
2058       || strcmp (str, "cpsr") == 0
2059       || strcmp (str, "spsr") == 0)
2060     skip = 4;
2061   /* This is for backwards compatability with older toolchains.  */
2062   else if (strcmp (str, "cpsr_all") == 0
2063            || strcmp (str, "spsr_all") == 0)
2064     skip = 7;
2065   else
2066     {
2067       inst.error = _("{C|S}PSR expected");
2068       return;
2069     }
2070
2071   if (* str == 's' || * str == 'S')
2072     inst.instruction |= SPSR_BIT;
2073   str += skip;
2074   
2075   inst.instruction |= flags;
2076   end_of_line (str);
2077 }
2078
2079 /* Two possible forms:
2080       "{C|S}PSR_<field>, Rm",
2081       "{C|S}PSR_f, #expression".  */
2082 static void
2083 do_msr (str, flags)
2084      char * str;
2085      unsigned long flags;
2086 {
2087   skip_whitespace (str);
2088
2089   if (psr_required_here (& str) == FAIL)
2090     return;
2091     
2092   if (skip_past_comma (& str) == FAIL)
2093     {
2094       inst.error = _("comma missing after psr flags");
2095       return;
2096     }
2097
2098   skip_whitespace (str);
2099
2100   if (reg_required_here (& str, 0) != FAIL)
2101     {
2102       inst.error = NULL; 
2103       inst.instruction |= flags;
2104       end_of_line (str);
2105       return;
2106     }
2107
2108   if (! is_immediate_prefix (* str))
2109     {
2110       inst.error = _("only a register or immediate value can follow a psr flag");
2111       return;
2112     }
2113
2114   str ++;
2115   inst.error = NULL;
2116   
2117   if (my_get_expression (& inst.reloc.exp, & str))
2118     {
2119       inst.error = _("only a register or immediate value can follow a psr flag");
2120       return;
2121     }
2122   
2123   if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2124     {
2125       inst.error = _("can only set flag field with immediate value");
2126       return;
2127     }
2128   
2129   flags |= INST_IMMEDIATE;
2130           
2131   if (inst.reloc.exp.X_add_symbol)
2132     {
2133       inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2134       inst.reloc.pc_rel = 0;
2135     }
2136   else
2137     {
2138       unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2139       
2140       if (value == (unsigned) FAIL)
2141         {
2142           inst.error = _("Invalid constant");
2143           return;
2144         }
2145       
2146       inst.instruction |= value;
2147     }
2148
2149   inst.error = NULL; 
2150   inst.instruction |= flags;
2151   end_of_line (str);
2152 }
2153
2154 /* Long Multiply Parser
2155    UMULL RdLo, RdHi, Rm, Rs
2156    SMULL RdLo, RdHi, Rm, Rs
2157    UMLAL RdLo, RdHi, Rm, Rs
2158    SMLAL RdLo, RdHi, Rm, Rs
2159 */   
2160 static void
2161 do_mull (str, flags)
2162      char * str;
2163      unsigned long flags;
2164 {
2165   int rdlo, rdhi, rm, rs;
2166
2167   /* Only one format "rdlo, rdhi, rm, rs" */
2168   skip_whitespace (str);
2169
2170   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2171     {
2172       inst.error = BAD_ARGS;
2173       return;
2174     }
2175
2176   if (skip_past_comma (&str) == FAIL
2177       || (rdhi = reg_required_here (&str, 16)) == FAIL)
2178     {
2179       inst.error = BAD_ARGS;
2180       return;
2181     }
2182
2183   if (skip_past_comma (&str) == FAIL
2184       || (rm = reg_required_here (&str, 0)) == FAIL)
2185     {
2186       inst.error = BAD_ARGS;
2187       return;
2188     }
2189
2190   /* rdhi, rdlo and rm must all be different */
2191   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2192     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2193
2194   if (skip_past_comma (&str) == FAIL
2195       || (rs = reg_required_here (&str, 8)) == FAIL)
2196     {
2197       inst.error = BAD_ARGS;
2198       return;
2199     }
2200
2201   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2202     {
2203       inst.error = BAD_PC;
2204       return;
2205     }
2206    
2207   inst.instruction |= flags;
2208   end_of_line (str);
2209   return;
2210 }
2211
2212 static void
2213 do_mul (str, flags)
2214      char *        str;
2215      unsigned long flags;
2216 {
2217   int rd, rm;
2218   
2219   /* Only one format "rd, rm, rs" */
2220   skip_whitespace (str);
2221
2222   if ((rd = reg_required_here (&str, 16)) == FAIL)
2223     {
2224       inst.error = BAD_ARGS;
2225       return;
2226     }
2227
2228   if (rd == REG_PC)
2229     {
2230       inst.error = BAD_PC;
2231       return;
2232     }
2233
2234   if (skip_past_comma (&str) == FAIL
2235       || (rm = reg_required_here (&str, 0)) == FAIL)
2236     {
2237       inst.error = BAD_ARGS;
2238       return;
2239     }
2240
2241   if (rm == REG_PC)
2242     {
2243       inst.error = BAD_PC;
2244       return;
2245     }
2246
2247   if (rm == rd)
2248     as_tsktsk (_("rd and rm should be different in mul"));
2249
2250   if (skip_past_comma (&str) == FAIL
2251       || (rm = reg_required_here (&str, 8)) == FAIL)
2252     {
2253       inst.error = BAD_ARGS;
2254       return;
2255     }
2256
2257   if (rm == REG_PC)
2258     {
2259       inst.error = BAD_PC;
2260       return;
2261     }
2262
2263   inst.instruction |= flags;
2264   end_of_line (str);
2265   return;
2266 }
2267
2268 static void
2269 do_mla (str, flags)
2270      char *        str;
2271      unsigned long flags;
2272 {
2273   int rd, rm;
2274
2275   /* Only one format "rd, rm, rs, rn" */
2276   skip_whitespace (str);
2277
2278   if ((rd = reg_required_here (&str, 16)) == FAIL)
2279     {
2280       inst.error = BAD_ARGS;
2281       return;
2282     }
2283
2284   if (rd == REG_PC)
2285     {
2286       inst.error = BAD_PC;
2287       return;
2288     }
2289
2290   if (skip_past_comma (&str) == FAIL
2291       || (rm = reg_required_here (&str, 0)) == FAIL)
2292     {
2293       inst.error = BAD_ARGS;
2294       return;
2295     }
2296
2297   if (rm == REG_PC)
2298     {
2299       inst.error = BAD_PC;
2300       return;
2301     }
2302
2303   if (rm == rd)
2304     as_tsktsk (_("rd and rm should be different in mla"));
2305
2306   if (skip_past_comma (&str) == FAIL
2307       || (rd = reg_required_here (&str, 8)) == FAIL
2308       || skip_past_comma (&str) == FAIL
2309       || (rm = reg_required_here (&str, 12)) == FAIL)
2310     {
2311       inst.error = BAD_ARGS;
2312       return;
2313     }
2314
2315   if (rd == REG_PC || rm == REG_PC)
2316     {
2317       inst.error = BAD_PC;
2318       return;
2319     }
2320
2321   inst.instruction |= flags;
2322   end_of_line (str);
2323   return;
2324 }
2325
2326 /* Returns the index into fp_values of a floating point number, or -1 if
2327    not in the table.  */
2328 static int
2329 my_get_float_expression (str)
2330      char ** str;
2331 {
2332   LITTLENUM_TYPE words[MAX_LITTLENUMS];
2333   char *         save_in;
2334   expressionS    exp;
2335   int            i;
2336   int            j;
2337
2338   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2339   /* Look for a raw floating point number */
2340   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2341       && is_end_of_line [(unsigned char) *save_in])
2342     {
2343       for (i = 0; i < NUM_FLOAT_VALS; i++)
2344         {
2345           for (j = 0; j < MAX_LITTLENUMS; j++)
2346             {
2347               if (words[j] != fp_values[i][j])
2348                 break;
2349             }
2350
2351           if (j == MAX_LITTLENUMS)
2352             {
2353               *str = save_in;
2354               return i;
2355             }
2356         }
2357     }
2358
2359   /* Try and parse a more complex expression, this will probably fail
2360      unless the code uses a floating point prefix (eg "0f") */
2361   save_in = input_line_pointer;
2362   input_line_pointer = *str;
2363   if (expression (&exp) == absolute_section
2364       && exp.X_op == O_big
2365       && exp.X_add_number < 0)
2366     {
2367       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2368          Ditto for 15.  */
2369       if (gen_to_words (words, 5, (long)15) == 0)
2370         {
2371           for (i = 0; i < NUM_FLOAT_VALS; i++)
2372             {
2373               for (j = 0; j < MAX_LITTLENUMS; j++)
2374                 {
2375                   if (words[j] != fp_values[i][j])
2376                     break;
2377                 }
2378
2379               if (j == MAX_LITTLENUMS)
2380                 {
2381                   *str = input_line_pointer;
2382                   input_line_pointer = save_in;
2383                   return i;
2384                 }
2385             }
2386         }
2387     }
2388
2389   *str = input_line_pointer;
2390   input_line_pointer = save_in;
2391   return -1;
2392 }
2393
2394 /* Return true if anything in the expression is a bignum */
2395 static int
2396 walk_no_bignums (sp)
2397      symbolS * sp;
2398 {
2399   if (symbol_get_value_expression (sp)->X_op == O_big)
2400     return 1;
2401
2402   if (symbol_get_value_expression (sp)->X_add_symbol)
2403     {
2404       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2405               || (symbol_get_value_expression (sp)->X_op_symbol
2406                   && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2407     }
2408
2409   return 0;
2410 }
2411
2412 static int
2413 my_get_expression (ep, str)
2414      expressionS * ep;
2415      char ** str;
2416 {
2417   char * save_in;
2418   segT   seg;
2419   
2420   save_in = input_line_pointer;
2421   input_line_pointer = *str;
2422   seg = expression (ep);
2423
2424 #ifdef OBJ_AOUT
2425   if (seg != absolute_section
2426       && seg != text_section
2427       && seg != data_section
2428       && seg != bss_section
2429       && seg != undefined_section)
2430     {
2431       inst.error = _("bad_segment");
2432       *str = input_line_pointer;
2433       input_line_pointer = save_in;
2434       return 1;
2435     }
2436 #endif
2437
2438   /* Get rid of any bignums now, so that we don't generate an error for which
2439      we can't establish a line number later on.  Big numbers are never valid
2440      in instructions, which is where this routine is always called.  */
2441   if (ep->X_op == O_big
2442       || (ep->X_add_symbol
2443           && (walk_no_bignums (ep->X_add_symbol)
2444               || (ep->X_op_symbol
2445                   && walk_no_bignums (ep->X_op_symbol)))))
2446     {
2447       inst.error = _("Invalid constant");
2448       *str = input_line_pointer;
2449       input_line_pointer = save_in;
2450       return 1;
2451     }
2452
2453   *str = input_line_pointer;
2454   input_line_pointer = save_in;
2455   return 0;
2456 }
2457
2458 /* unrestrict should be one if <shift> <register> is permitted for this
2459    instruction */
2460
2461 static int
2462 decode_shift (str, unrestrict)
2463      char ** str;
2464      int     unrestrict;
2465 {
2466   struct asm_shift * shft;
2467   char * p;
2468   char   c;
2469     
2470   skip_whitespace (* str);
2471     
2472   for (p = *str; isalpha (*p); p++)
2473     ;
2474
2475   if (p == *str)
2476     {
2477       inst.error = _("Shift expression expected");
2478       return FAIL;
2479     }
2480
2481   c = *p;
2482   *p = '\0';
2483   shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2484   *p = c;
2485   if (shft)
2486     {
2487       if (!strncmp (*str, "rrx", 3)
2488           || !strncmp (*str, "RRX", 3))
2489         {
2490           *str = p;
2491           inst.instruction |= shft->value;
2492           return SUCCESS;
2493         }
2494
2495       skip_whitespace (p);
2496       
2497       if (unrestrict && reg_required_here (&p, 8) != FAIL)
2498         {
2499           inst.instruction |= shft->value | SHIFT_BY_REG;
2500           *str = p;
2501           return SUCCESS;
2502         }
2503       else if (is_immediate_prefix (* p))
2504         {
2505           inst.error = NULL;
2506           p++;
2507           if (my_get_expression (&inst.reloc.exp, &p))
2508             return FAIL;
2509
2510           /* Validate some simple #expressions */
2511           if (inst.reloc.exp.X_op == O_constant)
2512             {
2513               unsigned num = inst.reloc.exp.X_add_number;
2514
2515               /* Reject operations greater than 32, or lsl #32 */
2516               if (num > 32 || (num == 32 && shft->value == 0))
2517                 {
2518                   inst.error = _("Invalid immediate shift");
2519                   return FAIL;
2520                 }
2521
2522               /* Shifts of zero should be converted to lsl (which is zero)*/
2523               if (num == 0)
2524                 {
2525                   *str = p;
2526                   return SUCCESS;
2527                 }
2528
2529               /* Shifts of 32 are encoded as 0, for those shifts that
2530                  support it.  */
2531               if (num == 32)
2532                 num = 0;
2533
2534               inst.instruction |= (num << 7) | shft->value;
2535               *str = p;
2536               return SUCCESS;
2537             }
2538
2539           inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2540           inst.reloc.pc_rel = 0;
2541           inst.instruction |= shft->value;
2542           *str = p;
2543           return SUCCESS;
2544         }
2545       else
2546         {
2547           inst.error = unrestrict ? _("shift requires register or #expression")
2548             : _("shift requires #expression");
2549           *str = p;
2550           return FAIL;
2551         }
2552     }
2553
2554   inst.error = _("Shift expression expected");
2555   return FAIL;
2556 }
2557
2558 /* Do those data_ops which can take a negative immediate constant */
2559 /* by altering the instuction. A bit of a hack really */
2560 /*      MOV <-> MVN
2561         AND <-> BIC
2562         ADC <-> SBC
2563         by inverting the second operand, and
2564         ADD <-> SUB
2565         CMP <-> CMN
2566         by negating the second operand.
2567 */
2568 static int
2569 negate_data_op (instruction, value)
2570      unsigned long * instruction;
2571      unsigned long   value;
2572 {
2573   int op, new_inst;
2574   unsigned long negated, inverted;
2575
2576   negated = validate_immediate (-value);
2577   inverted = validate_immediate (~value);
2578
2579   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2580   switch (op)
2581     {
2582       /* First negates */
2583     case OPCODE_SUB:             /* ADD <-> SUB */
2584       new_inst = OPCODE_ADD;
2585       value = negated;
2586       break;
2587
2588     case OPCODE_ADD: 
2589       new_inst = OPCODE_SUB;               
2590       value = negated;
2591       break;
2592
2593     case OPCODE_CMP:             /* CMP <-> CMN */
2594       new_inst = OPCODE_CMN;
2595       value = negated;
2596       break;
2597
2598     case OPCODE_CMN: 
2599       new_inst = OPCODE_CMP;               
2600       value = negated;
2601       break;
2602
2603       /* Now Inverted ops */
2604     case OPCODE_MOV:             /* MOV <-> MVN */
2605       new_inst = OPCODE_MVN;               
2606       value = inverted;
2607       break;
2608
2609     case OPCODE_MVN: 
2610       new_inst = OPCODE_MOV;
2611       value = inverted;
2612       break;
2613
2614     case OPCODE_AND:             /* AND <-> BIC */ 
2615       new_inst = OPCODE_BIC;               
2616       value = inverted;
2617       break;
2618
2619     case OPCODE_BIC: 
2620       new_inst = OPCODE_AND;
2621       value = inverted;
2622       break;
2623
2624     case OPCODE_ADC:              /* ADC <-> SBC */
2625       new_inst = OPCODE_SBC;               
2626       value = inverted;
2627       break;
2628
2629     case OPCODE_SBC: 
2630       new_inst = OPCODE_ADC;
2631       value = inverted;
2632       break;
2633
2634       /* We cannot do anything */
2635     default:  
2636       return FAIL;
2637     }
2638
2639   if (value == (unsigned) FAIL)
2640     return FAIL;
2641
2642   *instruction &= OPCODE_MASK;
2643   *instruction |= new_inst << DATA_OP_SHIFT;
2644   return value; 
2645 }
2646
2647 static int
2648 data_op2 (str)
2649      char ** str;
2650 {
2651   int value;
2652   expressionS expr;
2653
2654   skip_whitespace (* str);
2655     
2656   if (reg_required_here (str, 0) != FAIL)
2657     {
2658       if (skip_past_comma (str) == SUCCESS)
2659         /* Shift operation on register.  */
2660         return decode_shift (str, NO_SHIFT_RESTRICT);
2661
2662       return SUCCESS;
2663     }
2664   else
2665     {
2666       /* Immediate expression */
2667       if (is_immediate_prefix (**str))
2668         {
2669           (*str)++;
2670           inst.error = NULL;
2671           
2672           if (my_get_expression (&inst.reloc.exp, str))
2673             return FAIL;
2674
2675           if (inst.reloc.exp.X_add_symbol)
2676             {
2677               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2678               inst.reloc.pc_rel = 0;
2679             }
2680           else
2681             {
2682               if (skip_past_comma (str) == SUCCESS)
2683                 {
2684                   /* #x, y -- ie explicit rotation by Y  */
2685                   if (my_get_expression (&expr, str))
2686                     return FAIL;
2687
2688                   if (expr.X_op != O_constant)
2689                     {
2690                       inst.error = _("Constant expression expected");
2691                       return FAIL;
2692                     }
2693  
2694                   /* Rotate must be a multiple of 2 */
2695                   if (((unsigned) expr.X_add_number) > 30
2696                       || (expr.X_add_number & 1) != 0
2697                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2698                     {
2699                       inst.error = _("Invalid constant");
2700                       return FAIL;
2701                     }
2702                   inst.instruction |= INST_IMMEDIATE;
2703                   inst.instruction |= inst.reloc.exp.X_add_number;
2704                   inst.instruction |= expr.X_add_number << 7;
2705                   return SUCCESS;
2706                 }
2707
2708               /* Implicit rotation, select a suitable one  */
2709               value = validate_immediate (inst.reloc.exp.X_add_number);
2710
2711               if (value == FAIL)
2712                 {
2713                   /* Can't be done, perhaps the code reads something like
2714                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2715                   if ((value = negate_data_op (&inst.instruction,
2716                                                inst.reloc.exp.X_add_number))
2717                       == FAIL)
2718                     {
2719                       inst.error = _("Invalid constant");
2720                       return FAIL;
2721                     }
2722                 }
2723
2724               inst.instruction |= value;
2725             }
2726
2727           inst.instruction |= INST_IMMEDIATE;
2728           return SUCCESS;
2729         }
2730
2731       (*str)++;
2732       inst.error = _("Register or shift expression expected");
2733       return FAIL;
2734     }
2735 }
2736
2737 static int
2738 fp_op2 (str)
2739      char ** str;
2740 {
2741   skip_whitespace (* str);
2742
2743   if (fp_reg_required_here (str, 0) != FAIL)
2744     return SUCCESS;
2745   else
2746     {
2747       /* Immediate expression */
2748       if (*((*str)++) == '#')
2749         {
2750           int i;
2751
2752           inst.error = NULL;
2753
2754           skip_whitespace (* str);
2755
2756           /* First try and match exact strings, this is to guarantee that
2757              some formats will work even for cross assembly */
2758
2759           for (i = 0; fp_const[i]; i++)
2760             {
2761               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2762                 {
2763                   char *start = *str;
2764
2765                   *str += strlen (fp_const[i]);
2766                   if (is_end_of_line[(unsigned char) **str])
2767                     {
2768                       inst.instruction |= i + 8;
2769                       return SUCCESS;
2770                     }
2771                   *str = start;
2772                 }
2773             }
2774
2775           /* Just because we didn't get a match doesn't mean that the
2776              constant isn't valid, just that it is in a format that we
2777              don't automatically recognize.  Try parsing it with
2778              the standard expression routines.  */
2779           if ((i = my_get_float_expression (str)) >= 0)
2780             {
2781               inst.instruction |= i + 8;
2782               return SUCCESS;
2783             }
2784
2785           inst.error = _("Invalid floating point immediate expression");
2786           return FAIL;
2787         }
2788       inst.error = _("Floating point register or immediate expression expected");
2789       return FAIL;
2790     }
2791 }
2792
2793 static void
2794 do_arit (str, flags)
2795      char *        str;
2796      unsigned long flags;
2797 {
2798   skip_whitespace (str);
2799
2800   if (reg_required_here (&str, 12) == FAIL
2801       || skip_past_comma (&str) == FAIL
2802       || reg_required_here (&str, 16) == FAIL
2803       || skip_past_comma (&str) == FAIL
2804       || data_op2 (&str) == FAIL)
2805     {
2806       if (!inst.error)
2807         inst.error = BAD_ARGS;
2808       return;
2809     }
2810
2811   inst.instruction |= flags;
2812   end_of_line (str);
2813   return;
2814 }
2815
2816 static void
2817 do_adr (str, flags)
2818      char *        str;
2819      unsigned long flags;
2820 {
2821   /* This is a pseudo-op of the form "adr rd, label" to be converted
2822      into a relative address of the form "add rd, pc, #label-.-8".  */
2823   skip_whitespace (str);
2824
2825   if (reg_required_here (&str, 12) == FAIL
2826       || skip_past_comma (&str) == FAIL
2827       || my_get_expression (&inst.reloc.exp, &str))
2828     {
2829       if (!inst.error)
2830         inst.error = BAD_ARGS;
2831       return;
2832     }
2833   
2834   /* Frag hacking will turn this into a sub instruction if the offset turns
2835      out to be negative.  */
2836   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2837   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
2838   inst.reloc.pc_rel = 1;
2839   inst.instruction |= flags;
2840   
2841   end_of_line (str);
2842 }
2843
2844 static void
2845 do_adrl (str, flags)
2846      char *        str;
2847      unsigned long flags;
2848 {
2849   /* This is a pseudo-op of the form "adrl rd, label" to be converted
2850      into a relative address of the form:
2851         add rd, pc, #low(label-.-8)"
2852         add rd, rd, #high(label-.-8)"   */
2853
2854   skip_whitespace (str);
2855
2856   if (reg_required_here (& str, 12) == FAIL
2857       || skip_past_comma (& str) == FAIL
2858       || my_get_expression (& inst.reloc.exp, & str))
2859     {
2860       if (!inst.error)
2861         inst.error = BAD_ARGS;
2862       return;
2863     }
2864   
2865   end_of_line (str);
2866   
2867   /* Frag hacking will turn this into a sub instruction if the offset turns
2868      out to be negative.  */
2869   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2870   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2871   inst.reloc.pc_rel            = 1;
2872   inst.instruction            |= flags;
2873   inst.size                    = INSN_SIZE * 2;
2874   
2875   return;
2876 }
2877
2878 static void
2879 do_cmp (str, flags)
2880      char *        str;
2881      unsigned long flags;
2882 {
2883   skip_whitespace (str);
2884
2885   if (reg_required_here (&str, 16) == FAIL)
2886     {
2887       if (!inst.error)
2888         inst.error = BAD_ARGS;
2889       return;
2890     }
2891
2892   if (skip_past_comma (&str) == FAIL
2893       || data_op2 (&str) == FAIL)
2894     {
2895       if (!inst.error)
2896         inst.error = BAD_ARGS;
2897       return;
2898     }
2899
2900   inst.instruction |= flags;
2901   if ((flags & 0x0000f000) == 0)
2902     inst.instruction |= CONDS_BIT;
2903
2904   end_of_line (str);
2905   return;
2906 }
2907
2908 static void
2909 do_mov (str, flags)
2910      char *        str;
2911      unsigned long flags;
2912 {
2913   skip_whitespace (str);
2914
2915   if (reg_required_here (&str, 12) == FAIL)
2916     {
2917       if (!inst.error)
2918         inst.error = BAD_ARGS;
2919       return;
2920     }
2921
2922   if (skip_past_comma (&str) == FAIL
2923       || data_op2 (&str) == FAIL)
2924     {
2925       if (!inst.error)
2926         inst.error = BAD_ARGS;
2927       return;
2928     }
2929
2930   inst.instruction |= flags;
2931   end_of_line (str);
2932   return;
2933 }
2934
2935 static int
2936 ldst_extend (str, hwse)
2937      char ** str;
2938      int     hwse;
2939 {
2940   int add = INDEX_UP;
2941
2942   switch (**str)
2943     {
2944     case '#':
2945     case '$':
2946       (*str)++;
2947       if (my_get_expression (& inst.reloc.exp, str))
2948         return FAIL;
2949
2950       if (inst.reloc.exp.X_op == O_constant)
2951         {
2952           int value = inst.reloc.exp.X_add_number;
2953
2954           if ((hwse && (value < -255 || value > 255))
2955                || (value < -4095 || value > 4095))
2956             {
2957               inst.error = _("address offset too large");
2958               return FAIL;
2959             }
2960
2961           if (value < 0)
2962             {
2963               value = -value;
2964               add = 0;
2965             }
2966
2967           /* Halfword and signextension instructions have the
2968              immediate value split across bits 11..8 and bits 3..0 */
2969           if (hwse)
2970             inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2971           else
2972             inst.instruction |= add | value;
2973         }
2974       else
2975         {
2976           if (hwse)
2977             {
2978               inst.instruction |= HWOFFSET_IMM;
2979               inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2980             }
2981           else
2982             inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2983           inst.reloc.pc_rel = 0;
2984         }
2985       return SUCCESS;
2986
2987     case '-':
2988       add = 0;  /* and fall through */
2989     case '+':
2990       (*str)++; /* and fall through */
2991     default:
2992       if (reg_required_here (str, 0) == FAIL)
2993         return FAIL;
2994
2995       if (hwse)
2996         inst.instruction |= add;
2997       else
2998         {
2999           inst.instruction |= add | OFFSET_REG;
3000           if (skip_past_comma (str) == SUCCESS)
3001             return decode_shift (str, SHIFT_RESTRICT);
3002         }
3003
3004       return SUCCESS;
3005     }
3006 }
3007
3008 static void
3009 do_ldst (str, flags)
3010      char *        str;
3011      unsigned long flags;
3012 {
3013   int halfword = 0;
3014   int pre_inc = 0;
3015   int conflict_reg;
3016   int value;
3017
3018   /* This is not ideal, but it is the simplest way of dealing with the
3019      ARM7T halfword instructions (since they use a different
3020      encoding, but the same mnemonic): */
3021   halfword = (flags & 0x80000000) != 0;
3022   if (halfword)
3023     {
3024       /* This is actually a load/store of a halfword, or a
3025          signed-extension load */
3026       if ((cpu_variant & ARM_HALFWORD) == 0)
3027         {
3028           inst.error
3029             = _("Processor does not support halfwords or signed bytes");
3030           return;
3031         }
3032
3033       inst.instruction = (inst.instruction & COND_MASK)
3034                          | (flags & ~COND_MASK);
3035
3036       flags = 0;
3037     }
3038
3039   skip_whitespace (str);
3040     
3041   if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
3042     {
3043       if (!inst.error)
3044         inst.error = BAD_ARGS;
3045       return;
3046     }
3047
3048   if (skip_past_comma (& str) == FAIL)
3049     {
3050       inst.error = _("Address expected");
3051       return;
3052     }
3053
3054   if (*str == '[')
3055     {
3056       int reg;
3057
3058       str++;
3059
3060       skip_whitespace (str);
3061
3062       if ((reg = reg_required_here (&str, 16)) == FAIL)
3063         return;
3064
3065       /* Conflicts can occur on stores as well as loads.  */
3066       conflict_reg = (conflict_reg == reg);
3067
3068       skip_whitespace (str);
3069
3070       if (*str == ']')
3071         {
3072           str ++;
3073           
3074           if (skip_past_comma (&str) == SUCCESS)
3075             {
3076               /* [Rn],... (post inc) */
3077               if (ldst_extend (&str, halfword) == FAIL)
3078                 return;
3079               if (conflict_reg)
3080                 as_warn (_("%s register same as write-back base"),
3081                          (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3082             }
3083           else
3084             {
3085               /* [Rn] */
3086               if (halfword)
3087                 inst.instruction |= HWOFFSET_IMM;
3088
3089               skip_whitespace (str);
3090
3091               if (*str == '!')
3092                {
3093                  if (conflict_reg)
3094                    as_warn (_("%s register same as write-back base"),
3095                             (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3096                  str++;
3097                  inst.instruction |= WRITE_BACK;
3098                }
3099
3100               flags |= INDEX_UP;
3101               if (! (flags & TRANS_BIT))
3102                 pre_inc = 1;
3103             }
3104         }
3105       else
3106         {
3107           /* [Rn,...] */
3108           if (skip_past_comma (&str) == FAIL)
3109             {
3110               inst.error = _("pre-indexed expression expected");
3111               return;
3112             }
3113
3114           pre_inc = 1;
3115           if (ldst_extend (&str, halfword) == FAIL)
3116             return;
3117
3118           skip_whitespace (str);
3119
3120           if (*str++ != ']')
3121             {
3122               inst.error = _("missing ]");
3123               return;
3124             }
3125
3126           skip_whitespace (str);
3127
3128           if (*str == '!')
3129             {
3130               if (conflict_reg)
3131                 as_warn (_("%s register same as write-back base"),
3132                          (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3133               str++;
3134               inst.instruction |= WRITE_BACK;
3135             }
3136         }
3137     }
3138   else if (*str == '=')
3139     {
3140       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3141       str++;
3142
3143       skip_whitespace (str);
3144
3145       if (my_get_expression (&inst.reloc.exp, &str))
3146         return;
3147
3148       if (inst.reloc.exp.X_op != O_constant
3149           && inst.reloc.exp.X_op != O_symbol)
3150         {
3151           inst.error = _("Constant expression expected");
3152           return;
3153         }
3154
3155       if (inst.reloc.exp.X_op == O_constant
3156           && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
3157         {
3158           /* This can be done with a mov instruction */
3159           inst.instruction &= LITERAL_MASK;
3160           inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
3161           inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
3162           end_of_line(str);
3163           return; 
3164         }
3165       else
3166         {
3167           /* Insert into literal pool */     
3168           if (add_to_lit_pool () == FAIL)
3169             {
3170               if (!inst.error)
3171                 inst.error = _("literal pool insertion failed"); 
3172               return;
3173             }
3174
3175           /* Change the instruction exp to point to the pool */
3176           if (halfword)
3177             {
3178               inst.instruction |= HWOFFSET_IMM;
3179               inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
3180             }
3181           else
3182             inst.reloc.type = BFD_RELOC_ARM_LITERAL;
3183           inst.reloc.pc_rel = 1;
3184           inst.instruction |= (REG_PC << 16);
3185           pre_inc = 1; 
3186         }
3187     }
3188   else
3189     {
3190       if (my_get_expression (&inst.reloc.exp, &str))
3191         return;
3192
3193       if (halfword)
3194         {
3195           inst.instruction |= HWOFFSET_IMM;
3196           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3197         }
3198       else
3199         inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
3200 #ifndef TE_WINCE
3201       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust */
3202 #endif
3203       inst.reloc.pc_rel = 1;
3204       inst.instruction |= (REG_PC << 16);
3205       pre_inc = 1;
3206     }
3207     
3208   if (pre_inc && (flags & TRANS_BIT))
3209     inst.error = _("Pre-increment instruction with translate");
3210
3211   inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3212   end_of_line (str);
3213   return;
3214 }
3215
3216 static long
3217 reg_list (strp)
3218      char ** strp;
3219 {
3220   char * str = *strp;
3221   long   range = 0;
3222   int    another_range;
3223
3224   /* We come back here if we get ranges concatenated by '+' or '|' */
3225   do
3226     {
3227       another_range = 0;
3228
3229       if (*str == '{')
3230         {
3231           int in_range = 0;
3232           int cur_reg = -1;
3233       
3234           str++;
3235           do
3236             {
3237               int reg;
3238             
3239               skip_whitespace (str);
3240
3241               if ((reg = reg_required_here (& str, -1)) == FAIL)
3242                 return FAIL;
3243               
3244               if (in_range)
3245                 {
3246                   int i;
3247               
3248                   if (reg <= cur_reg)
3249                     {
3250                       inst.error = _("Bad range in register list");
3251                       return FAIL;
3252                     }
3253
3254                   for (i = cur_reg + 1; i < reg; i++)
3255                     {
3256                       if (range & (1 << i))
3257                         as_tsktsk 
3258                           (_("Warning: Duplicated register (r%d) in register list"),
3259                            i);
3260                       else
3261                         range |= 1 << i;
3262                     }
3263                   in_range = 0;
3264                 }
3265
3266               if (range & (1 << reg))
3267                 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3268                            reg);
3269               else if (reg <= cur_reg)
3270                 as_tsktsk (_("Warning: Register range not in ascending order"));
3271
3272               range |= 1 << reg;
3273               cur_reg = reg;
3274             } while (skip_past_comma (&str) != FAIL
3275                      || (in_range = 1, *str++ == '-'));
3276           str--;
3277           skip_whitespace (str);
3278
3279           if (*str++ != '}')
3280             {
3281               inst.error = _("Missing `}'");
3282               return FAIL;
3283             }
3284         }
3285       else
3286         {
3287           expressionS expr;
3288
3289           if (my_get_expression (&expr, &str))
3290             return FAIL;
3291
3292           if (expr.X_op == O_constant)
3293             {
3294               if (expr.X_add_number 
3295                   != (expr.X_add_number & 0x0000ffff))
3296                 {
3297                   inst.error = _("invalid register mask");
3298                   return FAIL;
3299                 }
3300
3301               if ((range & expr.X_add_number) != 0)
3302                 {
3303                   int regno = range & expr.X_add_number;
3304
3305                   regno &= -regno;
3306                   regno = (1 << regno) - 1;
3307                   as_tsktsk 
3308                     (_("Warning: Duplicated register (r%d) in register list"),
3309                      regno);
3310                 }
3311
3312               range |= expr.X_add_number;
3313             }
3314           else
3315             {
3316               if (inst.reloc.type != 0)
3317                 {
3318                   inst.error = _("expression too complex");
3319                   return FAIL;
3320                 }
3321
3322               memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3323               inst.reloc.type = BFD_RELOC_ARM_MULTI;
3324               inst.reloc.pc_rel = 0;
3325             }
3326         }
3327
3328       skip_whitespace (str);
3329
3330       if (*str == '|' || *str == '+')
3331         {
3332           str++;
3333           another_range = 1;
3334         }
3335     } while (another_range);
3336
3337   *strp = str;
3338   return range;
3339 }
3340
3341 static void
3342 do_ldmstm (str, flags)
3343      char *        str;
3344      unsigned long flags;
3345 {
3346   int base_reg;
3347   long range;
3348
3349   skip_whitespace (str);
3350
3351   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3352     return;
3353
3354   if (base_reg == REG_PC)
3355     {
3356       inst.error = _("r15 not allowed as base register");
3357       return;
3358     }
3359
3360   skip_whitespace (str);
3361
3362   if (*str == '!')
3363     {
3364       flags |= WRITE_BACK;
3365       str++;
3366     }
3367
3368   if (skip_past_comma (&str) == FAIL
3369       || (range = reg_list (&str)) == FAIL)
3370     {
3371       if (! inst.error)
3372         inst.error = BAD_ARGS;
3373       return;
3374     }
3375
3376   if (*str == '^')
3377     {
3378       str++;
3379       flags |= LDM_TYPE_2_OR_3;
3380     }
3381
3382   inst.instruction |= flags | range;
3383   end_of_line (str);
3384   return;
3385 }
3386
3387 static void
3388 do_swi (str, flags)
3389      char *        str;
3390      unsigned long flags;
3391 {
3392   skip_whitespace (str);
3393   
3394   /* Allow optional leading '#'.  */
3395   if (is_immediate_prefix (*str))
3396     str++;
3397
3398   if (my_get_expression (& inst.reloc.exp, & str))
3399     return;
3400
3401   inst.reloc.type = BFD_RELOC_ARM_SWI;
3402   inst.reloc.pc_rel = 0;
3403   inst.instruction |= flags;
3404   
3405   end_of_line (str);
3406   
3407   return;
3408 }
3409
3410 static void
3411 do_swap (str, flags)
3412      char *        str;
3413      unsigned long flags;
3414 {
3415   int reg;
3416   
3417   skip_whitespace (str);
3418
3419   if ((reg = reg_required_here (&str, 12)) == FAIL)
3420     return;
3421
3422   if (reg == REG_PC)
3423     {
3424       inst.error = _("r15 not allowed in swap");
3425       return;
3426     }
3427
3428   if (skip_past_comma (&str) == FAIL
3429       || (reg = reg_required_here (&str, 0)) == FAIL)
3430     {
3431       if (!inst.error)
3432         inst.error = BAD_ARGS;
3433       return;
3434     }
3435
3436   if (reg == REG_PC)
3437     {
3438       inst.error = _("r15 not allowed in swap");
3439       return;
3440     }
3441
3442   if (skip_past_comma (&str) == FAIL
3443       || *str++ != '[')
3444     {
3445       inst.error = BAD_ARGS;
3446       return;
3447     }
3448
3449   skip_whitespace (str);
3450
3451   if ((reg = reg_required_here (&str, 16)) == FAIL)
3452     return;
3453
3454   if (reg == REG_PC)
3455     {
3456       inst.error = BAD_PC;
3457       return;
3458     }
3459
3460   skip_whitespace (str);
3461
3462   if (*str++ != ']')
3463     {
3464       inst.error = _("missing ]");
3465       return;
3466     }
3467
3468   inst.instruction |= flags;
3469   end_of_line (str);
3470   return;
3471 }
3472
3473 static void
3474 do_branch (str, flags)
3475      char *        str;
3476      unsigned long flags ATTRIBUTE_UNUSED;
3477 {
3478   if (my_get_expression (&inst.reloc.exp, &str))
3479     return;
3480   
3481 #ifdef OBJ_ELF
3482   {
3483     char * save_in;
3484   
3485     /* ScottB: February 5, 1998 */
3486     /* Check to see of PLT32 reloc required for the instruction.  */
3487     
3488     /* arm_parse_reloc() works on input_line_pointer.
3489        We actually want to parse the operands to the branch instruction
3490        passed in 'str'.  Save the input pointer and restore it later.  */
3491     save_in = input_line_pointer;
3492     input_line_pointer = str;
3493     if (inst.reloc.exp.X_op == O_symbol
3494         && *str == '('
3495         && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3496       {
3497         inst.reloc.type   = BFD_RELOC_ARM_PLT32;
3498         inst.reloc.pc_rel = 0;
3499         /* Modify str to point to after parsed operands, otherwise
3500            end_of_line() will complain about the (PLT) left in str.  */
3501         str = input_line_pointer;
3502       }
3503     else
3504       {
3505         inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
3506         inst.reloc.pc_rel = 1;
3507       }
3508     input_line_pointer = save_in;
3509   }
3510 #else
3511   inst.reloc.type   = BFD_RELOC_ARM_PCREL_BRANCH;
3512   inst.reloc.pc_rel = 1;
3513 #endif /* OBJ_ELF */
3514   
3515   end_of_line (str);
3516   return;
3517 }
3518
3519 static void
3520 do_bx (str, flags)
3521      char *        str;
3522      unsigned long flags ATTRIBUTE_UNUSED;
3523 {
3524   int reg;
3525
3526   skip_whitespace (str);
3527
3528   if ((reg = reg_required_here (&str, 0)) == FAIL)
3529     {
3530       inst.error = BAD_ARGS;
3531       return;
3532     }
3533
3534   if (reg == REG_PC)
3535     inst.error = BAD_PC;
3536
3537   end_of_line (str);
3538 }
3539
3540 static void
3541 do_cdp (str, flags)
3542      char *        str;
3543      unsigned long flags ATTRIBUTE_UNUSED;
3544 {
3545   /* Co-processor data operation.
3546      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
3547   skip_whitespace (str);
3548
3549   if (co_proc_number (&str) == FAIL)
3550     {
3551       if (!inst.error)
3552         inst.error = BAD_ARGS;
3553       return;
3554     }
3555
3556   if (skip_past_comma (&str) == FAIL
3557       || cp_opc_expr (&str, 20,4) == FAIL)
3558     {
3559       if (!inst.error)
3560         inst.error = BAD_ARGS;
3561       return;
3562     }
3563
3564   if (skip_past_comma (&str) == FAIL
3565       || cp_reg_required_here (&str, 12) == FAIL)
3566     {
3567       if (!inst.error)
3568         inst.error = BAD_ARGS;
3569       return;
3570     }
3571
3572   if (skip_past_comma (&str) == FAIL
3573       || cp_reg_required_here (&str, 16) == FAIL)
3574     {
3575       if (!inst.error)
3576         inst.error = BAD_ARGS;
3577       return;
3578     }
3579
3580   if (skip_past_comma (&str) == FAIL
3581       || cp_reg_required_here (&str, 0) == FAIL)
3582     {
3583       if (!inst.error)
3584         inst.error = BAD_ARGS;
3585       return;
3586     }
3587
3588   if (skip_past_comma (&str) == SUCCESS)
3589     {
3590       if (cp_opc_expr (&str, 5, 3) == FAIL)
3591         {
3592           if (!inst.error)
3593             inst.error = BAD_ARGS;
3594           return;
3595         }
3596     }
3597
3598   end_of_line (str);
3599   return;
3600 }
3601
3602 static void
3603 do_lstc (str, flags)
3604      char *        str;
3605      unsigned long flags;
3606 {
3607   /* Co-processor register load/store.
3608      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
3609
3610   skip_whitespace (str);
3611
3612   if (co_proc_number (&str) == FAIL)
3613     {
3614       if (!inst.error)
3615         inst.error = BAD_ARGS;
3616       return;
3617     }
3618
3619   if (skip_past_comma (&str) == FAIL
3620       || cp_reg_required_here (&str, 12) == FAIL)
3621     {
3622       if (!inst.error)
3623         inst.error = BAD_ARGS;
3624       return;
3625     }
3626
3627   if (skip_past_comma (&str) == FAIL
3628       || cp_address_required_here (&str) == FAIL)
3629     {
3630       if (! inst.error)
3631         inst.error = BAD_ARGS;
3632       return;
3633     }
3634
3635   inst.instruction |= flags;
3636   end_of_line (str);
3637   return;
3638 }
3639
3640 static void
3641 do_co_reg (str, flags)
3642      char *        str;
3643      unsigned long flags;
3644 {
3645   /* Co-processor register transfer.
3646      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
3647
3648   skip_whitespace (str);
3649
3650   if (co_proc_number (&str) == FAIL)
3651     {
3652       if (!inst.error)
3653         inst.error = BAD_ARGS;
3654       return;
3655     }
3656
3657   if (skip_past_comma (&str) == FAIL
3658       || cp_opc_expr (&str, 21, 3) == FAIL)
3659     {
3660       if (!inst.error)
3661         inst.error = BAD_ARGS;
3662       return;
3663     }
3664
3665   if (skip_past_comma (&str) == FAIL
3666       || reg_required_here (&str, 12) == FAIL)
3667     {
3668       if (!inst.error)
3669         inst.error = BAD_ARGS;
3670       return;
3671     }
3672
3673   if (skip_past_comma (&str) == FAIL
3674       || cp_reg_required_here (&str, 16) == FAIL)
3675     {
3676       if (!inst.error)
3677         inst.error = BAD_ARGS;
3678       return;
3679     }
3680
3681   if (skip_past_comma (&str) == FAIL
3682       || cp_reg_required_here (&str, 0) == FAIL)
3683     {
3684       if (!inst.error)
3685         inst.error = BAD_ARGS;
3686       return;
3687     }
3688
3689   if (skip_past_comma (&str) == SUCCESS)
3690     {
3691       if (cp_opc_expr (&str, 5, 3) == FAIL)
3692         {
3693           if (!inst.error)
3694             inst.error = BAD_ARGS;
3695           return;
3696         }
3697     }
3698   if (flags)
3699     {
3700       inst.error = BAD_COND;
3701     }
3702
3703   end_of_line (str);
3704   return;
3705 }
3706
3707 static void
3708 do_fp_ctrl (str, flags)
3709      char *        str;
3710      unsigned long flags ATTRIBUTE_UNUSED;
3711 {
3712   /* FP control registers.
3713      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
3714
3715   skip_whitespace (str);
3716
3717   if (reg_required_here (&str, 12) == FAIL)
3718     {
3719       if (!inst.error)
3720         inst.error = BAD_ARGS;
3721       return;
3722     }
3723
3724   end_of_line (str);
3725   return;
3726 }
3727
3728 static void
3729 do_fp_ldst (str, flags)
3730      char *        str;
3731      unsigned long flags ATTRIBUTE_UNUSED;
3732 {
3733   skip_whitespace (str);
3734
3735   switch (inst.suffix)
3736     {
3737     case SUFF_S:
3738       break;
3739     case SUFF_D:
3740       inst.instruction |= CP_T_X;
3741       break;
3742     case SUFF_E:
3743       inst.instruction |= CP_T_Y;
3744       break;
3745     case SUFF_P:
3746       inst.instruction |= CP_T_X | CP_T_Y;
3747       break;
3748     default:
3749       abort ();
3750     }
3751
3752   if (fp_reg_required_here (&str, 12) == FAIL)
3753     {
3754       if (!inst.error)
3755         inst.error = BAD_ARGS;
3756       return;
3757     }
3758
3759   if (skip_past_comma (&str) == FAIL
3760       || cp_address_required_here (&str) == FAIL)
3761     {
3762       if (!inst.error)
3763         inst.error = BAD_ARGS;
3764       return;
3765     }
3766
3767   end_of_line (str);
3768 }
3769
3770 static void
3771 do_fp_ldmstm (str, flags)
3772      char *        str;
3773      unsigned long flags;
3774 {
3775   int num_regs;
3776
3777   skip_whitespace (str);
3778
3779   if (fp_reg_required_here (&str, 12) == FAIL)
3780     {
3781       if (! inst.error)
3782         inst.error = BAD_ARGS;
3783       return;
3784     }
3785
3786   /* Get Number of registers to transfer */
3787   if (skip_past_comma (&str) == FAIL
3788       || my_get_expression (&inst.reloc.exp, &str))
3789     {
3790       if (! inst.error)
3791         inst.error = _("constant expression expected");
3792       return;
3793     }
3794
3795   if (inst.reloc.exp.X_op != O_constant)
3796     {
3797       inst.error = _("Constant value required for number of registers");
3798       return;
3799     }
3800
3801   num_regs = inst.reloc.exp.X_add_number;
3802
3803   if (num_regs < 1 || num_regs > 4)
3804     {
3805       inst.error = _("number of registers must be in the range [1:4]");
3806       return;
3807     }
3808
3809   switch (num_regs)
3810     {
3811     case 1:
3812       inst.instruction |= CP_T_X;
3813       break;
3814     case 2:
3815       inst.instruction |= CP_T_Y;
3816       break;
3817     case 3:
3818       inst.instruction |= CP_T_Y | CP_T_X;
3819       break;
3820     case 4:
3821       break;
3822     default:
3823       abort ();
3824     }
3825
3826   if (flags)
3827     {
3828       int reg;
3829       int write_back;
3830       int offset;
3831
3832       /* The instruction specified "ea" or "fd", so we can only accept
3833          [Rn]{!}.  The instruction does not really support stacking or
3834          unstacking, so we have to emulate these by setting appropriate
3835          bits and offsets.  */
3836       if (skip_past_comma (&str) == FAIL
3837           || *str != '[')
3838         {
3839           if (! inst.error)
3840             inst.error = BAD_ARGS;
3841           return;
3842         }
3843
3844       str++;
3845       skip_whitespace (str);
3846
3847       if ((reg = reg_required_here (&str, 16)) == FAIL)
3848         return;
3849
3850       skip_whitespace (str);
3851
3852       if (*str != ']')
3853         {
3854           inst.error = BAD_ARGS;
3855           return;
3856         }
3857
3858       str++;
3859       if (*str == '!')
3860         {
3861           write_back = 1;
3862           str++;
3863           if (reg == REG_PC)
3864             {
3865               inst.error = _("R15 not allowed as base register with write-back");
3866               return;
3867             }
3868         }
3869       else
3870         write_back = 0;
3871
3872       if (flags & CP_T_Pre)
3873         {
3874           /* Pre-decrement */
3875           offset = 3 * num_regs;
3876           if (write_back)
3877             flags |= CP_T_WB;
3878         }
3879       else
3880         {
3881           /* Post-increment */
3882           if (write_back)
3883             {
3884               flags |= CP_T_WB;
3885               offset = 3 * num_regs;
3886             }
3887           else
3888             {
3889               /* No write-back, so convert this into a standard pre-increment
3890                  instruction -- aesthetically more pleasing.  */
3891               flags = CP_T_Pre | CP_T_UD;
3892               offset = 0;
3893             }
3894         }
3895
3896       inst.instruction |= flags | offset;
3897     }
3898   else if (skip_past_comma (&str) == FAIL
3899            || cp_address_required_here (&str) == FAIL)
3900     {
3901       if (! inst.error)
3902         inst.error = BAD_ARGS;
3903       return;
3904     }
3905
3906   end_of_line (str);
3907 }
3908
3909 static void
3910 do_fp_dyadic (str, flags)
3911      char *        str;
3912      unsigned long flags;
3913 {
3914   skip_whitespace (str);
3915
3916   switch (inst.suffix)
3917     {
3918     case SUFF_S:
3919       break;
3920     case SUFF_D:
3921       inst.instruction |= 0x00000080;
3922       break;
3923     case SUFF_E:
3924       inst.instruction |= 0x00080000;
3925       break;
3926     default:
3927       abort ();
3928     }
3929
3930   if (fp_reg_required_here (&str, 12) == FAIL)
3931     {
3932       if (! inst.error)
3933         inst.error = BAD_ARGS;
3934       return;
3935     }
3936
3937   if (skip_past_comma (&str) == FAIL
3938       || fp_reg_required_here (&str, 16) == FAIL)
3939     {
3940       if (! inst.error)
3941         inst.error = BAD_ARGS;
3942       return;
3943     }
3944
3945   if (skip_past_comma (&str) == FAIL
3946       || fp_op2 (&str) == FAIL)
3947     {
3948       if (! inst.error)
3949         inst.error = BAD_ARGS;
3950       return;
3951     }
3952
3953   inst.instruction |= flags;
3954   end_of_line (str);
3955   return;
3956 }
3957
3958 static void
3959 do_fp_monadic (str, flags)
3960      char *        str;
3961      unsigned long flags;
3962 {
3963   skip_whitespace (str);
3964
3965   switch (inst.suffix)
3966     {
3967     case SUFF_S:
3968       break;
3969     case SUFF_D:
3970       inst.instruction |= 0x00000080;
3971       break;
3972     case SUFF_E:
3973       inst.instruction |= 0x00080000;
3974       break;
3975     default:
3976       abort ();
3977     }
3978
3979   if (fp_reg_required_here (&str, 12) == FAIL)
3980     {
3981       if (! inst.error)
3982         inst.error = BAD_ARGS;
3983       return;
3984     }
3985
3986   if (skip_past_comma (&str) == FAIL
3987       || fp_op2 (&str) == FAIL)
3988     {
3989       if (! inst.error)
3990         inst.error = BAD_ARGS;
3991       return;
3992     }
3993
3994   inst.instruction |= flags;
3995   end_of_line (str);
3996   return;
3997 }
3998
3999 static void
4000 do_fp_cmp (str, flags)
4001      char *        str;
4002      unsigned long flags;
4003 {
4004   skip_whitespace (str);
4005
4006   if (fp_reg_required_here (&str, 16) == FAIL)
4007     {
4008       if (! inst.error)
4009         inst.error = BAD_ARGS;
4010       return;
4011     }
4012
4013   if (skip_past_comma (&str) == FAIL
4014       || fp_op2 (&str) == FAIL)
4015     {
4016       if (! inst.error)
4017         inst.error = BAD_ARGS;
4018       return;
4019     }
4020
4021   inst.instruction |= flags;
4022   end_of_line (str);
4023   return;
4024 }
4025
4026 static void
4027 do_fp_from_reg (str, flags)
4028      char *        str;
4029      unsigned long flags;
4030 {
4031   skip_whitespace (str);
4032
4033   switch (inst.suffix)
4034     {
4035     case SUFF_S:
4036       break;
4037     case SUFF_D:
4038       inst.instruction |= 0x00000080;
4039       break;
4040     case SUFF_E:
4041       inst.instruction |= 0x00080000;
4042       break;
4043     default:
4044       abort ();
4045     }
4046
4047   if (fp_reg_required_here (&str, 16) == FAIL)
4048     {
4049       if (! inst.error)
4050         inst.error = BAD_ARGS;
4051       return;
4052     }
4053
4054   if (skip_past_comma (&str) == FAIL
4055       || reg_required_here (&str, 12) == FAIL)
4056     {
4057       if (! inst.error)
4058         inst.error = BAD_ARGS;
4059       return;
4060     }
4061
4062   inst.instruction |= flags;
4063   end_of_line (str);
4064   return;
4065 }
4066
4067 static void
4068 do_fp_to_reg (str, flags)
4069      char *        str;
4070      unsigned long flags;
4071 {
4072   skip_whitespace (str);
4073
4074   if (reg_required_here (&str, 12) == FAIL)
4075     return;
4076
4077   if (skip_past_comma (&str) == FAIL
4078       || fp_reg_required_here (&str, 0) == FAIL)
4079     {
4080       if (! inst.error)
4081         inst.error = BAD_ARGS;
4082       return;
4083     }
4084
4085   inst.instruction |= flags;
4086   end_of_line (str);
4087   return;
4088 }
4089
4090 /* Thumb specific routines */
4091
4092 /* Parse and validate that a register is of the right form, this saves
4093    repeated checking of this information in many similar cases. 
4094    Unlike the 32-bit case we do not insert the register into the opcode 
4095    here, since the position is often unknown until the full instruction 
4096    has been parsed.  */
4097 static int
4098 thumb_reg (strp, hi_lo)
4099      char ** strp;
4100      int     hi_lo;
4101 {
4102   int reg;
4103
4104   if ((reg = reg_required_here (strp, -1)) == FAIL)
4105     return FAIL;
4106
4107   switch (hi_lo)
4108     {
4109     case THUMB_REG_LO:
4110       if (reg > 7)
4111         {
4112           inst.error = _("lo register required");
4113           return FAIL;
4114         }
4115       break;
4116
4117     case THUMB_REG_HI:
4118       if (reg < 8)
4119         {
4120           inst.error = _("hi register required");
4121           return FAIL;
4122         }
4123       break;
4124
4125     default:
4126       break;
4127     }
4128
4129   return reg;
4130 }
4131
4132 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4133    was SUB.  */
4134 static void
4135 thumb_add_sub (str, subtract)
4136      char * str;
4137      int    subtract;
4138 {
4139   int Rd, Rs, Rn = FAIL;
4140
4141   skip_whitespace (str);
4142
4143   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4144       || skip_past_comma (&str) == FAIL)
4145     {
4146       if (! inst.error)
4147         inst.error = BAD_ARGS;
4148       return;
4149     }
4150
4151   if (is_immediate_prefix (*str))
4152     {
4153       Rs = Rd;
4154       str++;
4155       if (my_get_expression (&inst.reloc.exp, &str))
4156         return;
4157     }
4158   else
4159     {
4160       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4161         return;
4162
4163       if (skip_past_comma (&str) == FAIL)
4164         {
4165           /* Two operand format, shuffle the registers and pretend there 
4166              are 3 */
4167           Rn = Rs;
4168           Rs = Rd;
4169         }
4170       else if (is_immediate_prefix (*str))
4171         {
4172           str++;
4173           if (my_get_expression (&inst.reloc.exp, &str))
4174             return;
4175         }
4176       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4177         return;
4178     }
4179
4180   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4181      for the latter case, EXPR contains the immediate that was found. */
4182   if (Rn != FAIL)
4183     {
4184       /* All register format.  */
4185       if (Rd > 7 || Rs > 7 || Rn > 7)
4186         {
4187           if (Rs != Rd)
4188             {
4189               inst.error = _("dest and source1 must be the same register");
4190               return;
4191             }
4192
4193           /* Can't do this for SUB */
4194           if (subtract)
4195             {
4196               inst.error = _("subtract valid only on lo regs");
4197               return;
4198             }
4199
4200           inst.instruction = (T_OPCODE_ADD_HI
4201                               | (Rd > 7 ? THUMB_H1 : 0)
4202                               | (Rn > 7 ? THUMB_H2 : 0));
4203           inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
4204         }
4205       else
4206         {
4207           inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
4208           inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
4209         }
4210     }
4211   else
4212     {
4213       /* Immediate expression, now things start to get nasty.  */
4214
4215       /* First deal with HI regs, only very restricted cases allowed:
4216          Adjusting SP, and using PC or SP to get an address.  */
4217       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4218           || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4219         {
4220           inst.error = _("invalid Hi register with immediate");
4221           return;
4222         }
4223
4224       if (inst.reloc.exp.X_op != O_constant)
4225         {
4226           /* Value isn't known yet, all we can do is store all the fragments
4227              we know about in the instruction and let the reloc hacking 
4228              work it all out.  */
4229           inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4230           inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4231         }
4232       else
4233         {
4234           int offset = inst.reloc.exp.X_add_number;
4235
4236           if (subtract)
4237             offset = -offset;
4238
4239           if (offset < 0)
4240             {
4241               offset = -offset;
4242               subtract = 1;
4243
4244               /* Quick check, in case offset is MIN_INT */
4245               if (offset < 0)
4246                 {
4247                   inst.error = _("immediate value out of range");
4248                   return;
4249                 }
4250             }
4251           else
4252             subtract = 0;
4253
4254           if (Rd == REG_SP)
4255             {
4256               if (offset & ~0x1fc)
4257                 {
4258                   inst.error = _("invalid immediate value for stack adjust");
4259                   return;
4260                 }
4261               inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4262               inst.instruction |= offset >> 2;
4263             }
4264           else if (Rs == REG_PC || Rs == REG_SP)
4265             {
4266               if (subtract
4267                   || (offset & ~0x3fc))
4268                 {
4269                   inst.error = _("invalid immediate for address calculation");
4270                   return;
4271                 }
4272               inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4273                                   : T_OPCODE_ADD_SP);
4274               inst.instruction |= (Rd << 8) | (offset >> 2);
4275             }
4276           else if (Rs == Rd)
4277             {
4278               if (offset & ~0xff)
4279                 {
4280                   inst.error = _("immediate value out of range");
4281                   return;
4282                 }
4283               inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4284               inst.instruction |= (Rd << 8) | offset;
4285             }
4286           else
4287             {
4288               if (offset & ~0x7)
4289                 {
4290                   inst.error = _("immediate value out of range");
4291                   return;
4292                 }
4293               inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4294               inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4295             }
4296         }
4297     }
4298   
4299   end_of_line (str);
4300 }
4301
4302 static void
4303 thumb_shift (str, shift)
4304      char * str;
4305      int    shift;
4306 {
4307   int Rd, Rs, Rn = FAIL;
4308
4309   skip_whitespace (str);
4310
4311   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4312       || skip_past_comma (&str) == FAIL)
4313     {
4314       if (! inst.error)
4315         inst.error = BAD_ARGS;
4316       return;
4317     }
4318
4319   if (is_immediate_prefix (*str))
4320     {
4321       /* Two operand immediate format, set Rs to Rd.  */
4322       Rs = Rd;
4323       str ++;
4324       if (my_get_expression (&inst.reloc.exp, &str))
4325         return;
4326     }
4327   else
4328     {
4329       if ((Rs =  thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4330         return;
4331
4332       if (skip_past_comma (&str) == FAIL)
4333         {
4334           /* Two operand format, shuffle the registers and pretend there
4335              are 3 */
4336           Rn = Rs;
4337           Rs = Rd;
4338         }
4339       else if (is_immediate_prefix (*str))
4340         {
4341           str++;
4342           if (my_get_expression (&inst.reloc.exp, &str))
4343             return;
4344         }
4345       else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4346         return;
4347     }
4348
4349   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4350      for the latter case, EXPR contains the immediate that was found. */
4351
4352   if (Rn != FAIL)
4353     {
4354       if (Rs != Rd)
4355         {
4356           inst.error = _("source1 and dest must be same register");
4357           return;
4358         }
4359
4360       switch (shift)
4361         {
4362         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4363         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4364         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4365         }
4366
4367       inst.instruction |= Rd | (Rn << 3);
4368     }
4369   else
4370     {
4371       switch (shift)
4372         {
4373         case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4374         case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4375         case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4376         }
4377
4378       if (inst.reloc.exp.X_op != O_constant)
4379         {
4380           /* Value isn't known yet, create a dummy reloc and let reloc
4381              hacking fix it up */
4382
4383           inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4384         }
4385       else
4386         {
4387           unsigned shift_value = inst.reloc.exp.X_add_number;
4388
4389           if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4390             {
4391               inst.error = _("Invalid immediate for shift");
4392               return;
4393             }
4394
4395           /* Shifts of zero are handled by converting to LSL */
4396           if (shift_value == 0)
4397             inst.instruction = T_OPCODE_LSL_I;
4398
4399           /* Shifts of 32 are encoded as a shift of zero */
4400           if (shift_value == 32)
4401             shift_value = 0;
4402
4403           inst.instruction |= shift_value << 6;
4404         }
4405
4406       inst.instruction |= Rd | (Rs << 3);
4407     }
4408   
4409   end_of_line (str);
4410 }
4411
4412 static void
4413 thumb_mov_compare (str, move)
4414      char * str;
4415      int    move;
4416 {
4417   int Rd, Rs = FAIL;
4418
4419   skip_whitespace (str);
4420
4421   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4422       || skip_past_comma (&str) == FAIL)
4423     {
4424       if (! inst.error)
4425         inst.error = BAD_ARGS;
4426       return;
4427     }
4428
4429   if (is_immediate_prefix (*str))
4430     {
4431       str++;
4432       if (my_get_expression (&inst.reloc.exp, &str))
4433         return;
4434     }
4435   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4436     return;
4437
4438   if (Rs != FAIL)
4439     {
4440       if (Rs < 8 && Rd < 8)
4441         {
4442           if (move == THUMB_MOVE)
4443             /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4444                since a MOV instruction produces unpredictable results */
4445             inst.instruction = T_OPCODE_ADD_I3;
4446           else
4447             inst.instruction = T_OPCODE_CMP_LR;
4448           inst.instruction |= Rd | (Rs << 3);
4449         }
4450       else
4451         {
4452           if (move == THUMB_MOVE)
4453             inst.instruction = T_OPCODE_MOV_HR;
4454           else
4455             inst.instruction = T_OPCODE_CMP_HR;
4456
4457           if (Rd > 7)
4458             inst.instruction |= THUMB_H1;
4459
4460           if (Rs > 7)
4461             inst.instruction |= THUMB_H2;
4462
4463           inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4464         }
4465     }
4466   else
4467     {
4468       if (Rd > 7)
4469         {
4470           inst.error = _("only lo regs allowed with immediate");
4471           return;
4472         }
4473
4474       if (move == THUMB_MOVE)
4475         inst.instruction = T_OPCODE_MOV_I8;
4476       else
4477         inst.instruction = T_OPCODE_CMP_I8;
4478
4479       inst.instruction |= Rd << 8;
4480
4481       if (inst.reloc.exp.X_op != O_constant)
4482         inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4483       else
4484         {
4485           unsigned value = inst.reloc.exp.X_add_number;
4486
4487           if (value > 255)
4488             {
4489               inst.error = _("invalid immediate");
4490               return;
4491             }
4492
4493           inst.instruction |= value;
4494         }
4495     }
4496
4497   end_of_line (str);
4498 }
4499
4500 static void
4501 thumb_load_store (str, load_store, size)
4502      char * str;
4503      int    load_store;
4504      int    size;
4505 {
4506   int Rd, Rb, Ro = FAIL;
4507
4508   skip_whitespace (str);
4509
4510   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4511       || skip_past_comma (&str) == FAIL)
4512     {
4513       if (! inst.error)
4514         inst.error = BAD_ARGS;
4515       return;
4516     }
4517
4518   if (*str == '[')
4519     {
4520       str++;
4521       if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4522         return;
4523
4524       if (skip_past_comma (&str) != FAIL)
4525         {
4526           if (is_immediate_prefix (*str))
4527             {
4528               str++;
4529               if (my_get_expression (&inst.reloc.exp, &str))
4530                 return;
4531             }
4532           else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4533             return;
4534         }
4535       else
4536         {
4537           inst.reloc.exp.X_op = O_constant;
4538           inst.reloc.exp.X_add_number = 0;
4539         }
4540
4541       if (*str != ']')
4542         {
4543           inst.error = _("expected ']'");
4544           return;
4545         }
4546       str++;
4547     }
4548   else if (*str == '=')
4549     {
4550       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4551       str++;
4552
4553       skip_whitespace (str);
4554
4555       if (my_get_expression (& inst.reloc.exp, & str))
4556         return;
4557
4558       end_of_line (str);
4559       
4560       if (   inst.reloc.exp.X_op != O_constant
4561           && inst.reloc.exp.X_op != O_symbol)
4562         {
4563           inst.error = "Constant expression expected";
4564           return;
4565         }
4566
4567       if (inst.reloc.exp.X_op == O_constant
4568           && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4569         {
4570           /* This can be done with a mov instruction */
4571
4572           inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
4573           inst.instruction |= inst.reloc.exp.X_add_number;
4574           return; 
4575         }
4576
4577       /* Insert into literal pool */     
4578       if (add_to_lit_pool () == FAIL)
4579         {
4580           if (!inst.error)
4581             inst.error = "literal pool insertion failed"; 
4582           return;
4583         }
4584
4585       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
4586       inst.reloc.pc_rel = 1;
4587       inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
4588       inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4589
4590       return;
4591     }
4592   else
4593     {
4594       if (my_get_expression (&inst.reloc.exp, &str))
4595         return;
4596
4597       inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4598       inst.reloc.pc_rel = 1;
4599       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4600       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4601       end_of_line (str);
4602       return;
4603     }
4604
4605   if (Rb == REG_PC || Rb == REG_SP)
4606     {
4607       if (size != THUMB_WORD)
4608         {
4609           inst.error = _("byte or halfword not valid for base register");
4610           return;
4611         }
4612       else if (Rb == REG_PC && load_store != THUMB_LOAD)
4613         {
4614           inst.error = _("R15 based store not allowed");
4615           return;
4616         }
4617       else if (Ro != FAIL)
4618         {
4619           inst.error = _("Invalid base register for register offset");
4620           return;
4621         }
4622
4623       if (Rb == REG_PC)
4624         inst.instruction = T_OPCODE_LDR_PC;
4625       else if (load_store == THUMB_LOAD)
4626         inst.instruction = T_OPCODE_LDR_SP;
4627       else
4628         inst.instruction = T_OPCODE_STR_SP;
4629
4630       inst.instruction |= Rd << 8;
4631       if (inst.reloc.exp.X_op == O_constant)
4632         {
4633           unsigned offset = inst.reloc.exp.X_add_number;
4634
4635           if (offset & ~0x3fc)
4636             {
4637               inst.error = _("invalid offset");
4638               return;
4639             }
4640
4641           inst.instruction |= offset >> 2;
4642         }
4643       else
4644         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4645     }
4646   else if (Rb > 7)
4647     {
4648       inst.error = _("invalid base register in load/store");
4649       return;
4650     }
4651   else if (Ro == FAIL)
4652     {
4653       /* Immediate offset */
4654       if (size == THUMB_WORD)
4655         inst.instruction = (load_store == THUMB_LOAD
4656                             ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4657       else if (size == THUMB_HALFWORD)
4658         inst.instruction = (load_store == THUMB_LOAD
4659                             ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4660       else
4661         inst.instruction = (load_store == THUMB_LOAD
4662                             ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4663
4664       inst.instruction |= Rd | (Rb << 3);
4665
4666       if (inst.reloc.exp.X_op == O_constant)
4667         {
4668           unsigned offset = inst.reloc.exp.X_add_number;
4669           
4670           if (offset & ~(0x1f << size))
4671             {
4672               inst.error = _("Invalid offset");
4673               return;
4674             }
4675           inst.instruction |= (offset >> size) << 6;
4676         }
4677       else
4678         inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4679     }
4680   else
4681     {
4682       /* Register offset */
4683       if (size == THUMB_WORD)
4684         inst.instruction = (load_store == THUMB_LOAD
4685                             ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4686       else if (size == THUMB_HALFWORD)
4687         inst.instruction = (load_store == THUMB_LOAD
4688                             ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4689       else
4690         inst.instruction = (load_store == THUMB_LOAD
4691                             ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4692
4693       inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4694     }
4695
4696   end_of_line (str);
4697 }
4698
4699 static void
4700 do_t_nop (str)
4701      char * str;
4702 {
4703   /* Do nothing */
4704   end_of_line (str);
4705   return;
4706 }
4707
4708 /* Handle the Format 4 instructions that do not have equivalents in other 
4709    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4710    BIC and MVN.  */
4711 static void
4712 do_t_arit (str)
4713      char * str;
4714 {
4715   int Rd, Rs, Rn;
4716
4717   skip_whitespace (str);
4718
4719   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4720       || skip_past_comma (&str) == FAIL
4721       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4722     {
4723         inst.error = BAD_ARGS;
4724         return;
4725     }
4726
4727   if (skip_past_comma (&str) != FAIL)
4728     {
4729       /* Three operand format not allowed for TST, CMN, NEG and MVN.
4730          (It isn't allowed for CMP either, but that isn't handled by this
4731          function.)  */
4732       if (inst.instruction == T_OPCODE_TST
4733           || inst.instruction == T_OPCODE_CMN
4734           || inst.instruction == T_OPCODE_NEG
4735           || inst.instruction == T_OPCODE_MVN)
4736         {
4737           inst.error = BAD_ARGS;
4738           return;
4739         }
4740
4741       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4742         return;
4743
4744       if (Rs != Rd)
4745         {
4746           inst.error = _("dest and source1 one must be the same register");
4747           return;
4748         }
4749       Rs = Rn;
4750     }
4751
4752   if (inst.instruction == T_OPCODE_MUL
4753       && Rs == Rd)
4754     as_tsktsk (_("Rs and Rd must be different in MUL"));
4755
4756   inst.instruction |= Rd | (Rs << 3);
4757   end_of_line (str);
4758 }
4759
4760 static void
4761 do_t_add (str)
4762      char * str;
4763 {
4764   thumb_add_sub (str, 0);
4765 }
4766
4767 static void
4768 do_t_asr (str)
4769      char * str;
4770 {
4771   thumb_shift (str, THUMB_ASR);
4772 }
4773
4774 static void
4775 do_t_branch9 (str)
4776      char * str;
4777 {
4778   if (my_get_expression (&inst.reloc.exp, &str))
4779     return;
4780   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4781   inst.reloc.pc_rel = 1;
4782   end_of_line (str);
4783 }
4784
4785 static void
4786 do_t_branch12 (str)
4787      char * str;
4788 {
4789   if (my_get_expression (&inst.reloc.exp, &str))
4790     return;
4791   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4792   inst.reloc.pc_rel = 1;
4793   end_of_line (str);
4794 }
4795
4796 /* Find the real, Thumb encoded start of a Thumb function.  */
4797
4798 static symbolS *
4799 find_real_start (symbolP)
4800      symbolS * symbolP;
4801 {
4802   char *       real_start;
4803   const char * name = S_GET_NAME (symbolP);
4804   symbolS *    new_target;
4805
4806   /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4807 #define STUB_NAME ".real_start_of"
4808
4809   if (name == NULL)
4810     abort();
4811
4812   /* Names that start with '.' are local labels, not function entry points.
4813      The compiler may generate BL instructions to these labels because it
4814      needs to perform a branch to a far away location.  */
4815   if (name[0] == '.')
4816     return symbolP;
4817   
4818   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4819   sprintf (real_start, "%s%s", STUB_NAME, name);
4820
4821   new_target = symbol_find (real_start);
4822   
4823   if (new_target == NULL)
4824     {
4825       as_warn ("Failed to find real start of function: %s\n", name);
4826       new_target = symbolP;
4827     }
4828
4829   free (real_start);
4830
4831   return new_target;
4832 }
4833
4834
4835 static void
4836 do_t_branch23 (str)
4837      char * str;
4838 {
4839   if (my_get_expression (& inst.reloc.exp, & str))
4840     return;
4841   
4842   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
4843   inst.reloc.pc_rel = 1;
4844   end_of_line (str);
4845
4846   /* If the destination of the branch is a defined symbol which does not have
4847      the THUMB_FUNC attribute, then we must be calling a function which has
4848      the (interfacearm) attribute.  We look for the Thumb entry point to that
4849      function and change the branch to refer to that function instead.  */
4850   if (   inst.reloc.exp.X_op == O_symbol
4851       && inst.reloc.exp.X_add_symbol != NULL
4852       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4853       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4854     inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4855 }
4856
4857 static void
4858 do_t_bx (str)
4859      char * str;
4860 {
4861   int reg;
4862
4863   skip_whitespace (str);
4864
4865   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4866     return;
4867
4868   /* This sets THUMB_H2 from the top bit of reg.  */
4869   inst.instruction |= reg << 3;
4870
4871   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
4872      should cause the alignment to be checked once it is known.  This is
4873      because BX PC only works if the instruction is word aligned.  */
4874
4875   end_of_line (str);
4876 }
4877
4878 static void
4879 do_t_compare (str)
4880      char * str;
4881 {
4882   thumb_mov_compare (str, THUMB_COMPARE);
4883 }
4884
4885 static void
4886 do_t_ldmstm (str)
4887      char * str;
4888 {
4889   int Rb;
4890   long range;
4891
4892   skip_whitespace (str);
4893
4894   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4895     return;
4896
4897   if (*str != '!')
4898     as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4899   else
4900     str++;
4901
4902   if (skip_past_comma (&str) == FAIL
4903       || (range = reg_list (&str)) == FAIL)
4904     {
4905       if (! inst.error)
4906         inst.error = BAD_ARGS;
4907       return;
4908     }
4909
4910   if (inst.reloc.type != BFD_RELOC_NONE)
4911     {
4912       /* This really doesn't seem worth it. */
4913       inst.reloc.type = BFD_RELOC_NONE;
4914       inst.error = _("Expression too complex");
4915       return;
4916     }
4917
4918   if (range & ~0xff)
4919     {
4920       inst.error = _("only lo-regs valid in load/store multiple");
4921       return;
4922     }
4923
4924   inst.instruction |= (Rb << 8) | range;
4925   end_of_line (str);
4926 }
4927
4928 static void
4929 do_t_ldr (str)
4930      char * str;
4931 {
4932   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4933 }
4934
4935 static void
4936 do_t_ldrb (str)
4937      char * str;
4938 {
4939   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4940 }
4941
4942 static void
4943 do_t_ldrh (str)
4944      char * str;
4945 {
4946   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4947 }
4948
4949 static void
4950 do_t_lds (str)
4951      char * str;
4952 {
4953   int Rd, Rb, Ro;
4954
4955   skip_whitespace (str);
4956
4957   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4958       || skip_past_comma (&str) == FAIL
4959       || *str++ != '['
4960       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4961       || skip_past_comma (&str) == FAIL
4962       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4963       || *str++ != ']')
4964     {
4965       if (! inst.error)
4966         inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4967       return;
4968     }
4969
4970   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4971   end_of_line (str);
4972 }
4973
4974 static void
4975 do_t_lsl (str)
4976      char * str;
4977 {
4978   thumb_shift (str, THUMB_LSL);
4979 }
4980
4981 static void
4982 do_t_lsr (str)
4983      char * str;
4984 {
4985   thumb_shift (str, THUMB_LSR);
4986 }
4987
4988 static void
4989 do_t_mov (str)
4990      char * str;
4991 {
4992   thumb_mov_compare (str, THUMB_MOVE);
4993 }
4994
4995 static void
4996 do_t_push_pop (str)
4997      char * str;
4998 {
4999   long range;
5000
5001   skip_whitespace (str);
5002
5003   if ((range = reg_list (&str)) == FAIL)
5004     {
5005       if (! inst.error)
5006         inst.error = BAD_ARGS;
5007       return;
5008     }
5009
5010   if (inst.reloc.type != BFD_RELOC_NONE)
5011     {
5012       /* This really doesn't seem worth it. */
5013       inst.reloc.type = BFD_RELOC_NONE;
5014       inst.error = _("Expression too complex");
5015       return;
5016     }
5017
5018   if (range & ~0xff)
5019     {
5020       if ((inst.instruction == T_OPCODE_PUSH
5021            && (range & ~0xff) == 1 << REG_LR)
5022           || (inst.instruction == T_OPCODE_POP
5023               && (range & ~0xff) == 1 << REG_PC))
5024         {
5025           inst.instruction |= THUMB_PP_PC_LR;
5026           range &= 0xff;
5027         }
5028       else
5029         {
5030           inst.error = _("invalid register list to push/pop instruction");
5031           return;
5032         }
5033     }
5034
5035   inst.instruction |= range;
5036   end_of_line (str);
5037 }
5038
5039 static void
5040 do_t_str (str)
5041      char * str;
5042 {
5043   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
5044 }
5045
5046 static void
5047 do_t_strb (str)
5048      char * str;
5049 {
5050   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
5051 }
5052
5053 static void
5054 do_t_strh (str)
5055      char * str;
5056 {
5057   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
5058 }
5059
5060 static void
5061 do_t_sub (str)
5062      char * str;
5063 {
5064   thumb_add_sub (str, 1);
5065 }
5066
5067 static void
5068 do_t_swi (str)
5069      char * str;
5070 {
5071   skip_whitespace (str);
5072
5073   if (my_get_expression (&inst.reloc.exp, &str))
5074     return;
5075
5076   inst.reloc.type = BFD_RELOC_ARM_SWI;
5077   end_of_line (str);
5078   return;
5079 }
5080
5081 static void
5082 do_t_adr (str)
5083      char * str;
5084 {
5085   int reg;
5086
5087   /* This is a pseudo-op of the form "adr rd, label" to be converted
5088      into a relative address of the form "add rd, pc, #label-.-4".  */
5089   skip_whitespace (str);
5090
5091   /* Store Rd in temporary location inside instruction.  */
5092   if ((reg = reg_required_here (&str, 4)) == FAIL
5093       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
5094       || skip_past_comma (&str) == FAIL
5095       || my_get_expression (&inst.reloc.exp, &str))
5096     {
5097       if (!inst.error)
5098         inst.error = BAD_ARGS;
5099       return;
5100     }
5101
5102   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
5103   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
5104   inst.reloc.pc_rel = 1;
5105   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
5106   
5107   end_of_line (str);
5108 }
5109
5110 static void
5111 insert_reg (entry)
5112      int entry;
5113 {
5114   int    len = strlen (reg_table[entry].name) + 2;
5115   char * buf = (char *) xmalloc (len);
5116   char * buf2 = (char *) xmalloc (len);
5117   int    i = 0;
5118
5119 #ifdef REGISTER_PREFIX
5120   buf[i++] = REGISTER_PREFIX;
5121 #endif
5122
5123   strcpy (buf + i, reg_table[entry].name);
5124
5125   for (i = 0; buf[i]; i++)
5126     buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
5127
5128   buf2[i] = '\0';
5129
5130   hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
5131   hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
5132 }
5133
5134 static void
5135 insert_reg_alias (str, regnum)
5136      char *str;
5137      int regnum;
5138 {
5139   struct reg_entry *new =
5140     (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
5141   char *name = xmalloc (strlen (str) + 1);
5142   strcpy (name, str);
5143
5144   new->name = name;
5145   new->number = regnum;
5146
5147   hash_insert (arm_reg_hsh, name, (PTR) new);
5148 }
5149
5150 static void
5151 set_constant_flonums ()
5152 {
5153   int i;
5154
5155   for (i = 0; i < NUM_FLOAT_VALS; i++)
5156     if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
5157       abort ();
5158 }
5159
5160 void
5161 md_begin ()
5162 {
5163   unsigned mach;
5164   unsigned int i;
5165   
5166   if (   (arm_ops_hsh = hash_new ()) == NULL
5167       || (arm_tops_hsh = hash_new ()) == NULL
5168       || (arm_cond_hsh = hash_new ()) == NULL
5169       || (arm_shift_hsh = hash_new ()) == NULL
5170       || (arm_reg_hsh = hash_new ()) == NULL
5171       || (arm_psr_hsh = hash_new ()) == NULL)
5172     as_fatal (_("Virtual memory exhausted"));
5173     
5174   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
5175     hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
5176   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
5177     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
5178   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
5179     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
5180   for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
5181     hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
5182   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
5183     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
5184
5185   for (i = 0; reg_table[i].name; i++)
5186     insert_reg (i);
5187
5188   set_constant_flonums ();
5189
5190 #if defined OBJ_COFF || defined OBJ_ELF
5191   {
5192     unsigned int flags = 0;
5193     
5194     /* Set the flags in the private structure.  */
5195     if (uses_apcs_26)      flags |= F_APCS26;
5196     if (support_interwork) flags |= F_INTERWORK;
5197     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
5198     if (pic_code)          flags |= F_PIC;
5199     if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
5200
5201     bfd_set_private_flags (stdoutput, flags);
5202   }
5203 #endif
5204   
5205   /* Record the CPU type as well.  */
5206   switch (cpu_variant & ARM_CPU_MASK)
5207     {
5208     case ARM_2:
5209       mach = bfd_mach_arm_2;
5210       break;
5211       
5212     case ARM_3:                 /* Also ARM_250.  */
5213       mach = bfd_mach_arm_2a;
5214       break;
5215       
5216     default:
5217     case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined.  */
5218       mach = bfd_mach_arm_4;
5219       break;
5220       
5221     case ARM_7:                 /* Also ARM_6.  */
5222       mach = bfd_mach_arm_3;
5223       break;
5224     }
5225   
5226   /* Catch special cases.  */
5227   if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5228     {
5229       if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5230         mach = bfd_mach_arm_5T;
5231       else if (cpu_variant & ARM_EXT_V5)
5232         mach = bfd_mach_arm_5;
5233       else if (cpu_variant & ARM_THUMB)
5234         mach = bfd_mach_arm_4T;
5235       else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5236         mach = bfd_mach_arm_4;
5237       else if (cpu_variant & ARM_LONGMUL)
5238         mach = bfd_mach_arm_3M;
5239     }
5240   
5241   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5242 }
5243
5244 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5245    for use in the a.out file, and stores them in the array pointed to by buf.
5246    This knows about the endian-ness of the target machine and does
5247    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
5248    2 (short) and 4 (long)  Floating numbers are put out as a series of
5249    LITTLENUMS (shorts, here at least).  */
5250 void
5251 md_number_to_chars (buf, val, n)
5252      char * buf;
5253      valueT val;
5254      int    n;
5255 {
5256   if (target_big_endian)
5257     number_to_chars_bigendian (buf, val, n);
5258   else
5259     number_to_chars_littleendian (buf, val, n);
5260 }
5261
5262 static valueT 
5263 md_chars_to_number (buf, n)
5264      char * buf;
5265      int n;
5266 {
5267   valueT result = 0;
5268   unsigned char * where = (unsigned char *) buf;
5269
5270   if (target_big_endian)
5271     {
5272       while (n--)
5273         {
5274           result <<= 8;
5275           result |= (*where++ & 255);
5276         }
5277     }
5278   else
5279     {
5280       while (n--)
5281         {
5282           result <<= 8;
5283           result |= (where[n] & 255);
5284         }
5285     }
5286
5287   return result;
5288 }
5289
5290 /* Turn a string in input_line_pointer into a floating point constant
5291    of type TYPE, and store the appropriate bytes in *litP.  The number
5292    of LITTLENUMS emitted is stored in *sizeP .  An error message is
5293    returned, or NULL on OK.
5294
5295    Note that fp constants aren't represent in the normal way on the ARM.
5296    In big endian mode, things are as expected.  However, in little endian
5297    mode fp constants are big-endian word-wise, and little-endian byte-wise
5298    within the words.  For example, (double) 1.1 in big endian mode is
5299    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5300    the byte sequence 99 99 f1 3f 9a 99 99 99.
5301
5302    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
5303
5304 char *
5305 md_atof (type, litP, sizeP)
5306      char   type;
5307      char * litP;
5308      int *  sizeP;
5309 {
5310   int prec;
5311   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5312   char *t;
5313   int i;
5314
5315   switch (type)
5316     {
5317     case 'f':
5318     case 'F':
5319     case 's':
5320     case 'S':
5321       prec = 2;
5322       break;
5323
5324     case 'd':
5325     case 'D':
5326     case 'r':
5327     case 'R':
5328       prec = 4;
5329       break;
5330
5331     case 'x':
5332     case 'X':
5333       prec = 6;
5334       break;
5335
5336     case 'p':
5337     case 'P':
5338       prec = 6;
5339       break;
5340
5341     default:
5342       *sizeP = 0;
5343       return _("Bad call to MD_ATOF()");
5344     }
5345
5346   t = atof_ieee (input_line_pointer, type, words);
5347   if (t)
5348     input_line_pointer = t;
5349   *sizeP = prec * 2;
5350
5351   if (target_big_endian)
5352     {
5353       for (i = 0; i < prec; i++)
5354         {
5355           md_number_to_chars (litP, (valueT) words[i], 2);
5356           litP += 2;
5357         }
5358     }
5359   else
5360     {
5361       /* For a 4 byte float the order of elements in `words' is 1 0.  For an
5362          8 byte float the order is 1 0 3 2.  */
5363       for (i = 0; i < prec; i += 2)
5364         {
5365           md_number_to_chars (litP, (valueT) words[i + 1], 2);
5366           md_number_to_chars (litP + 2, (valueT) words[i], 2);
5367           litP += 4;
5368         }
5369     }
5370
5371   return 0;
5372 }
5373
5374 /* The knowledge of the PC's pipeline offset is built into the insns themselves.  */ 
5375 long
5376 md_pcrel_from (fixP)
5377      fixS * fixP;
5378 {
5379   if (   fixP->fx_addsy
5380       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5381       && fixP->fx_subsy == NULL)
5382     return 0;
5383   
5384   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5385     {
5386       /* PC relative addressing on the Thumb is slightly odd
5387          as the bottom two bits of the PC are forced to zero
5388          for the calculation.  */
5389       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5390     }
5391
5392 #ifdef TE_WINCE
5393   /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5394      so we un-adjust here to compensate for the accomodation.  */
5395   return fixP->fx_where + fixP->fx_frag->fr_address + 8;
5396 #else
5397   return fixP->fx_where + fixP->fx_frag->fr_address;
5398 #endif
5399 }
5400
5401 /* Round up a section size to the appropriate boundary. */
5402 valueT
5403 md_section_align (segment, size)
5404      segT   segment ATTRIBUTE_UNUSED;
5405      valueT size;
5406 {
5407 #ifdef OBJ_ELF
5408   return size;
5409 #else
5410   /* Round all sects to multiple of 4 */
5411   return (size + 3) & ~3;
5412 #endif
5413 }
5414
5415 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.  Otherwise 
5416    we have no need to default values of symbols.  */
5417
5418 /* ARGSUSED */
5419 symbolS *
5420 md_undefined_symbol (name)
5421      char * name ATTRIBUTE_UNUSED;
5422 {
5423 #ifdef OBJ_ELF
5424   if (name[0] == '_' && name[1] == 'G'
5425       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5426     {
5427       if (!GOT_symbol)
5428         {
5429           if (symbol_find (name))
5430             as_bad ("GOT already in the symbol table");
5431           
5432           GOT_symbol = symbol_new (name, undefined_section,
5433                                    (valueT)0, & zero_address_frag);
5434         }
5435       
5436       return GOT_symbol;
5437     }
5438 #endif
5439   
5440   return 0;
5441 }
5442
5443 /* arm_reg_parse () := if it looks like a register, return its token and 
5444    advance the pointer. */
5445
5446 static int
5447 arm_reg_parse (ccp)
5448      register char ** ccp;
5449 {
5450   char * start = * ccp;
5451   char   c;
5452   char * p;
5453   struct reg_entry * reg;
5454
5455 #ifdef REGISTER_PREFIX
5456   if (*start != REGISTER_PREFIX)
5457     return FAIL;
5458   p = start + 1;
5459 #else
5460   p = start;
5461 #ifdef OPTIONAL_REGISTER_PREFIX
5462   if (*p == OPTIONAL_REGISTER_PREFIX)
5463     p++, start++;
5464 #endif
5465 #endif
5466   if (!isalpha (*p) || !is_name_beginner (*p))
5467     return FAIL;
5468
5469   c = *p++;
5470   while (isalpha (c) || isdigit (c) || c == '_')
5471     c = *p++;
5472
5473   *--p = 0;
5474   reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5475   *p = c;
5476   
5477   if (reg)
5478     {
5479       *ccp = p;
5480       return reg->number;
5481     }
5482
5483   return FAIL;
5484 }
5485
5486 int
5487 md_apply_fix3 (fixP, val, seg)
5488      fixS *      fixP;
5489      valueT *    val;
5490      segT        seg;
5491 {
5492   offsetT        value = * val;
5493   offsetT        newval;
5494   unsigned int   newimm;
5495   unsigned long  temp;
5496   int            sign;
5497   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5498   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5499
5500   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5501
5502   /* Note whether this will delete the relocation.  */
5503 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5504   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5505       && !fixP->fx_pcrel)
5506 #else
5507   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5508 #endif
5509     fixP->fx_done = 1;
5510
5511   /* If this symbol is in a different section then we need to leave it for
5512      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
5513      so we have to undo it's effects here.  */
5514   if (fixP->fx_pcrel)
5515     {
5516       if (fixP->fx_addsy != NULL
5517           && S_IS_DEFINED (fixP->fx_addsy)
5518           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5519         {
5520           if (target_oabi
5521               && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
5522                 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
5523                 ))
5524             value = 0;
5525           else
5526             value += md_pcrel_from (fixP);
5527         }
5528     }
5529
5530   fixP->fx_addnumber = value;   /* Remember value for emit_reloc.  */
5531
5532   switch (fixP->fx_r_type)
5533     {
5534     case BFD_RELOC_ARM_IMMEDIATE:
5535       newimm = validate_immediate (value);
5536       temp = md_chars_to_number (buf, INSN_SIZE);
5537
5538       /* If the instruction will fail, see if we can fix things up by
5539          changing the opcode.  */
5540       if (newimm == (unsigned int) FAIL
5541           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5542         {
5543           as_bad_where (fixP->fx_file, fixP->fx_line,
5544                         _("invalid constant (%lx) after fixup"),
5545                         (unsigned long) value);
5546           break;
5547         }
5548
5549       newimm |= (temp & 0xfffff000);
5550       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5551       break;
5552
5553     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5554       {
5555         unsigned int highpart = 0;
5556         unsigned int newinsn  = 0xe1a00000; /* nop */
5557         newimm = validate_immediate (value);
5558         temp = md_chars_to_number (buf, INSN_SIZE);
5559
5560         /* If the instruction will fail, see if we can fix things up by
5561            changing the opcode.  */
5562         if (newimm == (unsigned int) FAIL
5563             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5564           {
5565             /* No ?  OK - try using two ADD instructions to generate the value.  */
5566             newimm = validate_immediate_twopart (value, & highpart);
5567
5568             /* Yes - then make sure that the second instruction is also an add.  */
5569             if (newimm != (unsigned int) FAIL)
5570               newinsn = temp;
5571             /* Still No ?  Try using a negated value.  */
5572             else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5573                 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5574             /* Otherwise - give up.  */
5575             else
5576               {
5577                 as_bad_where (fixP->fx_file, fixP->fx_line,
5578                               _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5579                 break;
5580               }
5581
5582             /* Replace the first operand in the 2nd instruction (which is the PC)
5583                with the destination register.  We have already added in the PC in the
5584                first instruction and we do not want to do it again.  */
5585             newinsn &= ~ 0xf0000;
5586             newinsn |= ((newinsn & 0x0f000) << 4);
5587           }
5588
5589         newimm |= (temp & 0xfffff000);
5590         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5591
5592         highpart |= (newinsn & 0xfffff000);
5593         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5594       }
5595       break;
5596
5597     case BFD_RELOC_ARM_OFFSET_IMM:
5598       sign = value >= 0;
5599       
5600       if (value < 0)
5601         value = - value;
5602       
5603       if (validate_offset_imm (value, 0) == FAIL)
5604         {
5605           as_bad_where (fixP->fx_file, fixP->fx_line, 
5606                         _("bad immediate value for offset (%ld)"), (long) value);
5607           break;
5608         }
5609
5610       newval = md_chars_to_number (buf, INSN_SIZE);
5611       newval &= 0xff7ff000;
5612       newval |= value | (sign ? INDEX_UP : 0);
5613       md_number_to_chars (buf, newval, INSN_SIZE);
5614       break;
5615
5616      case BFD_RELOC_ARM_OFFSET_IMM8:
5617      case BFD_RELOC_ARM_HWLITERAL:
5618       sign = value >= 0;
5619       
5620       if (value < 0)
5621         value = - value;
5622
5623       if (validate_offset_imm (value, 1) == FAIL)
5624         {
5625           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5626             as_bad_where (fixP->fx_file, fixP->fx_line, 
5627                         _("invalid literal constant: pool needs to be closer"));
5628           else
5629             as_bad (_("bad immediate value for half-word offset (%ld)"),
5630                     (long) value);
5631           break;
5632         }
5633
5634       newval = md_chars_to_number (buf, INSN_SIZE);
5635       newval &= 0xff7ff0f0;
5636       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5637       md_number_to_chars (buf, newval, INSN_SIZE);
5638       break;
5639
5640     case BFD_RELOC_ARM_LITERAL:
5641       sign = value >= 0;
5642       
5643       if (value < 0)
5644         value = - value;
5645
5646       if (validate_offset_imm (value, 0) == FAIL)
5647         {
5648           as_bad_where (fixP->fx_file, fixP->fx_line, 
5649                         _("invalid literal constant: pool needs to be closer"));
5650           break;
5651         }
5652
5653       newval = md_chars_to_number (buf, INSN_SIZE);
5654       newval &= 0xff7ff000;
5655       newval |= value | (sign ? INDEX_UP : 0);
5656       md_number_to_chars (buf, newval, INSN_SIZE);
5657       break;
5658
5659     case BFD_RELOC_ARM_SHIFT_IMM:
5660       newval = md_chars_to_number (buf, INSN_SIZE);
5661       if (((unsigned long) value) > 32
5662           || (value == 32 
5663               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5664         {
5665           as_bad_where (fixP->fx_file, fixP->fx_line,
5666                         _("shift expression is too large"));
5667           break;
5668         }
5669
5670       if (value == 0)
5671         newval &= ~0x60;        /* Shifts of zero must be done as lsl */
5672       else if (value == 32)
5673         value = 0;
5674       newval &= 0xfffff07f;
5675       newval |= (value & 0x1f) << 7;
5676       md_number_to_chars (buf, newval , INSN_SIZE);
5677       break;
5678
5679     case BFD_RELOC_ARM_SWI:
5680       if (arm_data->thumb_mode)
5681         {
5682           if (((unsigned long) value) > 0xff)
5683             as_bad_where (fixP->fx_file, fixP->fx_line,
5684                           _("Invalid swi expression"));
5685           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5686           newval |= value;
5687           md_number_to_chars (buf, newval, THUMB_SIZE);
5688         }
5689       else
5690         {
5691           if (((unsigned long) value) > 0x00ffffff)
5692             as_bad_where (fixP->fx_file, fixP->fx_line, 
5693                           _("Invalid swi expression"));
5694           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5695           newval |= value;
5696           md_number_to_chars (buf, newval , INSN_SIZE);
5697         }
5698       break;
5699
5700     case BFD_RELOC_ARM_MULTI:
5701       if (((unsigned long) value) > 0xffff)
5702         as_bad_where (fixP->fx_file, fixP->fx_line,
5703                       _("Invalid expression in load/store multiple"));
5704       newval = value | md_chars_to_number (buf, INSN_SIZE);
5705       md_number_to_chars (buf, newval, INSN_SIZE);
5706       break;
5707
5708     case BFD_RELOC_ARM_PCREL_BRANCH:
5709       newval = md_chars_to_number (buf, INSN_SIZE);
5710
5711       /* Sign-extend a 24-bit number.  */
5712 #define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5713
5714 #ifdef OBJ_ELF
5715       if (! target_oabi)
5716         value = fixP->fx_offset;
5717 #endif
5718
5719       /* We are going to store value (shifted right by two) in the
5720          instruction, in a 24 bit, signed field.  Thus we need to check
5721          that none of the top 8 bits of the shifted value (top 7 bits of
5722          the unshifted, unsigned value) are set, or that they are all set.  */
5723       if ((value & ~ ((offsetT) 0x1ffffff)) != 0
5724           && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
5725         {
5726 #ifdef OBJ_ELF
5727           /* Normally we would be stuck at this point, since we cannot store
5728              the absolute address that is the destination of the branch in the
5729              24 bits of the branch instruction.  If however, we happen to know
5730              that the destination of the branch is in the same section as the
5731              branch instruciton itself, then we can compute the relocation for
5732              ourselves and not have to bother the linker with it.
5733              
5734              FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5735              because I have not worked out how to do this for OBJ_COFF or
5736              target_oabi.  */
5737           if (! target_oabi
5738               && fixP->fx_addsy != NULL
5739               && S_IS_DEFINED (fixP->fx_addsy)
5740               && S_GET_SEGMENT (fixP->fx_addsy) == seg)
5741             {
5742               /* Get pc relative value to go into the branch.  */
5743               value = * val;
5744
5745               /* Permit a backward branch provided that enough bits are set.
5746                  Allow a forwards branch, provided that enough bits are clear.  */
5747               if ((value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
5748                   || (value & ~ ((offsetT) 0x1ffffff)) == 0)
5749                 fixP->fx_done = 1;
5750             }
5751           
5752           if (! fixP->fx_done)
5753 #endif
5754             as_bad_where (fixP->fx_file, fixP->fx_line,
5755                           _("gas can't handle same-section branch dest >= 0x04000000"));
5756         }
5757
5758       value >>= 2;
5759       value += SEXT24 (newval);
5760       
5761       if ((value & ~ ((offsetT) 0xffffff)) != 0
5762           && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
5763         as_bad_where (fixP->fx_file, fixP->fx_line,
5764                       _("out of range branch"));
5765       
5766       newval = (value & 0x00ffffff) | (newval & 0xff000000);
5767       md_number_to_chars (buf, newval, INSN_SIZE);
5768       break;
5769
5770     case BFD_RELOC_ARM_PCREL_BLX:
5771       {
5772         offsetT hbit;
5773         newval = md_chars_to_number (buf, INSN_SIZE);
5774
5775 #ifdef OBJ_ELF
5776         if (! target_oabi)
5777            value = fixP->fx_offset;
5778 #endif
5779         hbit   = (value >> 1) & 1;
5780         value  = (value >> 2) & 0x00ffffff;
5781         value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5782         newval = value | (newval & 0xfe000000) | (hbit << 24);
5783         md_number_to_chars (buf, newval, INSN_SIZE);
5784       }
5785       break;
5786
5787     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5788       newval = md_chars_to_number (buf, THUMB_SIZE);
5789       {
5790         addressT diff = (newval & 0xff) << 1;
5791         if (diff & 0x100)
5792          diff |= ~0xff;
5793
5794         value += diff;
5795         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5796          as_bad_where (fixP->fx_file, fixP->fx_line,
5797                        _("Branch out of range"));
5798         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5799       }
5800       md_number_to_chars (buf, newval, THUMB_SIZE);
5801       break;
5802
5803     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5804       newval = md_chars_to_number (buf, THUMB_SIZE);
5805       {
5806         addressT diff = (newval & 0x7ff) << 1;
5807         if (diff & 0x800)
5808          diff |= ~0x7ff;
5809
5810         value += diff;
5811         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5812          as_bad_where (fixP->fx_file, fixP->fx_line,
5813                        _("Branch out of range"));
5814         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5815       }
5816       md_number_to_chars (buf, newval, THUMB_SIZE);
5817       break;
5818
5819     case BFD_RELOC_THUMB_PCREL_BLX:
5820     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5821       {
5822         offsetT newval2;
5823         addressT diff;
5824
5825         newval  = md_chars_to_number (buf, THUMB_SIZE);
5826         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5827         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5828         if (diff & 0x400000)
5829           diff |= ~0x3fffff;
5830 #ifdef OBJ_ELF
5831         value = fixP->fx_offset;
5832 #endif
5833         value += diff;
5834         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5835           as_bad_where (fixP->fx_file, fixP->fx_line,
5836                         _("Branch with link out of range"));
5837
5838         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
5839         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5840         md_number_to_chars (buf, newval, THUMB_SIZE);
5841         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5842       }
5843       break;
5844
5845     case BFD_RELOC_8:
5846       if (fixP->fx_done || fixP->fx_pcrel)
5847         md_number_to_chars (buf, value, 1);
5848 #ifdef OBJ_ELF
5849       else if (!target_oabi)
5850         {
5851           value = fixP->fx_offset;
5852           md_number_to_chars (buf, value, 1);
5853         }
5854 #endif
5855       break;
5856
5857     case BFD_RELOC_16:
5858       if (fixP->fx_done || fixP->fx_pcrel)
5859         md_number_to_chars (buf, value, 2);
5860 #ifdef OBJ_ELF
5861       else if (!target_oabi)
5862         {
5863           value = fixP->fx_offset;
5864           md_number_to_chars (buf, value, 2);
5865         }
5866 #endif
5867       break;
5868
5869 #ifdef OBJ_ELF
5870     case BFD_RELOC_ARM_GOT32:
5871     case BFD_RELOC_ARM_GOTOFF:
5872         md_number_to_chars (buf, 0, 4);
5873         break;
5874 #endif
5875
5876     case BFD_RELOC_RVA:
5877     case BFD_RELOC_32:
5878       if (fixP->fx_done || fixP->fx_pcrel)
5879         md_number_to_chars (buf, value, 4);
5880 #ifdef OBJ_ELF
5881       else if (!target_oabi)
5882         {
5883           value = fixP->fx_offset;
5884           md_number_to_chars (buf, value, 4);
5885         }
5886 #endif
5887       break;
5888
5889 #ifdef OBJ_ELF
5890     case BFD_RELOC_ARM_PLT32:
5891       /* It appears the instruction is fully prepared at this point. */
5892       break;
5893 #endif
5894
5895     case BFD_RELOC_ARM_GOTPC:
5896       md_number_to_chars (buf, value, 4);
5897       break;
5898       
5899     case BFD_RELOC_ARM_CP_OFF_IMM:
5900       sign = value >= 0;
5901       if (value < -1023 || value > 1023 || (value & 3))
5902         as_bad_where (fixP->fx_file, fixP->fx_line,
5903                       _("Illegal value for co-processor offset"));
5904       if (value < 0)
5905         value = -value;
5906       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5907       newval |= (value >> 2) | (sign ?  INDEX_UP : 0);
5908       md_number_to_chars (buf, newval , INSN_SIZE);
5909       break;
5910
5911     case BFD_RELOC_ARM_THUMB_OFFSET:
5912       newval = md_chars_to_number (buf, THUMB_SIZE);
5913       /* Exactly what ranges, and where the offset is inserted depends on
5914          the type of instruction, we can establish this from the top 4 bits */
5915       switch (newval >> 12)
5916         {
5917         case 4: /* PC load */
5918           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5919              forced to zero for these loads, so we will need to round
5920              up the offset if the instruction address is not word
5921              aligned (since the final address produced must be, and
5922              we can only describe word-aligned immediate offsets).  */
5923
5924           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5925             as_bad_where (fixP->fx_file, fixP->fx_line,
5926                           _("Invalid offset, target not word aligned (0x%08X)"),
5927                           (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5928
5929           if ((value + 2) & ~0x3fe)
5930             as_bad_where (fixP->fx_file, fixP->fx_line,
5931                           _("Invalid offset, value too big (0x%08X)"), value);
5932
5933           /* Round up, since pc will be rounded down.  */
5934           newval |= (value + 2) >> 2;
5935           break;
5936
5937         case 9: /* SP load/store */
5938           if (value & ~0x3fc)
5939             as_bad_where (fixP->fx_file, fixP->fx_line,
5940                           _("Invalid offset, value too big (0x%08X)"), value);
5941           newval |= value >> 2;
5942           break;
5943
5944         case 6: /* Word load/store */
5945           if (value & ~0x7c)
5946             as_bad_where (fixP->fx_file, fixP->fx_line,
5947                           _("Invalid offset, value too big (0x%08X)"), value);
5948           newval |= value << 4; /* 6 - 2 */
5949           break;
5950
5951         case 7: /* Byte load/store */
5952           if (value & ~0x1f)
5953             as_bad_where (fixP->fx_file, fixP->fx_line,
5954                           _("Invalid offset, value too big (0x%08X)"), value);
5955           newval |= value << 6;
5956           break;
5957
5958         case 8: /* Halfword load/store */
5959           if (value & ~0x3e)
5960             as_bad_where (fixP->fx_file, fixP->fx_line,
5961                           _("Invalid offset, value too big (0x%08X)"), value);
5962           newval |= value << 5; /* 6 - 1 */
5963           break;
5964
5965         default:
5966           as_bad_where (fixP->fx_file, fixP->fx_line,
5967                         "Unable to process relocation for thumb opcode: %lx",
5968                         (unsigned long) newval);
5969           break;
5970         }
5971       md_number_to_chars (buf, newval, THUMB_SIZE);
5972       break;
5973
5974     case BFD_RELOC_ARM_THUMB_ADD:
5975       /* This is a complicated relocation, since we use it for all of
5976          the following immediate relocations:
5977             3bit ADD/SUB
5978             8bit ADD/SUB
5979             9bit ADD/SUB SP word-aligned
5980            10bit ADD PC/SP word-aligned
5981
5982          The type of instruction being processed is encoded in the
5983          instruction field:
5984            0x8000  SUB
5985            0x00F0  Rd
5986            0x000F  Rs
5987       */
5988       newval = md_chars_to_number (buf, THUMB_SIZE);
5989       {
5990         int rd = (newval >> 4) & 0xf;
5991         int rs = newval & 0xf;
5992         int subtract = newval & 0x8000;
5993
5994         if (rd == REG_SP)
5995           {
5996             if (value & ~0x1fc)
5997               as_bad_where (fixP->fx_file, fixP->fx_line,
5998                             _("Invalid immediate for stack address calculation"));
5999             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
6000             newval |= value >> 2;
6001           }
6002         else if (rs == REG_PC || rs == REG_SP)
6003           {
6004             if (subtract ||
6005                 value & ~0x3fc)
6006               as_bad_where (fixP->fx_file, fixP->fx_line,
6007                             _("Invalid immediate for address calculation (value = 0x%08lX)"),
6008                             (unsigned long) value);
6009             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
6010             newval |= rd << 8;
6011             newval |= value >> 2;
6012           }
6013         else if (rs == rd)
6014           {
6015             if (value & ~0xff)
6016               as_bad_where (fixP->fx_file, fixP->fx_line,
6017                             _("Invalid 8bit immediate"));
6018             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
6019             newval |= (rd << 8) | value;
6020           }
6021         else
6022           {
6023             if (value & ~0x7)
6024               as_bad_where (fixP->fx_file, fixP->fx_line,
6025                             _("Invalid 3bit immediate"));
6026             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
6027             newval |= rd | (rs << 3) | (value << 6);
6028           }
6029       }
6030       md_number_to_chars (buf, newval , THUMB_SIZE);
6031       break;
6032
6033     case BFD_RELOC_ARM_THUMB_IMM:
6034       newval = md_chars_to_number (buf, THUMB_SIZE);
6035       switch (newval >> 11)
6036         {
6037         case 0x04: /* 8bit immediate MOV */
6038         case 0x05: /* 8bit immediate CMP */
6039           if (value < 0 || value > 255)
6040             as_bad_where (fixP->fx_file, fixP->fx_line,
6041                           _("Invalid immediate: %ld is too large"),
6042                           (long) value);
6043           newval |= value;
6044           break;
6045
6046         default:
6047           abort ();
6048         }
6049       md_number_to_chars (buf, newval , THUMB_SIZE);
6050       break;
6051
6052     case BFD_RELOC_ARM_THUMB_SHIFT:
6053       /* 5bit shift value (0..31) */
6054       if (value < 0 || value > 31)
6055         as_bad_where (fixP->fx_file, fixP->fx_line,
6056                       _("Illegal Thumb shift value: %ld"), (long) value);
6057       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
6058       newval |= value << 6;
6059       md_number_to_chars (buf, newval , THUMB_SIZE);
6060       break;
6061
6062     case BFD_RELOC_VTABLE_INHERIT:
6063     case BFD_RELOC_VTABLE_ENTRY:
6064       fixP->fx_done = 0;
6065       return 1;
6066
6067     case BFD_RELOC_NONE:
6068     default:
6069       as_bad_where (fixP->fx_file, fixP->fx_line,
6070                     _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
6071     }
6072
6073   return 1;
6074 }
6075
6076 /* Translate internal representation of relocation info to BFD target
6077    format.  */
6078 arelent *
6079 tc_gen_reloc (section, fixp)
6080      asection * section ATTRIBUTE_UNUSED;
6081      fixS * fixp;
6082 {
6083   arelent * reloc;
6084   bfd_reloc_code_real_type code;
6085
6086   reloc = (arelent *) xmalloc (sizeof (arelent));
6087
6088   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6089   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6090   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6091
6092   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
6093 #ifndef OBJ_ELF
6094   if (fixp->fx_pcrel == 0)
6095     reloc->addend = fixp->fx_offset;
6096   else
6097     reloc->addend = fixp->fx_offset = reloc->address;
6098 #else  /* OBJ_ELF */
6099   reloc->addend = fixp->fx_offset;
6100 #endif
6101
6102   switch (fixp->fx_r_type)
6103     {
6104     case BFD_RELOC_8:
6105       if (fixp->fx_pcrel)
6106         {
6107           code = BFD_RELOC_8_PCREL;
6108           break;
6109         }
6110
6111     case BFD_RELOC_16:
6112       if (fixp->fx_pcrel)
6113         {
6114           code = BFD_RELOC_16_PCREL;
6115           break;
6116         }
6117
6118     case BFD_RELOC_32:
6119       if (fixp->fx_pcrel)
6120         {
6121           code = BFD_RELOC_32_PCREL;
6122           break;
6123         }
6124
6125     case BFD_RELOC_ARM_PCREL_BRANCH:
6126     case BFD_RELOC_ARM_PCREL_BLX:
6127     case BFD_RELOC_RVA:      
6128     case BFD_RELOC_THUMB_PCREL_BRANCH9:
6129     case BFD_RELOC_THUMB_PCREL_BRANCH12:
6130     case BFD_RELOC_THUMB_PCREL_BRANCH23:
6131     case BFD_RELOC_THUMB_PCREL_BLX:
6132     case BFD_RELOC_VTABLE_ENTRY:
6133     case BFD_RELOC_VTABLE_INHERIT:
6134       code = fixp->fx_r_type;
6135       break;
6136
6137     case BFD_RELOC_ARM_LITERAL:
6138     case BFD_RELOC_ARM_HWLITERAL:
6139       /* If this is called then the a literal has been referenced across
6140          a section boundary - possibly due to an implicit dump */
6141       as_bad_where (fixp->fx_file, fixp->fx_line,
6142                     _("Literal referenced across section boundary (Implicit dump?)"));
6143       return NULL;
6144
6145 #ifdef OBJ_ELF
6146     case BFD_RELOC_ARM_GOT32:
6147     case BFD_RELOC_ARM_GOTOFF:
6148     case BFD_RELOC_ARM_PLT32:
6149        code = fixp->fx_r_type;
6150     break;
6151 #endif
6152
6153     case BFD_RELOC_ARM_IMMEDIATE:
6154       as_bad_where (fixp->fx_file, fixp->fx_line,
6155                     _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6156                     fixp->fx_r_type);
6157       return NULL;
6158
6159     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6160       as_bad_where (fixp->fx_file, fixp->fx_line,
6161                     _("ADRL used for a symbol not defined in the same file"),
6162                     fixp->fx_r_type);
6163       return NULL;
6164
6165     case BFD_RELOC_ARM_OFFSET_IMM:
6166       as_bad_where (fixp->fx_file, fixp->fx_line,
6167                     _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6168                     fixp->fx_r_type);
6169       return NULL;
6170
6171     default:
6172       {
6173         char * type;
6174         switch (fixp->fx_r_type)
6175           {
6176           case BFD_RELOC_ARM_IMMEDIATE:    type = "IMMEDIATE";    break;
6177           case BFD_RELOC_ARM_OFFSET_IMM:   type = "OFFSET_IMM";   break;
6178           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
6179           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
6180           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
6181           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
6182           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
6183           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
6184           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
6185           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
6186           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
6187           default:                         type = _("<unknown>"); break;
6188           }
6189         as_bad_where (fixp->fx_file, fixp->fx_line,
6190                       _("Can not represent %s relocation in this object file format (%d)"),
6191                       type, fixp->fx_pcrel);
6192         return NULL;
6193       }
6194     }
6195
6196 #ifdef OBJ_ELF
6197  if (code == BFD_RELOC_32_PCREL
6198      && GOT_symbol
6199      && fixp->fx_addsy == GOT_symbol)
6200    {
6201      code = BFD_RELOC_ARM_GOTPC;
6202      reloc->addend = fixp->fx_offset = reloc->address;
6203    }
6204 #endif
6205    
6206   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6207
6208   if (reloc->howto == NULL)
6209     {
6210       as_bad_where (fixp->fx_file, fixp->fx_line,
6211                     _("Can not represent %s relocation in this object file format"),
6212                     bfd_get_reloc_code_name (code));
6213       return NULL;
6214     }
6215
6216    /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6217       vtable entry to be used in the relocation's section offset.  */
6218    if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6219      reloc->address = fixp->fx_offset;
6220
6221   return reloc;
6222 }
6223
6224 int
6225 md_estimate_size_before_relax (fragP, segtype)
6226      fragS * fragP ATTRIBUTE_UNUSED;
6227      segT    segtype ATTRIBUTE_UNUSED;
6228 {
6229   as_fatal (_("md_estimate_size_before_relax\n"));
6230   return 1;
6231 }
6232
6233 static void
6234 output_inst PARAMS ((void))
6235 {
6236   char * to = NULL;
6237     
6238   if (inst.error)
6239     {
6240       as_bad (inst.error);
6241       return;
6242     }
6243
6244   to = frag_more (inst.size);
6245   
6246   if (thumb_mode && (inst.size > THUMB_SIZE))
6247     {
6248       assert (inst.size == (2 * THUMB_SIZE));
6249       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6250       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6251     }
6252   else if (inst.size > INSN_SIZE)
6253     {
6254       assert (inst.size == (2 * INSN_SIZE));
6255       md_number_to_chars (to, inst.instruction, INSN_SIZE);
6256       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6257     }
6258   else
6259     md_number_to_chars (to, inst.instruction, inst.size);
6260
6261   if (inst.reloc.type != BFD_RELOC_NONE)
6262     fix_new_arm (frag_now, to - frag_now->fr_literal,
6263                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6264                  inst.reloc.type);
6265
6266   return;
6267 }
6268
6269 void
6270 md_assemble (str)
6271      char * str;
6272 {
6273   char   c;
6274   char * p;
6275   char * q;
6276   char * start;
6277
6278   /* Align the instruction.
6279      This may not be the right thing to do but ... */
6280   /* arm_align (2, 0); */
6281   listing_prev_line (); /* Defined in listing.h */
6282
6283   /* Align the previous label if needed.  */
6284   if (last_label_seen != NULL)
6285     {
6286       symbol_set_frag (last_label_seen, frag_now);
6287       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6288       S_SET_SEGMENT (last_label_seen, now_seg);
6289     }
6290
6291   memset (&inst, '\0', sizeof (inst));
6292   inst.reloc.type = BFD_RELOC_NONE;
6293
6294   skip_whitespace (str);
6295   
6296   /* Scan up to the end of the op-code, which must end in white space or
6297      end of string.  */
6298   for (start = p = str; *p != '\0'; p++)
6299     if (*p == ' ')
6300       break;
6301     
6302   if (p == str)
6303     {
6304       as_bad (_("No operator -- statement `%s'\n"), str);
6305       return;
6306     }
6307
6308   if (thumb_mode)
6309     {
6310       CONST struct thumb_opcode * opcode;
6311
6312       c = *p;
6313       *p = '\0';
6314       opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6315       *p = c;
6316       
6317       if (opcode)
6318         {
6319           /* Check that this instruction is supported for this CPU.  */
6320           if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
6321              {
6322                 as_bad (_("selected processor does not support this opcode"));
6323                 return;
6324              }
6325
6326           inst.instruction = opcode->value;
6327           inst.size = opcode->size;
6328           (*opcode->parms)(p);
6329           output_inst ();
6330           return;
6331         }
6332     }
6333   else
6334     {
6335       CONST struct asm_opcode * opcode;
6336       unsigned long cond_code;
6337
6338       inst.size = INSN_SIZE;
6339       /* p now points to the end of the opcode, probably white space, but we
6340          have to break the opcode up in case it contains condionals and flags;
6341          keep trying with progressively smaller basic instructions until one
6342          matches, or we run out of opcode.  */
6343       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6344
6345       for (; q != str; q--)
6346         {
6347           c = *q;
6348           *q = '\0';
6349
6350           opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6351           *q = c;
6352           
6353           if (opcode && opcode->template)
6354             {
6355               unsigned long flag_bits = 0;
6356               char * r;
6357
6358               /* Check that this instruction is supported for this CPU.  */
6359               if ((opcode->variants & cpu_variant) == 0)
6360                 goto try_shorter;
6361
6362               inst.instruction = opcode->value;
6363               if (q == p)               /* Just a simple opcode.  */
6364                 {
6365                   if (opcode->comp_suffix)
6366                     {
6367                        if (*opcode->comp_suffix != '\0')
6368                          as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6369                              str, opcode->comp_suffix);
6370                        else
6371                          /* Not a conditional instruction. */
6372                          (*opcode->parms)(q, 0);
6373                     }
6374                   else
6375                     {
6376                       /* A conditional instruction with default condition. */
6377                       inst.instruction |= COND_ALWAYS;
6378                       (*opcode->parms)(q, 0);
6379                     }
6380                   output_inst ();
6381                   return;
6382                 }
6383
6384               /* Not just a simple opcode.  Check if extra is a conditional. */
6385               r = q;
6386               if (p - r >= 2)
6387                 {
6388                   CONST struct asm_cond *cond;
6389                   char d = *(r + 2);
6390
6391                   *(r + 2) = '\0';
6392                   cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6393                   *(r + 2) = d;
6394                   if (cond)
6395                     {
6396                       if (cond->value == 0xf0000000)
6397                         as_tsktsk (
6398 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6399
6400                       cond_code = cond->value;
6401                       r += 2;
6402                     }
6403                   else
6404                     cond_code = COND_ALWAYS;
6405                 }
6406               else
6407                 cond_code = COND_ALWAYS;
6408
6409               /* Apply the conditional, or complain it's not allowed. */
6410               if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6411                 {
6412                    /* Instruction isn't conditional */
6413                    if (cond_code != COND_ALWAYS)
6414                      {
6415                        as_bad (_("Opcode `%s' is unconditional\n"), str);
6416                        return;
6417                      }
6418                 }
6419               else
6420                 /* Instruction is conditional: set the condition into it. */
6421                 inst.instruction |= cond_code;       
6422
6423
6424               /* If there is a compulsory suffix, it should come here, before
6425                  any optional flags.  */
6426               if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
6427                 {
6428                   CONST char *s = opcode->comp_suffix;
6429
6430                   while (*s)
6431                     {
6432                       inst.suffix++;
6433                       if (*r == *s)
6434                         break;
6435                       s++;
6436                     }
6437
6438                   if (*s == '\0')
6439                     {
6440                       as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6441                               opcode->comp_suffix);
6442                       return;
6443                     }
6444
6445                   r++;
6446                 }
6447
6448               /* The remainder, if any should now be flags for the instruction;
6449                  Scan these checking each one found with the opcode.  */
6450               if (r != p)
6451                 {
6452                   char d;
6453                   CONST struct asm_flg *flag = opcode->flags;
6454
6455                   if (flag)
6456                     {
6457                       int flagno;
6458
6459                       d = *p;
6460                       *p = '\0';
6461
6462                       for (flagno = 0; flag[flagno].template; flagno++)
6463                         {
6464                           if (streq (r, flag[flagno].template))
6465                             {
6466                               flag_bits |= flag[flagno].set_bits;
6467                               break;
6468                             }
6469                         }
6470
6471                       *p = d;
6472                       if (! flag[flagno].template)
6473                         goto try_shorter;
6474                     }
6475                   else
6476                     goto try_shorter;
6477                 }
6478
6479               (*opcode->parms) (p, flag_bits);
6480               output_inst ();
6481               return;
6482             }
6483
6484         try_shorter:
6485           ;
6486         }
6487     }
6488
6489   /* It wasn't an instruction, but it might be a register alias of the form
6490      alias .req reg */
6491   q = p;
6492   skip_whitespace (q);
6493
6494   c = *p;
6495   *p = '\0';
6496     
6497   if (*q && !strncmp (q, ".req ", 4))
6498     {
6499       int    reg;
6500       char * copy_of_str = str;
6501       char * r;
6502       
6503       q += 4;
6504       skip_whitespace (q);
6505
6506       for (r = q; *r != '\0'; r++)
6507         if (*r == ' ')
6508           break;
6509       
6510       if (r != q)
6511         {
6512           int regnum;
6513           char d = *r;
6514
6515           *r = '\0';
6516           regnum = arm_reg_parse (& q);
6517           *r = d;
6518
6519           reg = arm_reg_parse (& str);
6520           
6521           if (reg == FAIL)
6522             {
6523               if (regnum != FAIL)
6524                 insert_reg_alias (str, regnum);
6525               else
6526                 as_warn (_("register '%s' does not exist\n"), q);
6527             }
6528           else if (regnum != FAIL)
6529             {
6530               if (reg != regnum)
6531                 as_warn (_("ignoring redefinition of register alias '%s'"),
6532                          copy_of_str );
6533               
6534               /* Do not warn about redefinitions to the same alias.  */
6535             }
6536           else
6537             as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6538                      copy_of_str, q);
6539         }
6540       else
6541         as_warn (_("ignoring incomplete .req pseuso op"));
6542       
6543       *p = c;
6544       return;
6545     }
6546
6547   *p = c;
6548   as_bad (_("bad instruction `%s'"), start);
6549 }
6550
6551 /*
6552  * md_parse_option
6553  *    Invocation line includes a switch not recognized by the base assembler.
6554  *    See if it's a processor-specific option.  These are:
6555  *    Cpu variants, the arm part is optional:
6556  *            -m[arm]1                Currently not supported.
6557  *            -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
6558  *            -m[arm]3                Arm 3 processor
6559  *            -m[arm]6[xx],           Arm 6 processors
6560  *            -m[arm]7[xx][t][[d]m]   Arm 7 processors
6561  *            -m[arm]8[10]            Arm 8 processors
6562  *            -m[arm]9[20][tdmi]      Arm 9 processors
6563  *            -mstrongarm[110[0]]     StrongARM processors
6564  *            -m[arm]v[2345[t]]       Arm architectures
6565  *            -mall                   All (except the ARM1)
6566  *    FP variants:
6567  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
6568  *            -mfpe-old               (No float load/store multiples)
6569  *            -mno-fpu                Disable all floating point instructions
6570  *    Run-time endian selection:
6571  *            -EB                     big endian cpu
6572  *            -EL                     little endian cpu
6573  *    ARM Procedure Calling Standard:
6574  *            -mapcs-32               32 bit APCS
6575  *            -mapcs-26               26 bit APCS
6576  *            -mapcs-float            Pass floats in float regs
6577  *            -mapcs-reentrant        Position independent code
6578  *            -mthumb-interwork       Code supports Arm/Thumb interworking
6579  *            -moabi                  Old ELF ABI
6580  */
6581
6582 CONST char * md_shortopts = "m:k";
6583 struct option md_longopts[] =
6584 {
6585 #ifdef ARM_BI_ENDIAN
6586 #define OPTION_EB (OPTION_MD_BASE + 0)
6587   {"EB", no_argument, NULL, OPTION_EB},
6588 #define OPTION_EL (OPTION_MD_BASE + 1)
6589   {"EL", no_argument, NULL, OPTION_EL},
6590 #ifdef OBJ_ELF
6591 #define OPTION_OABI (OPTION_MD_BASE +2)
6592   {"oabi", no_argument, NULL, OPTION_OABI},
6593 #endif
6594 #endif
6595   {NULL, no_argument, NULL, 0}
6596 };
6597 size_t md_longopts_size = sizeof (md_longopts);
6598
6599 int
6600 md_parse_option (c, arg)
6601      int    c;
6602      char * arg;
6603 {
6604   char * str = arg;
6605
6606   switch (c)
6607     {
6608 #ifdef ARM_BI_ENDIAN
6609     case OPTION_EB:
6610       target_big_endian = 1;
6611       break;
6612     case OPTION_EL:
6613       target_big_endian = 0;
6614       break;
6615 #endif
6616
6617     case 'm':
6618       switch (*str)
6619         {
6620         case 'f':
6621           if (streq (str, "fpa10"))
6622             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6623           else if (streq (str, "fpa11"))
6624             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6625           else if (streq (str, "fpe-old"))
6626             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6627           else
6628             goto bad;
6629           break;
6630
6631         case 'n':
6632           if (streq (str, "no-fpu"))
6633             cpu_variant &= ~FPU_ALL;
6634           break;
6635
6636 #ifdef OBJ_ELF
6637         case 'o':
6638           if (streq (str, "oabi"))
6639             target_oabi = true;
6640           break;
6641 #endif
6642           
6643         case 't':
6644           /* Limit assembler to generating only Thumb instructions: */
6645           if (streq (str, "thumb"))
6646             {
6647               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6648               cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6649               thumb_mode = 1;
6650             }
6651           else if (streq (str, "thumb-interwork"))
6652             {
6653               if ((cpu_variant & ARM_THUMB) == 0)
6654                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
6655 #if defined OBJ_COFF || defined OBJ_ELF
6656               support_interwork = true;
6657 #endif
6658             }
6659           else
6660             goto bad;
6661           break;
6662
6663         default:
6664           if (streq (str, "all"))
6665             {
6666               cpu_variant = ARM_ALL | FPU_ALL;
6667               return 1;
6668             }
6669 #if defined OBJ_COFF || defined OBJ_ELF
6670           if (! strncmp (str, "apcs-", 5))
6671             {
6672               /* GCC passes on all command line options starting "-mapcs-..."
6673                  to us, so we must parse them here.  */
6674
6675               str += 5;
6676               
6677               if (streq (str, "32"))
6678                 {
6679                   uses_apcs_26 = false;
6680                   return 1;
6681                 }
6682               else if (streq (str, "26"))
6683                 {
6684                   uses_apcs_26 = true;
6685                   return 1;
6686                 }
6687               else if (streq (str, "frame"))
6688                 {
6689                   /* Stack frames are being generated - does not affect
6690                      linkage of code.  */
6691                   return 1;
6692                 }
6693               else if (streq (str, "stack-check"))
6694                 {
6695                   /* Stack checking is being performed - does not affect
6696                      linkage, but does require that the functions
6697                      __rt_stkovf_split_small and __rt_stkovf_split_big be
6698                      present in the final link.  */
6699
6700                   return 1;
6701                 }
6702               else if (streq (str, "float"))
6703                 {
6704                   /* Floating point arguments are being passed in the floating
6705                      point registers.  This does affect linking, since this
6706                      version of the APCS is incompatible with the version that
6707                      passes floating points in the integer registers.  */
6708
6709                   uses_apcs_float = true;
6710                   return 1;
6711                 }
6712               else if (streq (str, "reentrant"))
6713                 {
6714                   /* Reentrant code has been generated.  This does affect
6715                      linking, since there is no point in linking reentrant/
6716                      position independent code with absolute position code. */
6717                   pic_code = true;
6718                   return 1;
6719                 }
6720               
6721               as_bad (_("Unrecognised APCS switch -m%s"), arg);
6722               return 0;
6723             }
6724 #endif
6725           /* Strip off optional "arm" */
6726           if (! strncmp (str, "arm", 3))
6727             str += 3;
6728
6729           switch (*str)
6730             {
6731             case '1':
6732               if (streq (str, "1"))
6733                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6734               else
6735                 goto bad;
6736               break;
6737
6738             case '2':
6739               if (streq (str, "2"))
6740                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6741               else if (streq (str, "250"))
6742                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6743               else
6744                 goto bad;
6745               break;
6746
6747             case '3':
6748               if (streq (str, "3"))
6749                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6750               else
6751                 goto bad;
6752               break;
6753
6754             case '6':
6755               switch (strtol (str, NULL, 10))
6756                 {
6757                 case 6:
6758                 case 60:
6759                 case 600:
6760                 case 610:
6761                 case 620:
6762                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6763                   break;
6764                 default:
6765                   goto bad;
6766                 }
6767               break;
6768
6769             case '7':
6770               switch (strtol (str, & str, 10))  /* Eat the processor name */
6771                 {
6772                 case 7:
6773                 case 70:
6774                 case 700:
6775                 case 710:
6776                 case 720:
6777                 case 7100:
6778                 case 7500:
6779                   break;
6780                 default:
6781                   goto bad;
6782                 }
6783               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6784               for (; *str; str++)
6785                 {
6786                 switch (* str)
6787                   {
6788                   case 't':
6789                     cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6790                     break;
6791
6792                   case 'm':
6793                     cpu_variant |= ARM_LONGMUL;
6794                     break;
6795
6796                   case 'f': /* fe => fp enabled cpu.  */
6797                     if (str[1] == 'e')
6798                       ++ str;
6799                     else
6800                       goto bad;
6801                     
6802                   case 'c': /* Left over from 710c processor name.  */
6803                   case 'd': /* Debug */
6804                   case 'i': /* Embedded ICE */
6805                     /* Included for completeness in ARM processor naming. */
6806                     break;
6807
6808                   default:
6809                     goto bad;
6810                   }
6811                 }
6812               break;
6813
6814             case '8':
6815               if (streq (str, "8") || streq (str, "810"))
6816                 cpu_variant = (cpu_variant & ~ARM_ANY)
6817                   | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6818               else
6819                 goto bad;
6820               break;
6821               
6822             case '9':
6823               if (streq (str, "9"))
6824                 cpu_variant = (cpu_variant & ~ARM_ANY)
6825                   | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6826               else if (streq (str, "920"))
6827                 cpu_variant = (cpu_variant & ~ARM_ANY)
6828                   | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6829               else if (streq (str, "920t"))
6830                 cpu_variant = (cpu_variant & ~ARM_ANY)
6831                   | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6832               else if (streq (str, "9tdmi"))
6833                 cpu_variant = (cpu_variant & ~ARM_ANY)
6834                   | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6835               else
6836                 goto bad;
6837               break;
6838
6839               
6840             case 's':
6841               if (streq (str, "strongarm")
6842                   || streq (str, "strongarm110")
6843                   || streq (str, "strongarm1100"))
6844                 cpu_variant = (cpu_variant & ~ARM_ANY)
6845                   | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6846               else
6847                 goto bad;
6848               break;
6849                 
6850             case 'v':
6851               /* Select variant based on architecture rather than processor.  */
6852               switch (*++str)
6853                 {
6854                 case '2':
6855                   switch (*++str)
6856                     {
6857                     case 'a':
6858                       cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6859                       break;
6860                     case 0:
6861                       cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6862                       break;
6863                     default:
6864                       as_bad (_("Invalid architecture variant -m%s"), arg);
6865                       break;
6866                     }
6867                   break;
6868                   
6869                 case '3':
6870                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6871                     
6872                   switch (*++str)
6873                     {
6874                     case 'm': cpu_variant |= ARM_LONGMUL; break;
6875                     case 0:   break;
6876                     default:
6877                       as_bad (_("Invalid architecture variant -m%s"), arg);
6878                       break;
6879                     }
6880                   break;
6881                   
6882                 case '4':
6883                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6884                   
6885                   switch (*++str)
6886                     {
6887                     case 't': cpu_variant |= ARM_THUMB; break;
6888                     case 0:   break;
6889                     default:
6890                       as_bad (_("Invalid architecture variant -m%s"), arg);
6891                       break;
6892                     }
6893                   break;
6894
6895                 case '5':
6896                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6897                   switch (*++str)
6898                     {
6899                     case 't': cpu_variant |= ARM_THUMB; break;
6900                     case 0:   break;
6901                     default:
6902                       as_bad (_("Invalid architecture variant -m%s"), arg);
6903                       break;
6904                     }
6905                   break;
6906                   
6907                 default:
6908                   as_bad (_("Invalid architecture variant -m%s"), arg);
6909                   break;
6910                 }
6911               break;
6912               
6913             default:
6914             bad:
6915               as_bad (_("Invalid processor variant -m%s"), arg);
6916               return 0;
6917             }
6918         }
6919       break;
6920
6921 #if defined OBJ_ELF || defined OBJ_COFF
6922     case 'k':
6923       pic_code = 1;
6924       break;
6925 #endif
6926       
6927     default:
6928       return 0;
6929     }
6930
6931    return 1;
6932 }
6933
6934 void
6935 md_show_usage (fp)
6936      FILE * fp;
6937 {
6938   fprintf (fp, _("\
6939  ARM Specific Assembler Options:\n\
6940   -m[arm][<processor name>] select processor variant\n\
6941   -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6942   -mthumb                   only allow Thumb instructions\n\
6943   -mthumb-interwork         mark the assembled code as supporting interworking\n\
6944   -mall                     allow any instruction\n\
6945   -mfpa10, -mfpa11          select floating point architecture\n\
6946   -mfpe-old                 don't allow floating-point multiple instructions\n\
6947   -mno-fpu                  don't allow any floating-point instructions.\n\
6948   -k                        generate PIC code.\n"));
6949 #if defined OBJ_COFF || defined OBJ_ELF
6950   fprintf (fp, _("\
6951   -mapcs-32, -mapcs-26      specify which ARM Procedure Calling Standard to use\n\
6952   -mapcs-float              floating point args are passed in FP regs\n\
6953   -mapcs-reentrant          the code is position independent/reentrant\n"));
6954   #endif
6955 #ifdef OBJ_ELF
6956   fprintf (fp, _("\
6957   -moabi                    support the old ELF ABI\n"));
6958 #endif
6959 #ifdef ARM_BI_ENDIAN
6960   fprintf (fp, _("\
6961   -EB                       assemble code for a big endian cpu\n\
6962   -EL                       assemble code for a little endian cpu\n"));
6963 #endif
6964 }
6965
6966 /* We need to be able to fix up arbitrary expressions in some statements.
6967    This is so that we can handle symbols that are an arbitrary distance from
6968    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6969    which returns part of an address in a form which will be valid for
6970    a data instruction.  We do this by pushing the expression into a symbol
6971    in the expr_section, and creating a fix for that.  */
6972
6973 static void
6974 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6975      fragS *       frag;
6976      int           where;
6977      short int     size;
6978      expressionS * exp;
6979      int           pc_rel;
6980      int           reloc;
6981 {
6982   fixS *         new_fix;
6983   arm_fix_data * arm_data;
6984
6985   switch (exp->X_op)
6986     {
6987     case O_constant:
6988     case O_symbol:
6989     case O_add:
6990     case O_subtract:
6991       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6992       break;
6993
6994     default:
6995       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6996                          pc_rel, reloc);
6997       break;
6998     }
6999
7000   /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
7001   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
7002   new_fix->tc_fix_data = (PTR) arm_data;
7003   arm_data->thumb_mode = thumb_mode;
7004
7005   return;
7006 }
7007
7008
7009 /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
7010 void
7011 cons_fix_new_arm (frag, where, size, exp)
7012      fragS *       frag;
7013      int           where;
7014      int           size;
7015      expressionS * exp;
7016 {
7017   bfd_reloc_code_real_type type;
7018   int pcrel = 0;
7019
7020   /* Pick a reloc.
7021      FIXME: @@ Should look at CPU word size.  */
7022   switch (size) 
7023     {
7024     case 1:
7025       type = BFD_RELOC_8;
7026       break;
7027     case 2:
7028       type = BFD_RELOC_16;
7029       break;
7030     case 4:
7031     default:
7032       type = BFD_RELOC_32;
7033       break;
7034     case 8:
7035       type = BFD_RELOC_64;
7036       break;
7037     }
7038   
7039   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
7040 }
7041
7042 /* A good place to do this, although this was probably not intended
7043    for this kind of use.  We need to dump the literal pool before
7044    references are made to a null symbol pointer.  */
7045 void
7046 arm_cleanup ()
7047 {
7048   if (current_poolP == NULL)
7049     return;
7050   
7051   subseg_set (text_section, 0); /* Put it at the end of text section.  */
7052   s_ltorg (0);
7053   listing_prev_line ();
7054 }
7055
7056 void
7057 arm_start_line_hook ()
7058 {
7059   last_label_seen = NULL;
7060 }
7061
7062 void
7063 arm_frob_label (sym)
7064      symbolS * sym;
7065 {
7066   last_label_seen = sym;
7067   
7068   ARM_SET_THUMB (sym, thumb_mode);
7069   
7070 #if defined OBJ_COFF || defined OBJ_ELF
7071   ARM_SET_INTERWORK (sym, support_interwork);
7072 #endif
7073   
7074   if (label_is_thumb_function_name)
7075     {
7076       /* When the address of a Thumb function is taken the bottom
7077          bit of that address should be set.  This will allow
7078          interworking between Arm and Thumb functions to work
7079          correctly.  */
7080
7081       THUMB_SET_FUNC (sym, 1);
7082       
7083       label_is_thumb_function_name = false;
7084     }
7085 }
7086
7087 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
7088    ARM ones.  */
7089
7090 void
7091 arm_adjust_symtab ()
7092 {
7093 #ifdef OBJ_COFF
7094   symbolS * sym;
7095
7096   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
7097     {
7098       if (ARM_IS_THUMB (sym))
7099         {
7100           if (THUMB_IS_FUNC (sym))
7101             {
7102               /* Mark the symbol as a Thumb function.  */
7103               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
7104                   || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
7105                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
7106
7107               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
7108                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
7109               else
7110                 as_bad (_("%s: unexpected function type: %d"),
7111                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
7112             }
7113           else switch (S_GET_STORAGE_CLASS (sym))
7114             {
7115               case C_EXT:
7116                 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
7117                 break;
7118               case C_STAT:
7119                 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
7120                 break;
7121               case C_LABEL:
7122                 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
7123                 break;
7124               default: /* do nothing */ 
7125                 break;
7126             }
7127         }
7128
7129       if (ARM_IS_INTERWORK (sym))
7130         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
7131     }
7132 #endif
7133 #ifdef OBJ_ELF
7134   symbolS *         sym;
7135   char              bind;
7136
7137   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
7138     {
7139       if (ARM_IS_THUMB (sym))
7140         {
7141           elf_symbol_type * elf_sym;
7142           
7143           elf_sym = elf_symbol (symbol_get_bfdsym (sym));
7144           bind = ELF_ST_BIND (elf_sym);
7145           
7146           /* If it's a .thumb_func, declare it as so,
7147              otherwise tag label as .code 16.  */
7148           if (THUMB_IS_FUNC (sym))
7149             elf_sym->internal_elf_sym.st_info =
7150               ELF_ST_INFO (bind, STT_ARM_TFUNC);
7151           else
7152             elf_sym->internal_elf_sym.st_info =
7153               ELF_ST_INFO (bind, STT_ARM_16BIT);
7154          }
7155      }
7156 #endif
7157 }
7158
7159 int
7160 arm_data_in_code ()
7161 {
7162   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
7163     {
7164       *input_line_pointer = '/';
7165       input_line_pointer += 5;
7166       *input_line_pointer = 0;
7167       return 1;
7168     }
7169   
7170   return 0;
7171 }
7172
7173 char *
7174 arm_canonicalize_symbol_name (name)
7175      char * name;
7176 {
7177   int len;
7178
7179   if (thumb_mode && (len = strlen (name)) > 5
7180       && streq (name + len - 5, "/data"))
7181     *(name + len - 5) = 0;
7182
7183   return name;
7184 }
7185
7186 boolean
7187 arm_validate_fix (fixP)
7188      fixS * fixP;
7189 {
7190   /* If the destination of the branch is a defined symbol which does not have
7191      the THUMB_FUNC attribute, then we must be calling a function which has
7192      the (interfacearm) attribute.  We look for the Thumb entry point to that
7193      function and change the branch to refer to that function instead.  */
7194   if (   fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
7195       && fixP->fx_addsy != NULL
7196       && S_IS_DEFINED (fixP->fx_addsy)
7197       && ! THUMB_IS_FUNC (fixP->fx_addsy))
7198     {
7199       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
7200       return true;
7201     }
7202
7203   return false;
7204 }
7205
7206 #ifdef OBJ_ELF
7207 /* Relocations against Thumb function names must be left unadjusted,
7208    so that the linker can use this information to correctly set the
7209    bottom bit of their addresses.  The MIPS version of this function
7210    also prevents relocations that are mips-16 specific, but I do not
7211    know why it does this.
7212
7213    FIXME:
7214    There is one other problem that ought to be addressed here, but
7215    which currently is not:  Taking the address of a label (rather
7216    than a function) and then later jumping to that address.  Such
7217    addresses also ought to have their bottom bit set (assuming that
7218    they reside in Thumb code), but at the moment they will not.  */
7219    
7220 boolean
7221 arm_fix_adjustable (fixP)
7222    fixS * fixP;
7223 {
7224   if (fixP->fx_addsy == NULL)
7225     return 1;
7226   
7227   /* Prevent all adjustments to global symbols. */
7228   if (S_IS_EXTERN (fixP->fx_addsy))
7229     return 0;
7230   
7231   if (S_IS_WEAK (fixP->fx_addsy))
7232     return 0;
7233
7234   if (THUMB_IS_FUNC (fixP->fx_addsy)
7235       && fixP->fx_subsy == NULL)
7236     return 0;
7237   
7238   /* We need the symbol name for the VTABLE entries */
7239   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7240       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7241     return 0;
7242
7243   return 1;
7244 }
7245
7246 const char *
7247 elf32_arm_target_format ()
7248 {
7249   if (target_big_endian)
7250     if (target_oabi)
7251       return "elf32-bigarm-oabi";
7252     else
7253       return "elf32-bigarm";
7254   else
7255     if (target_oabi)
7256       return "elf32-littlearm-oabi";
7257     else
7258       return "elf32-littlearm";
7259 }
7260
7261 void
7262 armelf_frob_symbol (symp, puntp)
7263      symbolS * symp;
7264      int * puntp;
7265 {
7266   elf_frob_symbol (symp, puntp);
7267
7268
7269 int
7270 arm_force_relocation (fixp)
7271      struct fix * fixp;
7272 {
7273   if (   fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7274       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7275       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7276       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
7277       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
7278       || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)    
7279     return 1;
7280   
7281   return 0;
7282 }
7283
7284 static bfd_reloc_code_real_type
7285 arm_parse_reloc ()
7286 {
7287   char   id[16];
7288   char * ip;
7289   unsigned int i;
7290   static struct
7291   {
7292     char * str;
7293     int    len;
7294     bfd_reloc_code_real_type reloc;
7295   }
7296   reloc_map[] =
7297   {
7298 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7299     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
7300     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7301     /* ScottB: Jan 30, 1998 */
7302     /* Added support for parsing "var(PLT)" branch instructions */
7303     /* generated by GCC for PLT relocs */
7304     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
7305     { NULL, 0,         BFD_RELOC_UNUSED }
7306 #undef MAP    
7307   };
7308
7309   for (i = 0, ip = input_line_pointer;
7310        i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7311        i++, ip++)
7312     id[i] = tolower (*ip);
7313   
7314   for (i = 0; reloc_map[i].str; i++)
7315     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7316       break;
7317   
7318   input_line_pointer += reloc_map[i].len;
7319   
7320   return reloc_map[i].reloc;
7321 }
7322
7323 static void
7324 s_arm_elf_cons (nbytes)
7325      int nbytes;
7326 {
7327   expressionS exp;
7328
7329 #ifdef md_flush_pending_output
7330   md_flush_pending_output ();
7331 #endif
7332
7333   if (is_it_end_of_statement ())
7334     {
7335       demand_empty_rest_of_line ();
7336       return;
7337     }
7338
7339 #ifdef md_cons_align
7340   md_cons_align (nbytes);
7341 #endif
7342
7343   do
7344     {
7345       bfd_reloc_code_real_type reloc;
7346       
7347       expression (& exp);
7348
7349       if (exp.X_op == O_symbol
7350           && * input_line_pointer == '('
7351           && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7352         {
7353           reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7354           int size = bfd_get_reloc_size (howto);
7355
7356           if (size > nbytes)
7357             as_bad ("%s relocations do not fit in %d bytes",
7358                     howto->name, nbytes);
7359           else
7360             {
7361               register char * p = frag_more ((int) nbytes);
7362               int offset = nbytes - size;
7363
7364               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7365                            & exp, 0, reloc);
7366             }
7367         }
7368       else
7369         emit_expr (& exp, (unsigned int) nbytes);
7370     }
7371   while (*input_line_pointer++ == ',');
7372
7373   input_line_pointer--;         /* Put terminator back into stream.  */
7374   demand_empty_rest_of_line ();
7375 }
7376
7377 #endif /* OBJ_ELF */