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