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