OSDN Git Service

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