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