Add support for armv5 architecture
[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
5040     bfd_set_private_flags (stdoutput, flags);
5041   }
5042 #endif
5043   
5044   {
5045     unsigned mach;
5046     
5047     /* Record the CPU type as well */
5048     switch (cpu_variant & ARM_CPU_MASK)
5049       {
5050       case ARM_2:
5051         mach = bfd_mach_arm_2;
5052         break;
5053         
5054       case ARM_3: /* also ARM_250 */
5055         mach = bfd_mach_arm_2a;
5056         break;
5057
5058       default:
5059       case ARM_6 | ARM_3 | ARM_2:       /* Actually no CPU type defined */
5060         mach = bfd_mach_arm_4;
5061         break;
5062         
5063       case ARM_7:                       /* also ARM_6 */
5064         mach = bfd_mach_arm_3;
5065         break;
5066       }
5067
5068     /* Catch special cases */
5069     if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5070       {
5071         if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5072           mach = bfd_mach_arm_5T;
5073         else if (cpu_variant & ARM_EXT_V5)
5074           mach = bfd_mach_arm_5;
5075         else if (cpu_variant & ARM_THUMB)
5076           mach = bfd_mach_arm_4T;
5077         else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5078           mach = bfd_mach_arm_4;
5079         else if (cpu_variant & ARM_LONGMUL)
5080           mach = bfd_mach_arm_3M;
5081       }
5082         
5083     bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5084   }
5085 }
5086
5087 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5088    for use in the a.out file, and stores them in the array pointed to by buf.
5089    This knows about the endian-ness of the target machine and does
5090    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
5091    2 (short) and 4 (long)  Floating numbers are put out as a series of
5092    LITTLENUMS (shorts, here at least)
5093    */
5094 void
5095 md_number_to_chars (buf, val, n)
5096      char * buf;
5097      valueT val;
5098      int    n;
5099 {
5100   if (target_big_endian)
5101     number_to_chars_bigendian (buf, val, n);
5102   else
5103     number_to_chars_littleendian (buf, val, n);
5104 }
5105
5106 static valueT 
5107 md_chars_to_number (buf, n)
5108      char * buf;
5109      int n;
5110 {
5111   valueT result = 0;
5112   unsigned char * where = (unsigned char *) buf;
5113
5114   if (target_big_endian)
5115     {
5116       while (n--)
5117         {
5118           result <<= 8;
5119           result |= (*where++ & 255);
5120         }
5121     }
5122   else
5123     {
5124       while (n--)
5125         {
5126           result <<= 8;
5127           result |= (where[n] & 255);
5128         }
5129     }
5130
5131   return result;
5132 }
5133
5134 /* Turn a string in input_line_pointer into a floating point constant
5135    of type TYPE, and store the appropriate bytes in *litP.  The number
5136    of LITTLENUMS emitted is stored in *sizeP .  An error message is
5137    returned, or NULL on OK.
5138
5139    Note that fp constants aren't represent in the normal way on the ARM.
5140    In big endian mode, things are as expected.  However, in little endian
5141    mode fp constants are big-endian word-wise, and little-endian byte-wise
5142    within the words.  For example, (double) 1.1 in big endian mode is
5143    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5144    the byte sequence 99 99 f1 3f 9a 99 99 99.
5145
5146    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
5147
5148 char *
5149 md_atof (type, litP, sizeP)
5150      char   type;
5151      char * litP;
5152      int *  sizeP;
5153 {
5154   int prec;
5155   LITTLENUM_TYPE words[MAX_LITTLENUMS];
5156   char *t;
5157   int i;
5158
5159   switch (type)
5160     {
5161     case 'f':
5162     case 'F':
5163     case 's':
5164     case 'S':
5165       prec = 2;
5166       break;
5167
5168     case 'd':
5169     case 'D':
5170     case 'r':
5171     case 'R':
5172       prec = 4;
5173       break;
5174
5175     case 'x':
5176     case 'X':
5177       prec = 6;
5178       break;
5179
5180     case 'p':
5181     case 'P':
5182       prec = 6;
5183       break;
5184
5185     default:
5186       *sizeP = 0;
5187       return _("Bad call to MD_ATOF()");
5188     }
5189
5190   t = atof_ieee (input_line_pointer, type, words);
5191   if (t)
5192     input_line_pointer = t;
5193   *sizeP = prec * 2;
5194
5195   if (target_big_endian)
5196     {
5197       for (i = 0; i < prec; i++)
5198         {
5199           md_number_to_chars (litP, (valueT) words[i], 2);
5200           litP += 2;
5201         }
5202     }
5203   else
5204     {
5205       /* For a 4 byte float the order of elements in `words' is 1 0.  For an
5206          8 byte float the order is 1 0 3 2.  */
5207       for (i = 0; i < prec; i += 2)
5208         {
5209           md_number_to_chars (litP, (valueT) words[i + 1], 2);
5210           md_number_to_chars (litP + 2, (valueT) words[i], 2);
5211           litP += 4;
5212         }
5213     }
5214
5215   return 0;
5216 }
5217
5218 /* The knowledge of the PC's pipeline offset is built into the insns themselves.  */ 
5219 long
5220 md_pcrel_from (fixP)
5221      fixS * fixP;
5222 {
5223   if (   fixP->fx_addsy
5224       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5225       && fixP->fx_subsy == NULL)
5226     return 0;
5227   
5228   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5229     {
5230       /* PC relative addressing on the Thumb is slightly odd
5231          as the bottom two bits of the PC are forced to zero
5232          for the calculation */
5233       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5234     }
5235
5236   return fixP->fx_where + fixP->fx_frag->fr_address;
5237 }
5238
5239 /* Round up a section size to the appropriate boundary. */
5240 valueT
5241 md_section_align (segment, size)
5242      segT   segment;
5243      valueT size;
5244 {
5245 #ifdef OBJ_ELF
5246   /* Don't align the dwarf2 debug sections */
5247   if (!strncmp (segment->name, ".debug", 5))
5248     return size;
5249 #endif
5250   /* Round all sects to multiple of 4 */
5251   return (size + 3) & ~3;
5252 }
5253
5254 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.  Otherwise 
5255    we have no need to default values of symbols.  */
5256
5257 /* ARGSUSED */
5258 symbolS *
5259 md_undefined_symbol (name)
5260      char * name;
5261 {
5262 #ifdef OBJ_ELF
5263   if (name[0] == '_' && name[1] == 'G'
5264       && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5265     {
5266       if (!GOT_symbol)
5267         {
5268           if (symbol_find (name))
5269             as_bad ("GOT already in the symbol table");
5270           
5271           GOT_symbol = symbol_new (name, undefined_section,
5272                                    (valueT)0, & zero_address_frag);
5273         }
5274       
5275       return GOT_symbol;
5276     }
5277 #endif
5278   
5279   return 0;
5280 }
5281
5282 /* arm_reg_parse () := if it looks like a register, return its token and 
5283    advance the pointer. */
5284
5285 static int
5286 arm_reg_parse (ccp)
5287      register char ** ccp;
5288 {
5289   char * start = * ccp;
5290   char   c;
5291   char * p;
5292   struct reg_entry * reg;
5293
5294 #ifdef REGISTER_PREFIX
5295   if (*start != REGISTER_PREFIX)
5296     return FAIL;
5297   p = start + 1;
5298 #else
5299   p = start;
5300 #ifdef OPTIONAL_REGISTER_PREFIX
5301   if (*p == OPTIONAL_REGISTER_PREFIX)
5302     p++, start++;
5303 #endif
5304 #endif
5305   if (!isalpha (*p) || !is_name_beginner (*p))
5306     return FAIL;
5307
5308   c = *p++;
5309   while (isalpha (c) || isdigit (c) || c == '_')
5310     c = *p++;
5311
5312   *--p = 0;
5313   reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5314   *p = c;
5315   
5316   if (reg)
5317     {
5318       *ccp = p;
5319       return reg->number;
5320     }
5321
5322   return FAIL;
5323 }
5324
5325 static int
5326 arm_psr_parse (ccp)
5327      register char ** ccp;
5328 {
5329   char * start = * ccp;
5330   char   c;
5331   char * p;
5332   CONST struct asm_psr * psr;
5333
5334   p = start;
5335   c = *p++;
5336   while (isalpha (c) || c == '_')
5337     c = *p++;
5338
5339   *--p = 0;  
5340   psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5341   *p = c;
5342
5343   if (psr)
5344     {
5345       *ccp = p;
5346       return psr->number;
5347     }
5348
5349   return FAIL;
5350 }
5351
5352 int
5353 md_apply_fix3 (fixP, val, seg)
5354      fixS *      fixP;
5355      valueT *    val;
5356      segT        seg;
5357 {
5358   offsetT        value = * val;
5359   offsetT        newval;
5360   unsigned int   newimm;
5361   unsigned long  temp;
5362   int            sign;
5363   char *         buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5364   arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5365
5366   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5367
5368   /* Note whether this will delete the relocation.  */
5369 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5370   if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5371       && !fixP->fx_pcrel)
5372 #else
5373   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5374 #endif
5375     fixP->fx_done = 1;
5376
5377   /* If this symbol is in a different section then we need to leave it for
5378      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
5379      so we have to undo it's effects here.  */
5380   if (fixP->fx_pcrel)
5381     {
5382       if (fixP->fx_addsy != NULL
5383           && S_IS_DEFINED (fixP->fx_addsy)
5384           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5385         {
5386           if (target_oabi
5387               && fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5388             value = 0;
5389           else
5390             value += md_pcrel_from (fixP);
5391         }
5392     }
5393
5394   fixP->fx_addnumber = value;   /* Remember value for emit_reloc */
5395
5396   switch (fixP->fx_r_type)
5397     {
5398     case BFD_RELOC_ARM_IMMEDIATE:
5399       newimm = validate_immediate (value);
5400       temp = md_chars_to_number (buf, INSN_SIZE);
5401
5402       /* If the instruction will fail, see if we can fix things up by
5403          changing the opcode.  */
5404       if (newimm == (unsigned int) FAIL
5405           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5406         {
5407           as_bad_where (fixP->fx_file, fixP->fx_line,
5408                         _("invalid constant (%lx) after fixup\n"),
5409                         (unsigned long) value);
5410           break;
5411         }
5412
5413       newimm |= (temp & 0xfffff000);
5414       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5415       break;
5416
5417     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5418       {
5419         unsigned int highpart = 0;
5420         unsigned int newinsn  = 0xe1a00000; /* nop */
5421         newimm = validate_immediate (value);
5422         temp = md_chars_to_number (buf, INSN_SIZE);
5423
5424         /* If the instruction will fail, see if we can fix things up by
5425            changing the opcode.  */
5426         if (newimm == (unsigned int) FAIL
5427             && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5428           {
5429             /* No ?  OK - try using two ADD instructions to generate the value.  */
5430             newimm = validate_immediate_twopart (value, & highpart);
5431
5432             /* Yes - then make sure that the second instruction is also an add.  */
5433             if (newimm != (unsigned int) FAIL)
5434               newinsn = temp;
5435             /* Still No ?  Try using a negated value.  */
5436             else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5437                 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5438             /* Otherwise - give up.  */
5439             else
5440               {
5441                 as_bad_where (fixP->fx_file, fixP->fx_line,
5442                               _("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value);
5443                 break;
5444               }
5445
5446             /* Replace the first operand in the 2nd instruction (which is the PC)
5447                with the destination register.  We have already added in the PC in the
5448                first instruction and we do not want to do it again.  */
5449             newinsn &= ~ 0xf0000;
5450             newinsn |= ((newinsn & 0x0f000) << 4);
5451           }
5452
5453         newimm |= (temp & 0xfffff000);
5454         md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5455
5456         highpart |= (newinsn & 0xfffff000);
5457         md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5458       }
5459       break;
5460
5461     case BFD_RELOC_ARM_OFFSET_IMM:
5462       sign = value >= 0;
5463       if ((value = validate_offset_imm (value, 0)) == FAIL)
5464         {
5465           as_bad (_("bad immediate value for offset (%ld)"), (long) value);
5466           break;
5467         }
5468       if (value < 0)
5469         value = -value;
5470
5471       newval = md_chars_to_number (buf, INSN_SIZE);
5472       newval &= 0xff7ff000;
5473       newval |= value | (sign ? INDEX_UP : 0);
5474       md_number_to_chars (buf, newval, INSN_SIZE);
5475       break;
5476
5477      case BFD_RELOC_ARM_OFFSET_IMM8:
5478      case BFD_RELOC_ARM_HWLITERAL:
5479       sign = value >= 0;
5480       if ((value = validate_offset_imm (value, 1)) == FAIL)
5481         {
5482           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5483             as_bad_where (fixP->fx_file, fixP->fx_line, 
5484                         _("invalid literal constant: pool needs to be closer\n"));
5485           else
5486             as_bad (_("bad immediate value for offset (%ld)"), (long) value);
5487           break;
5488         }
5489
5490       if (value < 0)
5491         value = -value;
5492
5493       newval = md_chars_to_number (buf, INSN_SIZE);
5494       newval &= 0xff7ff0f0;
5495       newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5496       md_number_to_chars (buf, newval, INSN_SIZE);
5497       break;
5498
5499     case BFD_RELOC_ARM_LITERAL:
5500       sign = value >= 0;
5501       if (value < 0)
5502         value = -value;
5503
5504       if ((value = validate_offset_imm (value, 0)) == FAIL)
5505         {
5506           as_bad_where (fixP->fx_file, fixP->fx_line, 
5507                         _("invalid literal constant: pool needs to be closer\n"));
5508           break;
5509         }
5510
5511       newval = md_chars_to_number (buf, INSN_SIZE);
5512       newval &= 0xff7ff000;
5513       newval |= value | (sign ? INDEX_UP : 0);
5514       md_number_to_chars (buf, newval, INSN_SIZE);
5515       break;
5516
5517     case BFD_RELOC_ARM_SHIFT_IMM:
5518       newval = md_chars_to_number (buf, INSN_SIZE);
5519       if (((unsigned long) value) > 32
5520           || (value == 32 
5521               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5522         {
5523           as_bad_where (fixP->fx_file, fixP->fx_line,
5524                         _("shift expression is too large"));
5525           break;
5526         }
5527
5528       if (value == 0)
5529         newval &= ~0x60;        /* Shifts of zero must be done as lsl */
5530       else if (value == 32)
5531         value = 0;
5532       newval &= 0xfffff07f;
5533       newval |= (value & 0x1f) << 7;
5534       md_number_to_chars (buf, newval , INSN_SIZE);
5535       break;
5536
5537     case BFD_RELOC_ARM_SWI:
5538       if (arm_data->thumb_mode)
5539         {
5540           if (((unsigned long) value) > 0xff)
5541             as_bad_where (fixP->fx_file, fixP->fx_line,
5542                           _("Invalid swi expression"));
5543           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5544           newval |= value;
5545           md_number_to_chars (buf, newval, THUMB_SIZE);
5546         }
5547       else
5548         {
5549           if (((unsigned long) value) > 0x00ffffff)
5550             as_bad_where (fixP->fx_file, fixP->fx_line, 
5551                           _("Invalid swi expression"));
5552           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5553           newval |= value;
5554           md_number_to_chars (buf, newval , INSN_SIZE);
5555         }
5556       break;
5557
5558     case BFD_RELOC_ARM_MULTI:
5559       if (((unsigned long) value) > 0xffff)
5560         as_bad_where (fixP->fx_file, fixP->fx_line,
5561                       _("Invalid expression in load/store multiple"));
5562       newval = value | md_chars_to_number (buf, INSN_SIZE);
5563       md_number_to_chars (buf, newval, INSN_SIZE);
5564       break;
5565
5566     case BFD_RELOC_ARM_PCREL_BRANCH:
5567       newval = md_chars_to_number (buf, INSN_SIZE);
5568
5569 #ifdef OBJ_ELF
5570       if (! target_oabi)
5571         value = fixP->fx_offset;
5572 #endif
5573       value  = (value >> 2) & 0x00ffffff;
5574       value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5575       newval = value | (newval & 0xff000000);
5576       md_number_to_chars (buf, newval, INSN_SIZE);
5577       break;
5578
5579     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5580       newval = md_chars_to_number (buf, THUMB_SIZE);
5581       {
5582         addressT diff = (newval & 0xff) << 1;
5583         if (diff & 0x100)
5584          diff |= ~0xff;
5585
5586         value += diff;
5587         if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5588          as_bad_where (fixP->fx_file, fixP->fx_line,
5589                        _("Branch out of range"));
5590         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5591       }
5592       md_number_to_chars (buf, newval, THUMB_SIZE);
5593       break;
5594
5595     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5596       newval = md_chars_to_number (buf, THUMB_SIZE);
5597       {
5598         addressT diff = (newval & 0x7ff) << 1;
5599         if (diff & 0x800)
5600          diff |= ~0x7ff;
5601
5602         value += diff;
5603         if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5604          as_bad_where (fixP->fx_file, fixP->fx_line,
5605                        _("Branch out of range"));
5606         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5607       }
5608       md_number_to_chars (buf, newval, THUMB_SIZE);
5609       break;
5610
5611     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5612       {
5613         offsetT newval2;
5614         addressT diff;
5615
5616         newval  = md_chars_to_number (buf, THUMB_SIZE);
5617         newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5618         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5619         if (diff & 0x400000)
5620           diff |= ~0x3fffff;
5621         value += diff;
5622         if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5623           as_bad_where (fixP->fx_file, fixP->fx_line,
5624                         _("Branch with link out of range"));
5625
5626         newval  = (newval  & 0xf800) | ((value & 0x7fffff) >> 12);
5627         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5628         md_number_to_chars (buf, newval, THUMB_SIZE);
5629         md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5630       }
5631       break;
5632
5633     case BFD_RELOC_8:
5634       if (fixP->fx_done || fixP->fx_pcrel)
5635         md_number_to_chars (buf, value, 1);
5636 #ifdef OBJ_ELF
5637       else if (!target_oabi)
5638         {
5639           value = fixP->fx_offset;
5640           md_number_to_chars (buf, value, 1);
5641         }
5642 #endif
5643       break;
5644
5645     case BFD_RELOC_16:
5646       if (fixP->fx_done || fixP->fx_pcrel)
5647         md_number_to_chars (buf, value, 2);
5648 #ifdef OBJ_ELF
5649       else if (!target_oabi)
5650         {
5651           value = fixP->fx_offset;
5652           md_number_to_chars (buf, value, 2);
5653         }
5654 #endif
5655       break;
5656
5657 #ifdef OBJ_ELF
5658     case BFD_RELOC_ARM_GOT32:
5659     case BFD_RELOC_ARM_GOTOFF:
5660         md_number_to_chars (buf, 0, 4);
5661         break;
5662 #endif
5663
5664     case BFD_RELOC_RVA:
5665     case BFD_RELOC_32:
5666       if (fixP->fx_done || fixP->fx_pcrel)
5667         md_number_to_chars (buf, value, 4);
5668 #ifdef OBJ_ELF
5669       else if (!target_oabi)
5670         {
5671           value = fixP->fx_offset;
5672           md_number_to_chars (buf, value, 4);
5673         }
5674 #endif
5675       break;
5676
5677 #ifdef OBJ_ELF
5678     case BFD_RELOC_ARM_PLT32:
5679       /* It appears the instruction is fully prepared at this point. */
5680       break;
5681 #endif
5682
5683     case BFD_RELOC_ARM_GOTPC:
5684       md_number_to_chars (buf, value, 4);
5685       break;
5686       
5687     case BFD_RELOC_ARM_CP_OFF_IMM:
5688       sign = value >= 0;
5689       if (value < -1023 || value > 1023 || (value & 3))
5690         as_bad_where (fixP->fx_file, fixP->fx_line,
5691                       _("Illegal value for co-processor offset"));
5692       if (value < 0)
5693         value = -value;
5694       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5695       newval |= (value >> 2) | (sign ?  INDEX_UP : 0);
5696       md_number_to_chars (buf, newval , INSN_SIZE);
5697       break;
5698
5699     case BFD_RELOC_ARM_THUMB_OFFSET:
5700       newval = md_chars_to_number (buf, THUMB_SIZE);
5701       /* Exactly what ranges, and where the offset is inserted depends on
5702          the type of instruction, we can establish this from the top 4 bits */
5703       switch (newval >> 12)
5704         {
5705         case 4: /* PC load */
5706           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5707              forced to zero for these loads, so we will need to round
5708              up the offset if the instruction address is not word
5709              aligned (since the final address produced must be, and
5710              we can only describe word-aligned immediate offsets).  */
5711
5712           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5713             as_bad_where (fixP->fx_file, fixP->fx_line,
5714                           _("Invalid offset, target not word aligned (0x%08X)"),
5715                           (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5716
5717           if ((value + 2) & ~0x3fe)
5718             as_bad_where (fixP->fx_file, fixP->fx_line,
5719                           _("Invalid offset"));
5720
5721           /* Round up, since pc will be rounded down.  */
5722           newval |= (value + 2) >> 2;
5723           break;
5724
5725         case 9: /* SP load/store */
5726           if (value & ~0x3fc)
5727             as_bad_where (fixP->fx_file, fixP->fx_line,
5728                           _("Invalid offset"));
5729           newval |= value >> 2;
5730           break;
5731
5732         case 6: /* Word load/store */
5733           if (value & ~0x7c)
5734             as_bad_where (fixP->fx_file, fixP->fx_line,
5735                           _("Invalid offset"));
5736           newval |= value << 4; /* 6 - 2 */
5737           break;
5738
5739         case 7: /* Byte load/store */
5740           if (value & ~0x1f)
5741             as_bad_where (fixP->fx_file, fixP->fx_line,
5742                           _("Invalid offset"));
5743           newval |= value << 6;
5744           break;
5745
5746         case 8: /* Halfword load/store */
5747           if (value & ~0x3e)
5748             as_bad_where (fixP->fx_file, fixP->fx_line,
5749                           _("Invalid offset"));
5750           newval |= value << 5; /* 6 - 1 */
5751           break;
5752
5753         default:
5754           as_bad_where (fixP->fx_file, fixP->fx_line,
5755                         "Unable to process relocation for thumb opcode: %lx",
5756                         (unsigned long) newval);
5757           break;
5758         }
5759       md_number_to_chars (buf, newval, THUMB_SIZE);
5760       break;
5761
5762     case BFD_RELOC_ARM_THUMB_ADD:
5763       /* This is a complicated relocation, since we use it for all of
5764          the following immediate relocations:
5765             3bit ADD/SUB
5766             8bit ADD/SUB
5767             9bit ADD/SUB SP word-aligned
5768            10bit ADD PC/SP word-aligned
5769
5770          The type of instruction being processed is encoded in the
5771          instruction field:
5772            0x8000  SUB
5773            0x00F0  Rd
5774            0x000F  Rs
5775       */
5776       newval = md_chars_to_number (buf, THUMB_SIZE);
5777       {
5778         int rd = (newval >> 4) & 0xf;
5779         int rs = newval & 0xf;
5780         int subtract = newval & 0x8000;
5781
5782         if (rd == REG_SP)
5783           {
5784             if (value & ~0x1fc)
5785               as_bad_where (fixP->fx_file, fixP->fx_line,
5786                             _("Invalid immediate for stack address calculation"));
5787             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5788             newval |= value >> 2;
5789           }
5790         else if (rs == REG_PC || rs == REG_SP)
5791           {
5792             if (subtract ||
5793                 value & ~0x3fc)
5794               as_bad_where (fixP->fx_file, fixP->fx_line,
5795                             _("Invalid immediate for address calculation (value = 0x%08lX)"),
5796                             (unsigned long) value);
5797             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5798             newval |= rd << 8;
5799             newval |= value >> 2;
5800           }
5801         else if (rs == rd)
5802           {
5803             if (value & ~0xff)
5804               as_bad_where (fixP->fx_file, fixP->fx_line,
5805                             _("Invalid 8bit immediate"));
5806             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5807             newval |= (rd << 8) | value;
5808           }
5809         else
5810           {
5811             if (value & ~0x7)
5812               as_bad_where (fixP->fx_file, fixP->fx_line,
5813                             _("Invalid 3bit immediate"));
5814             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5815             newval |= rd | (rs << 3) | (value << 6);
5816           }
5817       }
5818       md_number_to_chars (buf, newval , THUMB_SIZE);
5819       break;
5820
5821     case BFD_RELOC_ARM_THUMB_IMM:
5822       newval = md_chars_to_number (buf, THUMB_SIZE);
5823       switch (newval >> 11)
5824         {
5825         case 0x04: /* 8bit immediate MOV */
5826         case 0x05: /* 8bit immediate CMP */
5827           if (value < 0 || value > 255)
5828             as_bad_where (fixP->fx_file, fixP->fx_line,
5829                           _("Invalid immediate: %ld is too large"),
5830                           (long) value);
5831           newval |= value;
5832           break;
5833
5834         default:
5835           abort ();
5836         }
5837       md_number_to_chars (buf, newval , THUMB_SIZE);
5838       break;
5839
5840     case BFD_RELOC_ARM_THUMB_SHIFT:
5841       /* 5bit shift value (0..31) */
5842       if (value < 0 || value > 31)
5843         as_bad_where (fixP->fx_file, fixP->fx_line,
5844                       _("Illegal Thumb shift value: %ld"), (long) value);
5845       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5846       newval |= value << 6;
5847       md_number_to_chars (buf, newval , THUMB_SIZE);
5848       break;
5849
5850     case BFD_RELOC_VTABLE_INHERIT:
5851     case BFD_RELOC_VTABLE_ENTRY:
5852       fixP->fx_done = 0;
5853       return 1;
5854
5855     case BFD_RELOC_NONE:
5856     default:
5857       as_bad_where (fixP->fx_file, fixP->fx_line,
5858                     _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type);
5859     }
5860
5861   return 1;
5862 }
5863
5864 /* Translate internal representation of relocation info to BFD target
5865    format.  */
5866 arelent *
5867 tc_gen_reloc (section, fixp)
5868      asection * section;
5869      fixS * fixp;
5870 {
5871   arelent * reloc;
5872   bfd_reloc_code_real_type code;
5873
5874   reloc = (arelent *) xmalloc (sizeof (arelent));
5875
5876   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5877   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5878   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5879
5880   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
5881 #ifndef OBJ_ELF
5882   if (fixp->fx_pcrel == 0)
5883     reloc->addend = fixp->fx_offset;
5884   else
5885     reloc->addend = fixp->fx_offset = reloc->address;
5886 #else  /* OBJ_ELF */
5887   reloc->addend = fixp->fx_offset;
5888 #endif
5889
5890   switch (fixp->fx_r_type)
5891     {
5892     case BFD_RELOC_8:
5893       if (fixp->fx_pcrel)
5894         {
5895           code = BFD_RELOC_8_PCREL;
5896           break;
5897         }
5898
5899     case BFD_RELOC_16:
5900       if (fixp->fx_pcrel)
5901         {
5902           code = BFD_RELOC_16_PCREL;
5903           break;
5904         }
5905
5906     case BFD_RELOC_32:
5907       if (fixp->fx_pcrel)
5908         {
5909           code = BFD_RELOC_32_PCREL;
5910           break;
5911         }
5912
5913     case BFD_RELOC_ARM_PCREL_BRANCH:
5914     case BFD_RELOC_RVA:      
5915     case BFD_RELOC_THUMB_PCREL_BRANCH9:
5916     case BFD_RELOC_THUMB_PCREL_BRANCH12:
5917     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5918     case BFD_RELOC_VTABLE_ENTRY:
5919     case BFD_RELOC_VTABLE_INHERIT:
5920       code = fixp->fx_r_type;
5921       break;
5922
5923     case BFD_RELOC_ARM_LITERAL:
5924     case BFD_RELOC_ARM_HWLITERAL:
5925       /* If this is called then the a literal has been referenced across
5926          a section boundry - possibly due to an implicit dump */
5927       as_bad_where (fixp->fx_file, fixp->fx_line,
5928                     _("Literal referenced across section boundry (Implicit dump?)"));
5929       return NULL;
5930
5931     case BFD_RELOC_ARM_GOTPC:
5932       assert (fixp->fx_pcrel != 0);
5933       code = fixp->fx_r_type;
5934       code = BFD_RELOC_32_PCREL;
5935       break;
5936
5937 #ifdef OBJ_ELF
5938     case BFD_RELOC_ARM_GOT32:
5939     case BFD_RELOC_ARM_GOTOFF:
5940     case BFD_RELOC_ARM_PLT32:
5941        code = fixp->fx_r_type;
5942     break;
5943 #endif
5944
5945     case BFD_RELOC_ARM_IMMEDIATE:
5946       as_bad_where (fixp->fx_file, fixp->fx_line,
5947                     _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5948                     fixp->fx_r_type);
5949       return NULL;
5950
5951     case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5952       as_bad_where (fixp->fx_file, fixp->fx_line,
5953                     _("ADRL used for a symbol not defined in the same file"),
5954                     fixp->fx_r_type);
5955       return NULL;
5956
5957     case BFD_RELOC_ARM_OFFSET_IMM:
5958       as_bad_where (fixp->fx_file, fixp->fx_line,
5959                     _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5960                     fixp->fx_r_type);
5961       return NULL;
5962
5963     default:
5964       {
5965         char * type;
5966         switch (fixp->fx_r_type)
5967           {
5968           case BFD_RELOC_ARM_IMMEDIATE:    type = "IMMEDIATE";    break;
5969           case BFD_RELOC_ARM_OFFSET_IMM:   type = "OFFSET_IMM";   break;
5970           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
5971           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
5972           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
5973           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
5974           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
5975           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
5976           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
5977           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
5978           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5979           default:                         type = "<unknown>";    break;
5980           }
5981         as_bad_where (fixp->fx_file, fixp->fx_line,
5982                       _("Can not represent %s relocation in this object file format (%d)"),
5983                       type, fixp->fx_pcrel);
5984         return NULL;
5985       }
5986     }
5987
5988 #ifdef OBJ_ELF
5989  if (code == BFD_RELOC_32_PCREL
5990      && GOT_symbol
5991      && fixp->fx_addsy == GOT_symbol)
5992    {
5993      code = BFD_RELOC_ARM_GOTPC;
5994      reloc->addend = fixp->fx_offset = reloc->address;
5995    }
5996 #endif
5997    
5998   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5999
6000   if (reloc->howto == NULL)
6001     {
6002       as_bad_where (fixp->fx_file, fixp->fx_line,
6003                     _("Can not represent %s relocation in this object file format"),
6004                     bfd_get_reloc_code_name (code));
6005       return NULL;
6006     }
6007
6008   return reloc;
6009 }
6010
6011 int
6012 md_estimate_size_before_relax (fragP, segtype)
6013      fragS * fragP;
6014      segT    segtype;
6015 {
6016   as_fatal (_("md_estimate_size_before_relax\n"));
6017   return 1;
6018 }
6019
6020 static void
6021 output_inst PARAMS ((void))
6022 {
6023   char * to = NULL;
6024     
6025   if (inst.error)
6026     {
6027       as_bad (inst.error);
6028       return;
6029     }
6030
6031   to = frag_more (inst.size);
6032   if (thumb_mode && (inst.size > THUMB_SIZE))
6033     {
6034       assert (inst.size == (2 * THUMB_SIZE));
6035       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6036       md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6037     }
6038   else if (inst.size > INSN_SIZE)
6039     {
6040       assert (inst.size == (2 * INSN_SIZE));
6041       md_number_to_chars (to, inst.instruction, INSN_SIZE);
6042       md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6043     }
6044   else
6045     md_number_to_chars (to, inst.instruction, inst.size);
6046
6047   if (inst.reloc.type != BFD_RELOC_NONE)
6048     fix_new_arm (frag_now, to - frag_now->fr_literal,
6049                  inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6050                  inst.reloc.type);
6051
6052   return;
6053 }
6054
6055 void
6056 md_assemble (str)
6057      char * str;
6058 {
6059   char   c;
6060   char * p;
6061   char * q;
6062   char * start;
6063
6064   /* Align the instruction.
6065      This may not be the right thing to do but ... */
6066   /* arm_align (2, 0); */
6067   listing_prev_line (); /* Defined in listing.h */
6068
6069   /* Align the previous label if needed.  */
6070   if (last_label_seen != NULL)
6071     {
6072       symbol_set_frag (last_label_seen, frag_now);
6073       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6074       S_SET_SEGMENT (last_label_seen, now_seg);
6075     }
6076
6077   memset (&inst, '\0', sizeof (inst));
6078   inst.reloc.type = BFD_RELOC_NONE;
6079
6080   if (*str == ' ')
6081     str++;                      /* Skip leading white space */
6082   
6083   /* Scan up to the end of the op-code, which must end in white space or
6084      end of string.  */
6085   for (start = p = str; *p != '\0'; p++)
6086     if (*p == ' ')
6087       break;
6088     
6089   if (p == str)
6090     {
6091       as_bad (_("No operator -- statement `%s'\n"), str);
6092       return;
6093     }
6094
6095   if (thumb_mode)
6096     {
6097       CONST struct thumb_opcode * opcode;
6098
6099       c = *p;
6100       *p = '\0';
6101       opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6102       *p = c;
6103       
6104       if (opcode)
6105         {
6106           inst.instruction = opcode->value;
6107           inst.size = opcode->size;
6108           (*opcode->parms)(p);
6109           output_inst ();
6110           return;
6111         }
6112     }
6113   else
6114     {
6115       CONST struct asm_opcode * opcode;
6116
6117       inst.size = INSN_SIZE;
6118       /* p now points to the end of the opcode, probably white space, but we
6119          have to break the opcode up in case it contains condionals and flags;
6120          keep trying with progressively smaller basic instructions until one
6121          matches, or we run out of opcode. */
6122       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6123       for (; q != str; q--)
6124         {
6125           c = *q;
6126           *q = '\0';
6127           opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6128           *q = c;
6129           
6130           if (opcode && opcode->template)
6131             {
6132               unsigned long flag_bits = 0;
6133               char * r;
6134
6135               /* Check that this instruction is supported for this CPU */
6136               if ((opcode->variants & cpu_variant) == 0)
6137                 goto try_shorter;
6138
6139               inst.instruction = opcode->value;
6140               if (q == p)               /* Just a simple opcode */
6141                 {
6142                   if (opcode->comp_suffix != 0)
6143                     as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6144                             opcode->comp_suffix);
6145                   else
6146                     {
6147                       inst.instruction |= COND_ALWAYS;
6148                       (*opcode->parms)(q, 0);
6149                     }
6150                   output_inst ();
6151                   return;
6152                 }
6153
6154               /* Now check for a conditional */
6155               r = q;
6156               if (p - r >= 2)
6157                 {
6158                   CONST struct asm_cond *cond;
6159                   char d = *(r + 2);
6160
6161                   *(r + 2) = '\0';
6162                   cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6163                   *(r + 2) = d;
6164                   if (cond)
6165                     {
6166                       if (cond->value == 0xf0000000)
6167                         as_tsktsk (
6168 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6169
6170                       inst.instruction |= cond->value;
6171                       r += 2;
6172                     }
6173                   else
6174                     inst.instruction |= COND_ALWAYS;
6175                 }
6176               else
6177                 inst.instruction |= COND_ALWAYS;
6178
6179               /* if there is a compulsory suffix, it should come here, before
6180                  any optional flags. */
6181               if (opcode->comp_suffix)
6182                 {
6183                   CONST char *s = opcode->comp_suffix;
6184
6185                   while (*s)
6186                     {
6187                       inst.suffix++;
6188                       if (*r == *s)
6189                         break;
6190                       s++;
6191                     }
6192
6193                   if (*s == '\0')
6194                     {
6195                       as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6196                               opcode->comp_suffix);
6197                       return;
6198                     }
6199
6200                   r++;
6201                 }
6202
6203               /* The remainder, if any should now be flags for the instruction;
6204                  Scan these checking each one found with the opcode.  */
6205               if (r != p)
6206                 {
6207                   char d;
6208                   CONST struct asm_flg *flag = opcode->flags;
6209
6210                   if (flag)
6211                     {
6212                       int flagno;
6213
6214                       d = *p;
6215                       *p = '\0';
6216
6217                       for (flagno = 0; flag[flagno].template; flagno++)
6218                         {
6219                           if (streq (r, flag[flagno].template))
6220                             {
6221                               flag_bits |= flag[flagno].set_bits;
6222                               break;
6223                             }
6224                         }
6225
6226                       *p = d;
6227                       if (! flag[flagno].template)
6228                         goto try_shorter;
6229                     }
6230                   else
6231                     goto try_shorter;
6232                 }
6233
6234               (*opcode->parms) (p, flag_bits);
6235               output_inst ();
6236               return;
6237             }
6238
6239         try_shorter:
6240           ;
6241         }
6242     }
6243
6244   /* It wasn't an instruction, but it might be a register alias of the form
6245      alias .req reg
6246      */
6247   q = p;
6248   while (*q == ' ')
6249     q++;
6250
6251   c = *p;
6252   *p = '\0';
6253     
6254   if (*q && !strncmp (q, ".req ", 4))
6255     {
6256       int    reg;
6257       char * copy_of_str = str;
6258       char * r;
6259       
6260       q += 4;
6261       while (*q == ' ')
6262         q++;
6263
6264       for (r = q; *r != '\0'; r++)
6265         if (*r == ' ')
6266           break;
6267       
6268       if (r != q)
6269         {
6270           int regnum;
6271           char d = *r;
6272
6273           *r = '\0';
6274           regnum = arm_reg_parse (& q);
6275           *r = d;
6276
6277           reg = arm_reg_parse (& str);
6278           
6279           if (reg == FAIL)
6280             {
6281               if (regnum != FAIL)
6282                 {
6283                   insert_reg_alias (str, regnum);
6284                 }
6285               else
6286                 {
6287                   as_warn (_("register '%s' does not exist\n"), q);
6288                 }
6289             }
6290           else if (regnum != FAIL)
6291             {
6292               if (reg != regnum)
6293                 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
6294               
6295               /* Do not warn abpout redefinitions to the same alias.  */
6296             }
6297           else
6298             as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6299                      copy_of_str, q);
6300         }
6301       else
6302         as_warn (_("ignoring incomplete .req pseuso op"));
6303       
6304       *p = c;
6305       return;
6306     }
6307
6308   *p = c;
6309   as_bad (_("bad instruction `%s'"), start);
6310 }
6311
6312 /*
6313  * md_parse_option
6314  *    Invocation line includes a switch not recognized by the base assembler.
6315  *    See if it's a processor-specific option.  These are:
6316  *    Cpu variants, the arm part is optional:
6317  *            -m[arm]1                Currently not supported.
6318  *            -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
6319  *            -m[arm]3                Arm 3 processor
6320  *            -m[arm]6[xx],           Arm 6 processors
6321  *            -m[arm]7[xx][t][[d]m]   Arm 7 processors
6322  *            -m[arm]8[10]            Arm 8 processors
6323  *            -m[arm]9[20][tdmi]      Arm 9 processors
6324  *            -mstrongarm[110[0]]     StrongARM processors
6325  *            -m[arm]v[2345]          Arm architecures
6326  *            -mall                   All (except the ARM1)
6327  *    FP variants:
6328  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
6329  *            -mfpe-old               (No float load/store multiples)
6330  *            -mno-fpu                Disable all floating point instructions
6331  *    Run-time endian selection:
6332  *            -EB                     big endian cpu
6333  *            -EL                     little endian cpu
6334  *    ARM Procedure Calling Standard:
6335  *            -mapcs-32               32 bit APCS
6336  *            -mapcs-26               26 bit APCS
6337  *            -mapcs-float            Pass floats in float regs
6338  *            -mapcs-reentrant        Position independent code
6339  *            -mthumb-interwork       Code supports Arm/Thumb interworking
6340  *            -moabi                  Old ELF ABI
6341  */
6342
6343 CONST char * md_shortopts = "m:k";
6344 struct option md_longopts[] =
6345 {
6346 #ifdef ARM_BI_ENDIAN
6347 #define OPTION_EB (OPTION_MD_BASE + 0)
6348   {"EB", no_argument, NULL, OPTION_EB},
6349 #define OPTION_EL (OPTION_MD_BASE + 1)
6350   {"EL", no_argument, NULL, OPTION_EL},
6351 #ifdef OBJ_ELF
6352 #define OPTION_OABI (OPTION_MD_BASE +2)
6353   {"oabi", no_argument, NULL, OPTION_OABI},
6354 #endif
6355 #endif
6356   {NULL, no_argument, NULL, 0}
6357 };
6358 size_t md_longopts_size = sizeof (md_longopts);
6359
6360 int
6361 md_parse_option (c, arg)
6362      int    c;
6363      char * arg;
6364 {
6365   char * str = arg;
6366
6367   switch (c)
6368     {
6369 #ifdef ARM_BI_ENDIAN
6370     case OPTION_EB:
6371       target_big_endian = 1;
6372       break;
6373     case OPTION_EL:
6374       target_big_endian = 0;
6375       break;
6376 #endif
6377
6378     case 'm':
6379       switch (*str)
6380         {
6381         case 'f':
6382           if (streq (str, "fpa10"))
6383             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6384           else if (streq (str, "fpa11"))
6385             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6386           else if (streq (str, "fpe-old"))
6387             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6388           else
6389             goto bad;
6390           break;
6391
6392         case 'n':
6393           if (streq (str, "no-fpu"))
6394             cpu_variant &= ~FPU_ALL;
6395           break;
6396
6397 #ifdef OBJ_ELF
6398         case 'o':
6399           if (streq (str, "oabi"))
6400             target_oabi = true;
6401           break;
6402 #endif
6403           
6404         case 't':
6405           /* Limit assembler to generating only Thumb instructions: */
6406           if (streq (str, "thumb"))
6407             {
6408               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6409               cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6410               thumb_mode = 1;
6411             }
6412           else if (streq (str, "thumb-interwork"))
6413             {
6414               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
6415 #if defined OBJ_COFF || defined OBJ_ELF
6416               support_interwork = true;
6417 #endif
6418             }
6419           else
6420             goto bad;
6421           break;
6422
6423         default:
6424           if (streq (str, "all"))
6425             {
6426               cpu_variant = ARM_ALL | FPU_ALL;
6427               return 1;
6428             }
6429 #if defined OBJ_COFF || defined OBJ_ELF
6430           if (! strncmp (str, "apcs-", 5))
6431             {
6432               /* GCC passes on all command line options starting "-mapcs-..."
6433                  to us, so we must parse them here.  */
6434
6435               str += 5;
6436               
6437               if (streq (str, "32"))
6438                 {
6439                   uses_apcs_26 = false;
6440                   return 1;
6441                 }
6442               else if (streq (str, "26"))
6443                 {
6444                   uses_apcs_26 = true;
6445                   return 1;
6446                 }
6447               else if (streq (str, "frame"))
6448                 {
6449                   /* Stack frames are being generated - does not affect
6450                      linkage of code.  */
6451                   return 1;
6452                 }
6453               else if (streq (str, "stack-check"))
6454                 {
6455                   /* Stack checking is being performed - does not affect
6456                      linkage, but does require that the functions
6457                      __rt_stkovf_split_small and __rt_stkovf_split_big be
6458                      present in the final link.  */
6459
6460                   return 1;
6461                 }
6462               else if (streq (str, "float"))
6463                 {
6464                   /* Floating point arguments are being passed in the floating
6465                      point registers.  This does affect linking, since this
6466                      version of the APCS is incompatible with the version that
6467                      passes floating points in the integer registers.  */
6468
6469                   uses_apcs_float = true;
6470                   return 1;
6471                 }
6472               else if (streq (str, "reentrant"))
6473                 {
6474                   /* Reentrant code has been generated.  This does affect
6475                      linking, since there is no point in linking reentrant/
6476                      position independent code with absolute position code. */
6477                   pic_code = true;
6478                   return 1;
6479                 }
6480               
6481               as_bad (_("Unrecognised APCS switch -m%s"), arg);
6482               return 0;
6483             }
6484 #endif
6485           /* Strip off optional "arm" */
6486           if (! strncmp (str, "arm", 3))
6487             str += 3;
6488
6489           switch (*str)
6490             {
6491             case '1':
6492               if (streq (str, "1"))
6493                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6494               else
6495                 goto bad;
6496               break;
6497
6498             case '2':
6499               if (streq (str, "2"))
6500                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6501               else if (streq (str, "250"))
6502                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6503               else
6504                 goto bad;
6505               break;
6506
6507             case '3':
6508               if (streq (str, "3"))
6509                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6510               else
6511                 goto bad;
6512               break;
6513
6514             case '6':
6515               switch (strtol (str, NULL, 10))
6516                 {
6517                 case 6:
6518                 case 60:
6519                 case 600:
6520                 case 610:
6521                 case 620:
6522                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6523                   break;
6524                 default:
6525                   goto bad;
6526                 }
6527               break;
6528
6529             case '7':
6530               switch (strtol (str, & str, 10))  /* Eat the processor name */
6531                 {
6532                 case 7:
6533                 case 70:
6534                 case 700:
6535                 case 710:
6536                 case 7100:
6537                 case 7500:
6538                   break;
6539                 default:
6540                   goto bad;
6541                 }
6542               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6543               for (; *str; str++)
6544                 {
6545                 switch (* str)
6546                   {
6547                   case 't':
6548                     cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6549                     break;
6550
6551                   case 'm':
6552                     cpu_variant |= ARM_LONGMUL;
6553                     break;
6554
6555                   case 'f': /* fe => fp enabled cpu.  */
6556                     if (str[1] == 'e')
6557                       ++ str;
6558                     else
6559                       goto bad;
6560                     
6561                   case 'c': /* Left over from 710c processor name.  */
6562                   case 'd': /* Debug */
6563                   case 'i': /* Embedded ICE */
6564                     /* Included for completeness in ARM processor naming. */
6565                     break;
6566
6567                   default:
6568                     goto bad;
6569                   }
6570                 }
6571               break;
6572
6573             case '8':
6574               if (streq (str, "8") || streq (str, "810"))
6575                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6576               else
6577                 goto bad;
6578               break;
6579               
6580             case '9':
6581               if (streq (str, "9"))
6582                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6583               else if (streq (str, "920"))
6584                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6585               else if (streq (str, "920t"))
6586                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6587               else if (streq (str, "9tdmi"))
6588                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6589               else
6590                 goto bad;
6591               break;
6592               
6593             case 's':
6594               if (streq (str, "strongarm")
6595                   || streq (str, "strongarm110")
6596                   || streq (str, "strongarm1100"))
6597                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6598               else
6599                 goto bad;
6600               break;
6601                 
6602             case 'v':
6603               /* Select variant based on architecture rather than processor */
6604               switch (*++str)
6605                 {
6606                 case '2':
6607                   switch (*++str)
6608                     {
6609                     case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6610                     case 0:   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6611                     default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
6612                     }
6613                   break;
6614                   
6615                 case '3':
6616                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6617                     
6618                   switch (*++str)
6619                     {
6620                     case 'm': cpu_variant |= ARM_LONGMUL; break;
6621                     case 0:   break;
6622                     default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
6623                     }
6624                   break;
6625                   
6626                 case '4':
6627                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6628                   
6629                   switch (*++str)
6630                     {
6631                     case 't': cpu_variant |= ARM_THUMB; break;
6632                     case 0:   break;
6633                     default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
6634                     }
6635                   break;
6636                   
6637                 case '5':
6638                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6639                   
6640                   switch (*++str)
6641                     {
6642                     case 't': cpu_variant |= ARM_THUMB; break;
6643                     case 0:   break;
6644                     default:  as_bad (_("Invalid architecture variant -m%s"), arg); break;
6645                     }
6646                   break;
6647                   
6648                 default:
6649                   as_bad (_("Invalid architecture variant -m%s"), arg);
6650                   break;
6651                 }
6652               break;
6653               
6654             default:
6655             bad:
6656               as_bad (_("Invalid processor variant -m%s"), arg);
6657               return 0;
6658             }
6659         }
6660       break;
6661
6662     case 'k':
6663       pic_code = 1;
6664       break;
6665       
6666     default:
6667       return 0;
6668     }
6669
6670    return 1;
6671 }
6672
6673 void
6674 md_show_usage (fp)
6675      FILE * fp;
6676 {
6677   fprintf (fp,
6678 _("\
6679  ARM Specific Assembler Options:\n\
6680   -m[arm][<processor name>] select processor variant\n\
6681   -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6682   -mthumb                   only allow Thumb instructions\n\
6683   -mthumb-interwork         mark the assembled code as supporting interworking\n\
6684   -mall                     allow any instruction\n\
6685   -mfpa10, -mfpa11          select floating point architecture\n\
6686   -mfpe-old                 don't allow floating-point multiple instructions\n\
6687   -mno-fpu                  don't allow any floating-point instructions.\n"));
6688   fprintf (fp,
6689 _("\
6690   -k                        generate PIC code.\n"));
6691 #if defined OBJ_COFF || defined OBJ_ELF
6692   fprintf (fp,
6693 _("\
6694   -mapcs-32, -mapcs-26      specify which ARM Procedure Calling Standard to use\n"));
6695   fprintf (fp,
6696 _("\
6697   -mapcs-float              floating point args are passed in FP regs\n"));
6698   fprintf (fp,
6699 _("\
6700   -mapcs-reentrant          the code is position independent/reentrant\n"));
6701   #endif
6702 #ifdef OBJ_ELF
6703   fprintf (fp,
6704 _("\
6705   -moabi                    support the old ELF ABI\n"));
6706 #endif
6707 #ifdef ARM_BI_ENDIAN
6708   fprintf (fp,
6709 _("\
6710   -EB                       assemble code for a big endian cpu\n\
6711   -EL                       assemble code for a little endian cpu\n"));
6712 #endif
6713 }
6714
6715 /* We need to be able to fix up arbitrary expressions in some statements.
6716    This is so that we can handle symbols that are an arbitrary distance from
6717    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6718    which returns part of an address in a form which will be valid for
6719    a data instruction.  We do this by pushing the expression into a symbol
6720    in the expr_section, and creating a fix for that.  */
6721
6722 static void
6723 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6724      fragS *       frag;
6725      int           where;
6726      short int     size;
6727      expressionS * exp;
6728      int           pc_rel;
6729      int           reloc;
6730 {
6731   fixS *         new_fix;
6732   arm_fix_data * arm_data;
6733
6734   switch (exp->X_op)
6735     {
6736     case O_constant:
6737     case O_symbol:
6738     case O_add:
6739     case O_subtract:
6740       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6741       break;
6742
6743     default:
6744       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6745                          pc_rel, reloc);
6746       break;
6747     }
6748
6749   /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6750   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6751   new_fix->tc_fix_data = (PTR) arm_data;
6752   arm_data->thumb_mode = thumb_mode;
6753
6754   return;
6755 }
6756
6757
6758 /*
6759  * This fix_new is called by cons via TC_CONS_FIX_NEW
6760  *
6761  * We check the expression to see if it is of the form
6762  *  __GLOBAL_OFFSET_TABLE + ???
6763  * If it is then this is a PC relative reference to the GOT.
6764  * i.e.
6765  *      ldr     sl, L1
6766  *      add     sl, pc, sl
6767  * L2:
6768  *      ...
6769  * L1:
6770  *      .word   __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6771  *
6772  * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6773  * normal BFD_RELOC_{16,32,64}
6774  */
6775
6776 void
6777 cons_fix_new_arm (frag, where, size, exp)
6778      fragS *       frag;
6779      int           where;
6780      int           size;
6781      expressionS * exp;
6782 {
6783   bfd_reloc_code_real_type type;
6784   int pcrel = 0;
6785   
6786   /* Pick a reloc ...
6787    *
6788    * @@ Should look at CPU word size.
6789    */
6790   switch (size) 
6791     {
6792     case 2:
6793       type = BFD_RELOC_16;
6794       break;
6795     case 4:
6796     default:
6797       type = BFD_RELOC_32;
6798       break;
6799     case 8:
6800       type = BFD_RELOC_64;
6801       break;
6802     }
6803   
6804   /* Look for possible GOTPC reloc */
6805   
6806   /*
6807    * Look for pic assembler and 'undef symbol + expr symbol' expression
6808    * and a 32 bit size.
6809    */
6810   
6811   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6812 }
6813
6814 /* A good place to do this, although this was probably not intended
6815  * for this kind of use.  We need to dump the literal pool before
6816  * references are made to a null symbol pointer.  */
6817 void
6818 arm_cleanup ()
6819 {
6820   if (current_poolP != NULL)
6821     {
6822       subseg_set (text_section, 0); /* Put it at the end of text section */
6823       s_ltorg (0);
6824       listing_prev_line ();
6825     }
6826 }
6827
6828 void
6829 arm_start_line_hook ()
6830 {
6831   last_label_seen = NULL;
6832 }
6833
6834 void
6835 arm_frob_label (sym)
6836      symbolS * sym;
6837 {
6838   last_label_seen = sym;
6839   
6840   ARM_SET_THUMB (sym, thumb_mode);
6841   
6842 #if defined OBJ_COFF || defined OBJ_ELF
6843   ARM_SET_INTERWORK (sym, support_interwork);
6844 #endif
6845   
6846   if (label_is_thumb_function_name)
6847     {
6848       /* When the address of a Thumb function is taken the bottom
6849          bit of that address should be set.  This will allow
6850          interworking between Arm and Thumb functions to work
6851          correctly.  */
6852
6853       THUMB_SET_FUNC (sym, 1);
6854       
6855       label_is_thumb_function_name = false;
6856     }
6857 }
6858
6859 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
6860    ARM ones.  */
6861
6862 void
6863 arm_adjust_symtab ()
6864 {
6865 #ifdef OBJ_COFF
6866   symbolS * sym;
6867
6868   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6869     {
6870       if (ARM_IS_THUMB (sym))
6871         {
6872           if (THUMB_IS_FUNC (sym))
6873             {
6874               /* Mark the symbol as a Thumb function.  */
6875               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
6876                   || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6877                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6878
6879               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6880                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6881               else
6882                 as_bad (_("%s: unexpected function type: %d"),
6883                         S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6884             }
6885           else switch (S_GET_STORAGE_CLASS (sym))
6886             {
6887               case C_EXT:
6888                 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6889                 break;
6890               case C_STAT:
6891                 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6892                 break;
6893               case C_LABEL:
6894                 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6895                 break;
6896               default: /* do nothing */ 
6897                 break;
6898             }
6899         }
6900
6901       if (ARM_IS_INTERWORK (sym))
6902         coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
6903     }
6904 #endif
6905 #ifdef OBJ_ELF
6906   symbolS *         sym;
6907   elf_symbol_type * elf_sym;
6908   char              bind;
6909
6910   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6911     {
6912       if (ARM_IS_THUMB (sym))
6913         {
6914           if (THUMB_IS_FUNC (sym))
6915             {
6916               elf_sym = elf_symbol (symbol_get_bfdsym (sym));
6917               bind = ELF_ST_BIND (elf_sym);
6918               elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
6919             }
6920          }
6921      }
6922 #endif
6923 }
6924
6925 int
6926 arm_data_in_code ()
6927 {
6928   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6929     {
6930       *input_line_pointer = '/';
6931       input_line_pointer += 5;
6932       *input_line_pointer = 0;
6933       return 1;
6934     }
6935   
6936   return 0;
6937 }
6938
6939 char *
6940 arm_canonicalize_symbol_name (name)
6941      char * name;
6942 {
6943   int len;
6944
6945   if (thumb_mode && (len = strlen (name)) > 5
6946       && streq (name + len - 5, "/data"))
6947     {
6948       *(name + len - 5) = 0;
6949     }
6950
6951   return name;
6952 }
6953
6954 boolean
6955 arm_validate_fix (fixP)
6956      fixS * fixP;
6957 {
6958   /* If the destination of the branch is a defined symbol which does not have
6959      the THUMB_FUNC attribute, then we must be calling a function which has
6960      the (interfacearm) attribute.  We look for the Thumb entry point to that
6961      function and change the branch to refer to that function instead.  */
6962   if (   fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6963       && fixP->fx_addsy != NULL
6964       && S_IS_DEFINED (fixP->fx_addsy)
6965       && ! THUMB_IS_FUNC (fixP->fx_addsy))
6966     {
6967       fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6968       return true;
6969     }
6970
6971   return false;
6972 }
6973
6974 #ifdef OBJ_ELF
6975 /* Relocations against Thumb function names must be left unadjusted,
6976    so that the linker can use this information to correctly set the
6977    bottom bit of their addresses.  The MIPS version of this function
6978    also prevents relocations that are mips-16 specific, but I do not
6979    know why it does this.
6980
6981    FIXME:
6982    There is one other problem that ought to be addressed here, but
6983    which currently is not:  Taking the address of a label (rather
6984    than a function) and then later jumping to that address.  Such
6985    addresses also ought to have their bottom bit set (assuming that
6986    they reside in Thumb code), but at the moment they will not.  */
6987    
6988 boolean
6989 arm_fix_adjustable (fixP)
6990    fixS * fixP;
6991 {
6992
6993   if (fixP->fx_addsy == NULL)
6994     return 1;
6995   
6996   /* Prevent all adjustments to global symbols. */
6997   if (S_IS_EXTERN (fixP->fx_addsy))
6998     return 0;
6999   
7000   if (S_IS_WEAK (fixP->fx_addsy))
7001     return 0;
7002
7003   if (THUMB_IS_FUNC (fixP->fx_addsy)
7004       && fixP->fx_subsy == NULL)
7005     return 0;
7006   
7007   /* We need the symbol name for the VTABLE entries */
7008   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7009       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7010     return 0;
7011
7012   return 1;
7013 }
7014
7015 const char *
7016 elf32_arm_target_format ()
7017 {
7018   if (target_big_endian)
7019     if (target_oabi)
7020       return "elf32-bigarm-oabi";
7021     else
7022       return "elf32-bigarm";
7023   else
7024     if (target_oabi)
7025       return "elf32-littlearm-oabi";
7026     else
7027       return "elf32-littlearm";
7028 }
7029
7030 void
7031 armelf_frob_symbol (symp, puntp)
7032      symbolS * symp;
7033      int * puntp;
7034 {
7035   elf_frob_symbol (symp, puntp);
7036
7037
7038 int
7039 arm_force_relocation (fixp)
7040      struct fix * fixp;
7041 {
7042   if (   fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7043       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7044       || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)    
7045     return 1;
7046   
7047   return 0;
7048 }
7049
7050 static bfd_reloc_code_real_type
7051 arm_parse_reloc ()
7052 {
7053   char   id[16];
7054   char * ip;
7055   int    i;
7056   static struct
7057   {
7058     char * str;
7059     int    len;
7060     bfd_reloc_code_real_type reloc;
7061   }
7062   reloc_map[] =
7063   {
7064 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7065     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
7066     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7067     /* ScottB: Jan 30, 1998 */
7068     /* Added support for parsing "var(PLT)" branch instructions */
7069     /* generated by GCC for PLT relocs */
7070     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
7071     NULL, 0,         BFD_RELOC_UNUSED
7072 #undef MAP    
7073   };
7074
7075   for (i = 0, ip = input_line_pointer;
7076        i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7077        i++, ip++)
7078     id[i] = tolower (*ip);
7079   
7080   for (i = 0; reloc_map[i].str; i++)
7081     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7082       break;
7083   
7084   input_line_pointer += reloc_map[i].len;
7085   
7086   return reloc_map[i].reloc;
7087 }
7088
7089 static void
7090 s_arm_elf_cons (nbytes)
7091      int nbytes;
7092 {
7093   expressionS exp;
7094
7095 #ifdef md_flush_pending_output
7096   md_flush_pending_output ();
7097 #endif
7098
7099   if (is_it_end_of_statement ())
7100     {
7101       demand_empty_rest_of_line ();
7102       return;
7103     }
7104
7105 #ifdef md_cons_align
7106   md_cons_align (nbytes);
7107 #endif
7108
7109   do
7110     {
7111       bfd_reloc_code_real_type reloc;
7112       
7113       expression (& exp);
7114
7115       if (exp.X_op == O_symbol
7116           && * input_line_pointer == '('
7117           && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7118         {
7119           reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7120           int size = bfd_get_reloc_size (howto);
7121
7122           if (size > nbytes)
7123             as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
7124           else
7125             {
7126               register char * p = frag_more ((int) nbytes);
7127               int offset = nbytes - size;
7128
7129               fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7130                            & exp, 0, reloc);
7131             }
7132         }
7133       else
7134         emit_expr (& exp, (unsigned int) nbytes);
7135     }
7136   while (*input_line_pointer++ == ',');
7137
7138   input_line_pointer--;         /* Put terminator back into stream. */
7139   demand_empty_rest_of_line ();
7140 }
7141
7142 #endif /* OBJ_ELF */