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