tweak again
[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 (!strcmp (*str, "rrx")
2105           || !strcmp (*str, "RRX"))
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 static void
4394 do_t_branch23 (str)
4395      char *str;
4396 {
4397   if (my_get_expression (&inst.reloc.exp, &str))
4398     return;
4399   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4400   inst.reloc.pc_rel = 1;
4401   end_of_line (str);
4402 }
4403
4404 static void
4405 do_t_bx (str)
4406      char *str;
4407 {
4408   int reg;
4409
4410   while (*str == ' ')
4411     str++;
4412
4413   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4414     return;
4415
4416   /* This sets THUMB_H2 from the top bit of reg.  */
4417   inst.instruction |= reg << 3;
4418
4419   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
4420      should cause the alignment to be checked once it is known.  This is
4421      because BX PC only works if the instruction is word aligned.  */
4422
4423   end_of_line (str);
4424 }
4425
4426 static void
4427 do_t_compare (str)
4428      char *str;
4429 {
4430   thumb_mov_compare (str, THUMB_COMPARE);
4431 }
4432
4433 static void
4434 do_t_ldmstm (str)
4435      char *str;
4436 {
4437   int Rb;
4438   long range;
4439
4440   while (*str == ' ')
4441     str++;
4442
4443   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4444     return;
4445
4446   if (*str != '!')
4447     as_warn ("Inserted missing '!': load/store multiple always writes back base register");
4448   else
4449     str++;
4450
4451   if (skip_past_comma (&str) == FAIL
4452       || (range = reg_list (&str)) == FAIL)
4453     {
4454       if (! inst.error)
4455         inst.error = bad_args;
4456       return;
4457     }
4458
4459   if (inst.reloc.type != BFD_RELOC_NONE)
4460     {
4461       /* This really doesn't seem worth it. */
4462       inst.reloc.type = BFD_RELOC_NONE;
4463       inst.error = "Expression too complex";
4464       return;
4465     }
4466
4467   if (range & ~0xff)
4468     {
4469       inst.error = "only lo-regs valid in load/store multiple";
4470       return;
4471     }
4472
4473   inst.instruction |= (Rb << 8) | range;
4474   end_of_line (str);
4475 }
4476
4477 static void
4478 do_t_ldr (str)
4479      char *str;
4480 {
4481   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4482 }
4483
4484 static void
4485 do_t_ldrb (str)
4486      char *str;
4487 {
4488   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4489 }
4490
4491 static void
4492 do_t_ldrh (str)
4493      char *str;
4494 {
4495   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4496 }
4497
4498 static void
4499 do_t_lds (str)
4500      char *str;
4501 {
4502   int Rd, Rb, Ro;
4503
4504   while (*str == ' ')
4505     str++;
4506
4507   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4508       || skip_past_comma (&str) == FAIL
4509       || *str++ != '['
4510       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4511       || skip_past_comma (&str) == FAIL
4512       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4513       || *str++ != ']')
4514     {
4515       if (! inst.error)
4516         inst.error = "Syntax: ldrs[b] Rd, [Rb, Ro]";
4517       return;
4518     }
4519
4520   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4521   end_of_line (str);
4522 }
4523
4524 static void
4525 do_t_lsl (str)
4526      char *str;
4527 {
4528   thumb_shift (str, THUMB_LSL);
4529 }
4530
4531 static void
4532 do_t_lsr (str)
4533      char *str;
4534 {
4535   thumb_shift (str, THUMB_LSR);
4536 }
4537
4538 static void
4539 do_t_mov (str)
4540      char *str;
4541 {
4542   thumb_mov_compare (str, THUMB_MOVE);
4543 }
4544
4545 static void
4546 do_t_push_pop (str)
4547      char *str;
4548 {
4549   long range;
4550
4551   while (*str == ' ')
4552     str++;
4553
4554   if ((range = reg_list (&str)) == FAIL)
4555     {
4556       if (! inst.error)
4557         inst.error = bad_args;
4558       return;
4559     }
4560
4561   if (inst.reloc.type != BFD_RELOC_NONE)
4562     {
4563       /* This really doesn't seem worth it. */
4564       inst.reloc.type = BFD_RELOC_NONE;
4565       inst.error = "Expression too complex";
4566       return;
4567     }
4568
4569   if (range & ~0xff)
4570     {
4571       if ((inst.instruction == T_OPCODE_PUSH
4572            && (range & ~0xff) == 1 << REG_LR)
4573           || (inst.instruction == T_OPCODE_POP
4574               && (range & ~0xff) == 1 << REG_PC))
4575         {
4576           inst.instruction |= THUMB_PP_PC_LR;
4577           range &= 0xff;
4578         }
4579       else
4580         {
4581           inst.error = "invalid register list to push/pop instruction";
4582           return;
4583         }
4584     }
4585
4586   inst.instruction |= range;
4587   end_of_line (str);
4588 }
4589
4590 static void
4591 do_t_str (str)
4592      char *str;
4593 {
4594   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4595 }
4596
4597 static void
4598 do_t_strb (str)
4599      char *str;
4600 {
4601   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4602 }
4603
4604 static void
4605 do_t_strh (str)
4606      char *str;
4607 {
4608   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4609 }
4610
4611 static void
4612 do_t_sub (str)
4613      char *str;
4614 {
4615   thumb_add_sub (str, 1);
4616 }
4617
4618 static void
4619 do_t_swi (str)
4620      char *str;
4621 {
4622   while (*str == ' ')
4623     str++;
4624
4625   if (my_get_expression (&inst.reloc.exp, &str))
4626     return;
4627
4628   inst.reloc.type = BFD_RELOC_ARM_SWI;
4629   end_of_line (str);
4630   return;
4631 }
4632
4633 static void
4634 do_t_adr (str)
4635      char *str;
4636 {
4637   /* This is a pseudo-op of the form "adr rd, label" to be converted
4638      into a relative address of the form "add rd, pc, #label-.-4" */
4639   while (*str == ' ')
4640     str++;
4641
4642   if (reg_required_here (&str, 4) == FAIL  /* Store Rd in temporary location inside instruction.  */
4643       || skip_past_comma (&str) == FAIL
4644       || my_get_expression (&inst.reloc.exp, &str))
4645     {
4646       if (!inst.error)
4647         inst.error = bad_args;
4648       return;
4649     }
4650
4651   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4652   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4653   inst.reloc.pc_rel = 1;
4654   inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4655   end_of_line (str);
4656 }
4657
4658 static void
4659 insert_reg (entry)
4660      int entry;
4661 {
4662   int len = strlen (reg_table[entry].name) + 2;
4663   char *buf = (char *) xmalloc (len);
4664   char *buf2 = (char *) xmalloc (len);
4665   int i = 0;
4666
4667 #ifdef REGISTER_PREFIX
4668   buf[i++] = REGISTER_PREFIX;
4669 #endif
4670
4671   strcpy (buf + i, reg_table[entry].name);
4672
4673   for (i = 0; buf[i]; i++)
4674     buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4675
4676   buf2[i] = '\0';
4677
4678   hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4679   hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4680 }
4681
4682 static void
4683 insert_reg_alias (str, regnum)
4684      char *str;
4685      int regnum;
4686 {
4687   struct reg_entry *new =
4688     (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4689   char *name = xmalloc (strlen (str) + 1);
4690   strcpy (name, str);
4691
4692   new->name = name;
4693   new->number = regnum;
4694
4695   hash_insert (arm_reg_hsh, name, (PTR) new);
4696 }
4697
4698 static void
4699 set_constant_flonums ()
4700 {
4701   int i;
4702
4703   for (i = 0; i < NUM_FLOAT_VALS; i++)
4704     if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4705       abort ();
4706 }
4707
4708 void
4709 md_begin ()
4710 {
4711   int i;
4712   
4713   if ((arm_ops_hsh = hash_new ()) == NULL
4714       || (arm_tops_hsh = hash_new ()) == NULL
4715       || (arm_cond_hsh = hash_new ()) == NULL
4716       || (arm_shift_hsh = hash_new ()) == NULL
4717       || (arm_reg_hsh = hash_new ()) == NULL
4718       || (arm_psr_hsh = hash_new ()) == NULL)
4719     as_fatal ("Virtual memory exhausted");
4720     
4721   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4722     hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4723   for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4724     hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4725   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4726     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4727   for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4728     hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4729   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4730     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4731
4732   for (i = 0; reg_table[i].name; i++)
4733     insert_reg (i);
4734
4735   set_constant_flonums ();
4736
4737 #ifdef OBJ_COFF
4738   {
4739     unsigned int flags = 0;
4740     
4741     /* Set the flags in the private structure */
4742     if (uses_apcs_26)      flags |= F_APCS26;
4743     if (support_interwork) flags |= F_INTERWORK;
4744     if (uses_apcs_float)   flags |= F_APCS_FLOAT;
4745     if (pic_code)          flags |= F_PIC;
4746     
4747     bfd_set_private_flags (stdoutput, flags);
4748   }
4749 #endif
4750   
4751   {
4752     unsigned mach;
4753     
4754     /* Record the CPU type as well */
4755     switch (cpu_variant & ARM_CPU_MASK)
4756       {
4757       case ARM_2:
4758         mach = bfd_mach_arm_2;
4759         break;
4760         
4761       case ARM_3: /* also ARM_250 */
4762         mach = bfd_mach_arm_2a;
4763         break;
4764
4765       default:
4766       case ARM_6 | ARM_3 | ARM_2:       /* Actually no CPU type defined */
4767         mach = bfd_mach_arm_4;
4768         break;
4769         
4770       case ARM_7:                       /* also ARM_6 */
4771         mach = bfd_mach_arm_3;
4772         break;
4773       }
4774
4775     /* Catch special cases */
4776     if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
4777       {
4778         if (cpu_variant & ARM_THUMB)
4779           mach = bfd_mach_arm_4T;
4780         else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
4781           mach = bfd_mach_arm_4;
4782         else if (cpu_variant & ARM_LONGMUL)
4783           mach = bfd_mach_arm_3M;
4784       }
4785         
4786     bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
4787   }
4788 }
4789
4790 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4791    for use in the a.out file, and stores them in the array pointed to by buf.
4792    This knows about the endian-ness of the target machine and does
4793    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
4794    2 (short) and 4 (long)  Floating numbers are put out as a series of
4795    LITTLENUMS (shorts, here at least)
4796    */
4797 void
4798 md_number_to_chars (buf, val, n)
4799      char *buf;
4800      valueT val;
4801      int n;
4802 {
4803   if (target_big_endian)
4804     number_to_chars_bigendian (buf, val, n);
4805   else
4806     number_to_chars_littleendian (buf, val, n);
4807 }
4808
4809 static valueT 
4810 md_chars_to_number (buf, n)
4811      char *buf;
4812      int n;
4813 {
4814   valueT result = 0;
4815   unsigned char *where = (unsigned char *) buf;
4816
4817   if (target_big_endian)
4818     {
4819       while (n--)
4820         {
4821           result <<= 8;
4822           result |= (*where++ & 255);
4823         }
4824     }
4825   else
4826     {
4827       while (n--)
4828         {
4829           result <<= 8;
4830           result |= (where[n] & 255);
4831         }
4832     }
4833
4834   return result;
4835 }
4836
4837 /* Turn a string in input_line_pointer into a floating point constant
4838    of type TYPE, and store the appropriate bytes in *litP.  The number
4839    of LITTLENUMS emitted is stored in *sizeP .  An error message is
4840    returned, or NULL on OK.
4841
4842    Note that fp constants aren't represent in the normal way on the ARM.
4843    In big endian mode, things are as expected.  However, in little endian
4844    mode fp constants are big-endian word-wise, and little-endian byte-wise
4845    within the words.  For example, (double) 1.1 in big endian mode is
4846    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4847    the byte sequence 99 99 f1 3f 9a 99 99 99.
4848
4849    ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
4850
4851 char *
4852 md_atof (type, litP, sizeP)
4853      char type;
4854      char *litP;
4855      int *sizeP;
4856 {
4857   int prec;
4858   LITTLENUM_TYPE words[MAX_LITTLENUMS];
4859   char *t;
4860   int i;
4861
4862   switch (type)
4863     {
4864     case 'f':
4865     case 'F':
4866     case 's':
4867     case 'S':
4868       prec = 2;
4869       break;
4870
4871     case 'd':
4872     case 'D':
4873     case 'r':
4874     case 'R':
4875       prec = 4;
4876       break;
4877
4878     case 'x':
4879     case 'X':
4880       prec = 6;
4881       break;
4882
4883     case 'p':
4884     case 'P':
4885       prec = 6;
4886       break;
4887
4888     default:
4889       *sizeP = 0;
4890       return "Bad call to MD_ATOF()";
4891     }
4892
4893   t = atof_ieee (input_line_pointer, type, words);
4894   if (t)
4895     input_line_pointer = t;
4896   *sizeP = prec * 2;
4897
4898   if (target_big_endian)
4899     {
4900       for (i = 0; i < prec; i++)
4901         {
4902           md_number_to_chars (litP, (valueT) words[i], 2);
4903           litP += 2;
4904         }
4905     }
4906   else
4907     {
4908       /* For a 4 byte float the order of elements in `words' is 1 0.  For an
4909          8 byte float the order is 1 0 3 2.  */
4910       for (i = 0; i < prec; i += 2)
4911         {
4912           md_number_to_chars (litP, (valueT) words[i + 1], 2);
4913           md_number_to_chars (litP + 2, (valueT) words[i], 2);
4914           litP += 4;
4915         }
4916     }
4917
4918   return 0;
4919 }
4920
4921 /* We have already put the pipeline compensation in the instruction */
4922
4923 long
4924 md_pcrel_from (fixP)
4925      fixS *fixP;
4926 {
4927   if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
4928       && fixP->fx_subsy == NULL)
4929     return 0;   /* HACK */
4930
4931   if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
4932     {
4933       /* PC relative addressing on the Thumb is slightly odd
4934          as the bottom two bits of the PC are forced to zero
4935          for the calculation */
4936       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
4937     }
4938   
4939   return fixP->fx_where + fixP->fx_frag->fr_address;
4940 }
4941
4942 /* Round up a section size to the appropriate boundary. */
4943 valueT
4944 md_section_align (segment, size)
4945      segT segment;
4946      valueT size;
4947 {
4948   /* Round all sects to multiple of 4 */
4949   return (size + 3) & ~3;
4950 }
4951
4952 /* We have no need to default values of symbols.  */
4953
4954 /* ARGSUSED */
4955 symbolS *
4956 md_undefined_symbol (name)
4957      char *name;
4958 {
4959   return 0;
4960 }
4961
4962 /* arm_reg_parse () := if it looks like a register, return its token and 
4963    advance the pointer. */
4964
4965 static int
4966 arm_reg_parse (ccp)
4967      register char **ccp;
4968 {
4969   char *start = *ccp;
4970   char c;
4971   char *p;
4972   struct reg_entry *reg;
4973
4974 #ifdef REGISTER_PREFIX
4975   if (*start != REGISTER_PREFIX)
4976     return FAIL;
4977   p = start + 1;
4978 #else
4979   p = start;
4980 #ifdef OPTIONAL_REGISTER_PREFIX
4981   if (*p == OPTIONAL_REGISTER_PREFIX)
4982     p++, start++;
4983 #endif
4984 #endif
4985   if (!isalpha (*p) || !is_name_beginner (*p))
4986     return FAIL;
4987
4988   c = *p++;
4989   while (isalpha (c) || isdigit (c) || c == '_')
4990     c = *p++;
4991
4992   *--p = 0;
4993   reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
4994   *p = c;
4995   
4996   if (reg)
4997     {
4998       *ccp = p;
4999       return reg->number;
5000     }
5001
5002   return FAIL;
5003 }
5004
5005 static int
5006 arm_psr_parse (ccp)
5007      register char **ccp;
5008 {
5009   char *start = *ccp;
5010   char c, *p;
5011   CONST struct asm_psr *psr;
5012
5013   p = start;
5014   c = *p++;
5015   while (isalpha (c) || c == '_')
5016     c = *p++;
5017
5018   *--p = 0;  
5019   psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5020   *p = c;
5021
5022   if (psr)
5023     {
5024       *ccp = p;
5025       return psr->number;
5026     }
5027
5028   return FAIL;
5029 }
5030
5031 int
5032 md_apply_fix3 (fixP, val, seg)
5033      fixS *fixP;
5034      valueT *val;
5035      segT seg;
5036 {
5037   offsetT value = *val;
5038   offsetT newval;
5039   unsigned int newimm;
5040   unsigned long temp;
5041   int sign;
5042   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5043   arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
5044
5045   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5046
5047   /* Note whether this will delete the relocation.  */
5048 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5049   if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
5050       && !fixP->fx_pcrel)
5051 #else
5052   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5053 #endif
5054     fixP->fx_done = 1;
5055
5056   /* If this symbol is in a different section then we need to leave it for
5057      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
5058      so we have to undo it's effects here.  */
5059   if (fixP->fx_pcrel)
5060     {
5061       if (S_IS_DEFINED (fixP->fx_addsy)
5062           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5063         {
5064           if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5065             value = 0;
5066           else
5067             value += md_pcrel_from (fixP);
5068         }
5069     }
5070
5071   fixP->fx_addnumber = value;   /* Remember value for emit_reloc */
5072
5073   switch (fixP->fx_r_type)
5074     {
5075     case BFD_RELOC_ARM_IMMEDIATE:
5076       newimm = validate_immediate (value);
5077       temp = md_chars_to_number (buf, INSN_SIZE);
5078
5079       /* If the instruction will fail, see if we can fix things up by
5080          changing the opcode.  */
5081       if (newimm == (unsigned int) FAIL
5082           && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5083         {
5084           as_bad_where (fixP->fx_file, fixP->fx_line,
5085                         "invalid constant after fixup\n");
5086           break;
5087         }
5088
5089       newimm |= (temp & 0xfffff000);
5090       md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5091       break;
5092
5093      case BFD_RELOC_ARM_OFFSET_IMM:
5094       sign = value >= 0;
5095       if ((value = validate_offset_imm (value, 0)) == FAIL)
5096         {
5097           as_bad ("bad immediate value for offset (%d)", val);
5098           break;
5099         }
5100       if (value < 0)
5101         value = -value;
5102
5103       newval = md_chars_to_number (buf, INSN_SIZE);
5104       newval &= 0xff7ff000;
5105       newval |= value | (sign ? INDEX_UP : 0);
5106       md_number_to_chars (buf, newval, INSN_SIZE);
5107       break;
5108
5109      case BFD_RELOC_ARM_OFFSET_IMM8:
5110      case BFD_RELOC_ARM_HWLITERAL:
5111       sign = value >= 0;
5112       if ((value = validate_offset_imm (value, 1)) == FAIL)
5113         {
5114           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5115             as_bad_where (fixP->fx_file, fixP->fx_line, 
5116                         "invalid literal constant: pool needs to be closer\n");
5117           else
5118             as_bad ("bad immediate value for offset (%d)", value);
5119           break;
5120         }
5121
5122       if (value < 0)
5123         value = -value;
5124
5125       newval = md_chars_to_number (buf, INSN_SIZE);
5126       newval &= 0xff7ff0f0;
5127       newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
5128       md_number_to_chars (buf, newval, INSN_SIZE);
5129       break;
5130
5131     case BFD_RELOC_ARM_LITERAL:
5132       sign = value >= 0;
5133       if (value < 0)
5134         value = -value;
5135
5136       if ((value = validate_offset_imm (value, 0)) == FAIL)
5137         {
5138           as_bad_where (fixP->fx_file, fixP->fx_line, 
5139                         "invalid literal constant: pool needs to be closer\n");
5140           break;
5141         }
5142
5143       newval = md_chars_to_number (buf, INSN_SIZE);
5144       newval &= 0xff7ff000;
5145       newval |= value | (sign ? INDEX_UP : 0);
5146       md_number_to_chars (buf, newval, INSN_SIZE);
5147       break;
5148
5149     case BFD_RELOC_ARM_SHIFT_IMM:
5150       newval = md_chars_to_number (buf, INSN_SIZE);
5151       if (((unsigned long) value) > 32
5152           || (value == 32 
5153               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5154         {
5155           as_bad_where (fixP->fx_file, fixP->fx_line,
5156                         "shift expression is too large");
5157           break;
5158         }
5159
5160       if (value == 0)
5161         newval &= ~0x60;        /* Shifts of zero must be done as lsl */
5162       else if (value == 32)
5163         value = 0;
5164       newval &= 0xfffff07f;
5165       newval |= (value & 0x1f) << 7;
5166       md_number_to_chars (buf, newval , INSN_SIZE);
5167       break;
5168
5169     case BFD_RELOC_ARM_SWI:
5170       if (arm_data->thumb_mode)
5171         {
5172           if (((unsigned long) value) > 0xff)
5173             as_bad_where (fixP->fx_file, fixP->fx_line,
5174                           "Invalid swi expression");
5175           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5176           newval |= value;
5177           md_number_to_chars (buf, newval, THUMB_SIZE);
5178         }
5179       else
5180         {
5181           if (((unsigned long) value) > 0x00ffffff)
5182             as_bad_where (fixP->fx_file, fixP->fx_line, 
5183                           "Invalid swi expression");
5184           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5185           newval |= value;
5186           md_number_to_chars (buf, newval , INSN_SIZE);
5187         }
5188       break;
5189
5190     case BFD_RELOC_ARM_MULTI:
5191       if (((unsigned long) value) > 0xffff)
5192         as_bad_where (fixP->fx_file, fixP->fx_line,
5193                       "Invalid expression in load/store multiple");
5194       newval = value | md_chars_to_number (buf, INSN_SIZE);
5195       md_number_to_chars (buf, newval, INSN_SIZE);
5196       break;
5197
5198     case BFD_RELOC_ARM_PCREL_BRANCH:
5199       value = (value >> 2) & 0x00ffffff;
5200       newval = md_chars_to_number (buf, INSN_SIZE);
5201       value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5202       newval = value | (newval & 0xff000000);
5203       md_number_to_chars (buf, newval, INSN_SIZE);
5204       break;
5205
5206     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5207       newval = md_chars_to_number (buf, THUMB_SIZE);
5208       {
5209         addressT diff = (newval & 0xff) << 1;
5210         if (diff & 0x100)
5211          diff |= ~0xff;
5212
5213         value += diff;
5214         if ((value & 0x100) && ((value & ~0xff) != ~0xff))
5215          as_bad_where (fixP->fx_file, fixP->fx_line,
5216                        "Branch out of range");
5217         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5218       }
5219       md_number_to_chars (buf, newval, THUMB_SIZE);
5220       break;
5221
5222     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5223       newval = md_chars_to_number (buf, THUMB_SIZE);
5224       {
5225         addressT diff = (newval & 0x7ff) << 1;
5226         if (diff & 0x800)
5227          diff |= ~0x7ff;
5228
5229         value += diff;
5230         if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))
5231          as_bad_where (fixP->fx_file, fixP->fx_line,
5232                        "Branch out of range");
5233         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5234       }
5235       md_number_to_chars (buf, newval, THUMB_SIZE);
5236       break;
5237
5238     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5239       newval = md_chars_to_number (buf, THUMB_SIZE);
5240       {
5241         offsetT newval2;
5242         addressT diff;
5243
5244         newval2 = md_chars_to_number (buf + 2, THUMB_SIZE);
5245         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5246         if (diff & 0x400000)
5247          diff |= ~0x3fffff;
5248         value += diff;
5249         if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))
5250          as_bad_where (fixP->fx_file, fixP->fx_line,
5251                        "Branch with link out of range");
5252
5253         newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5254         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5255         md_number_to_chars (buf, newval, THUMB_SIZE);
5256         md_number_to_chars (buf + 2, newval2, THUMB_SIZE);
5257       }
5258       break;
5259
5260     case BFD_RELOC_8:
5261       if (fixP->fx_done || fixP->fx_pcrel)
5262         md_number_to_chars (buf, value, 1);
5263       break;
5264
5265     case BFD_RELOC_16:
5266       if (fixP->fx_done || fixP->fx_pcrel)
5267         md_number_to_chars (buf, value, 2);
5268       break;
5269
5270     case BFD_RELOC_RVA:
5271     case BFD_RELOC_32:
5272       if (fixP->fx_done || fixP->fx_pcrel)
5273         md_number_to_chars (buf, value, 4);
5274       break;
5275
5276     case BFD_RELOC_ARM_CP_OFF_IMM:
5277       sign = value >= 0;
5278       if (value < -1023 || value > 1023 || (value & 3))
5279         as_bad_where (fixP->fx_file, fixP->fx_line,
5280                       "Illegal value for co-processor offset");
5281       if (value < 0)
5282         value = -value;
5283       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5284       newval |= (value >> 2) | (sign ?  INDEX_UP : 0);
5285       md_number_to_chars (buf, newval , INSN_SIZE);
5286       break;
5287
5288     case BFD_RELOC_ARM_THUMB_OFFSET:
5289       newval = md_chars_to_number (buf, THUMB_SIZE);
5290       /* Exactly what ranges, and where the offset is inserted depends on
5291          the type of instruction, we can establish this from the top 4 bits */
5292       switch (newval >> 12)
5293         {
5294         case 4: /* PC load */
5295           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5296              forced to zero for these loads, so we will need to round
5297              up the offset if the instruction address is not word
5298              aligned (since the final address produced must be, and
5299              we can only describe word-aligned immediate offsets).  */
5300
5301           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5302             as_bad_where (fixP->fx_file, fixP->fx_line,
5303                           "Invalid offset, target not word aligned (0x%08X)",
5304                           (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5305
5306           if ((value + 2) & ~0x3fe)
5307             as_bad_where (fixP->fx_file, fixP->fx_line,
5308                           "Invalid offset");
5309
5310           /* Round up, since pc will be rounded down.  */
5311           newval |= (value + 2) >> 2;
5312           break;
5313
5314         case 9: /* SP load/store */
5315           if (value & ~0x3fc)
5316             as_bad_where (fixP->fx_file, fixP->fx_line,
5317                           "Invalid offset");
5318           newval |= value >> 2;
5319           break;
5320
5321         case 6: /* Word load/store */
5322           if (value & ~0x7c)
5323             as_bad_where (fixP->fx_file, fixP->fx_line,
5324                           "Invalid offset");
5325           newval |= value << 4; /* 6 - 2 */
5326           break;
5327
5328         case 7: /* Byte load/store */
5329           if (value & ~0x1f)
5330             as_bad_where (fixP->fx_file, fixP->fx_line,
5331                           "Invalid offset");
5332           newval |= value << 6;
5333           break;
5334
5335         case 8: /* Halfword load/store */
5336           if (value & ~0x3e)
5337             as_bad_where (fixP->fx_file, fixP->fx_line,
5338                           "Invalid offset");
5339           newval |= value << 5; /* 6 - 1 */
5340           break;
5341
5342         default:
5343           as_bad_where (fixP->fx_file, fixP->fx_line,
5344                         "Unable to process relocation for thumb opcode: %x", newval);
5345           break;
5346         }
5347       md_number_to_chars (buf, newval, THUMB_SIZE);
5348       break;
5349
5350     case BFD_RELOC_ARM_THUMB_ADD:
5351       /* This is a complicated relocation, since we use it for all of
5352          the following immediate relocations:
5353             3bit ADD/SUB
5354             8bit ADD/SUB
5355             9bit ADD/SUB SP word-aligned
5356            10bit ADD PC/SP word-aligned
5357
5358          The type of instruction being processed is encoded in the
5359          instruction field:
5360            0x8000  SUB
5361            0x00F0  Rd
5362            0x000F  Rs
5363       */
5364       newval = md_chars_to_number (buf, THUMB_SIZE);
5365       {
5366         int rd = (newval >> 4) & 0xf;
5367         int rs = newval & 0xf;
5368         int subtract = newval & 0x8000;
5369
5370         if (rd == REG_SP)
5371           {
5372             if (value & ~0x1fc)
5373               as_bad_where (fixP->fx_file, fixP->fx_line,
5374                             "Invalid immediate for stack address calculation");
5375             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5376             newval |= value >> 2;
5377           }
5378         else if (rs == REG_PC || rs == REG_SP)
5379           {
5380             if (subtract ||
5381                 value & ~0x3fc)
5382               as_bad_where (fixP->fx_file, fixP->fx_line,
5383                             "Invalid immediate for address calculation (value = 0x%08X)", value);
5384             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5385             newval |= rd << 8;
5386             newval |= value >> 2;
5387           }
5388         else if (rs == rd)
5389           {
5390             if (value & ~0xff)
5391               as_bad_where (fixP->fx_file, fixP->fx_line,
5392                             "Invalid 8bit immediate");
5393             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5394             newval |= (rd << 8) | value;
5395           }
5396         else
5397           {
5398             if (value & ~0x7)
5399               as_bad_where (fixP->fx_file, fixP->fx_line,
5400                             "Invalid 3bit immediate");
5401             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5402             newval |= rd | (rs << 3) | (value << 6);
5403           }
5404       }
5405       md_number_to_chars (buf, newval , THUMB_SIZE);
5406       break;
5407
5408     case BFD_RELOC_ARM_THUMB_IMM:
5409       newval = md_chars_to_number (buf, THUMB_SIZE);
5410       switch (newval >> 11)
5411         {
5412         case 0x04: /* 8bit immediate MOV */
5413         case 0x05: /* 8bit immediate CMP */
5414           if (value < 0 || value > 255)
5415             as_bad_where (fixP->fx_file, fixP->fx_line,
5416                           "Invalid immediate: %d is too large", value);
5417           newval |= value;
5418           break;
5419
5420         default:
5421           abort ();
5422         }
5423       md_number_to_chars (buf, newval , THUMB_SIZE);
5424       break;
5425
5426     case BFD_RELOC_ARM_THUMB_SHIFT:
5427       /* 5bit shift value (0..31) */
5428       if (value < 0 || value > 31)
5429         as_bad_where (fixP->fx_file, fixP->fx_line,
5430                       "Illegal Thumb shift value: %d", value);
5431       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5432       newval |= value << 6;
5433       md_number_to_chars (buf, newval , THUMB_SIZE);
5434       break;
5435
5436     case BFD_RELOC_NONE:
5437     default:
5438       as_bad_where (fixP->fx_file, fixP->fx_line,
5439                     "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
5440     }
5441
5442   return 1;
5443 }
5444
5445 /* Translate internal representation of relocation info to BFD target
5446    format.  */
5447 arelent *
5448 tc_gen_reloc (section, fixp)
5449      asection *section;
5450      fixS *fixp;
5451 {
5452   arelent *reloc;
5453   bfd_reloc_code_real_type code;
5454
5455   reloc = (arelent *) xmalloc (sizeof (arelent));
5456
5457   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5458   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5459
5460   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
5461   if (fixp->fx_pcrel == 0)
5462     reloc->addend = fixp->fx_offset;
5463   else
5464     reloc->addend = fixp->fx_offset = reloc->address;
5465
5466   switch (fixp->fx_r_type)
5467     {
5468     case BFD_RELOC_8:
5469       if (fixp->fx_pcrel)
5470         {
5471           code = BFD_RELOC_8_PCREL;
5472           break;
5473         }
5474
5475     case BFD_RELOC_16:
5476       if (fixp->fx_pcrel)
5477         {
5478           code = BFD_RELOC_16_PCREL;
5479           break;
5480         }
5481
5482     case BFD_RELOC_32:
5483       if (fixp->fx_pcrel)
5484         {
5485           code = BFD_RELOC_32_PCREL;
5486           break;
5487         }
5488
5489     case BFD_RELOC_ARM_PCREL_BRANCH:
5490     case BFD_RELOC_RVA:      
5491     case BFD_RELOC_THUMB_PCREL_BRANCH9:
5492     case BFD_RELOC_THUMB_PCREL_BRANCH12:
5493     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5494       code = fixp->fx_r_type;
5495       break;
5496
5497     case BFD_RELOC_ARM_LITERAL:
5498     case BFD_RELOC_ARM_HWLITERAL:
5499       /* If this is called then the a literal has been referenced across
5500          a section boundry - possibly due to an implicit dump */
5501       as_bad_where (fixp->fx_file, fixp->fx_line,
5502                     "Literal referenced across section boundry (Implicit dump?)");
5503       return NULL;
5504
5505     default:
5506       {
5507         char * type;
5508         switch (fixp->fx_r_type)
5509           {
5510           case BFD_RELOC_ARM_IMMEDIATE:    type = "IMMEDIATE";    break;
5511           case BFD_RELOC_ARM_OFFSET_IMM:   type = "OFFSET_IMM";   break;
5512           case BFD_RELOC_ARM_OFFSET_IMM8:  type = "OFFSET_IMM8";  break;
5513           case BFD_RELOC_ARM_SHIFT_IMM:    type = "SHIFT_IMM";    break;
5514           case BFD_RELOC_ARM_SWI:          type = "SWI";          break;
5515           case BFD_RELOC_ARM_MULTI:        type = "MULTI";        break;
5516           case BFD_RELOC_ARM_CP_OFF_IMM:   type = "CP_OFF_IMM";   break;
5517           case BFD_RELOC_ARM_THUMB_ADD:    type = "THUMB_ADD";    break;
5518           case BFD_RELOC_ARM_THUMB_SHIFT:  type = "THUMB_SHIFT";  break;
5519           case BFD_RELOC_ARM_THUMB_IMM:    type = "THUMB_IMM";    break;
5520           case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5521           default:                         type = "<unknown>";    break;
5522           }
5523         as_bad_where (fixp->fx_file, fixp->fx_line,
5524                       "Can not represent %s relocation in this object file format (%d)",
5525                       type, fixp->fx_pcrel);
5526         return NULL;
5527       }
5528     }
5529
5530   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5531
5532   if (reloc->howto == NULL)
5533     {
5534       as_bad_where (fixp->fx_file, fixp->fx_line,
5535                     "Can not represent %s relocation in this object file format",
5536                     bfd_get_reloc_code_name (code));
5537       return NULL;
5538     }
5539
5540   return reloc;
5541 }
5542
5543 CONST int md_short_jump_size = 4;
5544 CONST int md_long_jump_size = 4;
5545
5546 /* These should never be called on the arm */
5547 void
5548 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5549      char *ptr;
5550      addressT from_addr, to_addr;
5551      fragS *frag;
5552      symbolS *to_symbol;
5553 {
5554   as_fatal ("md_create_long_jump\n");
5555 }
5556
5557 void
5558 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5559      char *ptr;
5560      addressT from_addr, to_addr;
5561      fragS *frag;
5562      symbolS *to_symbol;
5563 {
5564   as_fatal ("md_create_short_jump\n");
5565 }
5566
5567 int
5568 md_estimate_size_before_relax (fragP, segtype)
5569      fragS *fragP;
5570      segT segtype;
5571 {
5572   as_fatal ("md_estimate_size_before_relax\n");
5573   return (1);
5574 }
5575
5576 static void
5577 output_inst (str)
5578      char *str;
5579 {
5580   char *to = NULL;
5581     
5582   if (inst.error)
5583     {
5584       as_bad (inst.error);
5585       return;
5586     }
5587
5588   to = frag_more (inst.size);
5589   if (thumb_mode && (inst.size > THUMB_SIZE))
5590     {
5591       assert (inst.size == (2 * THUMB_SIZE));
5592       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5593       md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
5594     }
5595   else
5596     md_number_to_chars (to, inst.instruction, inst.size);
5597
5598   if (inst.reloc.type != BFD_RELOC_NONE)
5599     fix_new_arm (frag_now, to - frag_now->fr_literal,
5600                  inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
5601                  inst.reloc.type);
5602
5603   return;
5604 }
5605
5606 void
5607 md_assemble (str)
5608      char *str;
5609 {
5610   char c;
5611   char *p, *q, *start;
5612
5613   /* Align the instruction */
5614   /* this may not be the right thing to do but ... */
5615   /* arm_align (2, 0); */
5616   listing_prev_line (); /* Defined in listing.h */
5617
5618   /* Align the previous label if needed */
5619   if (last_label_seen != NULL)
5620     {
5621       last_label_seen->sy_frag = frag_now;
5622       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5623       S_SET_SEGMENT (last_label_seen, now_seg);
5624     }
5625
5626   memset (&inst, '\0', sizeof (inst));
5627   inst.reloc.type = BFD_RELOC_NONE;
5628
5629   if (*str == ' ')
5630     str++;                      /* Skip leading white space */
5631     
5632   /* scan up to the end of the op-code, which must end in white space or
5633      end of string */
5634   for (start = p = str; *p != '\0'; p++)
5635     if (*p == ' ')
5636       break;
5637     
5638   if (p == str)
5639     {
5640       as_bad ("No operator -- statement `%s'\n", str);
5641       return;
5642     }
5643
5644   if (thumb_mode)
5645     {
5646       CONST struct thumb_opcode *opcode;
5647
5648       c = *p;
5649       *p = '\0';
5650       opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5651       *p = c;
5652       if (opcode)
5653         {
5654           inst.instruction = opcode->value;
5655           inst.size = opcode->size;
5656           (*opcode->parms)(p);
5657           output_inst (start);
5658           return;
5659         }
5660     }
5661   else
5662     {
5663       CONST struct asm_opcode *opcode;
5664
5665       inst.size = INSN_SIZE;
5666       /* p now points to the end of the opcode, probably white space, but we
5667          have to break the opcode up in case it contains condionals and flags;
5668          keep trying with progressively smaller basic instructions until one
5669          matches, or we run out of opcode. */
5670       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5671       for (; q != str; q--)
5672         {
5673           c = *q;
5674           *q = '\0';
5675           opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5676           *q = c;
5677           if (opcode && opcode->template)
5678             {
5679               unsigned long flag_bits = 0;
5680               char *r;
5681
5682               /* Check that this instruction is supported for this CPU */
5683               if ((opcode->variants & cpu_variant) == 0)
5684                 goto try_shorter;
5685
5686               inst.instruction = opcode->value;
5687               if (q == p)               /* Just a simple opcode */
5688                 {
5689                   if (opcode->comp_suffix != 0)
5690                     as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5691                             opcode->comp_suffix);
5692                   else
5693                     {
5694                       inst.instruction |= COND_ALWAYS;
5695                       (*opcode->parms)(q, 0);
5696                     }
5697                   output_inst (start);
5698                   return;
5699                 }
5700
5701               /* Now check for a conditional */
5702               r = q;
5703               if (p - r >= 2)
5704                 {
5705                   CONST struct asm_cond *cond;
5706                   char d = *(r + 2);
5707
5708                   *(r + 2) = '\0';
5709                   cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5710                   *(r + 2) = d;
5711                   if (cond)
5712                     {
5713                       if (cond->value == 0xf0000000)
5714                         as_tsktsk (
5715 "Warning: Use of the 'nv' conditional is deprecated\n");
5716
5717                       inst.instruction |= cond->value;
5718                       r += 2;
5719                     }
5720                   else
5721                     inst.instruction |= COND_ALWAYS;
5722                 }
5723               else
5724                 inst.instruction |= COND_ALWAYS;
5725
5726               /* if there is a compulsory suffix, it should come here, before
5727                  any optional flags. */
5728               if (opcode->comp_suffix)
5729                 {
5730                   CONST char *s = opcode->comp_suffix;
5731
5732                   while (*s)
5733                     {
5734                       inst.suffix++;
5735                       if (*r == *s)
5736                         break;
5737                       s++;
5738                     }
5739
5740                   if (*s == '\0')
5741                     {
5742                       as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5743                               opcode->comp_suffix);
5744                       return;
5745                     }
5746
5747                   r++;
5748                 }
5749
5750               /* The remainder, if any should now be flags for the instruction;
5751                  Scan these checking each one found with the opcode.  */
5752               if (r != p)
5753                 {
5754                   char d;
5755                   CONST struct asm_flg *flag = opcode->flags;
5756
5757                   if (flag)
5758                     {
5759                       int flagno;
5760
5761                       d = *p;
5762                       *p = '\0';
5763
5764                       for (flagno = 0; flag[flagno].template; flagno++)
5765                         {
5766                           if (! strcmp (r, flag[flagno].template))
5767                             {
5768                               flag_bits |= flag[flagno].set_bits;
5769                               break;
5770                             }
5771                         }
5772
5773                       *p = d;
5774                       if (! flag[flagno].template)
5775                         goto try_shorter;
5776                     }
5777                   else
5778                     goto try_shorter;
5779                 }
5780
5781               (*opcode->parms) (p, flag_bits);
5782               output_inst (start);
5783               return;
5784             }
5785
5786         try_shorter:
5787           ;
5788         }
5789     }
5790
5791   /* It wasn't an instruction, but it might be a register alias of the form
5792      alias .req reg
5793      */
5794   q = p;
5795   while (*q == ' ')
5796     q++;
5797
5798   c = *p;
5799   *p = '\0';
5800     
5801   if (*q && !strncmp (q, ".req ", 4))
5802     {
5803       int    reg;
5804       char * copy_of_str = str;
5805       char * r;
5806       
5807       q += 4;
5808       while (*q == ' ')
5809         q++;
5810
5811       for (r = q; *r != '\0'; r++)
5812         if (*r == ' ')
5813           break;
5814       
5815       if (r != q)
5816         {
5817           int regnum;
5818           char d = *r;
5819
5820           *r = '\0';
5821           regnum = arm_reg_parse (& q);
5822           *r = d;
5823
5824           reg = arm_reg_parse (& str);
5825           
5826           if (reg == FAIL)
5827             {
5828               if (regnum != FAIL)
5829                 {
5830                   insert_reg_alias (str, regnum);
5831                 }
5832               else
5833                 {
5834                   as_warn ("register '%s' does not exist\n", q);
5835                 }
5836             }
5837           else if (regnum != FAIL)
5838             {
5839               if (reg != regnum)
5840                 as_warn ("ignoring redefinition of register alias '%s'", copy_of_str );
5841               
5842               /* Do not warn abpout redefinitions to the same alias.  */
5843             }
5844           else
5845             as_warn ("ignoring redefinition of register alias '%s' to non-existant register '%s'",
5846                      copy_of_str, q);
5847         }
5848       else
5849         as_warn ("ignoring incomplete .req pseuso op");
5850       
5851       *p = c;
5852       return;
5853     }
5854
5855   *p = c;
5856   as_bad ("bad instruction `%s'", start);
5857 }
5858
5859 /*
5860  * md_parse_option
5861  *    Invocation line includes a switch not recognized by the base assembler.
5862  *    See if it's a processor-specific option.  These are:
5863  *    Cpu variants, the arm part is optional:
5864  *            -m[arm]1                Currently not supported.
5865  *            -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
5866  *            -m[arm]3                Arm 3 processor
5867  *            -m[arm]6,               Arm 6 processors
5868  *            -m[arm]7[t][[d]m]       Arm 7 processors
5869  *            -mall                   All (except the ARM1)
5870  *    FP variants:
5871  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
5872  *            -mfpe-old               (No float load/store multiples)
5873  *            -mno-fpu                Disable all floating point instructions
5874  *    Run-time endian selection:
5875  *            -EB                     big endian cpu
5876  *            -EL                     little endian cpu
5877  *    ARM Procedure Calling Standard:
5878  *            -mapcs-32               32 bit APCS
5879  *            -mapcs-26               26 bit APCS
5880  *            -mapcs-float            Pass floats in float regs
5881  *            -mapcs-reentrant        Position independent code
5882  *            -mthumb-interwork       Code supports Arm/Thumb interworking
5883  */
5884
5885 CONST char *md_shortopts = "m:";
5886 struct option md_longopts[] =
5887 {
5888 #ifdef ARM_BI_ENDIAN
5889 #define OPTION_EB (OPTION_MD_BASE + 0)
5890   {"EB", no_argument, NULL, OPTION_EB},
5891 #define OPTION_EL (OPTION_MD_BASE + 1)
5892   {"EL", no_argument, NULL, OPTION_EL},
5893 #endif
5894   {NULL, no_argument, NULL, 0}
5895 };
5896 size_t md_longopts_size = sizeof (md_longopts);
5897
5898 int
5899 md_parse_option (c, arg)
5900      int c;
5901      char *arg;
5902 {
5903   char *str = arg;
5904
5905   switch (c)
5906     {
5907 #ifdef ARM_BI_ENDIAN
5908     case OPTION_EB:
5909       target_big_endian = 1;
5910       break;
5911     case OPTION_EL:
5912       target_big_endian = 0;
5913       break;
5914 #endif
5915
5916     case 'm':
5917       switch (*str)
5918         {
5919         case 'f':
5920           if (! strcmp (str, "fpa10"))
5921             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5922           else if (! strcmp (str, "fpa11"))
5923             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5924           else if (! strcmp (str, "fpe-old"))
5925             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5926           else
5927             goto bad;
5928           break;
5929
5930         case 'n':
5931           if (! strcmp (str, "no-fpu"))
5932             cpu_variant &= ~FPU_ALL;
5933           break;
5934
5935         case 't':
5936           /* Limit assembler to generating only Thumb instructions: */
5937           if (! strcmp (str, "thumb"))
5938             {
5939               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5940               cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
5941               thumb_mode = 1;
5942             }
5943           else if (! strcmp (str, "thumb-interwork"))
5944             {
5945               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
5946 #ifdef OBJ_COFF
5947               support_interwork = true;
5948 #endif
5949             }
5950           else
5951             goto bad;
5952           break;
5953
5954         default:
5955           if (! strcmp (str, "all"))
5956             {
5957               cpu_variant = ARM_ALL | FPU_ALL;
5958               return 1;
5959             }
5960 #ifdef OBJ_COFF
5961           if (! strncmp (str, "apcs-", 5))
5962             {
5963               /* GCC passes on all command line options starting "-mapcs-..."
5964                  to us, so we must parse them here.  */
5965
5966               str += 5;
5967               
5968               if (! strcmp (str, "32"))
5969                 {
5970                   uses_apcs_26 = false;
5971                   return 1;
5972                 }
5973               else if (! strcmp (str, "26"))
5974                 {
5975                   uses_apcs_26 = true;
5976                   return 1;
5977                 }
5978               else if (! strcmp (str, "frame"))
5979                 {
5980                   /* Stack frames are being generated - does not affect
5981                      linkage of code.  */
5982                   return 1;
5983                 }
5984               else if (! strcmp (str, "stack-check"))
5985                 {
5986                   /* Stack checking is being performed - does not affect
5987                      linkage, but does require that the functions
5988                      __rt_stkovf_split_small and __rt_stkovf_split_big be
5989                      present in the final link.  */
5990
5991                   return 1;
5992                 }
5993               else if (! strcmp (str, "float"))
5994                 {
5995                   /* Floating point arguments are being passed in the floating
5996                      point registers.  This does affect linking, since this
5997                      version of the APCS is incompatible with the version that
5998                      passes floating points in the integer registers.  */
5999
6000                   uses_apcs_float = true;
6001                   return 1;
6002                 }
6003               else if (! strcmp (str, "reentrant"))
6004                 {
6005                   /* Reentrant code has been generated.  This does affect
6006                      linking, since there is no point in linking reentrant/
6007                      position independent code with absolute position code. */
6008                   pic_code = true;
6009                   return 1;
6010                 }
6011               
6012               as_bad ("Unrecognised APCS switch -m%s", arg);
6013               return 0;
6014             }
6015 #endif
6016           /* Strip off optional "arm" */
6017           if (! strncmp (str, "arm", 3))
6018             str += 3;
6019
6020           switch (*str)
6021             {
6022             case '1':
6023               if (! strcmp (str, "1"))
6024                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6025               else
6026                 goto bad;
6027               break;
6028
6029             case '2':
6030               if (! strcmp (str, "2"))
6031                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6032               else if (! strcmp (str, "250"))
6033                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6034               else
6035                 goto bad;
6036               break;
6037
6038             case '3':
6039               if (! strcmp (str, "3"))
6040                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6041               else
6042                 goto bad;
6043               break;
6044
6045             case 's':
6046               if (! strcmp (str, "strongarm") || ! strcmp (str, "strongarm110"))
6047                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6048               else
6049                 goto bad;
6050               break;
6051                 
6052             case '8':
6053               if (! strcmp (str, "8"))
6054                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6055               else
6056                 goto bad;
6057               break;
6058
6059             case '6':
6060               if (! strcmp (str, "6"))
6061                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6062               else
6063                 goto bad;
6064               break;
6065
6066             case '7':
6067               str++; /* eat the '7' */
6068               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6069               for (; *str; str++)
6070                 {
6071                 switch (* str)
6072                   {
6073                   case 't':
6074                     cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
6075                     break;
6076
6077                   case 'm':
6078                     cpu_variant |= ARM_LONGMUL;
6079                     break;
6080
6081                   case 'f': /* fe => fp enabled cpu.  */
6082                     if (str[1] == 'e')
6083                       ++ str;
6084                     else
6085                       goto bad;
6086                     
6087                   case 'c': /* Unknown */
6088                   case 'd': /* debug */
6089                   case 'i': /* embedded ice */
6090                     /* Included for completeness in ARM processor naming. */
6091                     break;
6092
6093                   default:
6094                     goto bad;
6095                   }
6096                 }
6097               break;
6098
6099             case 'v':
6100               /* Select variant based on architecture rather than processor */
6101               switch (*++str)
6102                 {
6103                 case '2':
6104                   switch (*++str)
6105                     {
6106                     case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6107                     case 0:   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6108                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
6109                     }
6110                   break;
6111                   
6112                 case '3':
6113                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6114                     
6115                   switch (*++str)
6116                     {
6117                     case 'm': cpu_variant |= ARM_LONGMUL; break;
6118                     case 0:   break;
6119                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
6120                     }
6121                   break;
6122                   
6123                 case '4':
6124                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
6125                   
6126                   switch (*++str)
6127                     {
6128                     case 't': cpu_variant |= ARM_THUMB; break;
6129                     case 0:   break;
6130                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
6131                     }
6132                   break;
6133                   
6134                 default:
6135                   as_bad ("Invalid architecture variant -m%s", arg);
6136                   break;
6137                 }
6138               break;
6139               
6140             default:
6141             bad:
6142               as_bad ("Invalid processor variant -m%s", arg);
6143               return 0;
6144             }
6145         }
6146       break;
6147
6148     default:
6149       return 0;
6150     }
6151
6152    return 1;
6153 }
6154
6155 void
6156 md_show_usage (fp)
6157      FILE *fp;
6158 {
6159   fprintf (fp,
6160 "-m[arm][<processor name>] select processor variant\n\
6161 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6162 -mthumb\t\t\tonly allow Thumb instructions\n\
6163 -mthumb-interwork\tmark the assembled code as supporting interworking\n\
6164 -mall\t\t\tallow any instruction\n\
6165 -mfpa10, -mfpa11\tselect floating point architecture\n\
6166 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
6167 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
6168 #ifdef OBJ_COFF
6169   fprintf (fp,
6170 "-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n");
6171   fprintf (fp,
6172 "-mapcs-float\t\tfloating point args are passed in floating point regs\n");
6173   fprintf (fp,
6174 "-mapcs-reentrant\tposition independent/reentrant code has been generated\n");
6175 #endif
6176 #ifdef ARM_BI_ENDIAN
6177   fprintf (fp,
6178 "-EB\t\t\tassemble code for a big endian cpu\n\
6179 -EL\t\t\tassemble code for a little endian cpu\n");
6180 #endif
6181 }
6182
6183 /* We need to be able to fix up arbitrary expressions in some statements.
6184    This is so that we can handle symbols that are an arbitrary distance from
6185    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6186    which returns part of an address in a form which will be valid for
6187    a data instruction.  We do this by pushing the expression into a symbol
6188    in the expr_section, and creating a fix for that.  */
6189
6190 static void
6191 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6192      fragS *frag;
6193      int where;
6194      short int size;
6195      expressionS *exp;
6196      int pc_rel;
6197      int reloc;
6198 {
6199   fixS *new_fix;
6200   arm_fix_data *arm_data;
6201
6202   switch (exp->X_op)
6203     {
6204     case O_constant:
6205     case O_symbol:
6206     case O_add:
6207     case O_subtract:
6208       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6209       break;
6210
6211     default:
6212       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6213                          pc_rel, reloc);
6214       break;
6215     }
6216
6217   /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6218   arm_data = (arm_fix_data *) obstack_alloc (&notes, sizeof (arm_fix_data));
6219   new_fix->tc_fix_data = (PTR) arm_data;
6220   arm_data->thumb_mode = thumb_mode;
6221
6222   return;
6223 }
6224
6225 /* A good place to do this, although this was probably not intended
6226  * for this kind of use.  We need to dump the literal pool before
6227  * references are made to a null symbol pointer.  */
6228 void
6229 arm_after_pass_hook ()
6230 {
6231   if (current_poolP != NULL)
6232     {
6233       subseg_set (text_section, 0); /* Put it at the end of text section */
6234       s_ltorg (0);
6235       listing_prev_line ();
6236     }
6237 }
6238
6239 void
6240 arm_start_line_hook ()
6241 {
6242   last_label_seen = NULL;
6243 }
6244
6245 void
6246 arm_frob_label (sym)
6247      symbolS *sym;
6248 {
6249   last_label_seen = sym;
6250   ARM_SET_THUMB (sym, thumb_mode);
6251 #ifdef OBJ_COFF
6252   ARM_SET_INTERWORK (sym, support_interwork);
6253 #endif
6254   
6255   if (label_is_thumb_function_name)
6256     {
6257       /* When the address of a Thumb function is taken the bottom
6258          bit of that address should be set.  This will allow
6259          interworking between Arm and Thumb functions to work
6260          correctly.  */
6261
6262       THUMB_SET_FUNC (sym, 1);
6263       
6264       label_is_thumb_function_name = false;
6265     }
6266 }
6267
6268 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
6269    ARM ones.  */
6270
6271 void
6272 arm_adjust_symtab ()
6273 {
6274 #ifdef OBJ_COFF
6275   symbolS *sym;
6276
6277   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6278     {
6279       if (ARM_IS_THUMB (sym))
6280         {
6281           if (THUMB_IS_FUNC (sym))
6282             {
6283               /* Mark the symbol as a Thumb function.  */
6284               if (   S_GET_STORAGE_CLASS (sym) == C_STAT
6285                   || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6286                 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6287               else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6288                 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6289               else
6290                 as_bad ("%s: unexpected function type: %d", S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6291             }
6292           else switch (S_GET_STORAGE_CLASS (sym))
6293             {
6294               case C_EXT:
6295                 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6296                 break;
6297               case C_STAT:
6298                 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6299                 break;
6300               case C_LABEL:
6301                 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6302                 break;
6303               default: /* do nothing */ 
6304                 break;
6305             }
6306         }
6307       
6308       if (ARM_IS_INTERWORK (sym))
6309         {
6310           coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF;
6311         }
6312     }
6313 #endif
6314 }
6315
6316 int
6317 arm_data_in_code ()
6318 {
6319   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6320     {
6321       *input_line_pointer = '/';
6322       input_line_pointer += 5;
6323       *input_line_pointer = 0;
6324       return 1;
6325     }
6326   return 0;
6327 }
6328
6329 char *
6330 arm_canonicalize_symbol_name (name)
6331      char *name;
6332 {
6333   int len;
6334
6335   if (thumb_mode && (len = strlen (name)) > 5
6336       && ! strcmp (name + len - 5, "/data"))
6337     {
6338       *(name + len - 5) = 0;
6339     }
6340
6341   return name;
6342 }