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