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