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