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