Tue Jun 10 11:18:09 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
[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, 8) == 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, temp;
4949   int sign;
4950   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
4951   arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
4952
4953   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
4954
4955   /* Note whether this will delete the relocation.  */
4956 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
4957   if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
4958       && !fixP->fx_pcrel)
4959 #else
4960   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
4961 #endif
4962     fixP->fx_done = 1;
4963
4964   /* If this symbol is in a different section then we need to leave it for
4965      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
4966      so we have to undo it's effects here.  */
4967   if (fixP->fx_pcrel)
4968     {
4969       if (S_IS_DEFINED (fixP->fx_addsy)
4970           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
4971         value += md_pcrel_from (fixP);
4972     }
4973
4974   fixP->fx_addnumber = value;   /* Remember value for emit_reloc */
4975
4976   switch (fixP->fx_r_type)
4977     {
4978     case BFD_RELOC_ARM_IMMEDIATE:
4979       newval = validate_immediate (value);
4980       temp = md_chars_to_number (buf, INSN_SIZE);
4981
4982       /* If the instruction will fail, see if we can fix things up by
4983          changing the opcode.  */
4984       if (newval == FAIL
4985           && (newval = negate_data_op (&temp, value)) == FAIL)
4986         {
4987           as_bad_where (fixP->fx_file, fixP->fx_line,
4988                         "invalid constant after fixup\n");
4989           break;
4990         }
4991
4992       newval |= (temp & 0xfffff000);
4993       md_number_to_chars (buf, newval, INSN_SIZE);
4994       break;
4995
4996      case BFD_RELOC_ARM_OFFSET_IMM:
4997       sign = value >= 0;
4998       if ((value = validate_offset_imm (value, 0)) == FAIL)
4999         {
5000           as_bad ("bad immediate value for offset (%d)", val);
5001           break;
5002         }
5003       if (value < 0)
5004         value = -value;
5005
5006       newval = md_chars_to_number (buf, INSN_SIZE);
5007       newval &= 0xff7ff000;
5008       newval |= value | (sign ? INDEX_UP : 0);
5009       md_number_to_chars (buf, newval, INSN_SIZE);
5010       break;
5011
5012      case BFD_RELOC_ARM_OFFSET_IMM8:
5013      case BFD_RELOC_ARM_HWLITERAL:
5014       sign = value >= 0;
5015       if ((value = validate_offset_imm (value, 1)) == FAIL)
5016         {
5017           if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5018             as_bad_where (fixP->fx_file, fixP->fx_line, 
5019                         "invalid literal constant: pool needs to be closer\n");
5020           else
5021             as_bad ("bad immediate value for offset (%d)", value);
5022           break;
5023         }
5024
5025       if (value < 0)
5026         value = -value;
5027
5028       newval = md_chars_to_number (buf, INSN_SIZE);
5029       newval &= 0xff7ff0f0;
5030       newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
5031       md_number_to_chars (buf, newval, INSN_SIZE);
5032       break;
5033
5034     case BFD_RELOC_ARM_LITERAL:
5035       sign = value >= 0;
5036       if (value < 0)
5037         value = -value;
5038
5039       if ((value = validate_offset_imm (value, 0)) == FAIL)
5040         {
5041           as_bad_where (fixP->fx_file, fixP->fx_line, 
5042                         "invalid literal constant: pool needs to be closer\n");
5043           break;
5044         }
5045
5046       newval = md_chars_to_number (buf, INSN_SIZE);
5047       newval &= 0xff7ff000;
5048       newval |= value | (sign ? INDEX_UP : 0);
5049       md_number_to_chars (buf, newval, INSN_SIZE);
5050       break;
5051
5052     case BFD_RELOC_ARM_SHIFT_IMM:
5053       newval = md_chars_to_number (buf, INSN_SIZE);
5054       if (((unsigned long) value) > 32
5055           || (value == 32 
5056               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5057         {
5058           as_bad_where (fixP->fx_file, fixP->fx_line,
5059                         "shift expression is too large");
5060           break;
5061         }
5062
5063       if (value == 0)
5064         newval &= ~0x60;        /* Shifts of zero must be done as lsl */
5065       else if (value == 32)
5066         value = 0;
5067       newval &= 0xfffff07f;
5068       newval |= (value & 0x1f) << 7;
5069       md_number_to_chars (buf, newval , INSN_SIZE);
5070       break;
5071
5072     case BFD_RELOC_ARM_SWI:
5073       if (arm_data->thumb_mode)
5074         {
5075           if (((unsigned long) value) > 0xff)
5076             as_bad_where (fixP->fx_file, fixP->fx_line,
5077                           "Invalid swi expression");
5078           newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5079           newval |= value;
5080           md_number_to_chars (buf, newval, THUMB_SIZE);
5081         }
5082       else
5083         {
5084           if (((unsigned long) value) > 0x00ffffff)
5085             as_bad_where (fixP->fx_file, fixP->fx_line, 
5086                           "Invalid swi expression");
5087           newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5088           newval |= value;
5089           md_number_to_chars (buf, newval , INSN_SIZE);
5090         }
5091       break;
5092
5093     case BFD_RELOC_ARM_MULTI:
5094       if (((unsigned long) value) > 0xffff)
5095         as_bad_where (fixP->fx_file, fixP->fx_line,
5096                       "Invalid expression in load/store multiple");
5097       newval = value | md_chars_to_number (buf, INSN_SIZE);
5098       md_number_to_chars (buf, newval, INSN_SIZE);
5099       break;
5100
5101     case BFD_RELOC_ARM_PCREL_BRANCH:
5102       value = (value >> 2) & 0x00ffffff;
5103       newval = md_chars_to_number (buf, INSN_SIZE);
5104       value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5105       newval = value | (newval & 0xff000000);
5106       md_number_to_chars (buf, newval, INSN_SIZE);
5107       break;
5108
5109     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5110       newval = md_chars_to_number (buf, THUMB_SIZE);
5111       {
5112         addressT diff = (newval & 0xff) << 1;
5113         if (diff & 0x100)
5114          diff |= ~0xff;
5115
5116         value += diff;
5117         if ((value & 0x100) && ((value & ~0xff) != ~0xff))
5118          as_bad_where (fixP->fx_file, fixP->fx_line,
5119                        "Branch out of range");
5120         newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5121       }
5122       md_number_to_chars (buf, newval, THUMB_SIZE);
5123       break;
5124
5125     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5126       newval = md_chars_to_number (buf, THUMB_SIZE);
5127       {
5128         addressT diff = (newval & 0x7ff) << 1;
5129         if (diff & 0x800)
5130          diff |= ~0x7ff;
5131
5132         value += diff;
5133         if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))
5134          as_bad_where (fixP->fx_file, fixP->fx_line,
5135                        "Branch out of range");
5136         newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5137       }
5138       md_number_to_chars (buf, newval, THUMB_SIZE);
5139       break;
5140
5141     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5142       newval = md_chars_to_number (buf, THUMB_SIZE);
5143       {
5144         offsetT newval2;
5145         addressT diff;
5146
5147         newval2 = md_chars_to_number (buf + 2, THUMB_SIZE);
5148         diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5149         if (diff & 0x400000)
5150          diff |= ~0x3fffff;
5151         value += diff;
5152         if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))
5153          as_bad_where (fixP->fx_file, fixP->fx_line,
5154                        "Branch with link out of range");
5155
5156         newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5157         newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5158         md_number_to_chars (buf, newval, THUMB_SIZE);
5159         md_number_to_chars (buf + 2, newval2, THUMB_SIZE);
5160       }
5161       break;
5162
5163     case BFD_RELOC_8:
5164       if (fixP->fx_done || fixP->fx_pcrel)
5165         md_number_to_chars (buf, value, 1);
5166       break;
5167
5168     case BFD_RELOC_16:
5169       if (fixP->fx_done || fixP->fx_pcrel)
5170         md_number_to_chars (buf, value, 2);
5171       break;
5172
5173     case BFD_RELOC_RVA:
5174     case BFD_RELOC_32:
5175       if (fixP->fx_done || fixP->fx_pcrel)
5176         md_number_to_chars (buf, value, 4);
5177       break;
5178
5179     case BFD_RELOC_ARM_CP_OFF_IMM:
5180       sign = value >= 0;
5181       if (value < -1023 || value > 1023 || (value & 3))
5182         as_bad_where (fixP->fx_file, fixP->fx_line,
5183                       "Illegal value for co-processor offset");
5184       if (value < 0)
5185         value = -value;
5186       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5187       newval |= (value >> 2) | (sign ?  INDEX_UP : 0);
5188       md_number_to_chars (buf, newval , INSN_SIZE);
5189       break;
5190
5191     case BFD_RELOC_ARM_THUMB_OFFSET:
5192       newval = md_chars_to_number (buf, THUMB_SIZE);
5193       /* Exactly what ranges, and where the offset is inserted depends on
5194          the type of instruction, we can establish this from the top 4 bits */
5195       switch (newval >> 12)
5196         {
5197         case 4: /* PC load */
5198           /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5199              forced to zero for these loads, so we will need to round
5200              up the offset if the instruction address is not word
5201              aligned (since the final address produced must be, and
5202              we can only describe word-aligned immediate offsets).  */
5203
5204           if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5205             as_bad_where (fixP->fx_file, fixP->fx_line,
5206                           "Invalid offset, target not word aligned (0x%08X)",
5207                           (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5208
5209           if ((value + 2) & ~0x3fe)
5210             as_bad_where (fixP->fx_file, fixP->fx_line,
5211                           "Invalid offset");
5212
5213           /* Round up, since pc will be rounded down.  */
5214           newval |= (value + 2) >> 2;
5215           break;
5216
5217         case 9: /* SP load/store */
5218           if (value & ~0x3fc)
5219             as_bad_where (fixP->fx_file, fixP->fx_line,
5220                           "Invalid offset");
5221           newval |= value >> 2;
5222           break;
5223
5224         case 6: /* Word load/store */
5225           if (value & ~0x7c)
5226             as_bad_where (fixP->fx_file, fixP->fx_line,
5227                           "Invalid offset");
5228           newval |= value << 4; /* 6 - 2 */
5229           break;
5230
5231         case 7: /* Byte load/store */
5232           if (value & ~0x1f)
5233             as_bad_where (fixP->fx_file, fixP->fx_line,
5234                           "Invalid offset");
5235           newval |= value << 6;
5236           break;
5237
5238         case 8: /* Halfword load/store */
5239           if (value & ~0x3e)
5240             as_bad_where (fixP->fx_file, fixP->fx_line,
5241                           "Invalid offset");
5242           newval |= value << 5; /* 6 - 1 */
5243           break;
5244
5245         default:
5246           abort ();
5247         }
5248       md_number_to_chars (buf, newval, THUMB_SIZE);
5249       break;
5250
5251     case BFD_RELOC_ARM_THUMB_ADD:
5252       /* This is a complicated relocation, since we use it for all of
5253          the following immediate relocations:
5254             3bit ADD/SUB
5255             8bit ADD/SUB
5256             9bit ADD/SUB SP word-aligned
5257            10bit ADD PC/SP word-aligned
5258
5259          The type of instruction being processed is encoded in the
5260          instruction field:
5261            0x8000  SUB
5262            0x00F0  Rd
5263            0x000F  Rs
5264       */
5265       newval = md_chars_to_number (buf, THUMB_SIZE);
5266       {
5267         int rd = (newval >> 4) & 0xf;
5268         int rs = newval & 0xf;
5269         int subtract = newval & 0x8000;
5270
5271         if (rd == REG_SP)
5272           {
5273             if (value & ~0x1fc)
5274               as_bad_where (fixP->fx_file, fixP->fx_line,
5275                             "Invalid immediate for stack address calculation");
5276             newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5277             newval |= value >> 2;
5278           }
5279         else if (rs == REG_PC || rs == REG_SP)
5280           {
5281             if (subtract ||
5282                 value & ~0x3fc)
5283               as_bad_where (fixP->fx_file, fixP->fx_line,
5284                             "Invalid immediate for address calculation (value = 0x%08X)", value);
5285             newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5286             newval |= value >> 2;
5287           }
5288         else if (rs == rd)
5289           {
5290             if (value & ~0xff)
5291               as_bad_where (fixP->fx_file, fixP->fx_line,
5292                             "Invalid 8bit immediate");
5293             newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5294             newval |= (rd << 8) | value;
5295           }
5296         else
5297           {
5298             if (value & ~0x7)
5299               as_bad_where (fixP->fx_file, fixP->fx_line,
5300                             "Invalid 3bit immediate");
5301             newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5302             newval |= rd | (rs << 3) | (value << 6);
5303           }
5304       }
5305       md_number_to_chars (buf, newval , THUMB_SIZE);
5306       break;
5307
5308     case BFD_RELOC_ARM_THUMB_IMM:
5309       newval = md_chars_to_number (buf, THUMB_SIZE);
5310       switch (newval >> 11)
5311         {
5312         case 0x04: /* 8bit immediate MOV */
5313         case 0x05: /* 8bit immediate CMP */
5314           if (value < 0 || value > 255)
5315             as_bad_where (fixP->fx_file, fixP->fx_line,
5316                           "Invalid immediate: %d is too large", value);
5317           newval |= value;
5318           break;
5319
5320         default:
5321           abort ();
5322         }
5323       md_number_to_chars (buf, newval , THUMB_SIZE);
5324       break;
5325
5326     case BFD_RELOC_ARM_THUMB_SHIFT:
5327       /* 5bit shift value (0..31) */
5328       if (value < 0 || value > 31)
5329         as_bad_where (fixP->fx_file, fixP->fx_line,
5330                       "Illegal Thumb shift value: %d", value);
5331       newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5332       newval |= value << 6;
5333       md_number_to_chars (buf, newval , THUMB_SIZE);
5334       break;
5335
5336     case BFD_RELOC_NONE:
5337     default:
5338       as_bad_where (fixP->fx_file, fixP->fx_line,
5339                     "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
5340     }
5341
5342   return 1;
5343 }
5344
5345 /* Translate internal representation of relocation info to BFD target
5346    format.  */
5347 arelent *
5348 tc_gen_reloc (section, fixp)
5349      asection *section;
5350      fixS *fixp;
5351 {
5352   arelent *reloc;
5353   bfd_reloc_code_real_type code;
5354
5355   reloc = (arelent *) xmalloc (sizeof (arelent));
5356
5357   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5358   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5359
5360   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
5361   if (fixp->fx_pcrel == 0)
5362     reloc->addend = fixp->fx_offset;
5363   else
5364     reloc->addend = fixp->fx_offset = reloc->address;
5365
5366   switch (fixp->fx_r_type)
5367     {
5368     case BFD_RELOC_8:
5369       if (fixp->fx_pcrel)
5370         {
5371           code = BFD_RELOC_8_PCREL;
5372           break;
5373         }
5374
5375     case BFD_RELOC_16:
5376       if (fixp->fx_pcrel)
5377         {
5378           code = BFD_RELOC_16_PCREL;
5379           break;
5380         }
5381
5382     case BFD_RELOC_32:
5383       if (fixp->fx_pcrel)
5384         {
5385           code = BFD_RELOC_32_PCREL;
5386           break;
5387         }
5388
5389     case BFD_RELOC_ARM_PCREL_BRANCH:
5390     case BFD_RELOC_RVA:      
5391     case BFD_RELOC_THUMB_PCREL_BRANCH9:
5392     case BFD_RELOC_THUMB_PCREL_BRANCH12:
5393     case BFD_RELOC_THUMB_PCREL_BRANCH23:
5394       code = fixp->fx_r_type;
5395       break;
5396
5397     case BFD_RELOC_ARM_LITERAL:
5398     case BFD_RELOC_ARM_HWLITERAL:
5399       /* If this is called then the a literal has been referenced across
5400          a section boundry - possibly due to an implicit dump */
5401       as_bad_where (fixp->fx_file, fixp->fx_line,
5402                     "Literal referenced across section boundry (Implicit dump?)");
5403       return NULL;
5404
5405     case BFD_RELOC_ARM_IMMEDIATE:
5406       as_bad_where (fixp->fx_file, fixp->fx_line,
5407                     "Internal_relocation (type %d) not fixed up (IMMEDIATE)",
5408                     fixp->fx_r_type);
5409       return NULL;
5410
5411     case BFD_RELOC_ARM_OFFSET_IMM:
5412       as_bad_where (fixp->fx_file, fixp->fx_line,
5413                     "Internal_relocation (type %d) not fixed up (OFFSET_IMM)",
5414                     fixp->fx_r_type);
5415       return NULL;
5416
5417     case BFD_RELOC_ARM_OFFSET_IMM8:
5418       as_bad_where (fixp->fx_file, fixp->fx_line,
5419                     "Internal_relocation (type %d) not fixed up (OFFSET_IMM8)",
5420                     fixp->fx_r_type);
5421       return NULL;
5422
5423     case BFD_RELOC_ARM_SHIFT_IMM:
5424       as_bad_where (fixp->fx_file, fixp->fx_line,
5425                     "Internal_relocation (type %d) not fixed up (SHIFT_IMM)",
5426                     fixp->fx_r_type);
5427       return NULL;
5428
5429     case BFD_RELOC_ARM_SWI:
5430       as_bad_where (fixp->fx_file, fixp->fx_line,
5431                     "Internal_relocation (type %d) not fixed up (SWI)",
5432                     fixp->fx_r_type);
5433       return NULL;
5434
5435     case BFD_RELOC_ARM_MULTI:
5436       as_bad_where (fixp->fx_file, fixp->fx_line,
5437                     "Internal_relocation (type %d) not fixed up (MULTI)",
5438                     fixp->fx_r_type);
5439       return NULL;
5440
5441     case BFD_RELOC_ARM_CP_OFF_IMM:
5442       as_bad_where (fixp->fx_file, fixp->fx_line,
5443                     "Internal_relocation (type %d) not fixed up (CP_OFF_IMM)",
5444                     fixp->fx_r_type);
5445       return NULL;
5446
5447     case BFD_RELOC_ARM_THUMB_OFFSET:
5448       as_bad_where (fixp->fx_file, fixp->fx_line,
5449                     "Internal_relocation (type %d) not fixed up (THUMB_OFFSET)",
5450                     fixp->fx_r_type);
5451       return NULL;
5452
5453     default:
5454       abort ();
5455     }
5456
5457   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5458   assert (reloc->howto != 0);
5459
5460   return reloc;
5461 }
5462
5463 CONST int md_short_jump_size = 4;
5464 CONST int md_long_jump_size = 4;
5465
5466 /* These should never be called on the arm */
5467 void
5468 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5469      char *ptr;
5470      addressT from_addr, to_addr;
5471      fragS *frag;
5472      symbolS *to_symbol;
5473 {
5474   as_fatal ("md_create_long_jump\n");
5475 }
5476
5477 void
5478 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5479      char *ptr;
5480      addressT from_addr, to_addr;
5481      fragS *frag;
5482      symbolS *to_symbol;
5483 {
5484   as_fatal ("md_create_short_jump\n");
5485 }
5486
5487 int
5488 md_estimate_size_before_relax (fragP, segtype)
5489      fragS *fragP;
5490      segT segtype;
5491 {
5492   as_fatal ("md_estimate_size_before_relax\n");
5493   return (1);
5494 }
5495
5496 static void
5497 output_inst (str)
5498      char *str;
5499 {
5500   char *to = NULL;
5501     
5502   if (inst.error)
5503     {
5504       as_bad ("%s -- statement `%s'\n", inst.error, str);
5505       return;
5506     }
5507
5508   to = frag_more (inst.size);
5509   if (thumb_mode && (inst.size > THUMB_SIZE))
5510     {
5511       assert (inst.size == (2 * THUMB_SIZE));
5512       md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5513       md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
5514     }
5515   else
5516     md_number_to_chars (to, inst.instruction, inst.size);
5517
5518   if (inst.reloc.type != BFD_RELOC_NONE)
5519     fix_new_arm (frag_now, to - frag_now->fr_literal,
5520                  inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
5521                  inst.reloc.type);
5522
5523   return;
5524 }
5525
5526 void
5527 md_assemble (str)
5528      char *str;
5529 {
5530   char c;
5531   char *p, *q, *start;
5532
5533   /* Align the instruction */
5534   /* this may not be the right thing to do but ... */
5535   /* arm_align (2, 0); */
5536   listing_prev_line (); /* Defined in listing.h */
5537
5538   /* Align the previous label if needed */
5539   if (last_label_seen != NULL)
5540     {
5541       last_label_seen->sy_frag = frag_now;
5542       S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5543       S_SET_SEGMENT (last_label_seen, now_seg);
5544     }
5545
5546   memset (&inst, '\0', sizeof (inst));
5547   inst.reloc.type = BFD_RELOC_NONE;
5548
5549   if (*str == ' ')
5550     str++;                      /* Skip leading white space */
5551     
5552   /* scan up to the end of the op-code, which must end in white space or
5553      end of string */
5554   for (start = p = str; *p != '\0'; p++)
5555     if (*p == ' ')
5556       break;
5557     
5558   if (p == str)
5559     {
5560       as_bad ("No operator -- statement `%s'\n", str);
5561       return;
5562     }
5563
5564   if (thumb_mode)
5565     {
5566       CONST struct thumb_opcode *opcode;
5567
5568       c = *p;
5569       *p = '\0';
5570       opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5571       *p = c;
5572       if (opcode)
5573         {
5574           inst.instruction = opcode->value;
5575           inst.size = opcode->size;
5576           (*opcode->parms)(p);
5577           output_inst (start);
5578           return;
5579         }
5580     }
5581   else
5582     {
5583       CONST struct asm_opcode *opcode;
5584
5585       inst.size = INSN_SIZE;
5586       /* p now points to the end of the opcode, probably white space, but we
5587          have to break the opcode up in case it contains condionals and flags;
5588          keep trying with progressively smaller basic instructions until one
5589          matches, or we run out of opcode. */
5590       q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5591       for (; q != str; q--)
5592         {
5593           c = *q;
5594           *q = '\0';
5595           opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5596           *q = c;
5597           if (opcode && opcode->template)
5598             {
5599               unsigned long flag_bits = 0;
5600               char *r;
5601
5602               /* Check that this instruction is supported for this CPU */
5603               if ((opcode->variants & cpu_variant) == 0)
5604                 goto try_shorter;
5605
5606               inst.instruction = opcode->value;
5607               if (q == p)               /* Just a simple opcode */
5608                 {
5609                   if (opcode->comp_suffix != 0)
5610                     as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5611                             opcode->comp_suffix);
5612                   else
5613                     {
5614                       inst.instruction |= COND_ALWAYS;
5615                       (*opcode->parms)(q, 0);
5616                     }
5617                   output_inst (start);
5618                   return;
5619                 }
5620
5621               /* Now check for a conditional */
5622               r = q;
5623               if (p - r >= 2)
5624                 {
5625                   CONST struct asm_cond *cond;
5626                   char d = *(r + 2);
5627
5628                   *(r + 2) = '\0';
5629                   cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5630                   *(r + 2) = d;
5631                   if (cond)
5632                     {
5633                       if (cond->value == 0xf0000000)
5634                         as_tsktsk (
5635 "Warning: Use of the 'nv' conditional is deprecated\n");
5636
5637                       inst.instruction |= cond->value;
5638                       r += 2;
5639                     }
5640                   else
5641                     inst.instruction |= COND_ALWAYS;
5642                 }
5643               else
5644                 inst.instruction |= COND_ALWAYS;
5645
5646               /* if there is a compulsory suffix, it should come here, before
5647                  any optional flags. */
5648               if (opcode->comp_suffix)
5649                 {
5650                   CONST char *s = opcode->comp_suffix;
5651
5652                   while (*s)
5653                     {
5654                       inst.suffix++;
5655                       if (*r == *s)
5656                         break;
5657                       s++;
5658                     }
5659
5660                   if (*s == '\0')
5661                     {
5662                       as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5663                               opcode->comp_suffix);
5664                       return;
5665                     }
5666
5667                   r++;
5668                 }
5669
5670               /* The remainder, if any should now be flags for the instruction;
5671                  Scan these checking each one found with the opcode.  */
5672               if (r != p)
5673                 {
5674                   char d;
5675                   CONST struct asm_flg *flag = opcode->flags;
5676
5677                   if (flag)
5678                     {
5679                       int flagno;
5680
5681                       d = *p;
5682                       *p = '\0';
5683
5684                       for (flagno = 0; flag[flagno].template; flagno++)
5685                         {
5686                           if (! strcmp (r, flag[flagno].template))
5687                             {
5688                               flag_bits |= flag[flagno].set_bits;
5689                               break;
5690                             }
5691                         }
5692
5693                       *p = d;
5694                       if (! flag[flagno].template)
5695                         goto try_shorter;
5696                     }
5697                   else
5698                     goto try_shorter;
5699                 }
5700
5701               (*opcode->parms) (p, flag_bits);
5702               output_inst (start);
5703               return;
5704             }
5705
5706         try_shorter:
5707           ;
5708         }
5709     }
5710
5711   /* It wasn't an instruction, but it might be a register alias of the form
5712      alias .req reg
5713      */
5714   q = p;
5715   while (*q == ' ')
5716     q++;
5717
5718   c = *p;
5719   *p = '\0';
5720     
5721   if (*q && !strncmp (q, ".req ", 4))
5722     {
5723       int reg;
5724       if ((reg = arm_reg_parse (&str)) == FAIL)
5725         {
5726           char *r;
5727       
5728           q += 4;
5729           while (*q == ' ')
5730             q++;
5731
5732           for (r = q; *r != '\0'; r++)
5733             if (*r == ' ')
5734               break;
5735
5736           if (r != q)
5737             {
5738               int regnum;
5739               char d = *r;
5740
5741               *r = '\0';
5742               regnum = arm_reg_parse (&q);
5743               *r = d;
5744               if (regnum != FAIL)
5745                 {
5746                   insert_reg_alias (str, regnum);
5747                   *p = c;
5748                   return;
5749                 }
5750             }
5751         }
5752       else
5753         {
5754           *p = c;
5755           return;
5756         }
5757     }
5758
5759   *p = c;
5760   as_bad ("bad instruction `%s'", start);
5761 }
5762
5763 /*
5764  * md_parse_option
5765  *    Invocation line includes a switch not recognized by the base assembler.
5766  *    See if it's a processor-specific option.  These are:
5767  *    Cpu variants, the arm part is optional:
5768  *            -m[arm]1                Currently not supported.
5769  *            -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
5770  *            -m[arm]3                Arm 3 processor
5771  *            -m[arm]6,               Arm 6 processors
5772  *            -m[arm]7[t][[d]m]       Arm 7 processors
5773  *            -mall                   All (except the ARM1)
5774  *    FP variants:
5775  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
5776  *            -mfpe-old               (No float load/store multiples)
5777  *            -mno-fpu                Disable all floating point instructions
5778  *    Run-time endian selection:
5779  *            -EB                     big endian cpu
5780  *            -EL                     little endian cpu
5781  *    ARM Procedure Calling Standard:
5782  *            -mapcs-32               32 bit APCS
5783  *            -mapcs-26               26 bit APCS
5784  */
5785
5786 CONST char *md_shortopts = "m:";
5787 struct option md_longopts[] =
5788 {
5789 #ifdef ARM_BI_ENDIAN
5790 #define OPTION_EB (OPTION_MD_BASE + 0)
5791   {"EB", no_argument, NULL, OPTION_EB},
5792 #define OPTION_EL (OPTION_MD_BASE + 1)
5793   {"EL", no_argument, NULL, OPTION_EL},
5794 #endif
5795   {NULL, no_argument, NULL, 0}
5796 };
5797 size_t md_longopts_size = sizeof (md_longopts);
5798
5799 int
5800 md_parse_option (c, arg)
5801      int c;
5802      char *arg;
5803 {
5804   char *str = arg;
5805
5806   switch (c)
5807     {
5808 #ifdef ARM_BI_ENDIAN
5809     case OPTION_EB:
5810       target_big_endian = 1;
5811       break;
5812     case OPTION_EL:
5813       target_big_endian = 0;
5814       break;
5815 #endif
5816
5817     case 'm':
5818       switch (*str)
5819         {
5820         case 'f':
5821           if (! strcmp (str, "fpa10"))
5822             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5823           else if (! strcmp (str, "fpa11"))
5824             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5825           else if (! strcmp (str, "fpe-old"))
5826             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5827           else
5828             goto bad;
5829           break;
5830
5831         case 'n':
5832           if (! strcmp (str, "no-fpu"))
5833             cpu_variant &= ~FPU_ALL;
5834           break;
5835
5836         case 't':
5837           /* Limit assembler to generating only Thumb instructions: */
5838           if (! strcmp (str, "thumb"))
5839             {
5840               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5841               cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
5842               thumb_mode = 1;
5843             }
5844           else
5845             goto bad;
5846           break;
5847
5848         default:
5849           if (! strcmp (str, "all"))
5850             {
5851               cpu_variant = ARM_ALL | FPU_ALL;
5852               return 1;
5853             }
5854 #ifdef OBJ_COFF
5855           if (! strcmp (str, "apcs-32"))
5856             {
5857               uses_apcs_26 = false;
5858               return 1;
5859             }
5860           else if (! strcmp (str, "apcs-26"))
5861             {
5862               uses_apcs_26 = true;
5863               return 1;
5864             }
5865 #endif
5866           /* Strip off optional "arm" */
5867           if (! strncmp (str, "arm", 3))
5868             str += 3;
5869
5870           switch (*str)
5871             {
5872             case '1':
5873               if (! strcmp (str, "1"))
5874                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
5875               else
5876                 goto bad;
5877               break;
5878
5879             case '2':
5880               if (! strcmp (str, "2"))
5881                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
5882               else if (! strcmp (str, "250"))
5883                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
5884               else
5885                 goto bad;
5886               break;
5887
5888             case '3':
5889               if (! strcmp (str, "3"))
5890                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
5891               else
5892                 goto bad;
5893               break;
5894
5895             case '6':
5896               if (! strcmp (str, "6"))
5897                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
5898               else
5899                 goto bad;
5900               break;
5901
5902             case '7':
5903               str++; /* eat the '7' */
5904               cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5905               for (; *str; str++)
5906                 {
5907                 switch (*str)
5908                   {
5909                   case 't':
5910                     cpu_variant |= ARM_THUMB;
5911                     break;
5912
5913                   case 'm':
5914                     cpu_variant |= ARM_LONGMUL;
5915                     break;
5916
5917                   case 'd': /* debug */
5918                   case 'i': /* embedded ice */
5919                     /* Included for completeness in ARM processor
5920                        naming. */
5921                     break;
5922
5923                   default:
5924                     goto bad;
5925                   }
5926                 }
5927               break;
5928
5929             case 'v':
5930               /* Select variant based on architecture rather than processor */
5931               switch (*++str)
5932                 {
5933                 case '2':
5934                   switch (*++str)
5935                     {
5936                     case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
5937                     case 0:   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
5938                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
5939                     }
5940                   break;
5941                   
5942                 case '3':
5943                     cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5944                     
5945                   switch (*++str)
5946                     {
5947                     case 'm': cpu_variant |= ARM_LONGMUL; break;
5948                     case 0:   break;
5949                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
5950                     }
5951                   break;
5952                   
5953                 case '4':
5954                   cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5955                   
5956                   switch (*++str)
5957                     {
5958                     case 't': cpu_variant |= ARM_THUMB; break;
5959                     case 0:   break;
5960                     default:  as_bad ("Invalid architecture variant -m%s", arg); break;
5961                     }
5962                   break;
5963                   
5964                 default:
5965                   as_bad ("Invalid architecture variant -m%s", arg);
5966                   break;
5967                 }
5968               break;
5969               
5970             default:
5971             bad:
5972               as_bad ("Invalid processor variant -m%s", arg);
5973               return 0;
5974             }
5975         }
5976       break;
5977
5978     default:
5979       return 0;
5980     }
5981
5982    return 1;
5983 }
5984
5985 void
5986 md_show_usage (fp)
5987      FILE *fp;
5988 {
5989   fprintf (fp,
5990 "-m[arm][1|2|250|3|6|7[t][d][m][i]] select processor variant\n\
5991 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
5992 -mthumb\t\t\tonly allow Thumb instructions\n\
5993 -mall\t\t\tallow any instruction\n\
5994 -mfpa10, -mfpa11\tselect floating point architecture\n\
5995 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
5996 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
5997 #ifdef OBJ_COFF
5998   fprintf (fp,
5999 "-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n");
6000 #endif
6001 #ifdef ARM_BI_ENDIAN
6002   fprintf (fp,
6003 "-EB\t\t\tassemble code for a big endian cpu\n\
6004 -EL\t\t\tassemble code for a little endian cpu\n");
6005 #endif
6006 }
6007
6008 /* We need to be able to fix up arbitrary expressions in some statements.
6009    This is so that we can handle symbols that are an arbitrary distance from
6010    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6011    which returns part of an address in a form which will be valid for
6012    a data instruction.  We do this by pushing the expression into a symbol
6013    in the expr_section, and creating a fix for that.  */
6014
6015 static void
6016 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6017      fragS *frag;
6018      int where;
6019      short int size;
6020      expressionS *exp;
6021      int pc_rel;
6022      int reloc;
6023 {
6024   fixS *new_fix;
6025   arm_fix_data *arm_data;
6026
6027   switch (exp->X_op)
6028     {
6029     case O_constant:
6030     case O_symbol:
6031     case O_add:
6032     case O_subtract:
6033       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6034       break;
6035
6036     default:
6037       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6038                          pc_rel, reloc);
6039       break;
6040     }
6041
6042   /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6043   arm_data = (arm_fix_data *) obstack_alloc (&notes, sizeof (arm_fix_data));
6044   new_fix->tc_fix_data = (PTR) arm_data;
6045   arm_data->thumb_mode = thumb_mode;
6046
6047   return;
6048 }
6049
6050 /* A good place to do this, although this was probably not intended
6051  * for this kind of use.  We need to dump the literal pool before
6052  * references are made to a null symbol pointer.  */
6053 void
6054 arm_after_pass_hook ()
6055 {
6056   if (current_poolP != NULL)
6057     {
6058       subseg_set (text_section, 0); /* Put it at the end of text section */
6059       s_ltorg (0);
6060       listing_prev_line ();
6061     }
6062 }
6063
6064 void
6065 arm_start_line_hook ()
6066 {
6067   last_label_seen = NULL;
6068 }
6069
6070 void
6071 arm_frob_label (sym)
6072      symbolS *sym;
6073 {
6074   last_label_seen = sym;
6075   ARM_SET_TYPE(sym,thumb_mode);
6076 }
6077
6078 /* Adjust the symbol table.  This marks Thumb symbols as distinct from
6079    ARM ones.  */
6080
6081 void
6082 arm_adjust_symtab ()
6083 {
6084 #ifdef OBJ_COFF
6085   symbolS *sym;
6086
6087   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6088     {
6089       if (ARM_GET_TYPE(sym)) /* Thumb */
6090         {
6091           switch (S_GET_STORAGE_CLASS (sym))
6092             {
6093               case C_EXT:
6094                 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6095                 break;
6096               case C_STAT:
6097                 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6098                 break;
6099               case C_LABEL:
6100                 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6101                 break;
6102               default: /* do nothing */ 
6103                 break;
6104             }
6105         }
6106     }
6107 #endif
6108 }
6109
6110 int
6111 arm_data_in_code ()
6112 {
6113   if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6114     {
6115       *input_line_pointer = '/';
6116       input_line_pointer += 5;
6117       *input_line_pointer = 0;
6118       return 1;
6119     }
6120   return 0;
6121 }
6122
6123 char *
6124 arm_canonicalize_symbol_name (name)
6125      char *name;
6126 {
6127   int len;
6128
6129   if (thumb_mode && (len = strlen (name)) > 5
6130       && ! strcmp (name + len - 5, "/data"))
6131     {
6132       *(name + len - 5) = 0;
6133     }
6134
6135   return name;
6136 }