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