* config/tc-arm.c (do_swi): Allow optional leading '#'.
[external/binutils.git] / gas / config / tc-arm.c
1 /* tc-arm.c  All the arm specific stuff in one convenient, huge,
2    slow to compile, easy to find file.
3    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4         Modified by David Taylor (dtaylor@armltd.co.uk)
5
6    Copyright (C) 1994, 1995 Free Software Foundation, Inc.
7
8    This file is part of GAS, the GNU Assembler.
9
10    GAS is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2, or (at your option)
13    any later version.
14
15    GAS is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with GAS; see the file COPYING.  If not, write to
22    the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 #include <ctype.h>
25 #include <string.h>
26 #define  NO_RELOC 0
27 #include "as.h"
28
29 /* need TARGET_CPU */
30 #include "config.h"
31 #include "subsegs.h"
32 #include "obstack.h"
33 #include "symbols.h"
34 #include "listing.h"
35
36 /* ??? This is currently unused.  */
37 #ifdef __STDC__
38 #define internalError() \
39   as_fatal ("ARM Internal Error, line %d, %s", __LINE__, __FILE__)
40 #else
41 #define internalError() as_fatal ("ARM Internal Error")
42 #endif
43
44 /* Types of processor to assemble for.  */
45 #define ARM_1           0x00000001
46 #define ARM_2           0x00000002
47 #define ARM_250         0x00000002      /* Checkme, should this be = ARM_3?  */
48 #define ARM_3           0x00000004
49 #define ARM_6           0x00000008
50 #define ARM_7           0x00000008
51 #define ARM_7DM         0x00000010
52
53 /* Some useful combinations:  */
54 #define ARM_ANY         0x00ffffff
55 #define ARM_2UP         0x00fffffe
56 #define ARM_ALL         ARM_2UP         /* Not arm1 only */
57 #define ARM_3UP         0x00fffffc
58 #define ARM_6UP         0x00fffff8
59 #define ARM_LONGMUL     0x00000010      /* Don't know which will have this.  */
60
61 #define FPU_CORE        0x80000000
62 #define FPU_FPA10       0x40000000
63 #define FPU_FPA11       0x40000000
64 #define FPU_NONE        0
65
66 /* Some useful combinations  */
67 #define FPU_ALL         0xff000000      /* Note this is ~ARM_ANY */
68 #define FPU_MEMMULTI    0x7f000000      /* Not fpu_core */
69
70 #ifndef CPU_DEFAULT
71 #define CPU_DEFAULT ARM_ALL
72 #endif
73
74 #ifndef FPU_DEFAULT
75 #define FPU_DEFAULT FPU_ALL
76 #endif
77
78 unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
79
80 /* This array holds the chars that always start a comment.  If the
81    pre-processor is disabled, these aren't very useful */
82 CONST char comment_chars[] = "@";
83
84 /* This array holds the chars that only start a comment at the beginning of
85    a line.  If the line seems to have the form '# 123 filename'
86    .line and .file directives will appear in the pre-processed output */
87 /* Note that input_file.c hand checks for '#' at the beginning of the
88    first line of the input file.  This is because the compiler outputs
89    #NO_APP at the beginning of its output. */
90 /* Also note that comments like this one will always work. */
91 CONST char line_comment_chars[] = "#";
92
93 CONST char line_separator_chars[] = "";
94
95 /* Chars that can be used to separate mant from exp in floating point nums */
96 CONST char EXP_CHARS[] = "eE";
97
98 /* Chars that mean this number is a floating point constant */
99 /* As in 0f12.456 */
100 /* or    0d1.2345e12 */
101
102 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
103
104 const int md_reloc_size = 8;            /* Size of relocation record */
105
106 struct arm_it
107 {
108   CONST char *error;
109   unsigned long instruction;
110   int suffix;
111   struct
112     {
113       bfd_reloc_code_real_type type;
114       expressionS exp;
115       int pc_rel;
116     } reloc;
117 };
118
119 struct arm_it inst;
120
121 struct asm_shift
122 {
123   CONST char *template;
124   unsigned long value;
125 };
126
127 static CONST struct asm_shift shift[] =
128 {
129   {"asl", 0},
130   {"lsl", 0},
131   {"lsr", 0x00000020},
132   {"asr", 0x00000040},
133   {"ror", 0x00000060},
134   {"rrx", 0x00000060},
135   {"ASL", 0},
136   {"LSL", 0},
137   {"LSR", 0x00000020},
138   {"ASR", 0x00000040},
139   {"ROR", 0x00000060},
140   {"RRX", 0x00000060}
141 };
142
143 #define NO_SHIFT_RESTRICT 1
144 #define SHIFT_RESTRICT    0
145
146 #define NUM_FLOAT_VALS 8
147
148 CONST char *fp_const[] = 
149 {
150   "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
151 };
152
153 /* Number of littlenums required to hold an extended precision number */
154 #define MAX_LITTLENUMS 6
155
156 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
157
158 #define FAIL    (-1)
159 #define SUCCESS (0)
160
161 #define SUFF_S 1
162 #define SUFF_D 2
163 #define SUFF_E 3
164 #define SUFF_P 4
165
166 #define CP_T_X   0x00008000
167 #define CP_T_Y   0x00400000
168 #define CP_T_Pre 0x01000000
169 #define CP_T_UD  0x00800000
170 #define CP_T_WB  0x00200000
171
172 #define TRANS_BIT       (0x00200000)
173
174 struct asm_cond
175 {
176   CONST char *template;
177   unsigned long value;
178 };
179
180 /* This is to save a hash look-up in the common case */
181 #define COND_ALWAYS 0xe0000000
182
183 static CONST struct asm_cond conds[] = 
184 {
185   {"eq", 0x00000000},
186   {"ne", 0x10000000},
187   {"cs", 0x20000000}, {"hs", 0x20000000},
188   {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
189   {"mi", 0x40000000},
190   {"pl", 0x50000000},
191   {"vs", 0x60000000},
192   {"vc", 0x70000000},
193   {"hi", 0x80000000},
194   {"ls", 0x90000000},
195   {"ge", 0xa0000000},
196   {"lt", 0xb0000000},
197   {"gt", 0xc0000000},
198   {"le", 0xd0000000},
199   {"al", 0xe0000000},
200   {"nv", 0xf0000000}
201 };
202
203
204 struct asm_flg
205 {
206   CONST char *template;         /* Basic flag string */
207   unsigned long set_bits;       /* Bits to set */
208 };
209
210 static CONST struct asm_flg s_flag[] =
211 {
212   {"s", 0x00100000},
213   {NULL, 0}
214 };
215
216 static CONST struct asm_flg ldst_flags[] =
217 {
218   {"b",  0x00400000},
219   {"t",  TRANS_BIT},
220   {"bt", 0x00400000 | TRANS_BIT},
221   {NULL, 0}
222 };
223
224 static CONST struct asm_flg byte_flag[] =
225 {
226   {"b", 0x00400000},
227   {NULL, 0}
228 };
229
230 static CONST struct asm_flg cmp_flags[] =
231 {
232   {"s", 0x00100000},
233   {"p", 0x0010f000},
234   {NULL, 0}
235 };
236
237 static CONST struct asm_flg ldm_flags[] =
238 {
239   {"ed", 0x01800000},
240   {"fd", 0x00800000},
241   {"ea", 0x01000000},
242   {"fa", 0x08000000},
243   {"ib", 0x01800000},
244   {"ia", 0x00800000},
245   {"db", 0x01000000},
246   {"da", 0x08000000},
247   {NULL, 0}
248 };
249
250 static CONST struct asm_flg stm_flags[] =
251 {
252   {"ed", 0x08000000},
253   {"fd", 0x01000000},
254   {"ea", 0x00800000},
255   {"fa", 0x01800000},
256   {"ib", 0x01800000},
257   {"ia", 0x00800000},
258   {"db", 0x01000000},
259   {"da", 0x08000000},
260   {NULL, 0}
261 };
262
263 static CONST struct asm_flg lfm_flags[] =
264 {
265   {"fd", 0x00800000},
266   {"ea", 0x01000000},
267   {NULL, 0}
268 };
269
270 static CONST struct asm_flg sfm_flags[] =
271 {
272   {"fd", 0x01000000},
273   {"ea", 0x00800000},
274   {NULL, 0}
275 };
276
277 static CONST struct asm_flg round_flags[] =
278 {
279   {"p", 0x00000020},
280   {"m", 0x00000040},
281   {"z", 0x00000060},
282   {NULL, 0}
283 };
284
285 static CONST struct asm_flg except_flag[] =
286 {
287   {"e", 0x00400000},
288   {NULL, 0}
289 };
290
291 static CONST struct asm_flg cplong_flag[] =
292 {
293   {"l", 0x00400000},
294   {NULL, 0}
295 };
296
297 struct asm_psr
298 {
299   CONST char *template;
300   unsigned long number;
301 };
302
303 #define PSR_ALL         0x00010000
304
305 static CONST struct asm_psr psrs[] =
306 {
307   /* Valid <psr>'s */
308   {"cpsr",      0},
309   {"cpsr_all",  0},
310   {"spsr",      1},
311   {"spsr_all",  1},
312
313   /* Valid <psrf>'s */
314   {"cpsr_flg",  2},
315   {"spsr_flg",  3}
316 };
317
318 /* Functions called by parser */
319 /* ARM instructions */
320 static void do_arit             PARAMS ((char *operands, unsigned long flags));
321 static void do_cmp              PARAMS ((char *operands, unsigned long flags));
322 static void do_mov              PARAMS ((char *operands, unsigned long flags));
323 static void do_ldst             PARAMS ((char *operands, unsigned long flags));
324 static void do_ldmstm           PARAMS ((char *operands, unsigned long flags));
325 static void do_branch           PARAMS ((char *operands, unsigned long flags));
326 static void do_swi              PARAMS ((char *operands, unsigned long flags));
327 /* Pseudo Op codes */
328 static void do_adr              PARAMS ((char *operands, unsigned long flags));
329 static void do_nop              PARAMS ((char *operands, unsigned long flags));
330 /* ARM 2 */
331 static void do_mul              PARAMS ((char *operands, unsigned long flags));
332 static void do_mla              PARAMS ((char *operands, unsigned long flags));
333 /* ARM 3 */
334 static void do_swap             PARAMS ((char *operands, unsigned long flags));
335 /* ARM 6 */
336 static void do_msr              PARAMS ((char *operands, unsigned long flags));
337 static void do_mrs              PARAMS ((char *operands, unsigned long flags));
338 /* ARM 7DM */
339 static void do_mull             PARAMS ((char *operands, unsigned long flags));
340 /* Coprocessor Instructions */
341 static void do_cdp              PARAMS ((char *operands, unsigned long flags));
342 static void do_lstc             PARAMS ((char *operands, unsigned long flags));
343 static void do_co_reg           PARAMS ((char *operands, unsigned long flags));
344 static void do_fp_ctrl          PARAMS ((char *operands, unsigned long flags));
345 static void do_fp_ldst          PARAMS ((char *operands, unsigned long flags));
346 static void do_fp_ldmstm        PARAMS ((char *operands, unsigned long flags));
347 static void do_fp_dyadic        PARAMS ((char *operands, unsigned long flags));
348 static void do_fp_monadic       PARAMS ((char *operands, unsigned long flags));
349 static void do_fp_cmp           PARAMS ((char *operands, unsigned long flags));
350 static void do_fp_from_reg      PARAMS ((char *operands, unsigned long flags));
351 static void do_fp_to_reg        PARAMS ((char *operands, unsigned long flags));
352
353 static void fix_new_arm         PARAMS ((fragS *frag, int where, 
354                                          short int size, expressionS *exp,
355                                          int pc_rel, int reloc));
356 static int arm_reg_parse        PARAMS ((char **ccp));
357 static int arm_psr_parse        PARAMS ((char **ccp));
358
359 /* All instructions take 4 bytes in the object file */
360
361 #define INSN_SIZE       4
362
363 /* LONGEST_INST is the longest basic instruction name without conditions or 
364  * flags.
365  * ARM7DM has 4 of length 5
366  */
367
368 #define LONGEST_INST 5
369
370 struct asm_opcode 
371 {
372   CONST char *template;         /* Basic string to match */
373   unsigned long value;          /* Basic instruction code */
374   CONST char *comp_suffix;      /* Compulsory suffix that must follow conds */
375   CONST struct asm_flg *flags;  /* Bits to toggle if flag 'n' set */
376   unsigned long variants;       /* Which CPU variants this exists for */
377   void (*parms)();              /* Function to call to parse args */
378 };
379
380 static CONST struct asm_opcode insns[] = 
381 {
382 /* ARM Instructions */
383   {"and",   0x00000000, NULL,   s_flag,      ARM_ANY,      do_arit},
384   {"eor",   0x00200000, NULL,   s_flag,      ARM_ANY,      do_arit},
385   {"sub",   0x00400000, NULL,   s_flag,      ARM_ANY,      do_arit},
386   {"rsb",   0x00600000, NULL,   s_flag,      ARM_ANY,      do_arit},
387   {"add",   0x00800000, NULL,   s_flag,      ARM_ANY,      do_arit},
388   {"adc",   0x00a00000, NULL,   s_flag,      ARM_ANY,      do_arit},
389   {"sbc",   0x00c00000, NULL,   s_flag,      ARM_ANY,      do_arit},
390   {"rsc",   0x00e00000, NULL,   s_flag,      ARM_ANY,      do_arit},
391   {"orr",   0x01800000, NULL,   s_flag,      ARM_ANY,      do_arit},
392   {"bic",   0x01c00000, NULL,   s_flag,      ARM_ANY,      do_arit},
393   {"tst",   0x01000000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
394   {"teq",   0x01200000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
395   {"cmp",   0x01400000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
396   {"cmn",   0x01600000, NULL,   cmp_flags,   ARM_ANY,      do_cmp},
397   {"mov",   0x01a00000, NULL,   s_flag,      ARM_ANY,      do_mov},
398   {"mvn",   0x01e00000, NULL,   s_flag,      ARM_ANY,      do_mov},
399   {"str",   0x04000000, NULL,   ldst_flags,  ARM_ANY,      do_ldst},
400   {"ldr",   0x04100000, NULL,   ldst_flags,  ARM_ANY,      do_ldst},
401   {"stm",   0x08000000, NULL,   stm_flags,   ARM_ANY,      do_ldmstm},
402   {"ldm",   0x08100000, NULL,   ldm_flags,   ARM_ANY,      do_ldmstm},
403   {"swi",   0x0f000000, NULL,   NULL,        ARM_ANY,      do_swi},
404   {"bl",    0x0b000000, NULL,   NULL,        ARM_ANY,      do_branch},
405   {"b",     0x0a000000, NULL,   NULL,        ARM_ANY,      do_branch},
406
407 /* Pseudo ops */
408   {"adr",   0x028f0000, NULL,   NULL,        ARM_ANY,      do_adr},
409   {"nop",   0x01a00000, NULL,   NULL,        ARM_ANY,      do_nop},
410
411 /* ARM 2 multiplies */
412   {"mul",   0x00000090, NULL,   s_flag,      ARM_2UP,      do_mul},
413   {"mla",   0x00200090, NULL,   s_flag,      ARM_2UP,      do_mla},
414
415 /* ARM 3 - swp instructions */
416   {"swp",   0x01000090, NULL,   byte_flag,   ARM_3UP,      do_swap},
417
418 /* ARM 6 Coprocessor instructions */
419   {"mrs",   0x010f0000, NULL,   NULL,        ARM_6UP,      do_mrs},
420   {"msr",   0x0128f000, NULL,   NULL,        ARM_6UP,      do_msr},
421
422 /* ARM 7DM long multiplies - need signed/unsigned flags! */
423   {"smull", 0x00c00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
424   {"umull", 0x00800090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
425   {"smlal", 0x00e00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
426   {"umlal", 0x00a00090, NULL,   s_flag,      ARM_LONGMUL,  do_mull},
427
428 /* Floating point instructions */
429   {"wfs",   0x0e200110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
430   {"rfs",   0x0e300110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
431   {"wfc",   0x0e400110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
432   {"rfc",   0x0e500110, NULL,   NULL,        FPU_ALL,      do_fp_ctrl},
433   {"ldf",   0x0c100100, "sdep", NULL,        FPU_ALL,      do_fp_ldst},
434   {"stf",   0x0c000100, "sdep", NULL,        FPU_ALL,      do_fp_ldst},
435   {"lfm",   0x0c100200, NULL,   lfm_flags,   FPU_MEMMULTI, do_fp_ldmstm},
436   {"sfm",   0x0c000200, NULL,   sfm_flags,   FPU_MEMMULTI, do_fp_ldmstm},
437   {"mvf",   0x0e008100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
438   {"mnf",   0x0e108100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
439   {"abs",   0x0e208100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
440   {"rnd",   0x0e308100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
441   {"sqt",   0x0e408100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
442   {"log",   0x0e508100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
443   {"lgn",   0x0e608100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
444   {"exp",   0x0e708100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
445   {"sin",   0x0e808100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
446   {"cos",   0x0e908100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
447   {"tan",   0x0ea08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
448   {"asn",   0x0eb08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
449   {"acs",   0x0ec08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
450   {"atn",   0x0ed08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
451   {"urd",   0x0ee08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
452   {"nrm",   0x0ef08100, "sde",  round_flags, FPU_ALL,      do_fp_monadic},
453   {"adf",   0x0e000100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
454   {"suf",   0x0e200100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
455   {"rsf",   0x0e300100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
456   {"muf",   0x0e100100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
457   {"dvf",   0x0e400100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
458   {"rdf",   0x0e500100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
459   {"pow",   0x0e600100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
460   {"rpw",   0x0e700100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
461   {"rmf",   0x0e800100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
462   {"fml",   0x0e900100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
463   {"fdv",   0x0ea00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
464   {"frd",   0x0eb00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
465   {"pol",   0x0ec00100, "sde",  round_flags, FPU_ALL,      do_fp_dyadic},
466   {"cmf",   0x0e90f110, NULL,   except_flag, FPU_ALL,      do_fp_cmp},
467   {"cnf",   0x0eb0f110, NULL,   except_flag, FPU_ALL,      do_fp_cmp},
468 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
469    be an optional suffix, but part of the instruction.  To be compatible,
470    we accept either.  */
471   {"cmfe",  0x0ed0f110, NULL,   NULL,        FPU_ALL,      do_fp_cmp},
472   {"cnfe",  0x0ef0f110, NULL,   NULL,        FPU_ALL,      do_fp_cmp},
473   {"flt",   0x0e000110, "sde",  round_flags, FPU_ALL,      do_fp_from_reg},
474   {"fix",   0x0e100110, NULL,   round_flags, FPU_ALL,      do_fp_to_reg},
475
476 /* Generic copressor instructions */
477   {"cdp",   0x0e000000, NULL,  NULL,         ARM_ANY,      do_cdp},
478   {"ldc",   0x0c100000, NULL,  cplong_flag,  ARM_ANY,      do_lstc},
479   {"stc",   0x0c000000, NULL,  cplong_flag,  ARM_ANY,      do_lstc},
480   {"mcr",   0x0e000010, NULL,  NULL,         ARM_ANY,      do_co_reg},
481   {"mrc",   0x0e100010, NULL,  NULL,         ARM_ANY,      do_co_reg},
482 };
483
484 /* defines for various bits that we will want to toggle */
485
486 #define INST_IMMEDIATE  0x02000000
487 #define OFFSET_REG      0x02000000
488 #define SHIFT_BY_REG    0x00000010
489 #define PRE_INDEX       0x01000000
490 #define INDEX_UP        0x00800000
491 #define WRITE_BACK      0x00200000
492 #define MULTI_SET_PSR   0x00400000
493
494 #define LITERAL_MASK    0xf000f000
495 #define COND_MASK       0xf0000000
496 #define OPCODE_MASK     0xfe1fffff
497 #define DATA_OP_SHIFT   21
498
499 /* Codes to distinguish the arithmetic instructions */
500
501 #define OPCODE_AND      0
502 #define OPCODE_EOR      1
503 #define OPCODE_SUB      2
504 #define OPCODE_RSB      3
505 #define OPCODE_ADD      4
506 #define OPCODE_ADC      5
507 #define OPCODE_SBC      6
508 #define OPCODE_RSC      7
509 #define OPCODE_TST      8
510 #define OPCODE_TEQ      9
511 #define OPCODE_CMP      10
512 #define OPCODE_CMN      11
513 #define OPCODE_ORR      12
514 #define OPCODE_MOV      13
515 #define OPCODE_BIC      14
516 #define OPCODE_MVN      15
517
518 struct reg_entry
519 {
520   CONST char *name;
521   int number;
522 };
523
524 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
525 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
526 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
527
528 #define REG_PC  15
529
530 /* These are the standard names;  Users can add aliases with .req */
531 static CONST struct reg_entry reg_table[] =
532 {
533   /* Processor Register Numbers */
534   {"r0", 0},    {"r1", 1},    {"r2", 2},    {"r3", 3},
535   {"r4", 4},    {"r5", 5},    {"r6", 6},    {"r7", 7},
536   {"r8", 8},    {"r9", 9},    {"r10", 10},  {"r11", 11},
537   {"r12", 12},  {"r13", 13},  {"r14", 14},  {"r15", REG_PC},
538   /* APCS conventions */
539   {"a1", 0},    {"a2", 1},    {"a3", 2},    {"a4", 3},
540   {"v1", 4},    {"v2", 5},    {"v3", 6},    {"v4", 7},     {"v5", 8},
541   {"v6", 9},    {"sb", 9},    {"v7", 10},   {"sl", 10},
542   {"fp", 11},   {"ip", 12},   {"sp", 13},   {"lr", 14},    {"pc", REG_PC},
543   /* FP Registers */
544   {"f0", 16},   {"f1", 17},   {"f2", 18},   {"f3", 19},
545   {"f4", 20},   {"f5", 21},   {"f6", 22},   {"f7", 23},
546   {"c0", 32},   {"c1", 33},   {"c2", 34},   {"c3", 35},
547   {"c4", 36},   {"c5", 37},   {"c6", 38},   {"c7", 39},
548   {"c8", 40},   {"c9", 41},   {"c10", 42},  {"c11", 43},
549   {"c12", 44},  {"c13", 45},  {"c14", 46},  {"c15", 47},
550   {"cr0", 32},  {"cr1", 33},  {"cr2", 34},  {"cr3", 35},
551   {"cr4", 36},  {"cr5", 37},  {"cr6", 38},  {"cr7", 39},
552   {"cr8", 40},  {"cr9", 41},  {"cr10", 42}, {"cr11", 43},
553   {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
554   {NULL, 0}
555 };
556
557 static CONST char *bad_args = "Bad arguments to instruction";
558 static CONST char *bad_pc = "r15 not allowed here";
559
560 static struct hash_control *arm_ops_hsh = NULL;
561 static struct hash_control *arm_cond_hsh = NULL;
562 static struct hash_control *arm_shift_hsh = NULL;
563 static struct hash_control *arm_reg_hsh = NULL;
564 static struct hash_control *arm_psr_hsh = NULL;
565
566 /* This table describes all the machine specific pseudo-ops the assembler
567    has to support.  The fields are:
568    pseudo-op name without dot
569    function to call to execute this pseudo-op
570    Integer arg to pass to the function
571    */
572
573 static void s_req PARAMS ((int));
574 static void s_align PARAMS ((int));
575 static void s_bss PARAMS ((int));
576 static void s_even PARAMS ((int));
577 static void s_ltorg PARAMS ((int));
578
579 static int my_get_expression PARAMS ((expressionS *, char **));
580
581 CONST pseudo_typeS md_pseudo_table[] =
582 {
583   {"req", s_req, 0},    /* Never called becasue '.req' does not start line */
584   {"bss", s_bss, 0},
585   {"align", s_align, 0},
586   {"even", s_even, 0},
587   {"ltorg", s_ltorg, 0},
588   {"pool", s_ltorg, 0},
589   {"word", cons, 4},
590   {"extend", float_cons, 'x'},
591   {"ldouble", float_cons, 'x'},
592   {"packed", float_cons, 'p'},
593   {0, 0, 0}
594 };
595
596 /* Stuff needed to resolve the label ambiguity
597    As:
598      ...
599      label:   <insn>
600    may differ from:
601      ...
602      label:
603               <insn>
604 */
605
606 symbolS *last_label_seen;
607
608 /* Literal stuff */
609
610 #define MAX_LITERAL_POOL_SIZE 1024
611
612 typedef struct literalS
613 {
614   struct expressionS  exp;
615   struct arm_it      *inst;
616 } literalT;
617
618 literalT literals[MAX_LITERAL_POOL_SIZE];
619 int next_literal_pool_place = 0; /* Next free entry in the pool */
620 int lit_pool_num = 1; /* Next literal pool number */
621 symbolS *current_poolP = NULL;
622 symbolS *symbol_make_empty (); 
623
624 static int
625 add_to_lit_pool ()
626 {
627   if (current_poolP == NULL)
628     current_poolP = symbol_make_empty();
629
630   if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
631     {
632       inst.error = "Literal Pool Overflow\n";
633       return FAIL;
634     }
635
636   literals[next_literal_pool_place].exp = inst.reloc.exp;
637   inst.reloc.exp.X_op = O_symbol;
638   inst.reloc.exp.X_add_number = (next_literal_pool_place++)*4-8;
639   inst.reloc.exp.X_add_symbol = current_poolP;
640
641   return SUCCESS;
642 }
643  
644 /* Can't use symbol_new here, so have to create a symbol and them at
645    a later datete assign iot a value. Thats what these functions do */
646 static void
647 symbol_locate (symbolP, name, segment, valu, frag)
648      symbolS *symbolP; 
649      CONST char *name;          /* It is copied, the caller can modify */
650      segT segment;              /* Segment identifier (SEG_<something>) */
651      valueT valu;               /* Symbol value */
652      fragS *frag;               /* Associated fragment */
653 {
654   unsigned int name_length;
655   char *preserved_copy_of_name;
656
657   name_length = strlen (name) + 1;      /* +1 for \0 */
658   obstack_grow (&notes, name, name_length);
659   preserved_copy_of_name = obstack_finish (&notes);
660 #ifdef STRIP_UNDERSCORE
661   if (preserved_copy_of_name[0] == '_')
662     preserved_copy_of_name++;
663 #endif
664
665 #ifdef tc_canonicalize_symbol_name
666   preserved_copy_of_name =
667     tc_canonicalize_symbol_name (preserved_copy_of_name);
668 #endif
669
670   S_SET_NAME (symbolP, preserved_copy_of_name);
671
672   S_SET_SEGMENT (symbolP, segment);
673   S_SET_VALUE (symbolP, valu);
674   symbol_clear_list_pointers(symbolP);
675
676   symbolP->sy_frag = frag;
677
678   /*
679    * Link to end of symbol chain.
680    */
681   {
682     extern int symbol_table_frozen;
683     if (symbol_table_frozen)
684       abort ();
685   }
686
687   symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
688
689   obj_symbol_new_hook (symbolP);
690
691 #ifdef tc_symbol_new_hook
692   tc_symbol_new_hook (symbolP);
693 #endif
694  
695 #ifdef DEBUG_SYMS
696   verify_symbol_chain(symbol_rootP, symbol_lastP);
697 #endif /* DEBUG_SYMS */
698 }
699
700 symbolS *
701 symbol_make_empty () 
702 {
703   symbolS *symbolP; 
704
705   symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
706
707   /* symbol must be born in some fixed state.  This seems as good as any. */
708   memset (symbolP, 0, sizeof (symbolS));
709
710 #ifdef BFD_ASSEMBLER
711   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
712   assert (symbolP->bsym != 0);
713   symbolP->bsym->udata.p = (PTR) symbolP;
714 #endif
715
716   return symbolP;
717 }
718  
719 /* Check that an immediate is valid, and if so, convert it to the right format
720  */
721
722 /* OH, for a rotate instruction in C! */
723
724 static int
725 validate_immediate (val)
726      int val;
727 {
728   unsigned int a = (unsigned int) val;
729   int i;
730   
731   /* Do the easy (and most common ones) quickly */
732   for (i = 0; i <= 24; i += 2)
733     {
734       if ((a & (0xff << i)) == a)
735         return (int) (((32 - i) & 0x1e) << 7) | ((a >> i) & 0xff);
736     }
737
738   /* Now do the harder ones */
739   for (; i < 32; i += 2)
740     {
741       if ((a & ((0xff << i) | (0xff >> (32 - i)))) == a)
742         {
743           a = ((a >> i) & 0xff) | ((a << (32 - i)) & 0xff);
744           return (int) a | (((32 - i) >> 1) << 8);
745         }
746     }
747   return FAIL;
748 }
749
750 static int
751 validate_offset_imm (val)
752      int val;
753 {
754   if (val < -4095 || val > 4095)
755     as_bad ("bad immediate value for offset (%d)", val);
756   return val;
757 }
758
759     
760 static void
761 s_req (a)
762      int a;
763 {
764   as_bad ("Invalid syntax for .req directive.");
765 }
766
767 static void
768 s_bss (ignore)
769      int ignore;
770 {
771   /* We don't support putting frags in the BSS segment, we fake it by
772      marking in_bss, then looking at s_skip for clues?.. */
773   subseg_set (bss_section, 0);
774   demand_empty_rest_of_line ();
775 }
776
777 static void
778 s_even (ignore)
779      int ignore;
780 {
781   if (!need_pass_2)             /* Never make frag if expect extra pass. */
782     frag_align (1, 0);
783   record_alignment (now_seg, 1);
784   demand_empty_rest_of_line ();
785 }
786
787 static void
788 s_ltorg (internal)
789      int internal;
790 {
791   int lit_count = 0;
792   char sym_name[20];
793
794   if (current_poolP == NULL)
795     {
796       /* Nothing to do */
797       if (!internal)
798         as_tsktsk ("Nothing to put in the pool\n");
799       return;
800     }
801
802   /* Align pool as you have word accesses */
803   /* Only make a frag if we have to ... */
804   if (!need_pass_2)
805     frag_align (2, 0);
806
807   record_alignment (now_seg, 2);
808
809   if (internal)
810     as_tsktsk ("Inserting implicit pool at change of section");
811
812   sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
813
814   symbol_locate (current_poolP, sym_name, now_seg,
815                  (valueT) ((char *)obstack_next_free (&frags)
816                            - frag_now->fr_literal), frag_now);
817   symbol_table_insert (current_poolP);
818
819   while (lit_count < next_literal_pool_place)
820     /* First output the expression in the instruction to the pool */
821     emit_expr (&(literals[lit_count++].exp), 4); /* .word */
822
823   next_literal_pool_place = 0;
824   current_poolP = NULL;
825 }
826
827 static void
828 arm_align (power, fill)
829      int power;
830      int fill;
831 {
832   /* Only make a frag if we HAVE to ... */
833   if (power && !need_pass_2)
834     frag_align (power, fill);
835
836   record_alignment (now_seg, power);
837 }
838
839 static void
840 s_align (unused)        /* Same as s_align_ptwo but align 0 => align 2 */
841      int unused;
842 {
843   register int temp;
844   register long temp_fill;
845   long max_alignment = 15;
846
847   temp = get_absolute_expression ();
848   if (temp > max_alignment)
849     as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
850   else if (temp < 0)
851     {
852       as_bad ("Alignment negative. 0 assumed.");
853       temp = 0;
854     }
855
856   if (*input_line_pointer == ',')
857     {
858       input_line_pointer++;
859       temp_fill = get_absolute_expression ();
860     }
861   else
862     temp_fill = 0;
863
864   if (!temp)
865     temp = 2;
866
867   /* Only make a frag if we HAVE to. . . */
868   if (temp && !need_pass_2)
869     frag_align (temp, (int) temp_fill);
870   demand_empty_rest_of_line ();
871
872   record_alignment (now_seg, temp);
873 }
874
875 static void
876 end_of_line (str)
877      char *str;
878 {
879   while (*str == ' ')
880     str++;
881
882   if (*str != '\0')
883     inst.error = "Garbage following instruction";
884 }
885
886 static int
887 skip_past_comma (str)
888      char **str;
889 {
890   char *p = *str, c;
891   int comma = 0;
892     
893   while ((c = *p) == ' ' || c == ',')
894     {
895       p++;
896       if (c == ',' && comma++)
897         return FAIL;
898     }
899
900   if (c == '\0')
901     return FAIL;
902
903   *str = p;
904   return comma ? SUCCESS : FAIL;
905 }
906
907 /* A standard register must be given at this point.  Shift is the place to
908    put it in the instruction. */
909
910 static int
911 reg_required_here (str, shift)
912      char **str;
913      int shift;
914 {
915   int reg;
916   char *start = *str;
917
918   if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
919     {
920       inst.instruction |= reg << shift;
921       return reg;
922     }
923
924   /* In the few cases where we might be able to accept something else
925      this error can be overridden */
926   inst.error = "Register expected";
927
928   /* Restore the start point, we may have got a reg of the wrong class.  */
929   *str = start;
930   return FAIL;
931 }
932
933 static int
934 psr_required_here (str, shift)
935      char **str;
936      int shift;
937 {
938   int psr;
939   char *start = *str;
940
941   if  ((psr = arm_psr_parse (str)) != FAIL && psr < 2)
942     {
943       if (psr == 1)
944         inst.instruction |= 1 << shift; /* Should be bit 22 */
945       return psr;
946     }
947
948   /* In the few cases where we might be able to accept something else
949      this error can be overridden */
950   inst.error = "<psr> expected";
951
952   /* Restore the start point.  */
953   *str = start;
954   return FAIL;
955 }
956
957 static int
958 psrf_required_here (str, shift)
959      char **str;
960      int shift;
961 {
962   int psrf;
963   char *start = *str;
964
965   if  ((psrf = arm_psr_parse (str)) != FAIL && psrf > 1)
966     {
967       if (psrf == 1 || psrf == 3)
968         inst.instruction |= 1 << shift; /* Should be bit 22 */
969       return psrf;
970     }
971
972   /* In the few cases where we might be able to accept something else
973      this error can be overridden */
974   inst.error = "<psrf> expected";
975
976   /* Restore the start point.  */
977   *str = start;
978   return FAIL;
979 }
980
981 static int
982 co_proc_number (str)
983      char **str;
984 {
985   int processor, pchar;
986
987   while (**str == ' ')
988     (*str)++;
989
990   /* The data sheet seems to imply that just a number on its own is valid
991      here, but the RISC iX assembler seems to accept a prefix 'p'.  We will
992      accept either.  */
993   if (**str == 'p' || **str == 'P')
994     (*str)++;
995
996   pchar = *(*str)++;
997   if (pchar >= '0' && pchar <= '9')
998     {
999       processor = pchar - '0';
1000       if (**str >= '0' && **str <= '9')
1001         {
1002           processor = processor * 10 + *(*str)++ - '0';
1003           if (processor > 15)
1004             {
1005               inst.error = "Illegal co-processor number";
1006               return FAIL;
1007             }
1008         }
1009     }
1010   else
1011     {
1012       inst.error = "Bad or missing co-processor number";
1013       return FAIL;
1014     }
1015
1016   inst.instruction |= processor << 8;
1017   return SUCCESS;
1018 }
1019
1020 static int
1021 cp_opc_expr (str, where, length)
1022      char **str;
1023      int where;
1024      int length;
1025 {
1026   expressionS expr;
1027
1028   while (**str == ' ')
1029     (*str)++;
1030
1031   memset (&expr, '\0', sizeof (expr));
1032
1033   if (my_get_expression (&expr, str))
1034     return FAIL;
1035   if (expr.X_op != O_constant)
1036     {
1037       inst.error = "bad or missing expression";
1038       return FAIL;
1039     }
1040
1041   if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1042     {
1043       inst.error = "immediate co-processor expression too large";
1044       return FAIL;
1045     }
1046
1047   inst.instruction |= expr.X_add_number << where;
1048   return SUCCESS;
1049 }
1050
1051 static int
1052 cp_reg_required_here (str, where)
1053      char **str;
1054      int where;
1055 {
1056   int reg;
1057   char *start = *str;
1058
1059   if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1060     {
1061       reg &= 15;
1062       inst.instruction |= reg << where;
1063       return reg;
1064     }
1065
1066   /* In the few cases where we might be able to accept something else
1067      this error can be overridden */
1068   inst.error = "Co-processor register expected";
1069
1070   /* Restore the start point */
1071   *str = start;
1072   return FAIL;
1073 }
1074
1075 static int
1076 fp_reg_required_here (str, where)
1077      char **str;
1078      int where;
1079 {
1080   int reg;
1081   char *start = *str;
1082
1083   if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1084     {
1085       reg &= 7;
1086       inst.instruction |= reg << where;
1087       return reg;
1088     }
1089
1090   /* In the few cases where we might be able to accept something else
1091      this error can be overridden */
1092   inst.error = "Floating point register expected";
1093
1094   /* Restore the start point */
1095   *str = start;
1096   return FAIL;
1097 }
1098
1099 static int
1100 cp_address_offset (str)
1101      char **str;
1102 {
1103   int offset;
1104
1105   while (**str == ' ')
1106     (*str)++;
1107
1108   if (**str != '#')
1109     {
1110       inst.error = "immediate expression expected";
1111       return FAIL;
1112     }
1113
1114   (*str)++;
1115   if (my_get_expression (&inst.reloc.exp, str))
1116     return FAIL;
1117   if (inst.reloc.exp.X_op == O_constant)
1118     {
1119       offset = inst.reloc.exp.X_add_number;
1120       if (offset & 3)
1121         {
1122           inst.error = "co-processor address must be word aligned";
1123           return FAIL;
1124         }
1125
1126       if (offset > 1023 || offset < -1023)
1127         {
1128           inst.error = "offset too large";
1129           return FAIL;
1130         }
1131
1132       if (offset >= 0)
1133         inst.instruction |= INDEX_UP;
1134       else
1135         offset = -offset;
1136
1137       inst.instruction |= offset >> 2;
1138     }
1139   else
1140     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1141
1142   return SUCCESS;
1143 }
1144
1145 static int
1146 cp_address_required_here (str)
1147      char **str;
1148 {
1149   char *p = *str;
1150   int pre_inc = 0;
1151   int write_back = 0;
1152
1153   if (*p == '[')
1154     {
1155       int reg;
1156
1157       p++;
1158       while (*p == ' ')
1159         p++;
1160
1161       if ((reg = reg_required_here (&p, 16)) == FAIL)
1162         {
1163           inst.error = "Register required";
1164           return FAIL;
1165         }
1166
1167       while (*p == ' ')
1168         p++;
1169
1170       if (*p == ']')
1171         {
1172           p++;
1173           if (skip_past_comma (&p) == SUCCESS)
1174             {
1175               /* [Rn], #expr */
1176               write_back = WRITE_BACK;
1177               if (reg == REG_PC)
1178                 {
1179                   inst.error = "pc may not be used in post-increment";
1180                   return FAIL;
1181                 }
1182
1183               if (cp_address_offset (&p) == FAIL)
1184                 return FAIL;
1185             }
1186           else
1187             pre_inc = PRE_INDEX | INDEX_UP;
1188         }
1189       else
1190         {
1191           /* '['Rn, #expr']'[!] */
1192
1193           if (skip_past_comma (&p) == FAIL)
1194             {
1195               inst.error = "pre-indexed expression expected";
1196               return FAIL;
1197             }
1198
1199           pre_inc = PRE_INDEX;
1200           if (cp_address_offset (&p) == FAIL)
1201             return FAIL;
1202
1203           while (*p == ' ')
1204             p++;
1205
1206           if (*p++ != ']')
1207             {
1208               inst.error = "missing ]";
1209               return FAIL;
1210             }
1211
1212           while (*p == ' ')
1213             p++;
1214
1215           if (*p == '!')
1216             {
1217               if (reg == REG_PC)
1218                 {
1219                   inst.error = "pc may not be used with write-back";
1220                   return FAIL;
1221                 }
1222
1223               p++;
1224               write_back = WRITE_BACK;
1225             }
1226         }
1227     }
1228   else
1229     {
1230       if (my_get_expression (&inst.reloc.exp, &p))
1231         return FAIL;
1232
1233       inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1234       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust */
1235       inst.reloc.pc_rel = 1;
1236       inst.instruction |= (REG_PC << 16);
1237     }
1238
1239   inst.instruction |= write_back | pre_inc;
1240   *str = p;
1241   return SUCCESS;
1242 }
1243
1244 static void
1245 do_nop (str, flags)
1246      char *str;
1247      unsigned long flags;
1248 {
1249   /* Do nothing really */
1250   inst.instruction |= flags; /* This is pointless */
1251   end_of_line (str);
1252   return;
1253 }
1254
1255 static void
1256 do_mrs (str, flags)
1257      char *str;
1258      unsigned long flags;
1259 {
1260   /* Only one syntax */
1261   while (*str == ' ')
1262     str++;
1263
1264   if (reg_required_here (&str, 12) == FAIL)
1265     {
1266       inst.error = bad_args;
1267       return;
1268     }
1269
1270   if (skip_past_comma (&str) == FAIL
1271       || psr_required_here (&str, 22) == FAIL)
1272     {
1273       inst.error = "<psr> expected";
1274       return;
1275     }
1276
1277   inst.instruction |= flags;
1278   end_of_line (str);
1279   return;
1280 }
1281
1282 static void
1283 do_msr (str, flags)
1284      char *str;
1285      unsigned long flags;
1286 {
1287   int psr, psrf, reg;
1288   /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1289
1290   while (*str == ' ')
1291     str++;
1292
1293   if ((psr = psr_required_here (&str, 22)) != FAIL)
1294     {
1295       inst.instruction |= PSR_ALL;
1296       /* Sytax should be "<psr>, Rm" */
1297       if (skip_past_comma (&str) == FAIL
1298           || (reg = reg_required_here (&str, 0)) == FAIL)
1299         {
1300           inst.error = bad_args;
1301           return;
1302         }
1303     }
1304   else if ((psrf = psrf_required_here (&str, 22)) != FAIL)
1305     /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1306     {
1307       if (skip_past_comma (&str) == FAIL)
1308         {
1309           inst.error = bad_args;
1310           return;
1311         }
1312       if ((reg = reg_required_here (&str, 0)) != FAIL)
1313         ;
1314       /* Immediate expression */
1315       else if (*(str++) == '#')
1316         {
1317           inst.error = NULL;
1318           if (my_get_expression (&inst.reloc.exp, &str))
1319             {
1320               inst.error = "Register or shift expression expected";
1321               return;
1322             }
1323
1324           if (inst.reloc.exp.X_add_symbol)
1325             {
1326               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1327               inst.reloc.pc_rel = 0;
1328             }
1329           else
1330             {
1331               int value = validate_immediate (inst.reloc.exp.X_add_number);
1332               if (value == FAIL)
1333                 {
1334                   inst.error = "Invalid constant";
1335                   return;
1336                 }
1337
1338               inst.instruction |= value;
1339             }
1340
1341           flags |= INST_IMMEDIATE;
1342         }
1343       else
1344         {
1345           inst.error = "Error: the other";
1346           return;
1347         }
1348     }
1349   else
1350     {
1351       inst.error = bad_args;
1352       return;
1353     }
1354      
1355   inst.error = NULL; 
1356   inst.instruction |= flags;
1357   end_of_line (str);
1358   return;
1359 }
1360
1361 /* Long Multiply Parser
1362    UMULL RdLo, RdHi, Rm, Rs
1363    SMULL RdLo, RdHi, Rm, Rs
1364    UMLAL RdLo, RdHi, Rm, Rs
1365    SMLAL RdLo, RdHi, Rm, Rs
1366 */   
1367 static void
1368 do_mull (str, flags)
1369      char *str;
1370      unsigned long flags;
1371 {
1372   int rdlo, rdhi, rm, rs;
1373
1374   /* only one format "rdlo, rdhi, rm, rs" */
1375   while (*str == ' ')
1376     str++;
1377
1378   if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1379     {
1380       inst.error = bad_args;
1381       return;
1382     }
1383
1384   if (skip_past_comma (&str) == FAIL
1385       || (rdhi = reg_required_here (&str, 16)) == FAIL)
1386     {
1387       inst.error = bad_args;
1388       return;
1389     }
1390
1391   if (skip_past_comma (&str) == FAIL
1392       || (rm = reg_required_here (&str, 0)) == FAIL)
1393     {
1394       inst.error = bad_args;
1395       return;
1396     }
1397
1398   /* rdhi, rdlo and rm must all be different */
1399   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1400     as_tsktsk ("rdhi, rdlo and rm must all be different");
1401
1402   if (skip_past_comma (&str) == FAIL
1403       || (rs = reg_required_here (&str, 8)) == FAIL)
1404     {
1405       inst.error = bad_args;
1406       return;
1407     }
1408
1409   if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1410     {
1411       inst.error = bad_pc;
1412       return;
1413     }
1414    
1415   inst.instruction |= flags;
1416   end_of_line (str);
1417   return;
1418 }
1419
1420 static void
1421 do_mul (str, flags)
1422      char *str;
1423      unsigned long flags;
1424 {
1425   int rd, rm;
1426   
1427   /* only one format "rd, rm, rs" */
1428   while (*str == ' ')
1429     str++;
1430
1431   if ((rd = reg_required_here (&str, 16)) == FAIL)
1432     {
1433       inst.error = bad_args;
1434       return;
1435     }
1436
1437   if (rd == REG_PC)
1438     {
1439       inst.error = bad_pc;
1440       return;
1441     }
1442
1443   if (skip_past_comma (&str) == FAIL
1444       || (rm = reg_required_here (&str, 0)) == FAIL)
1445     {
1446       inst.error = bad_args;
1447       return;
1448     }
1449
1450   if (rm == REG_PC)
1451     {
1452       inst.error = bad_pc;
1453       return;
1454     }
1455
1456   if (rm == rd)
1457     as_tsktsk ("rd and rm should be different in mul");
1458
1459   if (skip_past_comma (&str) == FAIL
1460       || (rm = reg_required_here (&str, 8)) == FAIL)
1461     {
1462       inst.error = bad_args;
1463       return;
1464     }
1465
1466   if (rm == REG_PC)
1467     {
1468       inst.error = bad_pc;
1469       return;
1470     }
1471
1472   inst.instruction |= flags;
1473   end_of_line (str);
1474   return;
1475 }
1476
1477 static void
1478 do_mla (str, flags)
1479      char *str;
1480      unsigned long flags;
1481 {
1482   int rd, rm;
1483
1484   /* only one format "rd, rm, rs, rn" */
1485   while (*str == ' ')
1486     str++;
1487
1488   if ((rd = reg_required_here (&str, 16)) == FAIL)
1489     {
1490       inst.error = bad_args;
1491       return;
1492     }
1493
1494   if (rd == REG_PC)
1495     {
1496       inst.error = bad_pc;
1497       return;
1498     }
1499
1500   if (skip_past_comma (&str) == FAIL
1501       || (rm = reg_required_here (&str, 0)) == FAIL)
1502     {
1503       inst.error = bad_args;
1504       return;
1505     }
1506
1507   if (rm == REG_PC)
1508     {
1509       inst.error = bad_pc;
1510       return;
1511     }
1512
1513   if (rm == rd)
1514     as_tsktsk ("rd and rm should be different in mla");
1515
1516   if (skip_past_comma (&str) == FAIL
1517       || (rd = reg_required_here (&str, 8)) == FAIL
1518       || skip_past_comma (&str) == FAIL
1519       || (rm = reg_required_here (&str, 12)) == FAIL)
1520     {
1521       inst.error = bad_args;
1522       return;
1523     }
1524
1525   if (rd == REG_PC || rm == REG_PC)
1526     {
1527       inst.error = bad_pc;
1528       return;
1529     }
1530
1531   inst.instruction |= flags;
1532   end_of_line (str);
1533   return;
1534 }
1535
1536 /* Returns the index into fp_values of a floating point number, or -1 if
1537    not in the table.  */
1538 static int
1539 my_get_float_expression (str)
1540      char **str;
1541 {
1542   LITTLENUM_TYPE words[MAX_LITTLENUMS];
1543   char *save_in;
1544   expressionS exp;
1545   int i, j;
1546
1547   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
1548   /* Look for a raw floating point number */
1549   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
1550       && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
1551     {
1552       for (i = 0; i < NUM_FLOAT_VALS; i++)
1553         {
1554           for (j = 0; j < MAX_LITTLENUMS; j++)
1555             {
1556               if (words[j] != fp_values[i][j])
1557                 break;
1558             }
1559
1560           if (j == MAX_LITTLENUMS)
1561             {
1562               *str = save_in;
1563               return i;
1564             }
1565         }
1566     }
1567
1568   /* Try and parse a more complex expression, this will probably fail
1569      unless the code uses a floating point prefix (eg "0f") */
1570   save_in = input_line_pointer;
1571   input_line_pointer = *str;
1572   if (expression (&exp) == absolute_section
1573       && exp.X_op == O_big
1574       && exp.X_add_number < 0)
1575     {
1576       if (gen_to_words (words, 6, (long)15) == 0)
1577         {
1578           for (i = 0; i < NUM_FLOAT_VALS; i++)
1579             {
1580               for (j = 0; j < MAX_LITTLENUMS; j++)
1581                 {
1582                   if (words[j] != fp_values[i][j])
1583                     break;
1584                 }
1585
1586               if (j == MAX_LITTLENUMS)
1587                 {
1588                   *str = input_line_pointer;
1589                   input_line_pointer = save_in;
1590                   return i;
1591                 }
1592             }
1593         }
1594     }
1595
1596   *str = input_line_pointer;
1597   input_line_pointer = save_in;
1598   return -1;
1599 }
1600
1601 /* Return true if anything in the expression is a bignum */
1602 static int
1603 walk_no_bignums (sp)
1604      symbolS *sp;
1605 {
1606   if (sp->sy_value.X_op == O_big)
1607     return 1;
1608
1609   if (sp->sy_value.X_add_symbol)
1610     {
1611       return (walk_no_bignums (sp->sy_value.X_add_symbol)
1612               || (sp->sy_value.X_op_symbol
1613                   && walk_no_bignums (sp->sy_value.X_op_symbol)));
1614     }
1615
1616   return 0;
1617 }
1618
1619 static int
1620 my_get_expression (ep, str)
1621      expressionS *ep;
1622      char **str;
1623 {
1624   char *save_in;
1625   segT seg;
1626   
1627   save_in = input_line_pointer;
1628   input_line_pointer = *str;
1629   seg = expression (ep);
1630   if (seg != absolute_section
1631       && seg != text_section
1632       && seg != data_section
1633       && seg != bss_section
1634       && seg != undefined_section)
1635     {
1636       inst.error = "bad_segment";
1637       *str = input_line_pointer;
1638       input_line_pointer = save_in;
1639       return 1;
1640     }
1641
1642   /* Get rid of any bignums now, so that we don't generate an error for which
1643      we can't establish a line number later on.  Big numbers are never valid
1644      in instructions, which is where is routine is always called.  */
1645   if (ep->X_op == O_big
1646       || (ep->X_add_symbol
1647           && (walk_no_bignums (ep->X_add_symbol)
1648               || (ep->X_op_symbol
1649                   && walk_no_bignums (ep->X_op_symbol)))))
1650     {
1651       inst.error = "Invalid constant";
1652       *str = input_line_pointer;
1653       input_line_pointer = save_in;
1654       return 1;
1655     }
1656
1657   *str = input_line_pointer;
1658   input_line_pointer = save_in;
1659   return 0;
1660 }
1661
1662 /* unrestrict should be one if <shift> <register> is permitted for this
1663    instruction */
1664
1665 static int
1666 decode_shift (str, unrestrict)
1667      char **str;
1668      int unrestrict;
1669 {
1670   struct asm_shift *shft;
1671   char *p;
1672   char c;
1673     
1674   while (**str == ' ')
1675     (*str)++;
1676     
1677   for (p = *str; isalpha (*p); p++)
1678     ;
1679
1680   if (p == *str)
1681     {
1682       inst.error = "Shift expression expected";
1683       return FAIL;
1684     }
1685
1686   c = *p;
1687   *p = '\0';
1688   shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
1689   *p = c;
1690   if (shft)
1691     {
1692       if (!strcmp (*str, "rrx"))
1693         {
1694           *str = p;
1695           inst.instruction |= shft->value;
1696           return SUCCESS;
1697         }
1698
1699       while (*p == ' ')
1700         p++;
1701
1702       if (unrestrict && reg_required_here (&p, 8) != FAIL)
1703         {
1704           inst.instruction |= shft->value | SHIFT_BY_REG;
1705           *str = p;
1706           return SUCCESS;
1707         }
1708       else if (*p == '#')
1709         {
1710           inst.error = NULL;
1711           p++;
1712           if (my_get_expression (&inst.reloc.exp, &p))
1713             return FAIL;
1714
1715           /* Validate some simple #expressions */
1716           if (! inst.reloc.exp.X_add_symbol)
1717             {
1718               int num = inst.reloc.exp.X_add_number;
1719               if (num < 0 || num > 32
1720                   || (num == 32 
1721                       && (shft->value == 0 || shft->value == 0x60)))
1722                 {
1723                   inst.error = "Invalid immediate shift";
1724                   return FAIL;
1725                 }
1726
1727               /* Shifts of zero should be converted to lsl (which is zero)*/
1728               if (num == 0)
1729                 {
1730                   *str = p;
1731                   return SUCCESS;
1732                 }
1733
1734               /* Shifts of 32 are encoded as 0, for those shifts that
1735                  support it.  */
1736               if (num == 32)
1737                 num = 0;
1738
1739               inst.instruction |= (num << 7) | shft->value;
1740               *str = p;
1741               return SUCCESS;
1742             }
1743
1744           inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
1745           inst.reloc.pc_rel = 0;
1746           inst.instruction |= shft->value;
1747           *str = p;
1748           return SUCCESS;
1749         }
1750       else
1751         {
1752           inst.error = unrestrict ? "shift requires register or #expression"
1753             : "shift requires #expression";
1754           *str = p;
1755           return FAIL;
1756         }
1757     }
1758
1759   inst.error = "Shift expression expected";
1760   return FAIL;
1761 }
1762
1763 /* Do those data_ops which can take a negative immediate constant */
1764 /* by altering the instuction. A bit of a hack really */
1765 /*      MOV <-> MVN
1766         AND <-> BIC
1767         ADC <-> SBC
1768         by inverting the second operand, and
1769         ADD <-> SUB
1770         CMP <-> CMN
1771         by negating the second operand.
1772 */
1773 static int
1774 negate_data_op (instruction, value)
1775      unsigned long *instruction;
1776      unsigned long value;
1777 {
1778   int op, new_inst;
1779   unsigned long negated, inverted;
1780
1781   negated = validate_immediate (-value);
1782   inverted = validate_immediate (~value);
1783
1784   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
1785   switch (op)
1786     {
1787       /* First negates */
1788     case OPCODE_SUB:             /* ADD <-> SUB */
1789       new_inst = OPCODE_ADD;
1790       value = negated;
1791       break;
1792
1793     case OPCODE_ADD: 
1794       new_inst = OPCODE_SUB;               
1795       value = negated;
1796       break;
1797
1798     case OPCODE_CMP:             /* CMP <-> CMN */
1799       new_inst = OPCODE_CMN;
1800       value = negated;
1801       break;
1802
1803     case OPCODE_CMN: 
1804       new_inst = OPCODE_CMP;               
1805       value = negated;
1806       break;
1807
1808       /* Now Inverted ops */
1809     case OPCODE_MOV:             /* MOV <-> MVN */
1810       new_inst = OPCODE_MVN;               
1811       value = inverted;
1812       break;
1813
1814     case OPCODE_MVN: 
1815       new_inst = OPCODE_MOV;
1816       value = inverted;
1817       break;
1818
1819     case OPCODE_AND:             /* AND <-> BIC */ 
1820       new_inst = OPCODE_BIC;               
1821       value = inverted;
1822       break;
1823
1824     case OPCODE_BIC: 
1825       new_inst = OPCODE_AND;
1826       value = inverted;
1827       break;
1828
1829     case OPCODE_ADC:              /* ADC <-> SBC */
1830       new_inst = OPCODE_SBC;               
1831       value = inverted;
1832       break;
1833
1834     case OPCODE_SBC: 
1835       new_inst = OPCODE_ADC;
1836       value = inverted;
1837       break;
1838
1839       /* We cannot do anything */
1840     default:  
1841       return FAIL;
1842     }
1843
1844   if (value == FAIL)
1845     return FAIL;
1846
1847   *instruction &= OPCODE_MASK;
1848   *instruction |= new_inst << DATA_OP_SHIFT;
1849   return value; 
1850 }
1851
1852 static int
1853 data_op2 (str)
1854      char **str;
1855 {
1856   int value;
1857   expressionS expr;
1858
1859   while (**str == ' ')
1860     (*str)++;
1861     
1862   if (reg_required_here (str, 0) != FAIL)
1863     {
1864       if (skip_past_comma (str) == SUCCESS)
1865         {
1866           /* Shift operation on register */
1867           return decode_shift (str, NO_SHIFT_RESTRICT);
1868         }
1869       return SUCCESS;
1870     }
1871   else
1872     {
1873       /* Immediate expression */
1874       if (*((*str)++) == '#')
1875         {
1876           inst.error = NULL;
1877           if (my_get_expression (&inst.reloc.exp, str))
1878             return FAIL;
1879
1880           if (inst.reloc.exp.X_add_symbol)
1881             {
1882               inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1883               inst.reloc.pc_rel = 0;
1884             }
1885           else
1886             {
1887               if (skip_past_comma (str) == SUCCESS)
1888                 {
1889                   /* #x, y -- ie explicit rotation by Y  */
1890                   if (my_get_expression (&expr, str))
1891                     return FAIL;
1892
1893                   if (expr.X_op != O_constant)
1894                     {
1895                       inst.error = "Constant expression expected";
1896                       return FAIL;
1897                     }
1898  
1899                   /* Rotate must be a multiple of 2 */
1900                   if (((unsigned) expr.X_add_number) > 30
1901                       || (expr.X_add_number & 1) != 0
1902                       || ((unsigned) inst.reloc.exp.X_add_number) > 255)
1903                     {
1904                       inst.error = "Invalid constant";
1905                       return FAIL;
1906                     }
1907                   inst.instruction |= INST_IMMEDIATE;
1908                   inst.instruction |= inst.reloc.exp.X_add_number;
1909                   inst.instruction |= expr.X_add_number << 7;
1910                   return SUCCESS;
1911                 }
1912
1913               /* Implicit rotation, select a suitable one  */
1914               value = validate_immediate (inst.reloc.exp.X_add_number);
1915
1916               if (value == FAIL)
1917                 {
1918                   /* Can't be done, perhaps the code reads something like
1919                      "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
1920                   if ((value = negate_data_op (&inst.instruction,
1921                                                inst.reloc.exp.X_add_number))
1922                       == FAIL)
1923                     {
1924                       inst.error = "Invalid constant";
1925                       return FAIL;
1926                     }
1927                 }
1928
1929               inst.instruction |= value;
1930             }
1931
1932           inst.instruction |= INST_IMMEDIATE;
1933           return SUCCESS;
1934         }
1935
1936       inst.error = "Register or shift expression expected";
1937       return FAIL;
1938     }
1939 }
1940
1941 static int
1942 fp_op2 (str, flags)
1943      char **str;
1944      unsigned long flags;
1945 {
1946   while (**str == ' ')
1947     (*str)++;
1948
1949   if (fp_reg_required_here (str, 0) != FAIL)
1950     return SUCCESS;
1951   else
1952     {
1953       /* Immediate expression */
1954       if (*((*str)++) == '#')
1955         {
1956           int i;
1957
1958           inst.error = NULL;
1959           while (**str == ' ')
1960             (*str)++;
1961
1962           /* First try and match exact strings, this is to guarantee that
1963              some formats will work even for cross assembly */
1964
1965           for (i = 0; fp_const[i]; i++)
1966             {
1967               if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
1968                 {
1969                   char *start = *str;
1970
1971                   *str += strlen (fp_const[i]);
1972                   if (is_end_of_line[(int)**str] || **str == '\0')
1973                     {
1974                       inst.instruction |= i + 8;
1975                       return SUCCESS;
1976                     }
1977                   *str = start;
1978                 }
1979             }
1980
1981           /* Just because we didn't get a match doesn't mean that the
1982              constant isn't valid, just that it is in a format that we
1983              don't automatically recognize.  Try parsing it with
1984              the standard expression routines.  */
1985           if ((i = my_get_float_expression (str)) >= 0)
1986             {
1987               inst.instruction |= i + 8;
1988               return SUCCESS;
1989             }
1990
1991           inst.error = "Invalid floating point immediate expression";
1992           return FAIL;
1993         }
1994       inst.error = "Floating point register or immediate expression expected";
1995       return FAIL;
1996     }
1997 }
1998
1999 static void
2000 do_arit (str, flags)
2001      char *str;
2002      unsigned long flags;
2003 {
2004   while (*str == ' ')
2005     str++;
2006
2007   if (reg_required_here (&str, 12) == FAIL
2008       || skip_past_comma (&str) == FAIL
2009       || reg_required_here (&str, 16) == FAIL
2010       || skip_past_comma (&str) == FAIL
2011       || data_op2 (&str) == FAIL)
2012     {
2013       if (!inst.error)
2014         inst.error = bad_args;
2015       return;
2016     }
2017
2018   inst.instruction |= flags;
2019   end_of_line (str);
2020   return;
2021 }
2022
2023 static void
2024 do_adr (str, flags)
2025      char *str;
2026      unsigned long flags;
2027 {
2028   /* This is a pseudo-op of the form "adr rd, label" to be converted into
2029      a relative address of the form add rd, pc, #label-.-8 */
2030
2031   while (*str == ' ')
2032     str++;
2033
2034   if (reg_required_here (&str, 12) == FAIL
2035       || skip_past_comma (&str) == FAIL
2036       || my_get_expression (&inst.reloc.exp, &str))
2037     {
2038       if (!inst.error)
2039         inst.error = bad_args;
2040       return;
2041     }
2042   /* Frag hacking will turn this into a sub instruction if the offset turns
2043      out to be negative.  */
2044   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2045   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2046   inst.reloc.pc_rel = 1;
2047   inst.instruction |= flags;
2048   end_of_line (str);
2049   return;
2050 }
2051
2052 static void
2053 do_cmp (str, flags)
2054      char *str;
2055      unsigned long flags;
2056 {
2057   while (*str == ' ')
2058     str++;
2059
2060   if (reg_required_here (&str, 16) == FAIL)
2061     {
2062       if (!inst.error)
2063         inst.error = bad_args;
2064       return;
2065     }
2066
2067   if (skip_past_comma (&str) == FAIL
2068       || data_op2 (&str) == FAIL)
2069     {
2070       if (!inst.error)
2071         inst.error = bad_args;
2072       return;
2073     }
2074
2075   inst.instruction |= flags;
2076   if ((flags & 0x0000f000) == 0)
2077     inst.instruction |= 0x00100000;
2078
2079   end_of_line (str);
2080   return;
2081 }
2082
2083 static void
2084 do_mov (str, flags)
2085      char *str;
2086      unsigned long flags;
2087 {
2088   while (*str == ' ')
2089     str++;
2090
2091   if (reg_required_here (&str, 12) == FAIL)
2092     {
2093       if (!inst.error)
2094         inst.error = bad_args;
2095       return;
2096     }
2097
2098   if (skip_past_comma (&str) == FAIL
2099       || data_op2 (&str) == FAIL)
2100     {
2101       if (!inst.error)
2102         inst.error = bad_args;
2103       return;
2104     }
2105
2106   inst.instruction |= flags;
2107   end_of_line (str);
2108   return;
2109 }
2110
2111 static int
2112 ldst_extend (str)
2113      char **str;
2114 {
2115   int add = INDEX_UP;
2116
2117   switch (**str)
2118     {
2119     case '#':
2120       (*str)++;
2121       if (my_get_expression (&inst.reloc.exp, str))
2122         return FAIL;
2123
2124       if (inst.reloc.exp.X_op == O_constant)
2125         {
2126           int value = inst.reloc.exp.X_add_number;
2127
2128           if (value < -4095 || value > 4095)
2129             {
2130               inst.error = "address offset too large";
2131               return FAIL;
2132             }
2133
2134           if (value < 0)
2135             {
2136               value = -value;
2137               add = 0;
2138             }
2139
2140           inst.instruction |= add | value;
2141         }
2142       else
2143         {
2144           inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2145           inst.reloc.pc_rel = 0;
2146         }
2147       return SUCCESS;
2148
2149     case '-':
2150       add = 0;  /* and fall through */
2151     case '+':
2152       (*str)++; /* and fall through */
2153     default:
2154       if (reg_required_here (str, 0) == FAIL)
2155         {
2156           inst.error = "Register expected";
2157           return FAIL;
2158         }
2159       inst.instruction |= add | OFFSET_REG;
2160       if (skip_past_comma (str) == SUCCESS)
2161         return decode_shift (str, SHIFT_RESTRICT);
2162       return SUCCESS;
2163     }
2164 }
2165
2166 static void
2167 do_ldst (str, flags)
2168      char *str;
2169      unsigned long flags;
2170 {
2171   int pre_inc = 0;
2172   int conflict_reg;
2173   int value;
2174
2175   while (*str == ' ')
2176     str++;
2177     
2178   if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
2179     {
2180       if (!inst.error)
2181         inst.error = bad_args;
2182       return;
2183     }
2184
2185   if (skip_past_comma (&str) == FAIL)
2186     {
2187       inst.error = "Address expected";
2188       return;
2189     }
2190
2191   if (*str == '[')
2192     {
2193       int reg;
2194
2195       str++;
2196       while (*str == ' ')
2197         str++;
2198
2199       if ((reg = reg_required_here (&str, 16)) == FAIL)
2200         {
2201           inst.error = "Register required";
2202           return;
2203         }
2204
2205       conflict_reg = (((conflict_reg == reg)
2206                        && (inst.instruction & 0x00100000))
2207                       ? 1 : 0);
2208
2209       while (*str == ' ')
2210         str++;
2211
2212       if (*str == ']')
2213         {
2214           str++;
2215           if (skip_past_comma (&str) == SUCCESS)
2216             {
2217               /* [Rn],... (post inc) */
2218               if (ldst_extend (&str) == FAIL)
2219                 return;
2220               if (conflict_reg)
2221                 as_warn ("destination register same as write-back base\n");
2222             }
2223           else
2224             {
2225               /* [Rn] */
2226               flags |= INDEX_UP;
2227             }
2228         }
2229       else
2230         {
2231           /* [Rn,...] */
2232           if (skip_past_comma (&str) == FAIL)
2233             {
2234               inst.error = "pre-indexed expression expected";
2235               return;
2236             }
2237
2238           pre_inc = 1;
2239           if (ldst_extend (&str) == FAIL)
2240             return;
2241
2242           while (*str == ' ')
2243             str++;
2244
2245           if (*str++ != ']')
2246             {
2247               inst.error = "missing ]";
2248               return;
2249             }
2250
2251           while (*str == ' ')
2252             str++;
2253
2254           if (*str == '!')
2255             {
2256               if (conflict_reg)
2257                 as_warn ("destination register same as write-back base\n");
2258               str++;
2259               inst.instruction |= WRITE_BACK;
2260             }
2261         }
2262     }
2263   else if (*str == '=')
2264     {
2265       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2266       str++;
2267
2268       while (*str == ' ')
2269         str++;
2270
2271       if (my_get_expression (&inst.reloc.exp, &str))
2272         return;
2273
2274       if (inst.reloc.exp.X_op != O_constant
2275           && inst.reloc.exp.X_op != O_symbol)
2276         {
2277           inst.error = "Constant expression expected";
2278           return;
2279         }
2280
2281       if (inst.reloc.exp.X_op == O_constant
2282           && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2283         {
2284           /* This can be done with a mov instruction */
2285           inst.instruction &= LITERAL_MASK;
2286           inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2287           inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2288           end_of_line(str);
2289           return; 
2290         }
2291       else
2292         {
2293           /* Insert into literal pool */     
2294           if (add_to_lit_pool () == FAIL)
2295             {
2296               if (!inst.error)
2297                 inst.error = "literal pool insertion failed\n"; 
2298               return;
2299             }
2300
2301           /* Change the instruction exp to point to the pool */
2302           inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2303           inst.reloc.pc_rel = 1;
2304           inst.instruction |= (REG_PC << 16);
2305           pre_inc = 1; 
2306         }
2307     }
2308   else
2309     {
2310       if (my_get_expression (&inst.reloc.exp, &str))
2311         return;
2312
2313       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2314       inst.reloc.exp.X_add_number -= 8;  /* PC rel adjust */
2315       inst.reloc.pc_rel = 1;
2316       inst.instruction |= (REG_PC << 16);
2317       pre_inc = 1;
2318     }
2319     
2320   if (pre_inc && (flags & TRANS_BIT))
2321     inst.error = "Pre-increment instruction with translate";
2322
2323   inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2324   end_of_line (str);
2325   return;
2326 }
2327
2328 static void
2329 do_ldmstm (str, flags)
2330      char *str;
2331      unsigned long flags;
2332 {
2333   int base_reg;
2334
2335   while (*str == ' ')
2336     str++;
2337
2338   if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2339     {
2340       if (!inst.error)
2341         inst.error = bad_args;
2342       return;
2343     }
2344
2345   if (base_reg == REG_PC)
2346     {
2347       inst.error = "r15 not allowed as base register";
2348       return;
2349     }
2350
2351   while (*str == ' ')
2352     str++;
2353   if (*str == '!')
2354     {
2355       flags |= WRITE_BACK;
2356       str++;
2357     }
2358
2359   if (skip_past_comma (&str) == FAIL)
2360     {
2361       inst.error = bad_args;
2362       return;
2363     }
2364
2365   /* We come back here if we get ranges concatenated by '+' or '|' */
2366  another_range:
2367   if (*str == '{')
2368     {
2369       int in_range = 0;
2370       int cur_reg = -1;
2371       
2372       str++;
2373       do
2374         {
2375           int reg;
2376             
2377           while (*str == ' ')
2378             str++;
2379
2380           if ((reg = arm_reg_parse (&str)) == FAIL || !int_register (reg))
2381             {
2382               inst.error = "Register expected";
2383               return;
2384             }
2385
2386           if (in_range)
2387             {
2388               int i;
2389               
2390               if (reg <= cur_reg)
2391                 {
2392                   inst.error = "Bad range in register list";
2393                   return;
2394                 }
2395
2396               for (i = cur_reg + 1; i < reg; i++)
2397                 {
2398                   if (flags & (1 << i))
2399                     as_tsktsk 
2400                       ("Warning: Duplicated register (r%d) in register list",
2401                        i);
2402                   else
2403                     flags |= 1 << i;
2404                 }
2405               in_range = 0;
2406             }
2407
2408           if (flags & (1 << reg))
2409             as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2410                        reg);
2411           else if (reg <= cur_reg)
2412             as_tsktsk ("Warning: Register range not in ascending order");
2413
2414           flags |= 1 << reg;
2415           cur_reg = reg;
2416         } while (skip_past_comma (&str) != FAIL
2417                  || (in_range = 1, *str++ == '-'));
2418       str--;
2419       while (*str == ' ')
2420         str++;
2421
2422       if (*str++ != '}')
2423         {
2424           inst.error = "Missing `}'";
2425           return;
2426         }
2427     }
2428   else
2429     {
2430       expressionS expr;
2431
2432       if (my_get_expression (&expr, &str))
2433         return;
2434
2435       if (expr.X_op == O_constant)
2436         {
2437           if (expr.X_add_number 
2438               != (expr.X_add_number & 0x0000ffff))
2439             {
2440               inst.error = "invalid register mask";
2441               return;
2442             }
2443
2444           if ((flags & expr.X_add_number) != 0)
2445             {
2446               int regno = flags & expr.X_add_number;
2447
2448               regno &= -regno;
2449               regno = (1 << regno) - 1;
2450               as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2451                          regno);
2452             }
2453
2454           flags |= expr.X_add_number;
2455         }
2456       else
2457         {
2458           if (inst.reloc.type != 0)
2459             {
2460               inst.error = "expression too complex";
2461               return;
2462             }
2463
2464           memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2465           inst.reloc.type = BFD_RELOC_ARM_MULTI;
2466           inst.reloc.pc_rel = 0;
2467         }
2468     }
2469
2470   while (*str == ' ')
2471     str++;
2472
2473   if (*str == '|' || *str == '+')
2474     {
2475       str++;
2476       goto another_range;
2477     }
2478
2479   if (*str == '^')
2480     {
2481       str++;
2482       flags |= MULTI_SET_PSR;
2483     }
2484   inst.instruction |= flags;
2485   end_of_line (str);
2486   return;
2487 }
2488
2489 static void
2490 do_swi (str, flags)
2491      char *str;
2492      unsigned long flags;
2493 {
2494   /* Allow optional leading '#'.  */
2495   while (*str == ' ')
2496     str++;
2497   if (*str == '#')
2498     str++;
2499
2500   if (my_get_expression (&inst.reloc.exp, &str))
2501     return;
2502
2503   inst.reloc.type = BFD_RELOC_ARM_SWI;
2504   inst.reloc.pc_rel = 0;
2505   inst.instruction |= flags;
2506   end_of_line (str);
2507   return;
2508 }
2509
2510 static void
2511 do_swap (str, flags)
2512      char *str;
2513      unsigned long flags;
2514 {
2515   int reg;
2516   
2517   while (*str == ' ')
2518     str++;
2519
2520   if ((reg = reg_required_here (&str, 12)) == FAIL)
2521     return;
2522
2523   if (reg == REG_PC)
2524     {
2525       inst.error = "r15 not allowed in swap";
2526       return;
2527     }
2528
2529   if (skip_past_comma (&str) == FAIL
2530       || (reg = reg_required_here (&str, 0)) == FAIL)
2531     {
2532       if (!inst.error)
2533         inst.error = bad_args;
2534       return;
2535     }
2536
2537   if (reg == REG_PC)
2538     {
2539       inst.error = "r15 not allowed in swap";
2540       return;
2541     }
2542
2543   if (skip_past_comma (&str) == FAIL
2544       || *str++ != '[')
2545     {
2546       inst.error = bad_args;
2547       return;
2548     }
2549
2550   while (*str == ' ')
2551     str++;
2552
2553   if ((reg = reg_required_here (&str, 16)) == FAIL)
2554     return;
2555
2556   if (reg == REG_PC)
2557     {
2558       inst.error = bad_pc;
2559       return;
2560     }
2561
2562   while (*str == ' ')
2563     str++;
2564
2565   if (*str++ != ']')
2566     {
2567       inst.error = "missing ]";
2568       return;
2569     }
2570
2571   inst.instruction |= flags;
2572   end_of_line (str);
2573   return;
2574 }
2575
2576 static void
2577 do_branch (str, flags)
2578      char *str;
2579      unsigned long flags;
2580 {
2581   if (my_get_expression (&inst.reloc.exp, &str))
2582     return;
2583   inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
2584   inst.reloc.pc_rel = 1;
2585   inst.instruction |= flags | 0x00fffffe;       /* PC-rel adjust */
2586   end_of_line (str);
2587   return;
2588 }
2589
2590 static void
2591 do_cdp (str, flags)
2592      char *str;
2593      unsigned long flags;
2594 {
2595   /* Co-processor data operation.
2596      Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
2597   while (*str == ' ')
2598     str++;
2599
2600   if (co_proc_number (&str) == FAIL)
2601     {
2602       if (!inst.error)
2603         inst.error = bad_args;
2604       return;
2605     }
2606
2607   if (skip_past_comma (&str) == FAIL
2608       || cp_opc_expr (&str, 20,4) == FAIL)
2609     {
2610       if (!inst.error)
2611         inst.error = bad_args;
2612       return;
2613     }
2614
2615   if (skip_past_comma (&str) == FAIL
2616       || cp_reg_required_here (&str, 12) == FAIL)
2617     {
2618       if (!inst.error)
2619         inst.error = bad_args;
2620       return;
2621     }
2622
2623   if (skip_past_comma (&str) == FAIL
2624       || cp_reg_required_here (&str, 16) == FAIL)
2625     {
2626       if (!inst.error)
2627         inst.error = bad_args;
2628       return;
2629     }
2630
2631   if (skip_past_comma (&str) == FAIL
2632       || cp_reg_required_here (&str, 0) == FAIL)
2633     {
2634       if (!inst.error)
2635         inst.error = bad_args;
2636       return;
2637     }
2638
2639   if (skip_past_comma (&str) == SUCCESS)
2640     {
2641       if (cp_opc_expr (&str, 5, 3) == FAIL)
2642         {
2643           if (!inst.error)
2644             inst.error = bad_args;
2645           return;
2646         }
2647     }
2648
2649   end_of_line (str);
2650   return;
2651 }
2652
2653 static void
2654 do_lstc (str, flags)
2655      char *str;
2656      unsigned long flags;
2657 {
2658   /* Co-processor register load/store.
2659      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
2660
2661   while (*str == ' ')
2662     str++;
2663
2664   if (co_proc_number (&str) == FAIL)
2665     {
2666       if (!inst.error)
2667         inst.error = bad_args;
2668       return;
2669     }
2670
2671   if (skip_past_comma (&str) == FAIL
2672       || cp_reg_required_here (&str, 12) == FAIL)
2673     {
2674       if (!inst.error)
2675         inst.error = bad_args;
2676       return;
2677     }
2678
2679   if (skip_past_comma (&str) == FAIL
2680       || cp_address_required_here (&str) == FAIL)
2681     {
2682       if (! inst.error)
2683         inst.error = bad_args;
2684       return;
2685     }
2686
2687   inst.instruction |= flags;
2688   end_of_line (str);
2689   return;
2690 }
2691
2692 static void
2693 do_co_reg (str, flags)
2694      char *str;
2695      unsigned long flags;
2696 {
2697   /* Co-processor register transfer.
2698      Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
2699
2700   while (*str == ' ')
2701     str++;
2702
2703   if (co_proc_number (&str) == FAIL)
2704     {
2705       if (!inst.error)
2706         inst.error = bad_args;
2707       return;
2708     }
2709
2710   if (skip_past_comma (&str) == FAIL
2711       || cp_opc_expr (&str, 21, 3) == FAIL)
2712     {
2713       if (!inst.error)
2714         inst.error = bad_args;
2715       return;
2716     }
2717
2718   if (skip_past_comma (&str) == FAIL
2719       || reg_required_here (&str, 12) == FAIL)
2720     {
2721       if (!inst.error)
2722         inst.error = bad_args;
2723       return;
2724     }
2725
2726   if (skip_past_comma (&str) == FAIL
2727       || cp_reg_required_here (&str, 16) == FAIL)
2728     {
2729       if (!inst.error)
2730         inst.error = bad_args;
2731       return;
2732     }
2733
2734   if (skip_past_comma (&str) == FAIL
2735       || cp_reg_required_here (&str, 0) == FAIL)
2736     {
2737       if (!inst.error)
2738         inst.error = bad_args;
2739       return;
2740     }
2741
2742   if (skip_past_comma (&str) == SUCCESS)
2743     {
2744       if (cp_opc_expr (&str, 5, 3) == FAIL)
2745         {
2746           if (!inst.error)
2747             inst.error = bad_args;
2748           return;
2749         }
2750     }
2751
2752   end_of_line (str);
2753   return;
2754 }
2755
2756 static void
2757 do_fp_ctrl (str, flags)
2758      char *str;
2759      unsigned long flags;
2760 {
2761   /* FP control registers.
2762      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
2763
2764   while (*str == ' ')
2765     str++;
2766
2767   if (reg_required_here (&str, 12) == FAIL)
2768     {
2769       if (!inst.error)
2770         inst.error = bad_args;
2771       return;
2772     }
2773
2774   end_of_line (str);
2775   return;
2776 }
2777
2778 static void
2779 do_fp_ldst (str, flags)
2780      char *str;
2781      unsigned long flags;
2782 {
2783   while (*str == ' ')
2784     str++;
2785
2786   switch (inst.suffix)
2787     {
2788     case SUFF_S:
2789       break;
2790     case SUFF_D:
2791       inst.instruction |= CP_T_X;
2792       break;
2793     case SUFF_E:
2794       inst.instruction |= CP_T_Y;
2795       break;
2796     case SUFF_P:
2797       inst.instruction |= CP_T_X | CP_T_Y;
2798       break;
2799     default:
2800       abort ();
2801     }
2802
2803   if (fp_reg_required_here (&str, 12) == FAIL)
2804     {
2805       if (!inst.error)
2806         inst.error = bad_args;
2807       return;
2808     }
2809
2810   if (skip_past_comma (&str) == FAIL
2811       || cp_address_required_here (&str) == FAIL)
2812     {
2813       if (!inst.error)
2814         inst.error = bad_args;
2815       return;
2816     }
2817
2818   end_of_line (str);
2819 }
2820
2821 static void
2822 do_fp_ldmstm (str, flags)
2823      char *str;
2824      unsigned long flags;
2825 {
2826   int num_regs;
2827
2828   while (*str == ' ')
2829     str++;
2830
2831   if (fp_reg_required_here (&str, 12) == FAIL)
2832     {
2833       if (! inst.error)
2834         inst.error = bad_args;
2835       return;
2836     }
2837
2838   /* Get Number of registers to transfer */
2839   if (skip_past_comma (&str) == FAIL
2840       || my_get_expression (&inst.reloc.exp, &str))
2841     {
2842       if (! inst.error)
2843         inst.error = "constant expression expected";
2844       return;
2845     }
2846
2847   if (inst.reloc.exp.X_op != O_constant)
2848     {
2849       inst.error = "Constant value required for number of registers";
2850       return;
2851     }
2852
2853   num_regs = inst.reloc.exp.X_add_number;
2854
2855   if (num_regs < 1 || num_regs > 4)
2856     {
2857       inst.error = "number of registers must be in the range [1:4]";
2858       return;
2859     }
2860
2861   switch (num_regs)
2862     {
2863     case 1:
2864       inst.instruction |= CP_T_X;
2865       break;
2866     case 2:
2867       inst.instruction |= CP_T_Y;
2868       break;
2869     case 3:
2870       inst.instruction |= CP_T_Y | CP_T_X;
2871       break;
2872     case 4:
2873       break;
2874     default:
2875       abort ();
2876     }
2877
2878   if (flags)
2879     {
2880       int reg;
2881       int write_back;
2882       int offset;
2883
2884       /* The instruction specified "ea" or "fd", so we can only accept
2885          [Rn]{!}.  The instruction does not really support stacking or
2886          unstacking, so we have to emulate these by setting appropriate
2887          bits and offsets.  */
2888       if (skip_past_comma (&str) == FAIL
2889           || *str != '[')
2890         {
2891           if (! inst.error)
2892             inst.error = bad_args;
2893           return;
2894         }
2895
2896       str++;
2897       while (*str == ' ')
2898         str++;
2899
2900       if ((reg = reg_required_here (&str, 16)) == FAIL)
2901         {
2902           inst.error = "Register required";
2903           return;
2904         }
2905
2906       while (*str == ' ')
2907         str++;
2908
2909       if (*str != ']')
2910         {
2911           inst.error = bad_args;
2912           return;
2913         }
2914
2915       str++;
2916       if (*str == '!')
2917         {
2918           write_back = 1;
2919           str++;
2920           if (reg == REG_PC)
2921             {
2922               inst.error = "R15 not allowed as base register with write-back";
2923               return;
2924             }
2925         }
2926       else
2927         write_back = 0;
2928
2929       if (flags & CP_T_Pre)
2930         {
2931           /* Pre-decrement */
2932           offset = 3 * num_regs;
2933           if (write_back)
2934             flags |= CP_T_WB;
2935         }
2936       else
2937         {
2938           /* Post-increment */
2939           if (write_back)
2940             {
2941               flags |= CP_T_WB;
2942               offset = 3 * num_regs;
2943             }
2944           else
2945             {
2946               /* No write-back, so convert this into a standard pre-increment
2947                  instruction -- aesthetically more pleasing.  */
2948               flags = CP_T_Pre | CP_T_UD;
2949               offset = 0;
2950             }
2951         }
2952
2953       inst.instruction |= flags | offset;
2954     }
2955   else if (skip_past_comma (&str) == FAIL
2956            || cp_address_required_here (&str) == FAIL)
2957     {
2958       if (! inst.error)
2959         inst.error = bad_args;
2960       return;
2961     }
2962
2963   end_of_line (str);
2964 }
2965
2966 static void
2967 do_fp_dyadic (str, flags)
2968      char *str;
2969      unsigned long flags;
2970 {
2971   while (*str == ' ')
2972     str++;
2973
2974   switch (inst.suffix)
2975     {
2976     case SUFF_S:
2977       break;
2978     case SUFF_D:
2979       inst.instruction |= 0x00000080;
2980       break;
2981     case SUFF_E:
2982       inst.instruction |= 0x00080000;
2983       break;
2984     default:
2985       abort ();
2986     }
2987
2988   if (fp_reg_required_here (&str, 12) == FAIL)
2989     {
2990       if (! inst.error)
2991         inst.error = bad_args;
2992       return;
2993     }
2994
2995   if (skip_past_comma (&str) == FAIL
2996       || fp_reg_required_here (&str, 16) == FAIL)
2997     {
2998       if (! inst.error)
2999         inst.error = bad_args;
3000       return;
3001     }
3002
3003   if (skip_past_comma (&str) == FAIL
3004       || fp_op2 (&str) == FAIL)
3005     {
3006       if (! inst.error)
3007         inst.error = bad_args;
3008       return;
3009     }
3010
3011   inst.instruction |= flags;
3012   end_of_line (str);
3013   return;
3014 }
3015
3016 static void
3017 do_fp_monadic (str, flags)
3018      char *str;
3019      unsigned long flags;
3020 {
3021   while (*str == ' ')
3022     str++;
3023
3024   switch (inst.suffix)
3025     {
3026     case SUFF_S:
3027       break;
3028     case SUFF_D:
3029       inst.instruction |= 0x00000080;
3030       break;
3031     case SUFF_E:
3032       inst.instruction |= 0x00080000;
3033       break;
3034     default:
3035       abort ();
3036     }
3037
3038   if (fp_reg_required_here (&str, 12) == FAIL)
3039     {
3040       if (! inst.error)
3041         inst.error = bad_args;
3042       return;
3043     }
3044
3045   if (skip_past_comma (&str) == FAIL
3046       || fp_op2 (&str) == FAIL)
3047     {
3048       if (! inst.error)
3049         inst.error = bad_args;
3050       return;
3051     }
3052
3053   inst.instruction |= flags;
3054   end_of_line (str);
3055   return;
3056 }
3057
3058 static void
3059 do_fp_cmp (str, flags)
3060      char *str;
3061      unsigned long flags;
3062 {
3063   while (*str == ' ')
3064     str++;
3065
3066   if (fp_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       || fp_op2 (&str) == FAIL)
3075     {
3076       if (! inst.error)
3077         inst.error = bad_args;
3078       return;
3079     }
3080
3081   inst.instruction |= flags;
3082   end_of_line (str);
3083   return;
3084 }
3085
3086 static void
3087 do_fp_from_reg (str, flags)
3088      char *str;
3089      unsigned long flags;
3090 {
3091   while (*str == ' ')
3092     str++;
3093
3094   switch (inst.suffix)
3095     {
3096     case SUFF_S:
3097       break;
3098     case SUFF_D:
3099       inst.instruction |= 0x00000080;
3100       break;
3101     case SUFF_E:
3102       inst.instruction |= 0x00080000;
3103       break;
3104     default:
3105       abort ();
3106     }
3107
3108   if (fp_reg_required_here (&str, 16) == FAIL)
3109     {
3110       if (! inst.error)
3111         inst.error = bad_args;
3112       return;
3113     }
3114
3115   if (skip_past_comma (&str) == FAIL
3116       || reg_required_here (&str, 12) == FAIL)
3117     {
3118       if (! inst.error)
3119         inst.error = bad_args;
3120       return;
3121     }
3122
3123   inst.instruction |= flags;
3124   end_of_line (str);
3125   return;
3126 }
3127
3128 static void
3129 do_fp_to_reg (str, flags)
3130      char *str;
3131      unsigned long flags;
3132 {
3133   while (*str == ' ')
3134     str++;
3135
3136   if (reg_required_here (&str, 12) == FAIL)
3137     {
3138       if (! inst.error)
3139         inst.error = bad_args;
3140       return;
3141     }
3142
3143   if (skip_past_comma (&str) == FAIL
3144       || fp_reg_required_here (&str, 0) == FAIL)
3145     {
3146       if (! inst.error)
3147         inst.error = bad_args;
3148       return;
3149     }
3150
3151   inst.instruction |= flags;
3152   end_of_line (str);
3153   return;
3154 }
3155
3156 static void
3157 insert_reg (entry)
3158      int entry;
3159 {
3160   int len = strlen (reg_table[entry].name) + 2;
3161   char *buf = (char *) xmalloc (len);
3162   char *buf2 = (char *) xmalloc (len);
3163   int i = 0;
3164
3165 #ifdef REGISTER_PREFIX
3166   buf[i++] = REGISTER_PREFIX;
3167 #endif
3168
3169   strcpy (buf + i, reg_table[entry].name);
3170
3171   for (i = 0; buf[i]; i++)
3172     buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
3173
3174   buf2[i] = '\0';
3175
3176   hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
3177   hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
3178 }
3179
3180 static void
3181 insert_reg_alias (str, regnum)
3182      char *str;
3183      int regnum;
3184 {
3185   struct reg_entry *new =
3186     (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
3187   char *name = xmalloc (strlen (str) + 1);
3188   strcpy (name, str);
3189
3190   new->name = name;
3191   new->number = regnum;
3192
3193   hash_insert (arm_reg_hsh, name, (PTR) new);
3194 }
3195
3196 static void
3197 set_constant_flonums ()
3198 {
3199   int i;
3200
3201   for (i = 0; i < NUM_FLOAT_VALS; i++)
3202     if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
3203       abort ();
3204 }
3205
3206 void
3207 md_begin ()
3208 {
3209   int i;
3210
3211   if ((arm_ops_hsh = hash_new ()) == NULL
3212       || (arm_cond_hsh = hash_new ()) == NULL
3213       || (arm_shift_hsh = hash_new ()) == NULL
3214       || (arm_reg_hsh = hash_new ()) == NULL
3215       || (arm_psr_hsh = hash_new ()) == NULL)
3216     as_fatal ("Virtual memory exhausted");
3217     
3218   for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
3219     hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
3220   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
3221     hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
3222   for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
3223     hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
3224   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
3225     hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
3226
3227   for (i = 0; reg_table[i].name; i++)
3228     insert_reg (i);
3229
3230   set_constant_flonums ();
3231 }
3232
3233 /* This funciton is called once, before the assembler exits.  It is
3234    supposed to do any final cleanup for this part of the assembler.
3235    */
3236 void
3237 md_end ()
3238 {
3239 }
3240
3241 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
3242    for use in the a.out file, and stores them in the array pointed to by buf.
3243    This knows about the endian-ness of the target machine and does
3244    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
3245    2 (short) and 4 (long)  Floating numbers are put out as a series of
3246    LITTLENUMS (shorts, here at least)
3247    */
3248 void
3249 md_number_to_chars (buf, val, n)
3250      char *buf;
3251      valueT val;
3252      int n;
3253 {
3254   if (target_big_endian)
3255     number_to_chars_bigendian (buf, val, n);
3256   else
3257     number_to_chars_littleendian (buf, val, n);
3258 }
3259
3260 static valueT 
3261 md_chars_to_number (buf, n)
3262      char *buf;
3263      int n;
3264 {
3265   valueT result = 0;
3266   unsigned char *where = (unsigned char *) buf;
3267
3268   if (target_big_endian)
3269     {
3270       while (n--)
3271         {
3272           result <<= 8;
3273           result |= (*where++ & 255);
3274         }
3275     }
3276   else
3277     {
3278       while (n--)
3279         {
3280           result <<= 8;
3281           result |= (where[n] & 255);
3282         }
3283     }
3284
3285   return result;
3286 }
3287
3288 /*
3289    This is identical to the md_atof in m68k.c.  I think this is right,
3290    but I'm not sure.
3291
3292    Turn a string in input_line_pointer into a floating point constant of type
3293    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
3294    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
3295    */
3296 char *
3297 md_atof (type, litP, sizeP)
3298      char type;
3299      char *litP;
3300      int *sizeP;
3301 {
3302   int prec;
3303   LITTLENUM_TYPE words[MAX_LITTLENUMS];
3304   LITTLENUM_TYPE *wordP;
3305   char *t;
3306   char *atof_ieee ();
3307
3308   switch (type)
3309     {
3310
3311     case 'f':
3312     case 'F':
3313     case 's':
3314     case 'S':
3315       prec = 2;
3316       break;
3317
3318     case 'd':
3319     case 'D':
3320     case 'r':
3321     case 'R':
3322       prec = 4;
3323       break;
3324
3325     case 'x':
3326     case 'X':
3327       prec = 6;
3328       break;
3329
3330     case 'p':
3331     case 'P':
3332       prec = 6;
3333       break;
3334
3335     default:
3336       *sizeP = 0;
3337       return "Bad call to MD_ATOF()";
3338     }
3339   t = atof_ieee (input_line_pointer, type, words);
3340   if (t)
3341     input_line_pointer = t;
3342   *sizeP = prec * sizeof (LITTLENUM_TYPE);
3343   for (wordP = words; prec--;)
3344     {
3345       fprintf (stderr, "%02x 02x ", ((*wordP) >> 8) & 255, (*wordP) & 255);
3346       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
3347       litP += sizeof (LITTLENUM_TYPE);
3348     }
3349   fprintf (stderr, "\n");
3350   return 0;
3351 }
3352
3353 /* We have already put the pipeline compensation in the instruction */
3354
3355 long
3356 md_pcrel_from (fixP)
3357      fixS *fixP;
3358 {
3359   if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
3360       && fixP->fx_subsy == NULL)
3361     return 0;   /* HACK */
3362
3363   return fixP->fx_where + fixP->fx_frag->fr_address;
3364 }
3365
3366 /* Round up a section size to the appropriate boundary. */
3367 valueT
3368 md_section_align (segment, size)
3369      segT segment;
3370      valueT size;
3371 {
3372   /* Round all sects to multiple of 4 */
3373   return (size + 3) & ~3;
3374 }
3375
3376 /* We have no need to default values of symbols.  */
3377
3378 /* ARGSUSED */
3379 symbolS *
3380 md_undefined_symbol (name)
3381      char *name;
3382 {
3383   return 0;
3384 }
3385
3386 /* arm_reg_parse () := if it looks like a register, return its token and 
3387    advance the pointer. */
3388
3389 static int
3390 arm_reg_parse (ccp)
3391      register char **ccp;
3392 {
3393   char *start = *ccp;
3394   char c;
3395   char *p;
3396   struct reg_entry *reg;
3397
3398 #ifdef REGISTER_PREFIX
3399   if (*start != REGISTER_PREFIX)
3400     return FAIL;
3401   p = start + 1;
3402 #else
3403   p = start;
3404 #ifdef OPTIONAL_REGISTER_PREFIX
3405   if (*p == OPTIONAL_REGISTER_PREFIX)
3406     p++, start++;
3407 #endif
3408 #endif
3409   if (!isalpha (*p) || !is_name_beginner (*p))
3410     return FAIL;
3411
3412   c = *p++;
3413   while (isalpha (c) || isdigit (c) || c == '_')
3414     c = *p++;
3415
3416   *--p = 0;
3417   reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
3418   *p = c;
3419   
3420   if (reg)
3421     {
3422       *ccp = p;
3423       return reg->number;
3424     }
3425
3426   return FAIL;
3427 }
3428
3429 static int
3430 arm_psr_parse (ccp)
3431      register char **ccp;
3432 {
3433   char *start = *ccp;
3434   char c, *p;
3435   CONST struct asm_psr *psr;
3436
3437   p = start;
3438   c = *p++;
3439   while (isalpha (c) || c == '_')
3440     c = *p++;
3441
3442   *--p = 0;  
3443   psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
3444   *p = c;
3445
3446   if (psr)
3447     {
3448       *ccp = p;
3449       return psr->number;
3450     }
3451
3452   return FAIL;
3453 }
3454
3455 int
3456 md_apply_fix (fixP, val)
3457      fixS *fixP;
3458      valueT *val;
3459 {
3460   offsetT value = *val;
3461   offsetT newval, temp;
3462   int sign;
3463   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3464
3465   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
3466
3467   fixP->fx_addnumber = value;   /* Remember value for emit_reloc */
3468
3469   /* Note whether this will delete the relocation.  */
3470   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
3471     fixP->fx_done = 1;
3472
3473   switch (fixP->fx_r_type)
3474     {
3475     case BFD_RELOC_ARM_IMMEDIATE:
3476       newval = validate_immediate (value);
3477       temp = md_chars_to_number (buf, INSN_SIZE);
3478
3479       /* If the instruction will fail, see if we can fix things up by
3480          changing the opcode.  */
3481       if (newval == FAIL
3482           && (newval = negate_data_op (&temp, value)) == FAIL)
3483         {
3484           as_bad_where (fixP->fx_file, fixP->fx_line,
3485                         "invalid constant after fixup\n");
3486           break;
3487         }
3488
3489       newval |= (temp & 0xfffff000);
3490       md_number_to_chars (buf, newval, INSN_SIZE);
3491       break;
3492
3493     case BFD_RELOC_ARM_OFFSET_IMM:
3494       sign = value >= 0;
3495       value = validate_offset_imm (value); /* Should be OK ... but .... */
3496       if (value < 0)
3497         value = -value;
3498
3499       newval = md_chars_to_number (buf, INSN_SIZE);
3500       newval &= 0xff7ff000;
3501       newval |= value | (sign ? 0x00800000 : 0);
3502       md_number_to_chars (buf, newval, INSN_SIZE);
3503       break;
3504
3505     case BFD_RELOC_ARM_LITERAL:
3506       sign = value >= 0;
3507       if (value < 0)
3508         value = -value;
3509
3510       if ((value = validate_immediate (value)) == FAIL)
3511         {
3512           as_bad_where (fixP->fx_file, fixP->fx_line, 
3513                         "invalid literal constant: pool needs to be closer\n");
3514           break;
3515         }
3516
3517       newval = md_chars_to_number (buf, INSN_SIZE);
3518       newval &= 0xff7ff000;
3519       newval |= value | (sign ? 0x00800000 : 0);
3520       md_number_to_chars (buf, newval, INSN_SIZE);
3521       break;
3522
3523     case BFD_RELOC_ARM_SHIFT_IMM:
3524       newval = md_chars_to_number (buf, INSN_SIZE);
3525       if (((unsigned long) value) > 32
3526           || (value == 32 
3527               && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
3528         {
3529           as_bad_where (fixP->fx_file, fixP->fx_line,
3530                         "shift expression is too large");
3531           break;
3532         }
3533
3534       if (value == 0)
3535         newval &= ~0x60;        /* Shifts of zero must be done as lsl */
3536       else if (value == 32)
3537         value = 0;
3538       newval &= 0xfffff07f;
3539       newval |= (value & 0x1f) << 7;
3540       md_number_to_chars (buf, newval , INSN_SIZE);
3541       break;
3542
3543     case BFD_RELOC_ARM_SWI:
3544       if (((unsigned long) value) > 0x00ffffff)
3545         as_bad_where (fixP->fx_file, fixP->fx_line, "Invalid swi expression");
3546       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
3547       newval |= value;
3548       md_number_to_chars (buf, newval , INSN_SIZE);
3549       break;
3550
3551     case BFD_RELOC_ARM_MULTI:
3552       if (((unsigned long) value) > 0xffff)
3553         as_bad_where (fixP->fx_file, fixP->fx_line,
3554                       "Invalid expression in load/store multiple");
3555       newval = value | md_chars_to_number (buf, INSN_SIZE);
3556       md_number_to_chars (buf, newval, INSN_SIZE);
3557       break;
3558
3559     case BFD_RELOC_ARM_PCREL_BRANCH:
3560       value = (value >> 2) & 0x00ffffff;
3561       newval = md_chars_to_number (buf, INSN_SIZE);
3562       value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
3563       newval = value | (newval & 0xff000000);
3564       md_number_to_chars (buf, newval, INSN_SIZE);
3565       break;
3566
3567     case BFD_RELOC_8:
3568       if (fixP->fx_done || fixP->fx_pcrel)
3569         md_number_to_chars (buf, value, 1);
3570       break;
3571
3572     case BFD_RELOC_16:
3573       if (fixP->fx_done || fixP->fx_pcrel)
3574         md_number_to_chars (buf, value, 2);
3575       break;
3576
3577     case BFD_RELOC_32:
3578       if (fixP->fx_done || fixP->fx_pcrel)
3579         md_number_to_chars (buf, value, 4);
3580       break;
3581
3582     case BFD_RELOC_ARM_CP_OFF_IMM:
3583       sign = value >= 0;
3584       if (value < -1023 || value > 1023 || (value & 3))
3585         as_bad_where (fixP->fx_file, fixP->fx_line,
3586                       "Illegal value for co-processor offset");
3587       if (value < 0)
3588         value = -value;
3589       newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
3590       newval |= (value >> 2) | (sign ?  0x00800000 : 0);
3591       md_number_to_chars (buf, newval , INSN_SIZE);
3592       break;
3593
3594     case BFD_RELOC_NONE:
3595     default:
3596       as_bad_where (fixP->fx_file, fixP->fx_line,
3597                     "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
3598     }
3599
3600   return 1;
3601 }
3602
3603 /* Translate internal representation of relocation info to BFD target
3604    format.  */
3605 arelent *
3606 tc_gen_reloc (section, fixp)
3607      asection *section;
3608      fixS *fixp;
3609 {
3610   arelent *reloc;
3611   bfd_reloc_code_real_type code;
3612
3613   reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
3614   assert (reloc != 0);
3615
3616   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
3617   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3618
3619   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
3620   if (fixp->fx_pcrel == 0)
3621     reloc->addend = fixp->fx_offset;
3622   else
3623     reloc->addend = fixp->fx_offset = reloc->address;
3624
3625   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
3626   if (fixp->fx_pcrel == 0)
3627     reloc->addend = fixp->fx_offset;
3628   else
3629     reloc->addend = fixp->fx_offset = reloc->address;
3630
3631   switch (fixp->fx_r_type)
3632     {
3633     case BFD_RELOC_8:
3634       if (fixp->fx_pcrel)
3635         {
3636           code = BFD_RELOC_8_PCREL;
3637           break;
3638         }
3639
3640     case BFD_RELOC_16:
3641       if (fixp->fx_pcrel)
3642         {
3643           code = BFD_RELOC_16_PCREL;
3644           break;
3645         }
3646
3647     case BFD_RELOC_32:
3648       if (fixp->fx_pcrel)
3649         {
3650           code = BFD_RELOC_32_PCREL;
3651           break;
3652         }
3653
3654     case BFD_RELOC_ARM_PCREL_BRANCH:
3655       code = fixp->fx_r_type;
3656       break;
3657
3658     case BFD_RELOC_ARM_LITERAL:
3659       /* If this is called then the a literal has been referenced across
3660          a section boundry - possibly due to an implicit dump */
3661       as_bad ("Literal referenced across section boundry (Implicit dump?)");
3662       return NULL;
3663
3664     case BFD_RELOC_ARM_IMMEDIATE:
3665       as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
3666               , fixp->fx_r_type);
3667       return NULL;
3668
3669     case BFD_RELOC_ARM_OFFSET_IMM:
3670       as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
3671               , fixp->fx_r_type);
3672       return NULL;
3673
3674     case BFD_RELOC_ARM_SHIFT_IMM:
3675       as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
3676               , fixp->fx_r_type);
3677       return NULL;
3678
3679     case BFD_RELOC_ARM_SWI:
3680       as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
3681               , fixp->fx_r_type);
3682       return NULL;
3683
3684     case BFD_RELOC_ARM_MULTI:
3685       as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
3686               , fixp->fx_r_type);
3687       return NULL;
3688
3689     case BFD_RELOC_ARM_CP_OFF_IMM:
3690       as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
3691               , fixp->fx_r_type);
3692       return NULL;
3693
3694     default:
3695       abort ();
3696     }
3697
3698   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3699   assert (reloc->howto != 0);
3700
3701   return reloc;
3702 }
3703
3704 CONST int md_short_jump_size = 4;
3705 CONST int md_long_jump_size = 4;
3706
3707 /* These should never be called on the arm */
3708 void
3709 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
3710      char *ptr;
3711      addressT from_addr, to_addr;
3712      fragS *frag;
3713      symbolS *to_symbol;
3714 {
3715   as_fatal ("md_create_long_jump\n");
3716 }
3717
3718 void
3719 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
3720      char *ptr;
3721      addressT from_addr, to_addr;
3722      fragS *frag;
3723      symbolS *to_symbol;
3724 {
3725   as_fatal ("md_create_short_jump\n");
3726 }
3727
3728 int
3729 md_estimate_size_before_relax (fragP, segtype)
3730      fragS *fragP;
3731      segT segtype;
3732 {
3733   as_fatal ("md_estimate_size_before_relax\n");
3734   return (1);
3735 }
3736
3737 void
3738 output_inst (str)
3739      char *str;
3740 {
3741   char *to = NULL;
3742     
3743   if (inst.error)
3744     {
3745       as_bad ("%s -- statement `%s'\n", inst.error, str);
3746       return;
3747     }
3748
3749   to = frag_more (INSN_SIZE);
3750   md_number_to_chars (to, inst.instruction, INSN_SIZE);
3751
3752   if (inst.reloc.type != BFD_RELOC_NONE)
3753     fix_new_arm (frag_now, to - frag_now->fr_literal,
3754                  4, &inst.reloc.exp, inst.reloc.pc_rel,
3755                  inst.reloc.type);
3756
3757   return;
3758 }
3759
3760 void
3761 md_assemble (str)
3762      char *str;
3763 {
3764   char c;
3765   CONST struct asm_opcode *opcode;
3766   char *p, *q, *start;
3767
3768   /* Align the instruction */
3769   /* this may not be the right thing to do but ... */
3770   /* arm_align (2, 0); */
3771   listing_prev_line (); /* Defined in listing.h */
3772
3773   /* Align the previous label if needed */
3774   if (last_label_seen != NULL)
3775     {
3776       last_label_seen->sy_frag = frag_now;
3777       S_SET_VALUE (last_label_seen,
3778                    (valueT) ((char *) obstack_next_free (&frags)
3779                              - frag_now->fr_literal));
3780       S_SET_SEGMENT (last_label_seen, now_seg);
3781     }
3782
3783   memset (&inst, '\0', sizeof (inst));
3784   inst.reloc.type = BFD_RELOC_NONE;
3785
3786   if (*str == ' ')
3787     str++;                      /* Skip leading white space */
3788     
3789   /* scan up to the end of the op-code, which must end in white space or
3790      end of string */
3791   for (start = p = str; *p != '\0'; p++)
3792     if (*p == ' ')
3793       break;
3794     
3795   if (p == str)
3796     {
3797       as_bad ("No operator -- statement `%s'\n", str);
3798       return;
3799     }
3800
3801   /* p now points to the end of the opcode, probably white space, but we have
3802      to break the opcode up in case it contains condionals and flags;
3803      keep trying with progressively smaller basic instructions until one
3804      matches, or we run out of opcode. */
3805   q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
3806   for (; q != str; q--)
3807     {
3808       c = *q;
3809       *q = '\0';
3810       opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
3811       *q = c;
3812       if (opcode && opcode->template)
3813         {
3814           unsigned long flag_bits = 0;
3815           char *r;
3816
3817           /* Check that this instruction is supported for this CPU */
3818           if ((opcode->variants & cpu_variant) == 0)
3819             goto try_shorter;
3820
3821           inst.instruction = opcode->value;
3822           if (q == p)           /* Just a simple opcode */
3823             {
3824               if (opcode->comp_suffix != 0)
3825                 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
3826                         opcode->comp_suffix);
3827               else
3828                 {
3829                   inst.instruction |= COND_ALWAYS;
3830                   (*opcode->parms)(q, 0);
3831                 }
3832               output_inst (start);
3833               return;
3834             }
3835
3836           /* Now check for a conditional */
3837           r = q;
3838           if (p - r >= 2)
3839             {
3840               CONST struct asm_cond *cond;
3841               char d = *(r + 2);
3842               
3843               *(r + 2) = '\0';
3844               cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
3845               *(r + 2) = d;
3846               if (cond)
3847                 {
3848                   if (cond->value == 0xf0000000)
3849                     as_tsktsk
3850                       ("Warning: Use of the 'nv' conditional is deprecated\n");
3851
3852                   inst.instruction |= cond->value;
3853                   r += 2;
3854                 }
3855               else
3856                 inst.instruction |= COND_ALWAYS;
3857             }
3858           else
3859             inst.instruction |= COND_ALWAYS;
3860
3861           /* if there is a compulsory suffix, it should come here, before
3862              any optional flags. */
3863           if (opcode->comp_suffix)
3864             {
3865               CONST char *s = opcode->comp_suffix;
3866
3867               while (*s)
3868                 {
3869                   inst.suffix++;
3870                   if (*r == *s)
3871                     break;
3872                   s++;
3873                 }
3874               
3875               if (*s == '\0')
3876                 {
3877                   as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
3878                           opcode->comp_suffix);
3879                   return;
3880                 }
3881                 
3882               r++;
3883             }
3884
3885           /* The remainder, if any should now be flags for the instruction;
3886              Scan these checking each one found with the opcode.  */
3887           if (r != p)
3888             {
3889               char d;
3890               CONST struct asm_flg *flag = opcode->flags;
3891
3892               if (flag)
3893                 {
3894                   int flagno;
3895
3896                   d = *p;
3897                   *p = '\0';
3898
3899                   for (flagno = 0; flag[flagno].template; flagno++)
3900                     {
3901                       if (! strcmp (r, flag[flagno].template))
3902                         {
3903                           flag_bits |= flag[flagno].set_bits;
3904                           break;
3905                         }
3906                     }
3907
3908                   *p = d;
3909                   if (! flag[flagno].template)
3910                     goto try_shorter;
3911                 }
3912               else
3913                 goto try_shorter;
3914             }
3915
3916           (*opcode->parms) (p, flag_bits);
3917           output_inst (start);
3918           return;
3919         }
3920
3921     try_shorter:
3922         ;
3923     }
3924   /* It wasn't an instruction, but it might be a register alias of the form
3925      alias .req reg
3926      */
3927   q = p;
3928   while (*q == ' ')
3929     q++;
3930
3931   c = *p;
3932   *p = '\0';
3933     
3934   if (*q && !strncmp (q, ".req ", 4))
3935     {
3936       int reg;
3937       if ((reg = arm_reg_parse (&str)) == FAIL)
3938         {
3939           char *r;
3940       
3941           q += 4;
3942           while (*q == ' ')
3943             q++;
3944
3945           for (r = q; *r != '\0'; r++)
3946             if (*r == ' ')
3947               break;
3948
3949           if (r != q)
3950             {
3951               int regnum;
3952               char d = *r;
3953
3954               *r = '\0';
3955               regnum = arm_reg_parse (&q);
3956               *r = d;
3957               if (regnum != FAIL)
3958                 {
3959                   insert_reg_alias (str, regnum);
3960                   *p = c;
3961                   return;
3962                 }
3963             }
3964         }
3965       else
3966         {
3967           *p = c;
3968           return;
3969         }
3970     }
3971
3972   *p = c;
3973   as_bad ("bad instruction `%s'", start);
3974 }
3975
3976 /*
3977  * md_parse_option
3978  *    Invocation line includes a switch not recognized by the base assembler.
3979  *    See if it's a processor-specific option.  These are:
3980  *    Cpu variants, the arm part is optional:
3981  *            -m[arm]1                Currently not supported.
3982  *            -m[arm]2, -m[arm]250    Arm 2 and Arm 250 processor
3983  *            -m[arm]3                Arm 3 processor
3984  *            -m[arm]6, -m[arm]7      Arm 6 and 7 processors
3985  *            -m[arm]7dm              Arm 7dm processors
3986  *            -mall                   All (except the ARM1)
3987  *    FP variants:
3988  *            -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
3989  *            -mfpe-old               (No float load/store multiples)
3990  *            -mno-fpu                Disable all floating point instructions
3991  *    Run-time endian selection:
3992  *            -EB                     big endian cpu
3993  *            -EL                     little endian cpu
3994  */
3995
3996 CONST char *md_shortopts = "m:";
3997 struct option md_longopts[] = {
3998 #ifdef ARM_BI_ENDIAN
3999 #define OPTION_EB (OPTION_MD_BASE + 0)
4000   {"EB", no_argument, NULL, OPTION_EB},
4001 #define OPTION_EL (OPTION_MD_BASE + 1)
4002   {"EL", no_argument, NULL, OPTION_EL},
4003 #endif
4004   {NULL, no_argument, NULL, 0}
4005 };
4006 size_t md_longopts_size = sizeof(md_longopts);
4007
4008 int
4009 md_parse_option (c, arg)
4010      int c;
4011      char *arg;
4012 {
4013   char *str = arg;
4014
4015   switch (c)
4016     {
4017 #ifdef ARM_BI_ENDIAN
4018     case OPTION_EB:
4019       target_big_endian = 1;
4020       break;
4021     case OPTION_EL:
4022       target_big_endian = 0;
4023       break;
4024 #endif
4025
4026     case 'm':
4027       switch (*str)
4028         {
4029         case 'f':
4030           if (! strcmp (str, "fpa10"))
4031             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
4032           else if (! strcmp (str, "fpa11"))
4033             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
4034           else if (! strcmp (str, "fpe-old"))
4035             cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
4036           else
4037             goto bad;
4038           break;
4039
4040         case 'n':
4041           if (! strcmp (str, "no-fpu"))
4042             cpu_variant &= ~FPU_ALL;
4043           break;
4044
4045         default:
4046           if (! strcmp (str, "all"))
4047             {
4048               cpu_variant = ARM_ALL | FPU_ALL;
4049               return 1;
4050             }
4051
4052           /* Strip off optional "arm" */
4053           if (! strncmp (str, "arm", 3))
4054             str += 3;
4055
4056           switch (*str)
4057             {
4058             case '1':
4059               if (! strcmp (str, "1"))
4060                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
4061               else
4062                 goto bad;
4063               break;
4064
4065             case '2':
4066               if (! strcmp (str, "2"))
4067                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
4068               else if (! strcmp (str, "250"))
4069                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
4070               else
4071                 goto bad;
4072               break;
4073
4074             case '3':
4075               if (! strcmp (str, "3"))
4076                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
4077               else
4078                 goto bad;
4079               break;
4080
4081             case '6':
4082               if (! strcmp (str, "6"))
4083                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
4084               else
4085                 goto bad;
4086               break;
4087
4088             case '7':
4089               if (! strcmp (str, "7"))
4090                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
4091               else if (! strcmp (str, "7dm"))
4092                 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7DM;
4093               else
4094                 goto bad;
4095               break;
4096
4097             default:
4098             bad:
4099               as_bad ("Invalid architecture -m%s", arg);
4100               return 0;
4101             }
4102         }
4103       break;
4104
4105     default:
4106       return 0;
4107     }
4108
4109    return 1;
4110 }
4111
4112 void
4113 md_show_usage (fp)
4114      FILE *fp;
4115 {
4116   fprintf (fp,
4117 "-m[arm]1, -m[arm]2, -m[arm]250,\n-m[arm]3, -m[arm]6, -m[arm]7, -m[arm]7dm\n\
4118 \t\t\tselect processor architecture\n\
4119 -mall\t\t\tallow any instruction\n\
4120 -mfpa10, -mfpa11\tselect floating point architecture\n\
4121 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
4122 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
4123 #ifdef ARM_BI_ENDIAN
4124   fprintf (fp,
4125 "-EB\t\t\tassemble code for a big endian cpu\n\
4126 -EL\t\t\tassemble code for a little endian cpu\n");
4127 #endif
4128 }
4129
4130 /* We need to be able to fix up arbitrary expressions in some statements.
4131    This is so that we can handle symbols that are an arbitrary distance from
4132    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
4133    which returns part of an address in a form which will be valid for
4134    a data instruction.  We do this by pushing the expression into a symbol
4135    in the expr_section, and creating a fix for that.  */
4136
4137 static void
4138 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
4139      fragS *frag;
4140      int where;
4141      short int size;
4142      expressionS *exp;
4143      int pc_rel;
4144      int reloc;
4145 {
4146   fixS *new_fix;
4147
4148   switch (exp->X_op)
4149     {
4150     case O_constant:
4151     case O_symbol:
4152     case O_add:
4153     case O_subtract:
4154       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
4155       break;
4156
4157     default:
4158       {
4159         const char *fake;
4160         symbolS *symbolP;
4161         
4162         /* FIXME: This should be something which decode_local_label_name
4163            will handle.  */
4164         fake = FAKE_LABEL_NAME;
4165
4166         /* Putting constant symbols in absolute_section rather than
4167            expr_section is convenient for the old a.out code, for which
4168            S_GET_SEGMENT does not always retrieve the value put in by
4169            S_SET_SEGMENT.  */
4170         symbolP = symbol_new (fake, expr_section, 0, &zero_address_frag);
4171         symbolP->sy_value = *exp;
4172         new_fix = fix_new (frag, where, size, symbolP, 0, pc_rel, reloc);
4173       }
4174       break;
4175     }
4176
4177   return;
4178 }
4179
4180 /* A good place to do this, although this was probably not intended
4181  * for this kind of use.  We need to dump the literal pool before
4182  * references are made to a null symbol pointer.  */
4183 void
4184 arm_after_pass_hook (ignore)
4185      asection *ignore;
4186 {
4187   if (current_poolP != NULL)
4188     {
4189       subseg_set (text_section, 0); /* Put it at the end of text section */
4190       s_ltorg (0);
4191       listing_prev_line ();
4192     }
4193 }
4194
4195 void
4196 arm_start_line_hook ()
4197 {
4198   last_label_seen = NULL;
4199 }
4200
4201 void
4202 arm_frob_label (sym)
4203      symbolS *sym;
4204 {
4205   last_label_seen = sym;
4206 }