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