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