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