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