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