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