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