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