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