Assign correct reloc value to size 1 fixes.
[binutils.git] / gas / config / tc-arm.c
blobc6a197966932780f4ea11c70059e7a3402aabc39
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
23 #include <ctype.h>
24 #include <string.h>
25 #define NO_RELOC 0
26 #include "as.h"
28 /* need TARGET_CPU */
29 #include "config.h"
30 #include "subsegs.h"
31 #include "obstack.h"
32 #include "symbols.h"
33 #include "listing.h"
35 #ifdef OBJ_ELF
36 #include "elf/arm.h"
37 #endif
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
43 #define ARM_250 ARM_3
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
55 #define ARM_EXT_V5E 0x00000200 /* "El Segundo" */
57 /* Architectures are the sum of the base and extensions. */
58 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
60 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
61 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP (ARM_ANY - ARM_1)
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
73 #define FPU_NONE 0
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
80 #ifndef CPU_DEFAULT
81 #if defined __thumb__
82 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #else
84 #define CPU_DEFAULT ARM_ALL
85 #endif
86 #endif
88 #ifndef FPU_DEFAULT
89 #define FPU_DEFAULT FPU_ALL
90 #endif
92 #define streq(a, b) (strcmp (a, b) == 0)
93 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
95 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
96 static int target_oabi = 0;
98 #if defined OBJ_COFF || defined OBJ_ELF
99 /* Flags stored in private area of BFD structure */
100 static boolean uses_apcs_26 = false;
101 static boolean support_interwork = false;
102 static boolean uses_apcs_float = false;
103 static boolean pic_code = false;
104 #endif
106 /* This array holds the chars that always start a comment. If the
107 pre-processor is disabled, these aren't very useful. */
108 CONST char comment_chars[] = "@";
110 /* This array holds the chars that only start a comment at the beginning of
111 a line. If the line seems to have the form '# 123 filename'
112 .line and .file directives will appear in the pre-processed output. */
113 /* Note that input_file.c hand checks for '#' at the beginning of the
114 first line of the input file. This is because the compiler outputs
115 #NO_APP at the beginning of its output. */
116 /* Also note that comments like this one will always work. */
117 CONST char line_comment_chars[] = "#";
119 #ifdef TE_LINUX
120 CONST char line_separator_chars[] = ";";
121 #else
122 CONST char line_separator_chars[] = "";
123 #endif
125 /* Chars that can be used to separate mant
126 from exp in floating point numbers. */
127 CONST char EXP_CHARS[] = "eE";
129 /* Chars that mean this number is a floating point constant */
130 /* As in 0f12.456 */
131 /* or 0d1.2345e12 */
133 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
135 /* Prefix characters that indicate the start of an immediate
136 value. */
137 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
139 #ifdef OBJ_ELF
140 symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
141 #endif
143 CONST int md_reloc_size = 8; /* Size of relocation record */
145 static int thumb_mode = 0; /* 0: assemble for ARM, 1: assemble for Thumb,
146 2: assemble for Thumb even though target cpu
147 does not support thumb instructions. */
148 typedef struct arm_fix
150 int thumb_mode;
151 } arm_fix_data;
153 struct arm_it
155 CONST char * error;
156 unsigned long instruction;
157 int suffix;
158 int size;
159 struct
161 bfd_reloc_code_real_type type;
162 expressionS exp;
163 int pc_rel;
164 } reloc;
167 struct arm_it inst;
169 struct asm_shift
171 CONST char * template;
172 unsigned long value;
175 static CONST struct asm_shift shift[] =
177 {"asl", 0},
178 {"lsl", 0},
179 {"lsr", 0x00000020},
180 {"asr", 0x00000040},
181 {"ror", 0x00000060},
182 {"rrx", 0x00000060},
183 {"ASL", 0},
184 {"LSL", 0},
185 {"LSR", 0x00000020},
186 {"ASR", 0x00000040},
187 {"ROR", 0x00000060},
188 {"RRX", 0x00000060}
191 #define NO_SHIFT_RESTRICT 1
192 #define SHIFT_RESTRICT 0
194 #define NUM_FLOAT_VALS 8
196 CONST char * fp_const[] =
198 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
201 /* Number of littlenums required to hold an extended precision number. */
202 #define MAX_LITTLENUMS 6
204 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
206 #define FAIL (-1)
207 #define SUCCESS (0)
209 #define SUFF_S 1
210 #define SUFF_D 2
211 #define SUFF_E 3
212 #define SUFF_P 4
214 #define CP_T_X 0x00008000
215 #define CP_T_Y 0x00400000
216 #define CP_T_Pre 0x01000000
217 #define CP_T_UD 0x00800000
218 #define CP_T_WB 0x00200000
220 #define CONDS_BIT (0x00100000)
221 #define LOAD_BIT (0x00100000)
222 #define TRANS_BIT (0x00200000)
224 struct asm_cond
226 CONST char * template;
227 unsigned long value;
230 /* This is to save a hash look-up in the common case. */
231 #define COND_ALWAYS 0xe0000000
233 static CONST struct asm_cond conds[] =
235 {"eq", 0x00000000},
236 {"ne", 0x10000000},
237 {"cs", 0x20000000}, {"hs", 0x20000000},
238 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
239 {"mi", 0x40000000},
240 {"pl", 0x50000000},
241 {"vs", 0x60000000},
242 {"vc", 0x70000000},
243 {"hi", 0x80000000},
244 {"ls", 0x90000000},
245 {"ge", 0xa0000000},
246 {"lt", 0xb0000000},
247 {"gt", 0xc0000000},
248 {"le", 0xd0000000},
249 {"al", 0xe0000000},
250 {"nv", 0xf0000000}
253 /* Warning: If the top bit of the set_bits is set, then the standard
254 instruction bitmask is ignored, and the new bitmask is taken from
255 the set_bits: */
256 struct asm_flg
258 CONST char * template; /* Basic flag string */
259 unsigned long set_bits; /* Bits to set */
262 static CONST struct asm_flg s_flag[] =
264 {"s", CONDS_BIT},
265 {NULL, 0}
268 static CONST struct asm_flg ldr_flags[] =
270 {"b", 0x00400000},
271 {"t", TRANS_BIT},
272 {"bt", 0x00400000 | TRANS_BIT},
273 {"h", 0x801000b0},
274 {"sh", 0x801000f0},
275 {"sb", 0x801000d0},
276 {NULL, 0}
279 static CONST struct asm_flg str_flags[] =
281 {"b", 0x00400000},
282 {"t", TRANS_BIT},
283 {"bt", 0x00400000 | TRANS_BIT},
284 {"h", 0x800000b0},
285 {NULL, 0}
288 static CONST struct asm_flg byte_flag[] =
290 {"b", 0x00400000},
291 {NULL, 0}
294 static CONST struct asm_flg cmp_flags[] =
296 {"s", CONDS_BIT},
297 {"p", 0x0010f000},
298 {NULL, 0}
301 static CONST struct asm_flg ldm_flags[] =
303 {"ed", 0x01800000},
304 {"fd", 0x00800000},
305 {"ea", 0x01000000},
306 {"fa", 0x08000000},
307 {"ib", 0x01800000},
308 {"ia", 0x00800000},
309 {"db", 0x01000000},
310 {"da", 0x08000000},
311 {NULL, 0}
314 static CONST struct asm_flg stm_flags[] =
316 {"ed", 0x08000000},
317 {"fd", 0x01000000},
318 {"ea", 0x00800000},
319 {"fa", 0x01800000},
320 {"ib", 0x01800000},
321 {"ia", 0x00800000},
322 {"db", 0x01000000},
323 {"da", 0x08000000},
324 {NULL, 0}
327 static CONST struct asm_flg lfm_flags[] =
329 {"fd", 0x00800000},
330 {"ea", 0x01000000},
331 {NULL, 0}
334 static CONST struct asm_flg sfm_flags[] =
336 {"fd", 0x01000000},
337 {"ea", 0x00800000},
338 {NULL, 0}
341 static CONST struct asm_flg round_flags[] =
343 {"p", 0x00000020},
344 {"m", 0x00000040},
345 {"z", 0x00000060},
346 {NULL, 0}
349 /* The implementation of the FIX instruction is broken on some assemblers,
350 in that it accepts a precision specifier as well as a rounding specifier,
351 despite the fact that this is meaningless. To be more compatible, we
352 accept it as well, though of course it does not set any bits. */
353 static CONST struct asm_flg fix_flags[] =
355 {"p", 0x00000020},
356 {"m", 0x00000040},
357 {"z", 0x00000060},
358 {"sp", 0x00000020},
359 {"sm", 0x00000040},
360 {"sz", 0x00000060},
361 {"dp", 0x00000020},
362 {"dm", 0x00000040},
363 {"dz", 0x00000060},
364 {"ep", 0x00000020},
365 {"em", 0x00000040},
366 {"ez", 0x00000060},
367 {NULL, 0}
370 static CONST struct asm_flg except_flag[] =
372 {"e", 0x00400000},
373 {NULL, 0}
376 static CONST struct asm_flg cplong_flag[] =
378 {"l", 0x00400000},
379 {NULL, 0}
382 struct asm_psr
384 CONST char * template;
385 boolean cpsr;
386 unsigned long field;
389 #define SPSR_BIT (1 << 22) /* The bit that distnguishes CPSR and SPSR. */
390 #define PSR_SHIFT 16 /* How many bits to shift the PSR_xxx bits up by. */
392 #define PSR_c (1 << 0)
393 #define PSR_x (1 << 1)
394 #define PSR_s (1 << 2)
395 #define PSR_f (1 << 3)
397 static CONST struct asm_psr psrs[] =
399 {"CPSR", true, PSR_c | PSR_f},
400 {"CPSR_all", true, PSR_c | PSR_f},
401 {"SPSR", false, PSR_c | PSR_f},
402 {"SPSR_all", false, PSR_c | PSR_f},
403 {"CPSR_flg", true, PSR_f},
404 {"CPSR_f", true, PSR_f},
405 {"SPSR_flg", false, PSR_f},
406 {"SPSR_f", false, PSR_f},
407 {"CPSR_c", true, PSR_c},
408 {"CPSR_ctl", true, PSR_c},
409 {"SPSR_c", false, PSR_c},
410 {"SPSR_ctl", false, PSR_c},
411 {"CPSR_x", true, PSR_x},
412 {"CPSR_s", true, PSR_s},
413 {"SPSR_x", false, PSR_x},
414 {"SPSR_s", false, PSR_s},
415 /* For backwards compatability with older toolchain we also
416 support lower case versions of some of these flags. */
417 {"cpsr", true, PSR_c | PSR_f},
418 {"cpsr_all", true, PSR_c | PSR_f},
419 {"spsr", false, PSR_c | PSR_f},
420 {"spsr_all", false, PSR_c | PSR_f},
421 {"cpsr_flg", true, PSR_f},
422 {"cpsr_f", true, PSR_f},
423 {"spsr_flg", false, PSR_f},
424 {"spsr_f", false, PSR_f},
425 {"cpsr_c", true, PSR_c},
426 {"cpsr_ctl", true, PSR_c},
427 {"spsr_c", false, PSR_c},
428 {"spsr_ctl", false, PSR_c}
431 /* Functions called by parser. */
432 /* ARM instructions */
433 static void do_arit PARAMS ((char *, unsigned long));
434 static void do_cmp PARAMS ((char *, unsigned long));
435 static void do_mov PARAMS ((char *, unsigned long));
436 static void do_ldst PARAMS ((char *, unsigned long));
437 static void do_ldmstm PARAMS ((char *, unsigned long));
438 static void do_branch PARAMS ((char *, unsigned long));
439 static void do_swi PARAMS ((char *, unsigned long));
440 /* Pseudo Op codes */
441 static void do_adr PARAMS ((char *, unsigned long));
442 static void do_adrl PARAMS ((char *, unsigned long));
443 static void do_nop PARAMS ((char *, unsigned long));
444 /* ARM 2 */
445 static void do_mul PARAMS ((char *, unsigned long));
446 static void do_mla PARAMS ((char *, unsigned long));
447 /* ARM 3 */
448 static void do_swap PARAMS ((char *, unsigned long));
449 /* ARM 6 */
450 static void do_msr PARAMS ((char *, unsigned long));
451 static void do_mrs PARAMS ((char *, unsigned long));
452 /* ARM 7M */
453 static void do_mull PARAMS ((char *, unsigned long));
454 /* ARM THUMB */
455 static void do_bx PARAMS ((char *, unsigned long));
458 /* Coprocessor Instructions */
459 static void do_cdp PARAMS ((char *, unsigned long));
460 static void do_lstc PARAMS ((char *, unsigned long));
461 static void do_co_reg PARAMS ((char *, unsigned long));
462 static void do_fp_ctrl PARAMS ((char *, unsigned long));
463 static void do_fp_ldst PARAMS ((char *, unsigned long));
464 static void do_fp_ldmstm PARAMS ((char *, unsigned long));
465 static void do_fp_dyadic PARAMS ((char *, unsigned long));
466 static void do_fp_monadic PARAMS ((char *, unsigned long));
467 static void do_fp_cmp PARAMS ((char *, unsigned long));
468 static void do_fp_from_reg PARAMS ((char *, unsigned long));
469 static void do_fp_to_reg PARAMS ((char *, unsigned long));
471 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
472 static int arm_reg_parse PARAMS ((char **));
473 static CONST struct asm_psr * arm_psr_parse PARAMS ((char **));
474 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
475 static int add_to_lit_pool PARAMS ((void));
476 static unsigned validate_immediate PARAMS ((unsigned));
477 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
478 static int validate_offset_imm PARAMS ((unsigned int, int));
479 static void opcode_select PARAMS ((int));
480 static void end_of_line PARAMS ((char *));
481 static int reg_required_here PARAMS ((char **, int));
482 static int psr_required_here PARAMS ((char **));
483 static int co_proc_number PARAMS ((char **));
484 static int cp_opc_expr PARAMS ((char **, int, int));
485 static int cp_reg_required_here PARAMS ((char **, int));
486 static int fp_reg_required_here PARAMS ((char **, int));
487 static int cp_address_offset PARAMS ((char **));
488 static int cp_address_required_here PARAMS ((char **));
489 static int my_get_float_expression PARAMS ((char **));
490 static int skip_past_comma PARAMS ((char **));
491 static int walk_no_bignums PARAMS ((symbolS *));
492 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
493 static int data_op2 PARAMS ((char **));
494 static int fp_op2 PARAMS ((char **));
495 static long reg_list PARAMS ((char **));
496 static void thumb_load_store PARAMS ((char *, int, int));
497 static int decode_shift PARAMS ((char **, int));
498 static int ldst_extend PARAMS ((char **, int));
499 static void thumb_add_sub PARAMS ((char *, int));
500 static void insert_reg PARAMS ((int));
501 static void thumb_shift PARAMS ((char *, int));
502 static void thumb_mov_compare PARAMS ((char *, int));
503 static void set_constant_flonums PARAMS ((void));
504 static valueT md_chars_to_number PARAMS ((char *, int));
505 static void insert_reg_alias PARAMS ((char *, int));
506 static void output_inst PARAMS ((void));
507 #ifdef OBJ_ELF
508 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
509 #endif
511 /* ARM instructions take 4bytes in the object file, Thumb instructions
512 take 2: */
513 #define INSN_SIZE 4
515 /* LONGEST_INST is the longest basic instruction name without conditions or
516 flags. ARM7M has 4 of length 5. */
518 #define LONGEST_INST 5
521 struct asm_opcode
523 CONST char * template; /* Basic string to match */
524 unsigned long value; /* Basic instruction code */
526 /* Compulsory suffix that must follow conds. If "", then the
527 instruction is not conditional and must have no suffix. */
528 CONST char * comp_suffix;
530 CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
531 unsigned long variants; /* Which CPU variants this exists for */
532 /* Function to call to parse args */
533 void (* parms) PARAMS ((char *, unsigned long));
536 static CONST struct asm_opcode insns[] =
538 /* ARM Instructions */
539 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
540 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
541 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
542 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
543 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
544 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
545 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
546 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
547 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
548 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
549 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
550 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
551 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
552 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
553 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
554 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
555 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
556 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
557 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
558 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
559 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
560 #ifdef TE_WINCE
561 {"bl", 0x0b000000, NULL, NULL, ARM_ANY, do_branch},
562 {"b", 0x0a000000, NULL, NULL, ARM_ANY, do_branch},
563 #else
564 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
565 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
566 #endif
568 /* Pseudo ops */
569 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
570 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
571 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
573 /* ARM 2 multiplies */
574 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
575 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
577 /* ARM 3 - swp instructions */
578 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
580 /* ARM 6 Coprocessor instructions */
581 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
582 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
583 /* ScottB: our code uses 0x0128f000 for msr.
584 NickC: but this is wrong because the bits 16 through 19 are
585 handled by the PSR_xxx defines above. */
587 /* ARM 7M long multiplies - need signed/unsigned flags! */
588 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
589 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
590 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
591 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
593 /* ARM THUMB interworking */
594 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
596 /* Floating point instructions */
597 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
598 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
599 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
600 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
601 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
602 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
603 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
604 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
605 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
606 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
607 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
608 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
609 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
610 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
611 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
612 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
613 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
614 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
615 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
616 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
617 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
618 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
619 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
620 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
621 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
622 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
623 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
624 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
625 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
626 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
627 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
628 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
629 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
630 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
631 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
632 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
633 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
634 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
635 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
636 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
637 be an optional suffix, but part of the instruction. To be compatible,
638 we accept either. */
639 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
640 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
641 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
642 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
644 /* Generic copressor instructions. */
645 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
646 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
647 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
648 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
649 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
652 /* Defines for various bits that we will want to toggle. */
653 #define INST_IMMEDIATE 0x02000000
654 #define OFFSET_REG 0x02000000
655 #define HWOFFSET_IMM 0x00400000
656 #define SHIFT_BY_REG 0x00000010
657 #define PRE_INDEX 0x01000000
658 #define INDEX_UP 0x00800000
659 #define WRITE_BACK 0x00200000
660 #define LDM_TYPE_2_OR_3 0x00400000
662 #define LITERAL_MASK 0xf000f000
663 #define COND_MASK 0xf0000000
664 #define OPCODE_MASK 0xfe1fffff
665 #define DATA_OP_SHIFT 21
667 /* Codes to distinguish the arithmetic instructions. */
668 #define OPCODE_AND 0
669 #define OPCODE_EOR 1
670 #define OPCODE_SUB 2
671 #define OPCODE_RSB 3
672 #define OPCODE_ADD 4
673 #define OPCODE_ADC 5
674 #define OPCODE_SBC 6
675 #define OPCODE_RSC 7
676 #define OPCODE_TST 8
677 #define OPCODE_TEQ 9
678 #define OPCODE_CMP 10
679 #define OPCODE_CMN 11
680 #define OPCODE_ORR 12
681 #define OPCODE_MOV 13
682 #define OPCODE_BIC 14
683 #define OPCODE_MVN 15
685 static void do_t_nop PARAMS ((char *));
686 static void do_t_arit PARAMS ((char *));
687 static void do_t_add PARAMS ((char *));
688 static void do_t_asr PARAMS ((char *));
689 static void do_t_branch9 PARAMS ((char *));
690 static void do_t_branch12 PARAMS ((char *));
691 static void do_t_branch23 PARAMS ((char *));
692 static void do_t_bx PARAMS ((char *));
693 static void do_t_compare PARAMS ((char *));
694 static void do_t_ldmstm PARAMS ((char *));
695 static void do_t_ldr PARAMS ((char *));
696 static void do_t_ldrb PARAMS ((char *));
697 static void do_t_ldrh PARAMS ((char *));
698 static void do_t_lds PARAMS ((char *));
699 static void do_t_lsl PARAMS ((char *));
700 static void do_t_lsr PARAMS ((char *));
701 static void do_t_mov PARAMS ((char *));
702 static void do_t_push_pop PARAMS ((char *));
703 static void do_t_str PARAMS ((char *));
704 static void do_t_strb PARAMS ((char *));
705 static void do_t_strh PARAMS ((char *));
706 static void do_t_sub PARAMS ((char *));
707 static void do_t_swi PARAMS ((char *));
708 static void do_t_adr PARAMS ((char *));
710 #define T_OPCODE_MUL 0x4340
711 #define T_OPCODE_TST 0x4200
712 #define T_OPCODE_CMN 0x42c0
713 #define T_OPCODE_NEG 0x4240
714 #define T_OPCODE_MVN 0x43c0
716 #define T_OPCODE_ADD_R3 0x1800
717 #define T_OPCODE_SUB_R3 0x1a00
718 #define T_OPCODE_ADD_HI 0x4400
719 #define T_OPCODE_ADD_ST 0xb000
720 #define T_OPCODE_SUB_ST 0xb080
721 #define T_OPCODE_ADD_SP 0xa800
722 #define T_OPCODE_ADD_PC 0xa000
723 #define T_OPCODE_ADD_I8 0x3000
724 #define T_OPCODE_SUB_I8 0x3800
725 #define T_OPCODE_ADD_I3 0x1c00
726 #define T_OPCODE_SUB_I3 0x1e00
728 #define T_OPCODE_ASR_R 0x4100
729 #define T_OPCODE_LSL_R 0x4080
730 #define T_OPCODE_LSR_R 0x40c0
731 #define T_OPCODE_ASR_I 0x1000
732 #define T_OPCODE_LSL_I 0x0000
733 #define T_OPCODE_LSR_I 0x0800
735 #define T_OPCODE_MOV_I8 0x2000
736 #define T_OPCODE_CMP_I8 0x2800
737 #define T_OPCODE_CMP_LR 0x4280
738 #define T_OPCODE_MOV_HR 0x4600
739 #define T_OPCODE_CMP_HR 0x4500
741 #define T_OPCODE_LDR_PC 0x4800
742 #define T_OPCODE_LDR_SP 0x9800
743 #define T_OPCODE_STR_SP 0x9000
744 #define T_OPCODE_LDR_IW 0x6800
745 #define T_OPCODE_STR_IW 0x6000
746 #define T_OPCODE_LDR_IH 0x8800
747 #define T_OPCODE_STR_IH 0x8000
748 #define T_OPCODE_LDR_IB 0x7800
749 #define T_OPCODE_STR_IB 0x7000
750 #define T_OPCODE_LDR_RW 0x5800
751 #define T_OPCODE_STR_RW 0x5000
752 #define T_OPCODE_LDR_RH 0x5a00
753 #define T_OPCODE_STR_RH 0x5200
754 #define T_OPCODE_LDR_RB 0x5c00
755 #define T_OPCODE_STR_RB 0x5400
757 #define T_OPCODE_PUSH 0xb400
758 #define T_OPCODE_POP 0xbc00
760 #define T_OPCODE_BRANCH 0xe7fe
762 static int thumb_reg PARAMS ((char ** str, int hi_lo));
764 #define THUMB_SIZE 2 /* Size of thumb instruction. */
765 #define THUMB_REG_LO 0x1
766 #define THUMB_REG_HI 0x2
767 #define THUMB_REG_ANY 0x3
769 #define THUMB_H1 0x0080
770 #define THUMB_H2 0x0040
772 #define THUMB_ASR 0
773 #define THUMB_LSL 1
774 #define THUMB_LSR 2
776 #define THUMB_MOVE 0
777 #define THUMB_COMPARE 1
779 #define THUMB_LOAD 0
780 #define THUMB_STORE 1
782 #define THUMB_PP_PC_LR 0x0100
784 /* These three are used for immediate shifts, do not alter. */
785 #define THUMB_WORD 2
786 #define THUMB_HALFWORD 1
787 #define THUMB_BYTE 0
789 struct thumb_opcode
791 CONST char * template; /* Basic string to match */
792 unsigned long value; /* Basic instruction code */
793 int size;
794 unsigned long variants; /* Which CPU variants this exists for */
795 void (* parms) PARAMS ((char *)); /* Function to call to parse args */
798 static CONST struct thumb_opcode tinsns[] =
800 {"adc", 0x4140, 2, ARM_THUMB, do_t_arit},
801 {"add", 0x0000, 2, ARM_THUMB, do_t_add},
802 {"and", 0x4000, 2, ARM_THUMB, do_t_arit},
803 {"asr", 0x0000, 2, ARM_THUMB, do_t_asr},
804 {"b", T_OPCODE_BRANCH, 2, ARM_THUMB, do_t_branch12},
805 {"beq", 0xd0fe, 2, ARM_THUMB, do_t_branch9},
806 {"bne", 0xd1fe, 2, ARM_THUMB, do_t_branch9},
807 {"bcs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
808 {"bhs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
809 {"bcc", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
810 {"bul", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
811 {"blo", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
812 {"bmi", 0xd4fe, 2, ARM_THUMB, do_t_branch9},
813 {"bpl", 0xd5fe, 2, ARM_THUMB, do_t_branch9},
814 {"bvs", 0xd6fe, 2, ARM_THUMB, do_t_branch9},
815 {"bvc", 0xd7fe, 2, ARM_THUMB, do_t_branch9},
816 {"bhi", 0xd8fe, 2, ARM_THUMB, do_t_branch9},
817 {"bls", 0xd9fe, 2, ARM_THUMB, do_t_branch9},
818 {"bge", 0xdafe, 2, ARM_THUMB, do_t_branch9},
819 {"blt", 0xdbfe, 2, ARM_THUMB, do_t_branch9},
820 {"bgt", 0xdcfe, 2, ARM_THUMB, do_t_branch9},
821 {"ble", 0xddfe, 2, ARM_THUMB, do_t_branch9},
822 {"bal", 0xdefe, 2, ARM_THUMB, do_t_branch9},
823 {"bic", 0x4380, 2, ARM_THUMB, do_t_arit},
824 {"bl", 0xf7fffffe, 4, ARM_THUMB, do_t_branch23},
825 {"bx", 0x4700, 2, ARM_THUMB, do_t_bx},
826 {"cmn", T_OPCODE_CMN, 2, ARM_THUMB, do_t_arit},
827 {"cmp", 0x0000, 2, ARM_THUMB, do_t_compare},
828 {"eor", 0x4040, 2, ARM_THUMB, do_t_arit},
829 {"ldmia", 0xc800, 2, ARM_THUMB, do_t_ldmstm},
830 {"ldr", 0x0000, 2, ARM_THUMB, do_t_ldr},
831 {"ldrb", 0x0000, 2, ARM_THUMB, do_t_ldrb},
832 {"ldrh", 0x0000, 2, ARM_THUMB, do_t_ldrh},
833 {"ldrsb", 0x5600, 2, ARM_THUMB, do_t_lds},
834 {"ldrsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
835 {"ldsb", 0x5600, 2, ARM_THUMB, do_t_lds},
836 {"ldsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
837 {"lsl", 0x0000, 2, ARM_THUMB, do_t_lsl},
838 {"lsr", 0x0000, 2, ARM_THUMB, do_t_lsr},
839 {"mov", 0x0000, 2, ARM_THUMB, do_t_mov},
840 {"mul", T_OPCODE_MUL, 2, ARM_THUMB, do_t_arit},
841 {"mvn", T_OPCODE_MVN, 2, ARM_THUMB, do_t_arit},
842 {"neg", T_OPCODE_NEG, 2, ARM_THUMB, do_t_arit},
843 {"orr", 0x4300, 2, ARM_THUMB, do_t_arit},
844 {"pop", 0xbc00, 2, ARM_THUMB, do_t_push_pop},
845 {"push", 0xb400, 2, ARM_THUMB, do_t_push_pop},
846 {"ror", 0x41c0, 2, ARM_THUMB, do_t_arit},
847 {"sbc", 0x4180, 2, ARM_THUMB, do_t_arit},
848 {"stmia", 0xc000, 2, ARM_THUMB, do_t_ldmstm},
849 {"str", 0x0000, 2, ARM_THUMB, do_t_str},
850 {"strb", 0x0000, 2, ARM_THUMB, do_t_strb},
851 {"strh", 0x0000, 2, ARM_THUMB, do_t_strh},
852 {"swi", 0xdf00, 2, ARM_THUMB, do_t_swi},
853 {"sub", 0x0000, 2, ARM_THUMB, do_t_sub},
854 {"tst", T_OPCODE_TST, 2, ARM_THUMB, do_t_arit},
855 /* Pseudo ops: */
856 {"adr", 0x0000, 2, ARM_THUMB, do_t_adr},
857 {"nop", 0x46C0, 2, ARM_THUMB, do_t_nop}, /* mov r8,r8 */
860 struct reg_entry
862 CONST char * name;
863 int number;
866 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
867 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
868 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
870 #define REG_PC 15
871 #define REG_LR 14
872 #define REG_SP 13
874 /* These are the standard names. Users can add aliases with .req */
875 static CONST struct reg_entry reg_table[] =
877 /* Processor Register Numbers. */
878 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
879 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
880 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
881 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
882 /* APCS conventions. */
883 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
884 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
885 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
886 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
887 /* ATPCS additions to APCS conventions. */
888 {"wr", 7}, {"v8", 11},
889 /* FP Registers. */
890 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
891 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
892 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
893 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
894 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
895 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
896 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
897 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
898 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
899 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
900 /* ATPCS additions to float register names. */
901 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
902 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
903 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
904 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
905 /* FIXME: At some point we need to add VFP register names. */
906 /* Array terminator. */
907 {NULL, 0}
910 #define BAD_ARGS _("Bad arguments to instruction")
911 #define BAD_PC _("r15 not allowed here")
912 #define BAD_FLAGS _("Instruction should not have flags")
913 #define BAD_COND _("Instruction is not conditional")
915 static struct hash_control * arm_ops_hsh = NULL;
916 static struct hash_control * arm_tops_hsh = NULL;
917 static struct hash_control * arm_cond_hsh = NULL;
918 static struct hash_control * arm_shift_hsh = NULL;
919 static struct hash_control * arm_reg_hsh = NULL;
920 static struct hash_control * arm_psr_hsh = NULL;
922 /* This table describes all the machine specific pseudo-ops the assembler
923 has to support. The fields are:
924 pseudo-op name without dot
925 function to call to execute this pseudo-op
926 Integer arg to pass to the function. */
928 static void s_req PARAMS ((int));
929 static void s_align PARAMS ((int));
930 static void s_bss PARAMS ((int));
931 static void s_even PARAMS ((int));
932 static void s_ltorg PARAMS ((int));
933 static void s_arm PARAMS ((int));
934 static void s_thumb PARAMS ((int));
935 static void s_code PARAMS ((int));
936 static void s_force_thumb PARAMS ((int));
937 static void s_thumb_func PARAMS ((int));
938 static void s_thumb_set PARAMS ((int));
939 static void arm_s_text PARAMS ((int));
940 static void arm_s_data PARAMS ((int));
941 #ifdef OBJ_ELF
942 static void arm_s_section PARAMS ((int));
943 static void s_arm_elf_cons PARAMS ((int));
944 #endif
946 static int my_get_expression PARAMS ((expressionS *, char **));
948 CONST pseudo_typeS md_pseudo_table[] =
950 { "req", s_req, 0 }, /* Never called becasue '.req' does not start line */
951 { "bss", s_bss, 0 },
952 { "align", s_align, 0 },
953 { "arm", s_arm, 0 },
954 { "thumb", s_thumb, 0 },
955 { "code", s_code, 0 },
956 { "force_thumb", s_force_thumb, 0 },
957 { "thumb_func", s_thumb_func, 0 },
958 { "thumb_set", s_thumb_set, 0 },
959 { "even", s_even, 0 },
960 { "ltorg", s_ltorg, 0 },
961 { "pool", s_ltorg, 0 },
962 /* Allow for the effect of section changes. */
963 { "text", arm_s_text, 0 },
964 { "data", arm_s_data, 0 },
965 #ifdef OBJ_ELF
966 { "section", arm_s_section, 0 },
967 { "section.s", arm_s_section, 0 },
968 { "sect", arm_s_section, 0 },
969 { "sect.s", arm_s_section, 0 },
970 { "word", s_arm_elf_cons, 4 },
971 { "long", s_arm_elf_cons, 4 },
972 #else
973 { "word", cons, 4},
974 #endif
975 { "extend", float_cons, 'x' },
976 { "ldouble", float_cons, 'x' },
977 { "packed", float_cons, 'p' },
978 { 0, 0, 0 }
981 /* Stuff needed to resolve the label ambiguity
984 label: <insn>
985 may differ from:
987 label:
988 <insn>
991 symbolS * last_label_seen;
992 static int label_is_thumb_function_name = false;
994 /* Literal stuff */
996 #define MAX_LITERAL_POOL_SIZE 1024
998 typedef struct literalS
1000 struct expressionS exp;
1001 struct arm_it * inst;
1002 } literalT;
1004 literalT literals[MAX_LITERAL_POOL_SIZE];
1005 int next_literal_pool_place = 0; /* Next free entry in the pool */
1006 int lit_pool_num = 1; /* Next literal pool number */
1007 symbolS * current_poolP = NULL;
1009 static int
1010 add_to_lit_pool ()
1012 int lit_count = 0;
1014 if (current_poolP == NULL)
1015 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
1016 (valueT) 0, &zero_address_frag);
1018 /* Check if this literal value is already in the pool: */
1019 while (lit_count < next_literal_pool_place)
1021 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1022 && inst.reloc.exp.X_op == O_constant
1023 && literals[lit_count].exp.X_add_number
1024 == inst.reloc.exp.X_add_number
1025 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1026 break;
1027 lit_count++;
1030 if (lit_count == next_literal_pool_place) /* new entry */
1032 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1034 inst.error = _("Literal Pool Overflow");
1035 return FAIL;
1038 literals[next_literal_pool_place].exp = inst.reloc.exp;
1039 lit_count = next_literal_pool_place++;
1042 inst.reloc.exp.X_op = O_symbol;
1043 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1044 inst.reloc.exp.X_add_symbol = current_poolP;
1046 return SUCCESS;
1049 /* Can't use symbol_new here, so have to create a symbol and then at
1050 a later date assign it a value. Thats what these functions do. */
1051 static void
1052 symbol_locate (symbolP, name, segment, valu, frag)
1053 symbolS * symbolP;
1054 CONST char * name; /* It is copied, the caller can modify */
1055 segT segment; /* Segment identifier (SEG_<something>) */
1056 valueT valu; /* Symbol value */
1057 fragS * frag; /* Associated fragment */
1059 unsigned int name_length;
1060 char * preserved_copy_of_name;
1062 name_length = strlen (name) + 1; /* +1 for \0 */
1063 obstack_grow (&notes, name, name_length);
1064 preserved_copy_of_name = obstack_finish (&notes);
1065 #ifdef STRIP_UNDERSCORE
1066 if (preserved_copy_of_name[0] == '_')
1067 preserved_copy_of_name++;
1068 #endif
1070 #ifdef tc_canonicalize_symbol_name
1071 preserved_copy_of_name =
1072 tc_canonicalize_symbol_name (preserved_copy_of_name);
1073 #endif
1075 S_SET_NAME (symbolP, preserved_copy_of_name);
1077 S_SET_SEGMENT (symbolP, segment);
1078 S_SET_VALUE (symbolP, valu);
1079 symbol_clear_list_pointers(symbolP);
1081 symbol_set_frag (symbolP, frag);
1083 /* Link to end of symbol chain. */
1085 extern int symbol_table_frozen;
1086 if (symbol_table_frozen)
1087 abort ();
1090 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1092 obj_symbol_new_hook (symbolP);
1094 #ifdef tc_symbol_new_hook
1095 tc_symbol_new_hook (symbolP);
1096 #endif
1098 #ifdef DEBUG_SYMS
1099 verify_symbol_chain (symbol_rootP, symbol_lastP);
1100 #endif /* DEBUG_SYMS */
1103 /* Check that an immediate is valid, and if so,
1104 convert it to the right format. */
1105 static unsigned int
1106 validate_immediate (val)
1107 unsigned int val;
1109 unsigned int a;
1110 unsigned int i;
1112 #define rotate_left(v, n) (v << n | v >> (32 - n))
1114 for (i = 0; i < 32; i += 2)
1115 if ((a = rotate_left (val, i)) <= 0xff)
1116 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1118 return FAIL;
1121 /* Check to see if an immediate can be computed as two seperate immediate
1122 values, added together. We already know that this value cannot be
1123 computed by just one ARM instruction. */
1124 static unsigned int
1125 validate_immediate_twopart (val, highpart)
1126 unsigned int val;
1127 unsigned int * highpart;
1129 unsigned int a;
1130 unsigned int i;
1132 for (i = 0; i < 32; i += 2)
1133 if (((a = rotate_left (val, i)) & 0xff) != 0)
1135 if (a & 0xff00)
1137 if (a & ~ 0xffff)
1138 continue;
1139 * highpart = (a >> 8) | ((i + 24) << 7);
1141 else if (a & 0xff0000)
1143 if (a & 0xff000000)
1144 continue;
1146 * highpart = (a >> 16) | ((i + 16) << 7);
1148 else
1150 assert (a & 0xff000000);
1152 * highpart = (a >> 24) | ((i + 8) << 7);
1155 return (a & 0xff) | (i << 7);
1158 return FAIL;
1161 static int
1162 validate_offset_imm (val, hwse)
1163 unsigned int val;
1164 int hwse;
1166 if ((hwse && val > 255) || val > 4095)
1167 return FAIL;
1168 return val;
1172 static void
1173 s_req (a)
1174 int a ATTRIBUTE_UNUSED;
1176 as_bad (_("Invalid syntax for .req directive."));
1179 static void
1180 s_bss (ignore)
1181 int ignore ATTRIBUTE_UNUSED;
1183 /* We don't support putting frags in the BSS segment, we fake it by
1184 marking in_bss, then looking at s_skip for clues?.. */
1185 subseg_set (bss_section, 0);
1186 demand_empty_rest_of_line ();
1189 static void
1190 s_even (ignore)
1191 int ignore ATTRIBUTE_UNUSED;
1193 if (!need_pass_2) /* Never make frag if expect extra pass. */
1194 frag_align (1, 0, 0);
1196 record_alignment (now_seg, 1);
1198 demand_empty_rest_of_line ();
1201 static void
1202 s_ltorg (ignored)
1203 int ignored ATTRIBUTE_UNUSED;
1205 int lit_count = 0;
1206 char sym_name[20];
1208 if (current_poolP == NULL)
1209 return;
1211 /* Align pool as you have word accesses */
1212 /* Only make a frag if we have to ... */
1213 if (!need_pass_2)
1214 frag_align (2, 0, 0);
1216 record_alignment (now_seg, 2);
1218 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1220 symbol_locate (current_poolP, sym_name, now_seg,
1221 (valueT) frag_now_fix (), frag_now);
1222 symbol_table_insert (current_poolP);
1224 ARM_SET_THUMB (current_poolP, thumb_mode);
1226 #if defined OBJ_COFF || defined OBJ_ELF
1227 ARM_SET_INTERWORK (current_poolP, support_interwork);
1228 #endif
1230 while (lit_count < next_literal_pool_place)
1231 /* First output the expression in the instruction to the pool. */
1232 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1234 next_literal_pool_place = 0;
1235 current_poolP = NULL;
1238 static void
1239 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1240 int unused ATTRIBUTE_UNUSED;
1242 register int temp;
1243 register long temp_fill;
1244 long max_alignment = 15;
1246 temp = get_absolute_expression ();
1247 if (temp > max_alignment)
1248 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1249 else if (temp < 0)
1251 as_bad (_("Alignment negative. 0 assumed."));
1252 temp = 0;
1255 if (*input_line_pointer == ',')
1257 input_line_pointer++;
1258 temp_fill = get_absolute_expression ();
1260 else
1261 temp_fill = 0;
1263 if (!temp)
1264 temp = 2;
1266 /* Only make a frag if we HAVE to. . . */
1267 if (temp && !need_pass_2)
1268 frag_align (temp, (int) temp_fill, 0);
1269 demand_empty_rest_of_line ();
1271 record_alignment (now_seg, temp);
1274 static void
1275 s_force_thumb (ignore)
1276 int ignore ATTRIBUTE_UNUSED;
1278 /* If we are not already in thumb mode go into it, EVEN if
1279 the target processor does not support thumb instructions.
1280 This is used by gcc/config/arm/lib1funcs.asm for example
1281 to compile interworking support functions even if the
1282 target processor should not support interworking. */
1284 if (! thumb_mode)
1286 thumb_mode = 2;
1288 record_alignment (now_seg, 1);
1291 demand_empty_rest_of_line ();
1294 static void
1295 s_thumb_func (ignore)
1296 int ignore ATTRIBUTE_UNUSED;
1298 /* The following label is the name/address of the start of a Thumb function.
1299 We need to know this for the interworking support. */
1301 label_is_thumb_function_name = true;
1303 demand_empty_rest_of_line ();
1306 /* Perform a .set directive, but also mark the alias as
1307 being a thumb function. */
1309 static void
1310 s_thumb_set (equiv)
1311 int equiv;
1313 /* XXX the following is a duplicate of the code for s_set() in read.c
1314 We cannot just call that code as we need to get at the symbol that
1315 is created. */
1316 register char * name;
1317 register char delim;
1318 register char * end_name;
1319 register symbolS * symbolP;
1322 * Especial apologies for the random logic:
1323 * this just grew, and could be parsed much more simply!
1324 * Dean in haste.
1326 name = input_line_pointer;
1327 delim = get_symbol_end ();
1328 end_name = input_line_pointer;
1329 *end_name = delim;
1331 SKIP_WHITESPACE ();
1333 if (*input_line_pointer != ',')
1335 *end_name = 0;
1336 as_bad (_("Expected comma after name \"%s\""), name);
1337 *end_name = delim;
1338 ignore_rest_of_line ();
1339 return;
1342 input_line_pointer++;
1343 *end_name = 0;
1345 if (name[0] == '.' && name[1] == '\0')
1347 /* XXX - this should not happen to .thumb_set */
1348 abort ();
1351 if ((symbolP = symbol_find (name)) == NULL
1352 && (symbolP = md_undefined_symbol (name)) == NULL)
1354 #ifndef NO_LISTING
1355 /* When doing symbol listings, play games with dummy fragments living
1356 outside the normal fragment chain to record the file and line info
1357 for this symbol. */
1358 if (listing & LISTING_SYMBOLS)
1360 extern struct list_info_struct * listing_tail;
1361 fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
1362 memset (dummy_frag, 0, sizeof(fragS));
1363 dummy_frag->fr_type = rs_fill;
1364 dummy_frag->line = listing_tail;
1365 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1366 dummy_frag->fr_symbol = symbolP;
1368 else
1369 #endif
1370 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1372 #ifdef OBJ_COFF
1373 /* "set" symbols are local unless otherwise specified. */
1374 SF_SET_LOCAL (symbolP);
1375 #endif /* OBJ_COFF */
1376 } /* make a new symbol */
1378 symbol_table_insert (symbolP);
1380 * end_name = delim;
1382 if (equiv
1383 && S_IS_DEFINED (symbolP)
1384 && S_GET_SEGMENT (symbolP) != reg_section)
1385 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1387 pseudo_set (symbolP);
1389 demand_empty_rest_of_line ();
1391 /* XXX Now we come to the Thumb specific bit of code. */
1393 THUMB_SET_FUNC (symbolP, 1);
1394 ARM_SET_THUMB (symbolP, 1);
1395 #if defined OBJ_ELF || defined OBJ_COFF
1396 ARM_SET_INTERWORK (symbolP, support_interwork);
1397 #endif
1400 /* If we change section we must dump the literal pool first. */
1401 static void
1402 arm_s_text (ignore)
1403 int ignore;
1405 if (now_seg != text_section)
1406 s_ltorg (0);
1408 #ifdef OBJ_ELF
1409 obj_elf_text (ignore);
1410 #else
1411 s_text (ignore);
1412 #endif
1415 static void
1416 arm_s_data (ignore)
1417 int ignore;
1419 if (flag_readonly_data_in_text)
1421 if (now_seg != text_section)
1422 s_ltorg (0);
1424 else if (now_seg != data_section)
1425 s_ltorg (0);
1427 #ifdef OBJ_ELF
1428 obj_elf_data (ignore);
1429 #else
1430 s_data (ignore);
1431 #endif
1434 #ifdef OBJ_ELF
1435 static void
1436 arm_s_section (ignore)
1437 int ignore;
1439 s_ltorg (0);
1441 obj_elf_section (ignore);
1443 #endif
1445 static void
1446 opcode_select (width)
1447 int width;
1449 switch (width)
1451 case 16:
1452 if (! thumb_mode)
1454 if (! (cpu_variant & ARM_THUMB))
1455 as_bad (_("selected processor does not support THUMB opcodes"));
1456 thumb_mode = 1;
1457 /* No need to force the alignment, since we will have been
1458 coming from ARM mode, which is word-aligned. */
1459 record_alignment (now_seg, 1);
1461 break;
1463 case 32:
1464 if (thumb_mode)
1466 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1467 as_bad (_("selected processor does not support ARM opcodes"));
1468 thumb_mode = 0;
1469 if (!need_pass_2)
1470 frag_align (2, 0, 0);
1471 record_alignment (now_seg, 1);
1473 break;
1475 default:
1476 as_bad (_("invalid instruction size selected (%d)"), width);
1480 static void
1481 s_arm (ignore)
1482 int ignore ATTRIBUTE_UNUSED;
1484 opcode_select (32);
1485 demand_empty_rest_of_line ();
1488 static void
1489 s_thumb (ignore)
1490 int ignore ATTRIBUTE_UNUSED;
1492 opcode_select (16);
1493 demand_empty_rest_of_line ();
1496 static void
1497 s_code (unused)
1498 int unused ATTRIBUTE_UNUSED;
1500 register int temp;
1502 temp = get_absolute_expression ();
1503 switch (temp)
1505 case 16:
1506 case 32:
1507 opcode_select (temp);
1508 break;
1510 default:
1511 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1515 static void
1516 end_of_line (str)
1517 char * str;
1519 skip_whitespace (str);
1521 if (* str != '\0')
1522 inst.error = _("Garbage following instruction");
1525 static int
1526 skip_past_comma (str)
1527 char ** str;
1529 char *p = *str, c;
1530 int comma = 0;
1532 while ((c = *p) == ' ' || c == ',')
1534 p++;
1535 if (c == ',' && comma++)
1536 return FAIL;
1539 if (c == '\0')
1540 return FAIL;
1542 *str = p;
1543 return comma ? SUCCESS : FAIL;
1546 /* A standard register must be given at this point.
1547 Shift is the place to put it in inst.instruction.
1548 Restores input start point on err.
1549 Returns the reg#, or FAIL. */
1550 static int
1551 reg_required_here (str, shift)
1552 char ** str;
1553 int shift;
1555 static char buff [128]; /* XXX */
1556 int reg;
1557 char * start = *str;
1559 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1561 if (shift >= 0)
1562 inst.instruction |= reg << shift;
1563 return reg;
1566 /* Restore the start point, we may have got a reg of the wrong class. */
1567 *str = start;
1569 /* In the few cases where we might be able to accept something else
1570 this error can be overridden. */
1571 sprintf (buff, _("Register expected, not '%.100s'"), start);
1572 inst.error = buff;
1574 return FAIL;
1577 static CONST struct asm_psr *
1578 arm_psr_parse (ccp)
1579 register char ** ccp;
1581 char * start = * ccp;
1582 char c;
1583 char * p;
1584 CONST struct asm_psr * psr;
1586 p = start;
1588 /* Skip to the end of the next word in the input stream. */
1591 c = *p++;
1593 while (isalpha (c) || c == '_');
1595 /* Terminate the word. */
1596 *--p = 0;
1598 /* Now locate the word in the psr hash table. */
1599 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
1601 /* Restore the input stream. */
1602 *p = c;
1604 /* If we found a valid match, advance the
1605 stream pointer past the end of the word. */
1606 *ccp = p;
1608 return psr;
1611 /* Parse the input looking for a PSR flag. */
1612 static int
1613 psr_required_here (str)
1614 char ** str;
1616 char * start = *str;
1617 CONST struct asm_psr * psr;
1619 psr = arm_psr_parse (str);
1621 if (psr)
1623 /* If this is the SPSR that is being modified, set the R bit. */
1624 if (! psr->cpsr)
1625 inst.instruction |= SPSR_BIT;
1627 /* Set the psr flags in the MSR instruction. */
1628 inst.instruction |= psr->field << PSR_SHIFT;
1630 return SUCCESS;
1633 /* In the few cases where we might be able to accept
1634 something else this error can be overridden. */
1635 inst.error = _("flag for {c}psr instruction expected");
1637 /* Restore the start point. */
1638 *str = start;
1639 return FAIL;
1642 static int
1643 co_proc_number (str)
1644 char ** str;
1646 int processor, pchar;
1648 skip_whitespace (* str);
1650 /* The data sheet seems to imply that just a number on its own is valid
1651 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1652 accept either. */
1653 if (**str == 'p' || **str == 'P')
1654 (*str)++;
1656 pchar = *(*str)++;
1657 if (pchar >= '0' && pchar <= '9')
1659 processor = pchar - '0';
1660 if (**str >= '0' && **str <= '9')
1662 processor = processor * 10 + *(*str)++ - '0';
1663 if (processor > 15)
1665 inst.error = _("Illegal co-processor number");
1666 return FAIL;
1670 else
1672 inst.error = _("Bad or missing co-processor number");
1673 return FAIL;
1676 inst.instruction |= processor << 8;
1677 return SUCCESS;
1680 static int
1681 cp_opc_expr (str, where, length)
1682 char ** str;
1683 int where;
1684 int length;
1686 expressionS expr;
1688 skip_whitespace (* str);
1690 memset (&expr, '\0', sizeof (expr));
1692 if (my_get_expression (&expr, str))
1693 return FAIL;
1694 if (expr.X_op != O_constant)
1696 inst.error = _("bad or missing expression");
1697 return FAIL;
1700 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1702 inst.error = _("immediate co-processor expression too large");
1703 return FAIL;
1706 inst.instruction |= expr.X_add_number << where;
1707 return SUCCESS;
1710 static int
1711 cp_reg_required_here (str, where)
1712 char ** str;
1713 int where;
1715 int reg;
1716 char * start = *str;
1718 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1720 reg &= 15;
1721 inst.instruction |= reg << where;
1722 return reg;
1725 /* In the few cases where we might be able to accept something else
1726 this error can be overridden. */
1727 inst.error = _("Co-processor register expected");
1729 /* Restore the start point. */
1730 *str = start;
1731 return FAIL;
1734 static int
1735 fp_reg_required_here (str, where)
1736 char ** str;
1737 int where;
1739 int reg;
1740 char * start = *str;
1742 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1744 reg &= 7;
1745 inst.instruction |= reg << where;
1746 return reg;
1749 /* In the few cases where we might be able to accept something else
1750 this error can be overridden. */
1751 inst.error = _("Floating point register expected");
1753 /* Restore the start point. */
1754 *str = start;
1755 return FAIL;
1758 static int
1759 cp_address_offset (str)
1760 char ** str;
1762 int offset;
1764 skip_whitespace (* str);
1766 if (! is_immediate_prefix (**str))
1768 inst.error = _("immediate expression expected");
1769 return FAIL;
1772 (*str)++;
1774 if (my_get_expression (& inst.reloc.exp, str))
1775 return FAIL;
1777 if (inst.reloc.exp.X_op == O_constant)
1779 offset = inst.reloc.exp.X_add_number;
1781 if (offset & 3)
1783 inst.error = _("co-processor address must be word aligned");
1784 return FAIL;
1787 if (offset > 1023 || offset < -1023)
1789 inst.error = _("offset too large");
1790 return FAIL;
1793 if (offset >= 0)
1794 inst.instruction |= INDEX_UP;
1795 else
1796 offset = -offset;
1798 inst.instruction |= offset >> 2;
1800 else
1801 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1803 return SUCCESS;
1806 static int
1807 cp_address_required_here (str)
1808 char ** str;
1810 char * p = * str;
1811 int pre_inc = 0;
1812 int write_back = 0;
1814 if (*p == '[')
1816 int reg;
1818 p++;
1819 skip_whitespace (p);
1821 if ((reg = reg_required_here (& p, 16)) == FAIL)
1822 return FAIL;
1824 skip_whitespace (p);
1826 if (*p == ']')
1828 p++;
1830 if (skip_past_comma (& p) == SUCCESS)
1832 /* [Rn], #expr */
1833 write_back = WRITE_BACK;
1835 if (reg == REG_PC)
1837 inst.error = _("pc may not be used in post-increment");
1838 return FAIL;
1841 if (cp_address_offset (& p) == FAIL)
1842 return FAIL;
1844 else
1845 pre_inc = PRE_INDEX | INDEX_UP;
1847 else
1849 /* '['Rn, #expr']'[!] */
1851 if (skip_past_comma (& p) == FAIL)
1853 inst.error = _("pre-indexed expression expected");
1854 return FAIL;
1857 pre_inc = PRE_INDEX;
1859 if (cp_address_offset (& p) == FAIL)
1860 return FAIL;
1862 skip_whitespace (p);
1864 if (*p++ != ']')
1866 inst.error = _("missing ]");
1867 return FAIL;
1870 skip_whitespace (p);
1872 if (*p == '!')
1874 if (reg == REG_PC)
1876 inst.error = _("pc may not be used with write-back");
1877 return FAIL;
1880 p++;
1881 write_back = WRITE_BACK;
1885 else
1887 if (my_get_expression (&inst.reloc.exp, &p))
1888 return FAIL;
1890 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1891 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1892 inst.reloc.pc_rel = 1;
1893 inst.instruction |= (REG_PC << 16);
1894 pre_inc = PRE_INDEX;
1897 inst.instruction |= write_back | pre_inc;
1898 *str = p;
1899 return SUCCESS;
1902 static void
1903 do_nop (str, flags)
1904 char * str;
1905 unsigned long flags;
1907 /* Do nothing really. */
1908 inst.instruction |= flags; /* This is pointless. */
1909 end_of_line (str);
1910 return;
1913 static void
1914 do_mrs (str, flags)
1915 char *str;
1916 unsigned long flags;
1918 int skip = 0;
1920 /* Only one syntax. */
1921 skip_whitespace (str);
1923 if (reg_required_here (&str, 12) == FAIL)
1925 inst.error = BAD_ARGS;
1926 return;
1929 if (skip_past_comma (&str) == FAIL)
1931 inst.error = _("comma expected after register name");
1932 return;
1935 skip_whitespace (str);
1937 if ( strcmp (str, "CPSR") == 0
1938 || strcmp (str, "SPSR") == 0
1939 /* Lower case versions for backwards compatability. */
1940 || strcmp (str, "cpsr") == 0
1941 || strcmp (str, "spsr") == 0)
1942 skip = 4;
1943 /* This is for backwards compatability with older toolchains. */
1944 else if (strcmp (str, "cpsr_all") == 0
1945 || strcmp (str, "spsr_all") == 0)
1946 skip = 7;
1947 else
1949 inst.error = _("{C|S}PSR expected");
1950 return;
1953 if (* str == 's' || * str == 'S')
1954 inst.instruction |= SPSR_BIT;
1955 str += skip;
1957 inst.instruction |= flags;
1958 end_of_line (str);
1961 /* Two possible forms:
1962 "{C|S}PSR_<field>, Rm",
1963 "{C|S}PSR_f, #expression". */
1964 static void
1965 do_msr (str, flags)
1966 char * str;
1967 unsigned long flags;
1969 skip_whitespace (str);
1971 if (psr_required_here (& str) == FAIL)
1972 return;
1974 if (skip_past_comma (& str) == FAIL)
1976 inst.error = _("comma missing after psr flags");
1977 return;
1980 skip_whitespace (str);
1982 if (reg_required_here (& str, 0) != FAIL)
1984 inst.error = NULL;
1985 inst.instruction |= flags;
1986 end_of_line (str);
1987 return;
1990 if (! is_immediate_prefix (* str))
1992 inst.error = _("only a register or immediate value can follow a psr flag");
1993 return;
1996 str ++;
1997 inst.error = NULL;
1999 if (my_get_expression (& inst.reloc.exp, & str))
2001 inst.error = _("only a register or immediate value can follow a psr flag");
2002 return;
2005 if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2007 inst.error = _("can only set flag field with immediate value");
2008 return;
2011 flags |= INST_IMMEDIATE;
2013 if (inst.reloc.exp.X_add_symbol)
2015 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2016 inst.reloc.pc_rel = 0;
2018 else
2020 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2022 if (value == (unsigned) FAIL)
2024 inst.error = _("Invalid constant");
2025 return;
2028 inst.instruction |= value;
2031 inst.error = NULL;
2032 inst.instruction |= flags;
2033 end_of_line (str);
2036 /* Long Multiply Parser
2037 UMULL RdLo, RdHi, Rm, Rs
2038 SMULL RdLo, RdHi, Rm, Rs
2039 UMLAL RdLo, RdHi, Rm, Rs
2040 SMLAL RdLo, RdHi, Rm, Rs
2042 static void
2043 do_mull (str, flags)
2044 char * str;
2045 unsigned long flags;
2047 int rdlo, rdhi, rm, rs;
2049 /* Only one format "rdlo, rdhi, rm, rs" */
2050 skip_whitespace (str);
2052 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2054 inst.error = BAD_ARGS;
2055 return;
2058 if (skip_past_comma (&str) == FAIL
2059 || (rdhi = reg_required_here (&str, 16)) == FAIL)
2061 inst.error = BAD_ARGS;
2062 return;
2065 if (skip_past_comma (&str) == FAIL
2066 || (rm = reg_required_here (&str, 0)) == FAIL)
2068 inst.error = BAD_ARGS;
2069 return;
2072 /* rdhi, rdlo and rm must all be different */
2073 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2074 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2076 if (skip_past_comma (&str) == FAIL
2077 || (rs = reg_required_here (&str, 8)) == FAIL)
2079 inst.error = BAD_ARGS;
2080 return;
2083 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2085 inst.error = BAD_PC;
2086 return;
2089 inst.instruction |= flags;
2090 end_of_line (str);
2091 return;
2094 static void
2095 do_mul (str, flags)
2096 char * str;
2097 unsigned long flags;
2099 int rd, rm;
2101 /* Only one format "rd, rm, rs" */
2102 skip_whitespace (str);
2104 if ((rd = reg_required_here (&str, 16)) == FAIL)
2106 inst.error = BAD_ARGS;
2107 return;
2110 if (rd == REG_PC)
2112 inst.error = BAD_PC;
2113 return;
2116 if (skip_past_comma (&str) == FAIL
2117 || (rm = reg_required_here (&str, 0)) == FAIL)
2119 inst.error = BAD_ARGS;
2120 return;
2123 if (rm == REG_PC)
2125 inst.error = BAD_PC;
2126 return;
2129 if (rm == rd)
2130 as_tsktsk (_("rd and rm should be different in mul"));
2132 if (skip_past_comma (&str) == FAIL
2133 || (rm = reg_required_here (&str, 8)) == FAIL)
2135 inst.error = BAD_ARGS;
2136 return;
2139 if (rm == REG_PC)
2141 inst.error = BAD_PC;
2142 return;
2145 inst.instruction |= flags;
2146 end_of_line (str);
2147 return;
2150 static void
2151 do_mla (str, flags)
2152 char * str;
2153 unsigned long flags;
2155 int rd, rm;
2157 /* Only one format "rd, rm, rs, rn" */
2158 skip_whitespace (str);
2160 if ((rd = reg_required_here (&str, 16)) == FAIL)
2162 inst.error = BAD_ARGS;
2163 return;
2166 if (rd == REG_PC)
2168 inst.error = BAD_PC;
2169 return;
2172 if (skip_past_comma (&str) == FAIL
2173 || (rm = reg_required_here (&str, 0)) == FAIL)
2175 inst.error = BAD_ARGS;
2176 return;
2179 if (rm == REG_PC)
2181 inst.error = BAD_PC;
2182 return;
2185 if (rm == rd)
2186 as_tsktsk (_("rd and rm should be different in mla"));
2188 if (skip_past_comma (&str) == FAIL
2189 || (rd = reg_required_here (&str, 8)) == FAIL
2190 || skip_past_comma (&str) == FAIL
2191 || (rm = reg_required_here (&str, 12)) == FAIL)
2193 inst.error = BAD_ARGS;
2194 return;
2197 if (rd == REG_PC || rm == REG_PC)
2199 inst.error = BAD_PC;
2200 return;
2203 inst.instruction |= flags;
2204 end_of_line (str);
2205 return;
2208 /* Returns the index into fp_values of a floating point number, or -1 if
2209 not in the table. */
2210 static int
2211 my_get_float_expression (str)
2212 char ** str;
2214 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2215 char * save_in;
2216 expressionS exp;
2217 int i;
2218 int j;
2220 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2221 /* Look for a raw floating point number */
2222 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2223 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
2225 for (i = 0; i < NUM_FLOAT_VALS; i++)
2227 for (j = 0; j < MAX_LITTLENUMS; j++)
2229 if (words[j] != fp_values[i][j])
2230 break;
2233 if (j == MAX_LITTLENUMS)
2235 *str = save_in;
2236 return i;
2241 /* Try and parse a more complex expression, this will probably fail
2242 unless the code uses a floating point prefix (eg "0f") */
2243 save_in = input_line_pointer;
2244 input_line_pointer = *str;
2245 if (expression (&exp) == absolute_section
2246 && exp.X_op == O_big
2247 && exp.X_add_number < 0)
2249 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2250 Ditto for 15. */
2251 if (gen_to_words (words, 5, (long)15) == 0)
2253 for (i = 0; i < NUM_FLOAT_VALS; i++)
2255 for (j = 0; j < MAX_LITTLENUMS; j++)
2257 if (words[j] != fp_values[i][j])
2258 break;
2261 if (j == MAX_LITTLENUMS)
2263 *str = input_line_pointer;
2264 input_line_pointer = save_in;
2265 return i;
2271 *str = input_line_pointer;
2272 input_line_pointer = save_in;
2273 return -1;
2276 /* Return true if anything in the expression is a bignum */
2277 static int
2278 walk_no_bignums (sp)
2279 symbolS * sp;
2281 if (symbol_get_value_expression (sp)->X_op == O_big)
2282 return 1;
2284 if (symbol_get_value_expression (sp)->X_add_symbol)
2286 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2287 || (symbol_get_value_expression (sp)->X_op_symbol
2288 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2291 return 0;
2294 static int
2295 my_get_expression (ep, str)
2296 expressionS * ep;
2297 char ** str;
2299 char * save_in;
2300 segT seg;
2302 save_in = input_line_pointer;
2303 input_line_pointer = *str;
2304 seg = expression (ep);
2306 #ifdef OBJ_AOUT
2307 if (seg != absolute_section
2308 && seg != text_section
2309 && seg != data_section
2310 && seg != bss_section
2311 && seg != undefined_section)
2313 inst.error = _("bad_segment");
2314 *str = input_line_pointer;
2315 input_line_pointer = save_in;
2316 return 1;
2318 #endif
2320 /* Get rid of any bignums now, so that we don't generate an error for which
2321 we can't establish a line number later on. Big numbers are never valid
2322 in instructions, which is where this routine is always called. */
2323 if (ep->X_op == O_big
2324 || (ep->X_add_symbol
2325 && (walk_no_bignums (ep->X_add_symbol)
2326 || (ep->X_op_symbol
2327 && walk_no_bignums (ep->X_op_symbol)))))
2329 inst.error = _("Invalid constant");
2330 *str = input_line_pointer;
2331 input_line_pointer = save_in;
2332 return 1;
2335 *str = input_line_pointer;
2336 input_line_pointer = save_in;
2337 return 0;
2340 /* unrestrict should be one if <shift> <register> is permitted for this
2341 instruction */
2343 static int
2344 decode_shift (str, unrestrict)
2345 char ** str;
2346 int unrestrict;
2348 struct asm_shift * shft;
2349 char * p;
2350 char c;
2352 skip_whitespace (* str);
2354 for (p = *str; isalpha (*p); p++)
2357 if (p == *str)
2359 inst.error = _("Shift expression expected");
2360 return FAIL;
2363 c = *p;
2364 *p = '\0';
2365 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2366 *p = c;
2367 if (shft)
2369 if (!strncmp (*str, "rrx", 3)
2370 || !strncmp (*str, "RRX", 3))
2372 *str = p;
2373 inst.instruction |= shft->value;
2374 return SUCCESS;
2377 skip_whitespace (p);
2379 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2381 inst.instruction |= shft->value | SHIFT_BY_REG;
2382 *str = p;
2383 return SUCCESS;
2385 else if (is_immediate_prefix (* p))
2387 inst.error = NULL;
2388 p++;
2389 if (my_get_expression (&inst.reloc.exp, &p))
2390 return FAIL;
2392 /* Validate some simple #expressions */
2393 if (inst.reloc.exp.X_op == O_constant)
2395 unsigned num = inst.reloc.exp.X_add_number;
2397 /* Reject operations greater than 32, or lsl #32 */
2398 if (num > 32 || (num == 32 && shft->value == 0))
2400 inst.error = _("Invalid immediate shift");
2401 return FAIL;
2404 /* Shifts of zero should be converted to lsl (which is zero)*/
2405 if (num == 0)
2407 *str = p;
2408 return SUCCESS;
2411 /* Shifts of 32 are encoded as 0, for those shifts that
2412 support it. */
2413 if (num == 32)
2414 num = 0;
2416 inst.instruction |= (num << 7) | shft->value;
2417 *str = p;
2418 return SUCCESS;
2421 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2422 inst.reloc.pc_rel = 0;
2423 inst.instruction |= shft->value;
2424 *str = p;
2425 return SUCCESS;
2427 else
2429 inst.error = unrestrict ? _("shift requires register or #expression")
2430 : _("shift requires #expression");
2431 *str = p;
2432 return FAIL;
2436 inst.error = _("Shift expression expected");
2437 return FAIL;
2440 /* Do those data_ops which can take a negative immediate constant */
2441 /* by altering the instuction. A bit of a hack really */
2442 /* MOV <-> MVN
2443 AND <-> BIC
2444 ADC <-> SBC
2445 by inverting the second operand, and
2446 ADD <-> SUB
2447 CMP <-> CMN
2448 by negating the second operand.
2450 static int
2451 negate_data_op (instruction, value)
2452 unsigned long * instruction;
2453 unsigned long value;
2455 int op, new_inst;
2456 unsigned long negated, inverted;
2458 negated = validate_immediate (-value);
2459 inverted = validate_immediate (~value);
2461 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2462 switch (op)
2464 /* First negates */
2465 case OPCODE_SUB: /* ADD <-> SUB */
2466 new_inst = OPCODE_ADD;
2467 value = negated;
2468 break;
2470 case OPCODE_ADD:
2471 new_inst = OPCODE_SUB;
2472 value = negated;
2473 break;
2475 case OPCODE_CMP: /* CMP <-> CMN */
2476 new_inst = OPCODE_CMN;
2477 value = negated;
2478 break;
2480 case OPCODE_CMN:
2481 new_inst = OPCODE_CMP;
2482 value = negated;
2483 break;
2485 /* Now Inverted ops */
2486 case OPCODE_MOV: /* MOV <-> MVN */
2487 new_inst = OPCODE_MVN;
2488 value = inverted;
2489 break;
2491 case OPCODE_MVN:
2492 new_inst = OPCODE_MOV;
2493 value = inverted;
2494 break;
2496 case OPCODE_AND: /* AND <-> BIC */
2497 new_inst = OPCODE_BIC;
2498 value = inverted;
2499 break;
2501 case OPCODE_BIC:
2502 new_inst = OPCODE_AND;
2503 value = inverted;
2504 break;
2506 case OPCODE_ADC: /* ADC <-> SBC */
2507 new_inst = OPCODE_SBC;
2508 value = inverted;
2509 break;
2511 case OPCODE_SBC:
2512 new_inst = OPCODE_ADC;
2513 value = inverted;
2514 break;
2516 /* We cannot do anything */
2517 default:
2518 return FAIL;
2521 if (value == (unsigned) FAIL)
2522 return FAIL;
2524 *instruction &= OPCODE_MASK;
2525 *instruction |= new_inst << DATA_OP_SHIFT;
2526 return value;
2529 static int
2530 data_op2 (str)
2531 char ** str;
2533 int value;
2534 expressionS expr;
2536 skip_whitespace (* str);
2538 if (reg_required_here (str, 0) != FAIL)
2540 if (skip_past_comma (str) == SUCCESS)
2541 /* Shift operation on register. */
2542 return decode_shift (str, NO_SHIFT_RESTRICT);
2544 return SUCCESS;
2546 else
2548 /* Immediate expression */
2549 if (is_immediate_prefix (**str))
2551 (*str)++;
2552 inst.error = NULL;
2554 if (my_get_expression (&inst.reloc.exp, str))
2555 return FAIL;
2557 if (inst.reloc.exp.X_add_symbol)
2559 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2560 inst.reloc.pc_rel = 0;
2562 else
2564 if (skip_past_comma (str) == SUCCESS)
2566 /* #x, y -- ie explicit rotation by Y */
2567 if (my_get_expression (&expr, str))
2568 return FAIL;
2570 if (expr.X_op != O_constant)
2572 inst.error = _("Constant expression expected");
2573 return FAIL;
2576 /* Rotate must be a multiple of 2 */
2577 if (((unsigned) expr.X_add_number) > 30
2578 || (expr.X_add_number & 1) != 0
2579 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2581 inst.error = _("Invalid constant");
2582 return FAIL;
2584 inst.instruction |= INST_IMMEDIATE;
2585 inst.instruction |= inst.reloc.exp.X_add_number;
2586 inst.instruction |= expr.X_add_number << 7;
2587 return SUCCESS;
2590 /* Implicit rotation, select a suitable one */
2591 value = validate_immediate (inst.reloc.exp.X_add_number);
2593 if (value == FAIL)
2595 /* Can't be done, perhaps the code reads something like
2596 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2597 if ((value = negate_data_op (&inst.instruction,
2598 inst.reloc.exp.X_add_number))
2599 == FAIL)
2601 inst.error = _("Invalid constant");
2602 return FAIL;
2606 inst.instruction |= value;
2609 inst.instruction |= INST_IMMEDIATE;
2610 return SUCCESS;
2613 (*str)++;
2614 inst.error = _("Register or shift expression expected");
2615 return FAIL;
2619 static int
2620 fp_op2 (str)
2621 char ** str;
2623 skip_whitespace (* str);
2625 if (fp_reg_required_here (str, 0) != FAIL)
2626 return SUCCESS;
2627 else
2629 /* Immediate expression */
2630 if (*((*str)++) == '#')
2632 int i;
2634 inst.error = NULL;
2636 skip_whitespace (* str);
2638 /* First try and match exact strings, this is to guarantee that
2639 some formats will work even for cross assembly */
2641 for (i = 0; fp_const[i]; i++)
2643 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2645 char *start = *str;
2647 *str += strlen (fp_const[i]);
2648 if (is_end_of_line[(int)**str] || **str == '\0')
2650 inst.instruction |= i + 8;
2651 return SUCCESS;
2653 *str = start;
2657 /* Just because we didn't get a match doesn't mean that the
2658 constant isn't valid, just that it is in a format that we
2659 don't automatically recognize. Try parsing it with
2660 the standard expression routines. */
2661 if ((i = my_get_float_expression (str)) >= 0)
2663 inst.instruction |= i + 8;
2664 return SUCCESS;
2667 inst.error = _("Invalid floating point immediate expression");
2668 return FAIL;
2670 inst.error = _("Floating point register or immediate expression expected");
2671 return FAIL;
2675 static void
2676 do_arit (str, flags)
2677 char * str;
2678 unsigned long flags;
2680 skip_whitespace (str);
2682 if (reg_required_here (&str, 12) == FAIL
2683 || skip_past_comma (&str) == FAIL
2684 || reg_required_here (&str, 16) == FAIL
2685 || skip_past_comma (&str) == FAIL
2686 || data_op2 (&str) == FAIL)
2688 if (!inst.error)
2689 inst.error = BAD_ARGS;
2690 return;
2693 inst.instruction |= flags;
2694 end_of_line (str);
2695 return;
2698 static void
2699 do_adr (str, flags)
2700 char * str;
2701 unsigned long flags;
2703 /* This is a pseudo-op of the form "adr rd, label" to be converted
2704 into a relative address of the form "add rd, pc, #label-.-8". */
2705 skip_whitespace (str);
2707 if (reg_required_here (&str, 12) == FAIL
2708 || skip_past_comma (&str) == FAIL
2709 || my_get_expression (&inst.reloc.exp, &str))
2711 if (!inst.error)
2712 inst.error = BAD_ARGS;
2713 return;
2716 /* Frag hacking will turn this into a sub instruction if the offset turns
2717 out to be negative. */
2718 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2719 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
2720 inst.reloc.pc_rel = 1;
2721 inst.instruction |= flags;
2722 end_of_line (str);
2723 return;
2726 static void
2727 do_adrl (str, flags)
2728 char * str;
2729 unsigned long flags;
2731 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2732 into a relative address of the form:
2733 add rd, pc, #low(label-.-8)"
2734 add rd, rd, #high(label-.-8)" */
2736 skip_whitespace (str);
2738 if (reg_required_here (& str, 12) == FAIL
2739 || skip_past_comma (& str) == FAIL
2740 || my_get_expression (& inst.reloc.exp, & str))
2742 if (!inst.error)
2743 inst.error = BAD_ARGS;
2744 return;
2747 end_of_line (str);
2749 /* Frag hacking will turn this into a sub instruction if the offset turns
2750 out to be negative. */
2751 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2752 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2753 inst.reloc.pc_rel = 1;
2754 inst.instruction |= flags;
2755 inst.size = INSN_SIZE * 2;
2757 return;
2760 static void
2761 do_cmp (str, flags)
2762 char * str;
2763 unsigned long flags;
2765 skip_whitespace (str);
2767 if (reg_required_here (&str, 16) == FAIL)
2769 if (!inst.error)
2770 inst.error = BAD_ARGS;
2771 return;
2774 if (skip_past_comma (&str) == FAIL
2775 || data_op2 (&str) == FAIL)
2777 if (!inst.error)
2778 inst.error = BAD_ARGS;
2779 return;
2782 inst.instruction |= flags;
2783 if ((flags & 0x0000f000) == 0)
2784 inst.instruction |= CONDS_BIT;
2786 end_of_line (str);
2787 return;
2790 static void
2791 do_mov (str, flags)
2792 char * str;
2793 unsigned long flags;
2795 skip_whitespace (str);
2797 if (reg_required_here (&str, 12) == FAIL)
2799 if (!inst.error)
2800 inst.error = BAD_ARGS;
2801 return;
2804 if (skip_past_comma (&str) == FAIL
2805 || data_op2 (&str) == FAIL)
2807 if (!inst.error)
2808 inst.error = BAD_ARGS;
2809 return;
2812 inst.instruction |= flags;
2813 end_of_line (str);
2814 return;
2817 static int
2818 ldst_extend (str, hwse)
2819 char ** str;
2820 int hwse;
2822 int add = INDEX_UP;
2824 switch (**str)
2826 case '#':
2827 case '$':
2828 (*str)++;
2829 if (my_get_expression (& inst.reloc.exp, str))
2830 return FAIL;
2832 if (inst.reloc.exp.X_op == O_constant)
2834 int value = inst.reloc.exp.X_add_number;
2836 if ((hwse && (value < -255 || value > 255))
2837 || (value < -4095 || value > 4095))
2839 inst.error = _("address offset too large");
2840 return FAIL;
2843 if (value < 0)
2845 value = -value;
2846 add = 0;
2849 /* Halfword and signextension instructions have the
2850 immediate value split across bits 11..8 and bits 3..0 */
2851 if (hwse)
2852 inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2853 else
2854 inst.instruction |= add | value;
2856 else
2858 if (hwse)
2860 inst.instruction |= HWOFFSET_IMM;
2861 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2863 else
2864 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2865 inst.reloc.pc_rel = 0;
2867 return SUCCESS;
2869 case '-':
2870 add = 0; /* and fall through */
2871 case '+':
2872 (*str)++; /* and fall through */
2873 default:
2874 if (reg_required_here (str, 0) == FAIL)
2875 return FAIL;
2877 if (hwse)
2878 inst.instruction |= add;
2879 else
2881 inst.instruction |= add | OFFSET_REG;
2882 if (skip_past_comma (str) == SUCCESS)
2883 return decode_shift (str, SHIFT_RESTRICT);
2886 return SUCCESS;
2890 static void
2891 do_ldst (str, flags)
2892 char * str;
2893 unsigned long flags;
2895 int halfword = 0;
2896 int pre_inc = 0;
2897 int conflict_reg;
2898 int value;
2900 /* This is not ideal, but it is the simplest way of dealing with the
2901 ARM7T halfword instructions (since they use a different
2902 encoding, but the same mnemonic): */
2903 halfword = (flags & 0x80000000) != 0;
2904 if (halfword)
2906 /* This is actually a load/store of a halfword, or a
2907 signed-extension load */
2908 if ((cpu_variant & ARM_HALFWORD) == 0)
2910 inst.error
2911 = _("Processor does not support halfwords or signed bytes");
2912 return;
2915 inst.instruction = (inst.instruction & COND_MASK)
2916 | (flags & ~COND_MASK);
2918 flags = 0;
2921 skip_whitespace (str);
2923 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2925 if (!inst.error)
2926 inst.error = BAD_ARGS;
2927 return;
2930 if (skip_past_comma (& str) == FAIL)
2932 inst.error = _("Address expected");
2933 return;
2936 if (*str == '[')
2938 int reg;
2940 str++;
2942 skip_whitespace (str);
2944 if ((reg = reg_required_here (&str, 16)) == FAIL)
2945 return;
2947 /* Conflicts can occur on stores as well as loads. */
2948 conflict_reg = (conflict_reg == reg);
2950 skip_whitespace (str);
2952 if (*str == ']')
2954 str ++;
2956 if (skip_past_comma (&str) == SUCCESS)
2958 /* [Rn],... (post inc) */
2959 if (ldst_extend (&str, halfword) == FAIL)
2960 return;
2961 if (conflict_reg)
2962 as_warn (_("%s register same as write-back base"),
2963 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2965 else
2967 /* [Rn] */
2968 if (halfword)
2969 inst.instruction |= HWOFFSET_IMM;
2971 skip_whitespace (str);
2973 if (*str == '!')
2975 if (conflict_reg)
2976 as_warn (_("%s register same as write-back base"),
2977 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2978 str++;
2979 inst.instruction |= WRITE_BACK;
2982 flags |= INDEX_UP;
2983 if (! (flags & TRANS_BIT))
2984 pre_inc = 1;
2987 else
2989 /* [Rn,...] */
2990 if (skip_past_comma (&str) == FAIL)
2992 inst.error = _("pre-indexed expression expected");
2993 return;
2996 pre_inc = 1;
2997 if (ldst_extend (&str, halfword) == FAIL)
2998 return;
3000 skip_whitespace (str);
3002 if (*str++ != ']')
3004 inst.error = _("missing ]");
3005 return;
3008 skip_whitespace (str);
3010 if (*str == '!')
3012 if (conflict_reg)
3013 as_warn (_("%s register same as write-back base"),
3014 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3015 str++;
3016 inst.instruction |= WRITE_BACK;
3020 else if (*str == '=')
3022 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3023 str++;
3025 skip_whitespace (str);
3027 if (my_get_expression (&inst.reloc.exp, &str))
3028 return;
3030 if (inst.reloc.exp.X_op != O_constant
3031 && inst.reloc.exp.X_op != O_symbol)
3033 inst.error = _("Constant expression expected");
3034 return;
3037 if (inst.reloc.exp.X_op == O_constant
3038 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
3040 /* This can be done with a mov instruction */
3041 inst.instruction &= LITERAL_MASK;
3042 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
3043 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
3044 end_of_line(str);
3045 return;
3047 else
3049 /* Insert into literal pool */
3050 if (add_to_lit_pool () == FAIL)
3052 if (!inst.error)
3053 inst.error = _("literal pool insertion failed");
3054 return;
3057 /* Change the instruction exp to point to the pool */
3058 if (halfword)
3060 inst.instruction |= HWOFFSET_IMM;
3061 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
3063 else
3064 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
3065 inst.reloc.pc_rel = 1;
3066 inst.instruction |= (REG_PC << 16);
3067 pre_inc = 1;
3070 else
3072 if (my_get_expression (&inst.reloc.exp, &str))
3073 return;
3075 if (halfword)
3077 inst.instruction |= HWOFFSET_IMM;
3078 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3080 else
3081 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
3082 #ifndef TE_WINCE
3083 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
3084 #endif
3085 inst.reloc.pc_rel = 1;
3086 inst.instruction |= (REG_PC << 16);
3087 pre_inc = 1;
3090 if (pre_inc && (flags & TRANS_BIT))
3091 inst.error = _("Pre-increment instruction with translate");
3093 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3094 end_of_line (str);
3095 return;
3098 static long
3099 reg_list (strp)
3100 char ** strp;
3102 char * str = *strp;
3103 long range = 0;
3104 int another_range;
3106 /* We come back here if we get ranges concatenated by '+' or '|' */
3109 another_range = 0;
3111 if (*str == '{')
3113 int in_range = 0;
3114 int cur_reg = -1;
3116 str++;
3119 int reg;
3121 skip_whitespace (str);
3123 if ((reg = reg_required_here (& str, -1)) == FAIL)
3124 return FAIL;
3126 if (in_range)
3128 int i;
3130 if (reg <= cur_reg)
3132 inst.error = _("Bad range in register list");
3133 return FAIL;
3136 for (i = cur_reg + 1; i < reg; i++)
3138 if (range & (1 << i))
3139 as_tsktsk
3140 (_("Warning: Duplicated register (r%d) in register list"),
3142 else
3143 range |= 1 << i;
3145 in_range = 0;
3148 if (range & (1 << reg))
3149 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3150 reg);
3151 else if (reg <= cur_reg)
3152 as_tsktsk (_("Warning: Register range not in ascending order"));
3154 range |= 1 << reg;
3155 cur_reg = reg;
3156 } while (skip_past_comma (&str) != FAIL
3157 || (in_range = 1, *str++ == '-'));
3158 str--;
3159 skip_whitespace (str);
3161 if (*str++ != '}')
3163 inst.error = _("Missing `}'");
3164 return FAIL;
3167 else
3169 expressionS expr;
3171 if (my_get_expression (&expr, &str))
3172 return FAIL;
3174 if (expr.X_op == O_constant)
3176 if (expr.X_add_number
3177 != (expr.X_add_number & 0x0000ffff))
3179 inst.error = _("invalid register mask");
3180 return FAIL;
3183 if ((range & expr.X_add_number) != 0)
3185 int regno = range & expr.X_add_number;
3187 regno &= -regno;
3188 regno = (1 << regno) - 1;
3189 as_tsktsk
3190 (_("Warning: Duplicated register (r%d) in register list"),
3191 regno);
3194 range |= expr.X_add_number;
3196 else
3198 if (inst.reloc.type != 0)
3200 inst.error = _("expression too complex");
3201 return FAIL;
3204 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3205 inst.reloc.type = BFD_RELOC_ARM_MULTI;
3206 inst.reloc.pc_rel = 0;
3210 skip_whitespace (str);
3212 if (*str == '|' || *str == '+')
3214 str++;
3215 another_range = 1;
3217 } while (another_range);
3219 *strp = str;
3220 return range;
3223 static void
3224 do_ldmstm (str, flags)
3225 char * str;
3226 unsigned long flags;
3228 int base_reg;
3229 long range;
3231 skip_whitespace (str);
3233 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3234 return;
3236 if (base_reg == REG_PC)
3238 inst.error = _("r15 not allowed as base register");
3239 return;
3242 skip_whitespace (str);
3244 if (*str == '!')
3246 flags |= WRITE_BACK;
3247 str++;
3250 if (skip_past_comma (&str) == FAIL
3251 || (range = reg_list (&str)) == FAIL)
3253 if (! inst.error)
3254 inst.error = BAD_ARGS;
3255 return;
3258 if (*str == '^')
3260 str++;
3261 flags |= LDM_TYPE_2_OR_3;
3264 inst.instruction |= flags | range;
3265 end_of_line (str);
3266 return;
3269 static void
3270 do_swi (str, flags)
3271 char * str;
3272 unsigned long flags;
3274 skip_whitespace (str);
3276 /* Allow optional leading '#'. */
3277 if (is_immediate_prefix (*str))
3278 str++;
3280 if (my_get_expression (& inst.reloc.exp, & str))
3281 return;
3283 inst.reloc.type = BFD_RELOC_ARM_SWI;
3284 inst.reloc.pc_rel = 0;
3285 inst.instruction |= flags;
3287 end_of_line (str);
3289 return;
3292 static void
3293 do_swap (str, flags)
3294 char * str;
3295 unsigned long flags;
3297 int reg;
3299 skip_whitespace (str);
3301 if ((reg = reg_required_here (&str, 12)) == FAIL)
3302 return;
3304 if (reg == REG_PC)
3306 inst.error = _("r15 not allowed in swap");
3307 return;
3310 if (skip_past_comma (&str) == FAIL
3311 || (reg = reg_required_here (&str, 0)) == FAIL)
3313 if (!inst.error)
3314 inst.error = BAD_ARGS;
3315 return;
3318 if (reg == REG_PC)
3320 inst.error = _("r15 not allowed in swap");
3321 return;
3324 if (skip_past_comma (&str) == FAIL
3325 || *str++ != '[')
3327 inst.error = BAD_ARGS;
3328 return;
3331 skip_whitespace (str);
3333 if ((reg = reg_required_here (&str, 16)) == FAIL)
3334 return;
3336 if (reg == REG_PC)
3338 inst.error = BAD_PC;
3339 return;
3342 skip_whitespace (str);
3344 if (*str++ != ']')
3346 inst.error = _("missing ]");
3347 return;
3350 inst.instruction |= flags;
3351 end_of_line (str);
3352 return;
3355 static void
3356 do_branch (str, flags)
3357 char * str;
3358 unsigned long flags ATTRIBUTE_UNUSED;
3360 if (my_get_expression (&inst.reloc.exp, &str))
3361 return;
3363 #ifdef OBJ_ELF
3365 char * save_in;
3367 /* ScottB: February 5, 1998 */
3368 /* Check to see of PLT32 reloc required for the instruction. */
3370 /* arm_parse_reloc() works on input_line_pointer.
3371 We actually want to parse the operands to the branch instruction
3372 passed in 'str'. Save the input pointer and restore it later. */
3373 save_in = input_line_pointer;
3374 input_line_pointer = str;
3375 if (inst.reloc.exp.X_op == O_symbol
3376 && *str == '('
3377 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3379 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3380 inst.reloc.pc_rel = 0;
3381 /* Modify str to point to after parsed operands, otherwise
3382 end_of_line() will complain about the (PLT) left in str. */
3383 str = input_line_pointer;
3385 else
3387 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3388 inst.reloc.pc_rel = 1;
3390 input_line_pointer = save_in;
3392 #else
3393 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3394 inst.reloc.pc_rel = 1;
3395 #endif /* OBJ_ELF */
3397 end_of_line (str);
3398 return;
3401 static void
3402 do_bx (str, flags)
3403 char * str;
3404 unsigned long flags ATTRIBUTE_UNUSED;
3406 int reg;
3408 skip_whitespace (str);
3410 if ((reg = reg_required_here (&str, 0)) == FAIL)
3412 inst.error = BAD_ARGS;
3413 return;
3416 if (reg == REG_PC)
3417 inst.error = BAD_PC;
3419 end_of_line (str);
3422 static void
3423 do_cdp (str, flags)
3424 char * str;
3425 unsigned long flags ATTRIBUTE_UNUSED;
3427 /* Co-processor data operation.
3428 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3429 skip_whitespace (str);
3431 if (co_proc_number (&str) == FAIL)
3433 if (!inst.error)
3434 inst.error = BAD_ARGS;
3435 return;
3438 if (skip_past_comma (&str) == FAIL
3439 || cp_opc_expr (&str, 20,4) == FAIL)
3441 if (!inst.error)
3442 inst.error = BAD_ARGS;
3443 return;
3446 if (skip_past_comma (&str) == FAIL
3447 || cp_reg_required_here (&str, 12) == FAIL)
3449 if (!inst.error)
3450 inst.error = BAD_ARGS;
3451 return;
3454 if (skip_past_comma (&str) == FAIL
3455 || cp_reg_required_here (&str, 16) == FAIL)
3457 if (!inst.error)
3458 inst.error = BAD_ARGS;
3459 return;
3462 if (skip_past_comma (&str) == FAIL
3463 || cp_reg_required_here (&str, 0) == FAIL)
3465 if (!inst.error)
3466 inst.error = BAD_ARGS;
3467 return;
3470 if (skip_past_comma (&str) == SUCCESS)
3472 if (cp_opc_expr (&str, 5, 3) == FAIL)
3474 if (!inst.error)
3475 inst.error = BAD_ARGS;
3476 return;
3480 end_of_line (str);
3481 return;
3484 static void
3485 do_lstc (str, flags)
3486 char * str;
3487 unsigned long flags;
3489 /* Co-processor register load/store.
3490 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3492 skip_whitespace (str);
3494 if (co_proc_number (&str) == FAIL)
3496 if (!inst.error)
3497 inst.error = BAD_ARGS;
3498 return;
3501 if (skip_past_comma (&str) == FAIL
3502 || cp_reg_required_here (&str, 12) == FAIL)
3504 if (!inst.error)
3505 inst.error = BAD_ARGS;
3506 return;
3509 if (skip_past_comma (&str) == FAIL
3510 || cp_address_required_here (&str) == FAIL)
3512 if (! inst.error)
3513 inst.error = BAD_ARGS;
3514 return;
3517 inst.instruction |= flags;
3518 end_of_line (str);
3519 return;
3522 static void
3523 do_co_reg (str, flags)
3524 char * str;
3525 unsigned long flags;
3527 /* Co-processor register transfer.
3528 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3530 skip_whitespace (str);
3532 if (co_proc_number (&str) == FAIL)
3534 if (!inst.error)
3535 inst.error = BAD_ARGS;
3536 return;
3539 if (skip_past_comma (&str) == FAIL
3540 || cp_opc_expr (&str, 21, 3) == FAIL)
3542 if (!inst.error)
3543 inst.error = BAD_ARGS;
3544 return;
3547 if (skip_past_comma (&str) == FAIL
3548 || reg_required_here (&str, 12) == FAIL)
3550 if (!inst.error)
3551 inst.error = BAD_ARGS;
3552 return;
3555 if (skip_past_comma (&str) == FAIL
3556 || cp_reg_required_here (&str, 16) == FAIL)
3558 if (!inst.error)
3559 inst.error = BAD_ARGS;
3560 return;
3563 if (skip_past_comma (&str) == FAIL
3564 || cp_reg_required_here (&str, 0) == FAIL)
3566 if (!inst.error)
3567 inst.error = BAD_ARGS;
3568 return;
3571 if (skip_past_comma (&str) == SUCCESS)
3573 if (cp_opc_expr (&str, 5, 3) == FAIL)
3575 if (!inst.error)
3576 inst.error = BAD_ARGS;
3577 return;
3580 if (flags)
3582 inst.error = BAD_COND;
3585 end_of_line (str);
3586 return;
3589 static void
3590 do_fp_ctrl (str, flags)
3591 char * str;
3592 unsigned long flags ATTRIBUTE_UNUSED;
3594 /* FP control registers.
3595 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3597 skip_whitespace (str);
3599 if (reg_required_here (&str, 12) == FAIL)
3601 if (!inst.error)
3602 inst.error = BAD_ARGS;
3603 return;
3606 end_of_line (str);
3607 return;
3610 static void
3611 do_fp_ldst (str, flags)
3612 char * str;
3613 unsigned long flags ATTRIBUTE_UNUSED;
3615 skip_whitespace (str);
3617 switch (inst.suffix)
3619 case SUFF_S:
3620 break;
3621 case SUFF_D:
3622 inst.instruction |= CP_T_X;
3623 break;
3624 case SUFF_E:
3625 inst.instruction |= CP_T_Y;
3626 break;
3627 case SUFF_P:
3628 inst.instruction |= CP_T_X | CP_T_Y;
3629 break;
3630 default:
3631 abort ();
3634 if (fp_reg_required_here (&str, 12) == FAIL)
3636 if (!inst.error)
3637 inst.error = BAD_ARGS;
3638 return;
3641 if (skip_past_comma (&str) == FAIL
3642 || cp_address_required_here (&str) == FAIL)
3644 if (!inst.error)
3645 inst.error = BAD_ARGS;
3646 return;
3649 end_of_line (str);
3652 static void
3653 do_fp_ldmstm (str, flags)
3654 char * str;
3655 unsigned long flags;
3657 int num_regs;
3659 skip_whitespace (str);
3661 if (fp_reg_required_here (&str, 12) == FAIL)
3663 if (! inst.error)
3664 inst.error = BAD_ARGS;
3665 return;
3668 /* Get Number of registers to transfer */
3669 if (skip_past_comma (&str) == FAIL
3670 || my_get_expression (&inst.reloc.exp, &str))
3672 if (! inst.error)
3673 inst.error = _("constant expression expected");
3674 return;
3677 if (inst.reloc.exp.X_op != O_constant)
3679 inst.error = _("Constant value required for number of registers");
3680 return;
3683 num_regs = inst.reloc.exp.X_add_number;
3685 if (num_regs < 1 || num_regs > 4)
3687 inst.error = _("number of registers must be in the range [1:4]");
3688 return;
3691 switch (num_regs)
3693 case 1:
3694 inst.instruction |= CP_T_X;
3695 break;
3696 case 2:
3697 inst.instruction |= CP_T_Y;
3698 break;
3699 case 3:
3700 inst.instruction |= CP_T_Y | CP_T_X;
3701 break;
3702 case 4:
3703 break;
3704 default:
3705 abort ();
3708 if (flags)
3710 int reg;
3711 int write_back;
3712 int offset;
3714 /* The instruction specified "ea" or "fd", so we can only accept
3715 [Rn]{!}. The instruction does not really support stacking or
3716 unstacking, so we have to emulate these by setting appropriate
3717 bits and offsets. */
3718 if (skip_past_comma (&str) == FAIL
3719 || *str != '[')
3721 if (! inst.error)
3722 inst.error = BAD_ARGS;
3723 return;
3726 str++;
3727 skip_whitespace (str);
3729 if ((reg = reg_required_here (&str, 16)) == FAIL)
3730 return;
3732 skip_whitespace (str);
3734 if (*str != ']')
3736 inst.error = BAD_ARGS;
3737 return;
3740 str++;
3741 if (*str == '!')
3743 write_back = 1;
3744 str++;
3745 if (reg == REG_PC)
3747 inst.error = _("R15 not allowed as base register with write-back");
3748 return;
3751 else
3752 write_back = 0;
3754 if (flags & CP_T_Pre)
3756 /* Pre-decrement */
3757 offset = 3 * num_regs;
3758 if (write_back)
3759 flags |= CP_T_WB;
3761 else
3763 /* Post-increment */
3764 if (write_back)
3766 flags |= CP_T_WB;
3767 offset = 3 * num_regs;
3769 else
3771 /* No write-back, so convert this into a standard pre-increment
3772 instruction -- aesthetically more pleasing. */
3773 flags = CP_T_Pre | CP_T_UD;
3774 offset = 0;
3778 inst.instruction |= flags | offset;
3780 else if (skip_past_comma (&str) == FAIL
3781 || cp_address_required_here (&str) == FAIL)
3783 if (! inst.error)
3784 inst.error = BAD_ARGS;
3785 return;
3788 end_of_line (str);
3791 static void
3792 do_fp_dyadic (str, flags)
3793 char * str;
3794 unsigned long flags;
3796 skip_whitespace (str);
3798 switch (inst.suffix)
3800 case SUFF_S:
3801 break;
3802 case SUFF_D:
3803 inst.instruction |= 0x00000080;
3804 break;
3805 case SUFF_E:
3806 inst.instruction |= 0x00080000;
3807 break;
3808 default:
3809 abort ();
3812 if (fp_reg_required_here (&str, 12) == FAIL)
3814 if (! inst.error)
3815 inst.error = BAD_ARGS;
3816 return;
3819 if (skip_past_comma (&str) == FAIL
3820 || fp_reg_required_here (&str, 16) == FAIL)
3822 if (! inst.error)
3823 inst.error = BAD_ARGS;
3824 return;
3827 if (skip_past_comma (&str) == FAIL
3828 || fp_op2 (&str) == FAIL)
3830 if (! inst.error)
3831 inst.error = BAD_ARGS;
3832 return;
3835 inst.instruction |= flags;
3836 end_of_line (str);
3837 return;
3840 static void
3841 do_fp_monadic (str, flags)
3842 char * str;
3843 unsigned long flags;
3845 skip_whitespace (str);
3847 switch (inst.suffix)
3849 case SUFF_S:
3850 break;
3851 case SUFF_D:
3852 inst.instruction |= 0x00000080;
3853 break;
3854 case SUFF_E:
3855 inst.instruction |= 0x00080000;
3856 break;
3857 default:
3858 abort ();
3861 if (fp_reg_required_here (&str, 12) == FAIL)
3863 if (! inst.error)
3864 inst.error = BAD_ARGS;
3865 return;
3868 if (skip_past_comma (&str) == FAIL
3869 || fp_op2 (&str) == FAIL)
3871 if (! inst.error)
3872 inst.error = BAD_ARGS;
3873 return;
3876 inst.instruction |= flags;
3877 end_of_line (str);
3878 return;
3881 static void
3882 do_fp_cmp (str, flags)
3883 char * str;
3884 unsigned long flags;
3886 skip_whitespace (str);
3888 if (fp_reg_required_here (&str, 16) == FAIL)
3890 if (! inst.error)
3891 inst.error = BAD_ARGS;
3892 return;
3895 if (skip_past_comma (&str) == FAIL
3896 || fp_op2 (&str) == FAIL)
3898 if (! inst.error)
3899 inst.error = BAD_ARGS;
3900 return;
3903 inst.instruction |= flags;
3904 end_of_line (str);
3905 return;
3908 static void
3909 do_fp_from_reg (str, flags)
3910 char * str;
3911 unsigned long flags;
3913 skip_whitespace (str);
3915 switch (inst.suffix)
3917 case SUFF_S:
3918 break;
3919 case SUFF_D:
3920 inst.instruction |= 0x00000080;
3921 break;
3922 case SUFF_E:
3923 inst.instruction |= 0x00080000;
3924 break;
3925 default:
3926 abort ();
3929 if (fp_reg_required_here (&str, 16) == FAIL)
3931 if (! inst.error)
3932 inst.error = BAD_ARGS;
3933 return;
3936 if (skip_past_comma (&str) == FAIL
3937 || reg_required_here (&str, 12) == FAIL)
3939 if (! inst.error)
3940 inst.error = BAD_ARGS;
3941 return;
3944 inst.instruction |= flags;
3945 end_of_line (str);
3946 return;
3949 static void
3950 do_fp_to_reg (str, flags)
3951 char * str;
3952 unsigned long flags;
3954 skip_whitespace (str);
3956 if (reg_required_here (&str, 12) == FAIL)
3957 return;
3959 if (skip_past_comma (&str) == FAIL
3960 || fp_reg_required_here (&str, 0) == FAIL)
3962 if (! inst.error)
3963 inst.error = BAD_ARGS;
3964 return;
3967 inst.instruction |= flags;
3968 end_of_line (str);
3969 return;
3972 /* Thumb specific routines */
3974 /* Parse and validate that a register is of the right form, this saves
3975 repeated checking of this information in many similar cases.
3976 Unlike the 32-bit case we do not insert the register into the opcode
3977 here, since the position is often unknown until the full instruction
3978 has been parsed. */
3979 static int
3980 thumb_reg (strp, hi_lo)
3981 char ** strp;
3982 int hi_lo;
3984 int reg;
3986 if ((reg = reg_required_here (strp, -1)) == FAIL)
3987 return FAIL;
3989 switch (hi_lo)
3991 case THUMB_REG_LO:
3992 if (reg > 7)
3994 inst.error = _("lo register required");
3995 return FAIL;
3997 break;
3999 case THUMB_REG_HI:
4000 if (reg < 8)
4002 inst.error = _("hi register required");
4003 return FAIL;
4005 break;
4007 default:
4008 break;
4011 return reg;
4014 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4015 was SUB. */
4016 static void
4017 thumb_add_sub (str, subtract)
4018 char * str;
4019 int subtract;
4021 int Rd, Rs, Rn = FAIL;
4023 skip_whitespace (str);
4025 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4026 || skip_past_comma (&str) == FAIL)
4028 if (! inst.error)
4029 inst.error = BAD_ARGS;
4030 return;
4033 if (is_immediate_prefix (*str))
4035 Rs = Rd;
4036 str++;
4037 if (my_get_expression (&inst.reloc.exp, &str))
4038 return;
4040 else
4042 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4043 return;
4045 if (skip_past_comma (&str) == FAIL)
4047 /* Two operand format, shuffle the registers and pretend there
4048 are 3 */
4049 Rn = Rs;
4050 Rs = Rd;
4052 else if (is_immediate_prefix (*str))
4054 str++;
4055 if (my_get_expression (&inst.reloc.exp, &str))
4056 return;
4058 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4059 return;
4062 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4063 for the latter case, EXPR contains the immediate that was found. */
4064 if (Rn != FAIL)
4066 /* All register format. */
4067 if (Rd > 7 || Rs > 7 || Rn > 7)
4069 if (Rs != Rd)
4071 inst.error = _("dest and source1 must be the same register");
4072 return;
4075 /* Can't do this for SUB */
4076 if (subtract)
4078 inst.error = _("subtract valid only on lo regs");
4079 return;
4082 inst.instruction = (T_OPCODE_ADD_HI
4083 | (Rd > 7 ? THUMB_H1 : 0)
4084 | (Rn > 7 ? THUMB_H2 : 0));
4085 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
4087 else
4089 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
4090 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
4093 else
4095 /* Immediate expression, now things start to get nasty. */
4097 /* First deal with HI regs, only very restricted cases allowed:
4098 Adjusting SP, and using PC or SP to get an address. */
4099 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4100 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4102 inst.error = _("invalid Hi register with immediate");
4103 return;
4106 if (inst.reloc.exp.X_op != O_constant)
4108 /* Value isn't known yet, all we can do is store all the fragments
4109 we know about in the instruction and let the reloc hacking
4110 work it all out. */
4111 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4112 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4114 else
4116 int offset = inst.reloc.exp.X_add_number;
4118 if (subtract)
4119 offset = -offset;
4121 if (offset < 0)
4123 offset = -offset;
4124 subtract = 1;
4126 /* Quick check, in case offset is MIN_INT */
4127 if (offset < 0)
4129 inst.error = _("immediate value out of range");
4130 return;
4133 else
4134 subtract = 0;
4136 if (Rd == REG_SP)
4138 if (offset & ~0x1fc)
4140 inst.error = _("invalid immediate value for stack adjust");
4141 return;
4143 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4144 inst.instruction |= offset >> 2;
4146 else if (Rs == REG_PC || Rs == REG_SP)
4148 if (subtract
4149 || (offset & ~0x3fc))
4151 inst.error = _("invalid immediate for address calculation");
4152 return;
4154 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4155 : T_OPCODE_ADD_SP);
4156 inst.instruction |= (Rd << 8) | (offset >> 2);
4158 else if (Rs == Rd)
4160 if (offset & ~0xff)
4162 inst.error = _("immediate value out of range");
4163 return;
4165 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4166 inst.instruction |= (Rd << 8) | offset;
4168 else
4170 if (offset & ~0x7)
4172 inst.error = _("immediate value out of range");
4173 return;
4175 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4176 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4181 end_of_line (str);
4184 static void
4185 thumb_shift (str, shift)
4186 char * str;
4187 int shift;
4189 int Rd, Rs, Rn = FAIL;
4191 skip_whitespace (str);
4193 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4194 || skip_past_comma (&str) == FAIL)
4196 if (! inst.error)
4197 inst.error = BAD_ARGS;
4198 return;
4201 if (is_immediate_prefix (*str))
4203 /* Two operand immediate format, set Rs to Rd. */
4204 Rs = Rd;
4205 str ++;
4206 if (my_get_expression (&inst.reloc.exp, &str))
4207 return;
4209 else
4211 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4212 return;
4214 if (skip_past_comma (&str) == FAIL)
4216 /* Two operand format, shuffle the registers and pretend there
4217 are 3 */
4218 Rn = Rs;
4219 Rs = Rd;
4221 else if (is_immediate_prefix (*str))
4223 str++;
4224 if (my_get_expression (&inst.reloc.exp, &str))
4225 return;
4227 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4228 return;
4231 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4232 for the latter case, EXPR contains the immediate that was found. */
4234 if (Rn != FAIL)
4236 if (Rs != Rd)
4238 inst.error = _("source1 and dest must be same register");
4239 return;
4242 switch (shift)
4244 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4245 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4246 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4249 inst.instruction |= Rd | (Rn << 3);
4251 else
4253 switch (shift)
4255 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4256 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4257 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4260 if (inst.reloc.exp.X_op != O_constant)
4262 /* Value isn't known yet, create a dummy reloc and let reloc
4263 hacking fix it up */
4265 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4267 else
4269 unsigned shift_value = inst.reloc.exp.X_add_number;
4271 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4273 inst.error = _("Invalid immediate for shift");
4274 return;
4277 /* Shifts of zero are handled by converting to LSL */
4278 if (shift_value == 0)
4279 inst.instruction = T_OPCODE_LSL_I;
4281 /* Shifts of 32 are encoded as a shift of zero */
4282 if (shift_value == 32)
4283 shift_value = 0;
4285 inst.instruction |= shift_value << 6;
4288 inst.instruction |= Rd | (Rs << 3);
4291 end_of_line (str);
4294 static void
4295 thumb_mov_compare (str, move)
4296 char * str;
4297 int move;
4299 int Rd, Rs = FAIL;
4301 skip_whitespace (str);
4303 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4304 || skip_past_comma (&str) == FAIL)
4306 if (! inst.error)
4307 inst.error = BAD_ARGS;
4308 return;
4311 if (is_immediate_prefix (*str))
4313 str++;
4314 if (my_get_expression (&inst.reloc.exp, &str))
4315 return;
4317 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4318 return;
4320 if (Rs != FAIL)
4322 if (Rs < 8 && Rd < 8)
4324 if (move == THUMB_MOVE)
4325 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4326 since a MOV instruction produces unpredictable results */
4327 inst.instruction = T_OPCODE_ADD_I3;
4328 else
4329 inst.instruction = T_OPCODE_CMP_LR;
4330 inst.instruction |= Rd | (Rs << 3);
4332 else
4334 if (move == THUMB_MOVE)
4335 inst.instruction = T_OPCODE_MOV_HR;
4336 else
4337 inst.instruction = T_OPCODE_CMP_HR;
4339 if (Rd > 7)
4340 inst.instruction |= THUMB_H1;
4342 if (Rs > 7)
4343 inst.instruction |= THUMB_H2;
4345 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4348 else
4350 if (Rd > 7)
4352 inst.error = _("only lo regs allowed with immediate");
4353 return;
4356 if (move == THUMB_MOVE)
4357 inst.instruction = T_OPCODE_MOV_I8;
4358 else
4359 inst.instruction = T_OPCODE_CMP_I8;
4361 inst.instruction |= Rd << 8;
4363 if (inst.reloc.exp.X_op != O_constant)
4364 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4365 else
4367 unsigned value = inst.reloc.exp.X_add_number;
4369 if (value > 255)
4371 inst.error = _("invalid immediate");
4372 return;
4375 inst.instruction |= value;
4379 end_of_line (str);
4382 static void
4383 thumb_load_store (str, load_store, size)
4384 char * str;
4385 int load_store;
4386 int size;
4388 int Rd, Rb, Ro = FAIL;
4390 skip_whitespace (str);
4392 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4393 || skip_past_comma (&str) == FAIL)
4395 if (! inst.error)
4396 inst.error = BAD_ARGS;
4397 return;
4400 if (*str == '[')
4402 str++;
4403 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4404 return;
4406 if (skip_past_comma (&str) != FAIL)
4408 if (is_immediate_prefix (*str))
4410 str++;
4411 if (my_get_expression (&inst.reloc.exp, &str))
4412 return;
4414 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4415 return;
4417 else
4419 inst.reloc.exp.X_op = O_constant;
4420 inst.reloc.exp.X_add_number = 0;
4423 if (*str != ']')
4425 inst.error = _("expected ']'");
4426 return;
4428 str++;
4430 else if (*str == '=')
4432 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4433 str++;
4435 skip_whitespace (str);
4437 if (my_get_expression (& inst.reloc.exp, & str))
4438 return;
4440 end_of_line (str);
4442 if ( inst.reloc.exp.X_op != O_constant
4443 && inst.reloc.exp.X_op != O_symbol)
4445 inst.error = "Constant expression expected";
4446 return;
4449 if (inst.reloc.exp.X_op == O_constant
4450 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4452 /* This can be done with a mov instruction */
4454 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4455 inst.instruction |= inst.reloc.exp.X_add_number;
4456 return;
4459 /* Insert into literal pool */
4460 if (add_to_lit_pool () == FAIL)
4462 if (!inst.error)
4463 inst.error = "literal pool insertion failed";
4464 return;
4467 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4468 inst.reloc.pc_rel = 1;
4469 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4470 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4472 return;
4474 else
4476 if (my_get_expression (&inst.reloc.exp, &str))
4477 return;
4479 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4480 inst.reloc.pc_rel = 1;
4481 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4482 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4483 end_of_line (str);
4484 return;
4487 if (Rb == REG_PC || Rb == REG_SP)
4489 if (size != THUMB_WORD)
4491 inst.error = _("byte or halfword not valid for base register");
4492 return;
4494 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4496 inst.error = _("R15 based store not allowed");
4497 return;
4499 else if (Ro != FAIL)
4501 inst.error = _("Invalid base register for register offset");
4502 return;
4505 if (Rb == REG_PC)
4506 inst.instruction = T_OPCODE_LDR_PC;
4507 else if (load_store == THUMB_LOAD)
4508 inst.instruction = T_OPCODE_LDR_SP;
4509 else
4510 inst.instruction = T_OPCODE_STR_SP;
4512 inst.instruction |= Rd << 8;
4513 if (inst.reloc.exp.X_op == O_constant)
4515 unsigned offset = inst.reloc.exp.X_add_number;
4517 if (offset & ~0x3fc)
4519 inst.error = _("invalid offset");
4520 return;
4523 inst.instruction |= offset >> 2;
4525 else
4526 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4528 else if (Rb > 7)
4530 inst.error = _("invalid base register in load/store");
4531 return;
4533 else if (Ro == FAIL)
4535 /* Immediate offset */
4536 if (size == THUMB_WORD)
4537 inst.instruction = (load_store == THUMB_LOAD
4538 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4539 else if (size == THUMB_HALFWORD)
4540 inst.instruction = (load_store == THUMB_LOAD
4541 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4542 else
4543 inst.instruction = (load_store == THUMB_LOAD
4544 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4546 inst.instruction |= Rd | (Rb << 3);
4548 if (inst.reloc.exp.X_op == O_constant)
4550 unsigned offset = inst.reloc.exp.X_add_number;
4552 if (offset & ~(0x1f << size))
4554 inst.error = _("Invalid offset");
4555 return;
4557 inst.instruction |= (offset >> size) << 6;
4559 else
4560 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4562 else
4564 /* Register offset */
4565 if (size == THUMB_WORD)
4566 inst.instruction = (load_store == THUMB_LOAD
4567 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4568 else if (size == THUMB_HALFWORD)
4569 inst.instruction = (load_store == THUMB_LOAD
4570 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4571 else
4572 inst.instruction = (load_store == THUMB_LOAD
4573 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4575 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4578 end_of_line (str);
4581 static void
4582 do_t_nop (str)
4583 char * str;
4585 /* Do nothing */
4586 end_of_line (str);
4587 return;
4590 /* Handle the Format 4 instructions that do not have equivalents in other
4591 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4592 BIC and MVN. */
4593 static void
4594 do_t_arit (str)
4595 char * str;
4597 int Rd, Rs, Rn;
4599 skip_whitespace (str);
4601 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4602 || skip_past_comma (&str) == FAIL
4603 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4605 inst.error = BAD_ARGS;
4606 return;
4609 if (skip_past_comma (&str) != FAIL)
4611 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4612 (It isn't allowed for CMP either, but that isn't handled by this
4613 function.) */
4614 if (inst.instruction == T_OPCODE_TST
4615 || inst.instruction == T_OPCODE_CMN
4616 || inst.instruction == T_OPCODE_NEG
4617 || inst.instruction == T_OPCODE_MVN)
4619 inst.error = BAD_ARGS;
4620 return;
4623 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4624 return;
4626 if (Rs != Rd)
4628 inst.error = _("dest and source1 one must be the same register");
4629 return;
4631 Rs = Rn;
4634 if (inst.instruction == T_OPCODE_MUL
4635 && Rs == Rd)
4636 as_tsktsk (_("Rs and Rd must be different in MUL"));
4638 inst.instruction |= Rd | (Rs << 3);
4639 end_of_line (str);
4642 static void
4643 do_t_add (str)
4644 char * str;
4646 thumb_add_sub (str, 0);
4649 static void
4650 do_t_asr (str)
4651 char * str;
4653 thumb_shift (str, THUMB_ASR);
4656 static void
4657 do_t_branch9 (str)
4658 char * str;
4660 if (my_get_expression (&inst.reloc.exp, &str))
4661 return;
4662 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4663 inst.reloc.pc_rel = 1;
4664 end_of_line (str);
4667 static void
4668 do_t_branch12 (str)
4669 char * str;
4671 if (my_get_expression (&inst.reloc.exp, &str))
4672 return;
4673 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4674 inst.reloc.pc_rel = 1;
4675 end_of_line (str);
4678 /* Find the real, Thumb encoded start of a Thumb function. */
4680 static symbolS *
4681 find_real_start (symbolP)
4682 symbolS * symbolP;
4684 char * real_start;
4685 const char * name = S_GET_NAME (symbolP);
4686 symbolS * new_target;
4688 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4689 #define STUB_NAME ".real_start_of"
4691 if (name == NULL)
4692 abort();
4694 /* Names that start with '.' are local labels, not function entry points.
4695 The compiler may generate BL instructions to these labels because it
4696 needs to perform a branch to a far away location. */
4697 if (name[0] == '.')
4698 return symbolP;
4700 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4701 sprintf (real_start, "%s%s", STUB_NAME, name);
4703 new_target = symbol_find (real_start);
4705 if (new_target == NULL)
4707 as_warn ("Failed to find real start of function: %s\n", name);
4708 new_target = symbolP;
4711 free (real_start);
4713 return new_target;
4717 static void
4718 do_t_branch23 (str)
4719 char * str;
4721 if (my_get_expression (& inst.reloc.exp, & str))
4722 return;
4724 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4725 inst.reloc.pc_rel = 1;
4726 end_of_line (str);
4728 /* If the destination of the branch is a defined symbol which does not have
4729 the THUMB_FUNC attribute, then we must be calling a function which has
4730 the (interfacearm) attribute. We look for the Thumb entry point to that
4731 function and change the branch to refer to that function instead. */
4732 if ( inst.reloc.exp.X_op == O_symbol
4733 && inst.reloc.exp.X_add_symbol != NULL
4734 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4735 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4736 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4739 static void
4740 do_t_bx (str)
4741 char * str;
4743 int reg;
4745 skip_whitespace (str);
4747 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4748 return;
4750 /* This sets THUMB_H2 from the top bit of reg. */
4751 inst.instruction |= reg << 3;
4753 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4754 should cause the alignment to be checked once it is known. This is
4755 because BX PC only works if the instruction is word aligned. */
4757 end_of_line (str);
4760 static void
4761 do_t_compare (str)
4762 char * str;
4764 thumb_mov_compare (str, THUMB_COMPARE);
4767 static void
4768 do_t_ldmstm (str)
4769 char * str;
4771 int Rb;
4772 long range;
4774 skip_whitespace (str);
4776 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4777 return;
4779 if (*str != '!')
4780 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4781 else
4782 str++;
4784 if (skip_past_comma (&str) == FAIL
4785 || (range = reg_list (&str)) == FAIL)
4787 if (! inst.error)
4788 inst.error = BAD_ARGS;
4789 return;
4792 if (inst.reloc.type != BFD_RELOC_NONE)
4794 /* This really doesn't seem worth it. */
4795 inst.reloc.type = BFD_RELOC_NONE;
4796 inst.error = _("Expression too complex");
4797 return;
4800 if (range & ~0xff)
4802 inst.error = _("only lo-regs valid in load/store multiple");
4803 return;
4806 inst.instruction |= (Rb << 8) | range;
4807 end_of_line (str);
4810 static void
4811 do_t_ldr (str)
4812 char * str;
4814 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4817 static void
4818 do_t_ldrb (str)
4819 char * str;
4821 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4824 static void
4825 do_t_ldrh (str)
4826 char * str;
4828 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4831 static void
4832 do_t_lds (str)
4833 char * str;
4835 int Rd, Rb, Ro;
4837 skip_whitespace (str);
4839 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4840 || skip_past_comma (&str) == FAIL
4841 || *str++ != '['
4842 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4843 || skip_past_comma (&str) == FAIL
4844 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4845 || *str++ != ']')
4847 if (! inst.error)
4848 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4849 return;
4852 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4853 end_of_line (str);
4856 static void
4857 do_t_lsl (str)
4858 char * str;
4860 thumb_shift (str, THUMB_LSL);
4863 static void
4864 do_t_lsr (str)
4865 char * str;
4867 thumb_shift (str, THUMB_LSR);
4870 static void
4871 do_t_mov (str)
4872 char * str;
4874 thumb_mov_compare (str, THUMB_MOVE);
4877 static void
4878 do_t_push_pop (str)
4879 char * str;
4881 long range;
4883 skip_whitespace (str);
4885 if ((range = reg_list (&str)) == FAIL)
4887 if (! inst.error)
4888 inst.error = BAD_ARGS;
4889 return;
4892 if (inst.reloc.type != BFD_RELOC_NONE)
4894 /* This really doesn't seem worth it. */
4895 inst.reloc.type = BFD_RELOC_NONE;
4896 inst.error = _("Expression too complex");
4897 return;
4900 if (range & ~0xff)
4902 if ((inst.instruction == T_OPCODE_PUSH
4903 && (range & ~0xff) == 1 << REG_LR)
4904 || (inst.instruction == T_OPCODE_POP
4905 && (range & ~0xff) == 1 << REG_PC))
4907 inst.instruction |= THUMB_PP_PC_LR;
4908 range &= 0xff;
4910 else
4912 inst.error = _("invalid register list to push/pop instruction");
4913 return;
4917 inst.instruction |= range;
4918 end_of_line (str);
4921 static void
4922 do_t_str (str)
4923 char * str;
4925 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4928 static void
4929 do_t_strb (str)
4930 char * str;
4932 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4935 static void
4936 do_t_strh (str)
4937 char * str;
4939 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4942 static void
4943 do_t_sub (str)
4944 char * str;
4946 thumb_add_sub (str, 1);
4949 static void
4950 do_t_swi (str)
4951 char * str;
4953 skip_whitespace (str);
4955 if (my_get_expression (&inst.reloc.exp, &str))
4956 return;
4958 inst.reloc.type = BFD_RELOC_ARM_SWI;
4959 end_of_line (str);
4960 return;
4963 static void
4964 do_t_adr (str)
4965 char * str;
4967 int reg;
4969 /* This is a pseudo-op of the form "adr rd, label" to be converted
4970 into a relative address of the form "add rd, pc, #label-.-4". */
4971 skip_whitespace (str);
4973 /* Store Rd in temporary location inside instruction. */
4974 if ((reg = reg_required_here (&str, 4)) == FAIL
4975 || (reg > 7) /* For Thumb reg must be r0..r7. */
4976 || skip_past_comma (&str) == FAIL
4977 || my_get_expression (&inst.reloc.exp, &str))
4979 if (!inst.error)
4980 inst.error = BAD_ARGS;
4981 return;
4984 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4985 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
4986 inst.reloc.pc_rel = 1;
4987 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
4989 end_of_line (str);
4992 static void
4993 insert_reg (entry)
4994 int entry;
4996 int len = strlen (reg_table[entry].name) + 2;
4997 char * buf = (char *) xmalloc (len);
4998 char * buf2 = (char *) xmalloc (len);
4999 int i = 0;
5001 #ifdef REGISTER_PREFIX
5002 buf[i++] = REGISTER_PREFIX;
5003 #endif
5005 strcpy (buf + i, reg_table[entry].name);
5007 for (i = 0; buf[i]; i++)
5008 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
5010 buf2[i] = '\0';
5012 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
5013 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
5016 static void
5017 insert_reg_alias (str, regnum)
5018 char *str;
5019 int regnum;
5021 struct reg_entry *new =
5022 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
5023 char *name = xmalloc (strlen (str) + 1);
5024 strcpy (name, str);
5026 new->name = name;
5027 new->number = regnum;
5029 hash_insert (arm_reg_hsh, name, (PTR) new);
5032 static void
5033 set_constant_flonums ()
5035 int i;
5037 for (i = 0; i < NUM_FLOAT_VALS; i++)
5038 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
5039 abort ();
5042 void
5043 md_begin ()
5045 unsigned mach;
5046 unsigned int i;
5048 if ( (arm_ops_hsh = hash_new ()) == NULL
5049 || (arm_tops_hsh = hash_new ()) == NULL
5050 || (arm_cond_hsh = hash_new ()) == NULL
5051 || (arm_shift_hsh = hash_new ()) == NULL
5052 || (arm_reg_hsh = hash_new ()) == NULL
5053 || (arm_psr_hsh = hash_new ()) == NULL)
5054 as_fatal (_("Virtual memory exhausted"));
5056 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
5057 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
5058 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
5059 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
5060 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
5061 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
5062 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
5063 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
5064 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
5065 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
5067 for (i = 0; reg_table[i].name; i++)
5068 insert_reg (i);
5070 set_constant_flonums ();
5072 #if defined OBJ_COFF || defined OBJ_ELF
5074 unsigned int flags = 0;
5076 /* Set the flags in the private structure. */
5077 if (uses_apcs_26) flags |= F_APCS26;
5078 if (support_interwork) flags |= F_INTERWORK;
5079 if (uses_apcs_float) flags |= F_APCS_FLOAT;
5080 if (pic_code) flags |= F_PIC;
5081 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
5083 bfd_set_private_flags (stdoutput, flags);
5085 #endif
5087 /* Record the CPU type as well. */
5088 switch (cpu_variant & ARM_CPU_MASK)
5090 case ARM_2:
5091 mach = bfd_mach_arm_2;
5092 break;
5094 case ARM_3: /* Also ARM_250. */
5095 mach = bfd_mach_arm_2a;
5096 break;
5098 default:
5099 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
5100 mach = bfd_mach_arm_4;
5101 break;
5103 case ARM_7: /* Also ARM_6. */
5104 mach = bfd_mach_arm_3;
5105 break;
5108 /* Catch special cases. */
5109 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5111 if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5112 mach = bfd_mach_arm_5T;
5113 else if (cpu_variant & ARM_EXT_V5)
5114 mach = bfd_mach_arm_5;
5115 else if (cpu_variant & ARM_THUMB)
5116 mach = bfd_mach_arm_4T;
5117 else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5118 mach = bfd_mach_arm_4;
5119 else if (cpu_variant & ARM_LONGMUL)
5120 mach = bfd_mach_arm_3M;
5123 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5126 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5127 for use in the a.out file, and stores them in the array pointed to by buf.
5128 This knows about the endian-ness of the target machine and does
5129 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5130 2 (short) and 4 (long) Floating numbers are put out as a series of
5131 LITTLENUMS (shorts, here at least). */
5132 void
5133 md_number_to_chars (buf, val, n)
5134 char * buf;
5135 valueT val;
5136 int n;
5138 if (target_big_endian)
5139 number_to_chars_bigendian (buf, val, n);
5140 else
5141 number_to_chars_littleendian (buf, val, n);
5144 static valueT
5145 md_chars_to_number (buf, n)
5146 char * buf;
5147 int n;
5149 valueT result = 0;
5150 unsigned char * where = (unsigned char *) buf;
5152 if (target_big_endian)
5154 while (n--)
5156 result <<= 8;
5157 result |= (*where++ & 255);
5160 else
5162 while (n--)
5164 result <<= 8;
5165 result |= (where[n] & 255);
5169 return result;
5172 /* Turn a string in input_line_pointer into a floating point constant
5173 of type TYPE, and store the appropriate bytes in *litP. The number
5174 of LITTLENUMS emitted is stored in *sizeP . An error message is
5175 returned, or NULL on OK.
5177 Note that fp constants aren't represent in the normal way on the ARM.
5178 In big endian mode, things are as expected. However, in little endian
5179 mode fp constants are big-endian word-wise, and little-endian byte-wise
5180 within the words. For example, (double) 1.1 in big endian mode is
5181 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5182 the byte sequence 99 99 f1 3f 9a 99 99 99.
5184 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5186 char *
5187 md_atof (type, litP, sizeP)
5188 char type;
5189 char * litP;
5190 int * sizeP;
5192 int prec;
5193 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5194 char *t;
5195 int i;
5197 switch (type)
5199 case 'f':
5200 case 'F':
5201 case 's':
5202 case 'S':
5203 prec = 2;
5204 break;
5206 case 'd':
5207 case 'D':
5208 case 'r':
5209 case 'R':
5210 prec = 4;
5211 break;
5213 case 'x':
5214 case 'X':
5215 prec = 6;
5216 break;
5218 case 'p':
5219 case 'P':
5220 prec = 6;
5221 break;
5223 default:
5224 *sizeP = 0;
5225 return _("Bad call to MD_ATOF()");
5228 t = atof_ieee (input_line_pointer, type, words);
5229 if (t)
5230 input_line_pointer = t;
5231 *sizeP = prec * 2;
5233 if (target_big_endian)
5235 for (i = 0; i < prec; i++)
5237 md_number_to_chars (litP, (valueT) words[i], 2);
5238 litP += 2;
5241 else
5243 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5244 8 byte float the order is 1 0 3 2. */
5245 for (i = 0; i < prec; i += 2)
5247 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5248 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5249 litP += 4;
5253 return 0;
5256 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5257 long
5258 md_pcrel_from (fixP)
5259 fixS * fixP;
5261 if ( fixP->fx_addsy
5262 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5263 && fixP->fx_subsy == NULL)
5264 return 0;
5266 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5268 /* PC relative addressing on the Thumb is slightly odd
5269 as the bottom two bits of the PC are forced to zero
5270 for the calculation. */
5271 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5274 #ifdef TE_WINCE
5275 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5276 so we un-adjust here to compensate for the accomodation. */
5277 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
5278 #else
5279 return fixP->fx_where + fixP->fx_frag->fr_address;
5280 #endif
5283 /* Round up a section size to the appropriate boundary. */
5284 valueT
5285 md_section_align (segment, size)
5286 segT segment ATTRIBUTE_UNUSED;
5287 valueT size;
5289 #ifdef OBJ_ELF
5290 return size;
5291 #else
5292 /* Round all sects to multiple of 4 */
5293 return (size + 3) & ~3;
5294 #endif
5297 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5298 we have no need to default values of symbols. */
5300 /* ARGSUSED */
5301 symbolS *
5302 md_undefined_symbol (name)
5303 char * name ATTRIBUTE_UNUSED;
5305 #ifdef OBJ_ELF
5306 if (name[0] == '_' && name[1] == 'G'
5307 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5309 if (!GOT_symbol)
5311 if (symbol_find (name))
5312 as_bad ("GOT already in the symbol table");
5314 GOT_symbol = symbol_new (name, undefined_section,
5315 (valueT)0, & zero_address_frag);
5318 return GOT_symbol;
5320 #endif
5322 return 0;
5325 /* arm_reg_parse () := if it looks like a register, return its token and
5326 advance the pointer. */
5328 static int
5329 arm_reg_parse (ccp)
5330 register char ** ccp;
5332 char * start = * ccp;
5333 char c;
5334 char * p;
5335 struct reg_entry * reg;
5337 #ifdef REGISTER_PREFIX
5338 if (*start != REGISTER_PREFIX)
5339 return FAIL;
5340 p = start + 1;
5341 #else
5342 p = start;
5343 #ifdef OPTIONAL_REGISTER_PREFIX
5344 if (*p == OPTIONAL_REGISTER_PREFIX)
5345 p++, start++;
5346 #endif
5347 #endif
5348 if (!isalpha (*p) || !is_name_beginner (*p))
5349 return FAIL;
5351 c = *p++;
5352 while (isalpha (c) || isdigit (c) || c == '_')
5353 c = *p++;
5355 *--p = 0;
5356 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5357 *p = c;
5359 if (reg)
5361 *ccp = p;
5362 return reg->number;
5365 return FAIL;
5369 md_apply_fix3 (fixP, val, seg)
5370 fixS * fixP;
5371 valueT * val;
5372 segT seg;
5374 offsetT value = * val;
5375 offsetT newval;
5376 unsigned int newimm;
5377 unsigned long temp;
5378 int sign;
5379 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5380 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5382 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5384 /* Note whether this will delete the relocation. */
5385 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5386 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5387 && !fixP->fx_pcrel)
5388 #else
5389 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5390 #endif
5391 fixP->fx_done = 1;
5393 /* If this symbol is in a different section then we need to leave it for
5394 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5395 so we have to undo it's effects here. */
5396 if (fixP->fx_pcrel)
5398 if (fixP->fx_addsy != NULL
5399 && S_IS_DEFINED (fixP->fx_addsy)
5400 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5402 if (target_oabi
5403 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
5405 value = 0;
5406 else
5407 value += md_pcrel_from (fixP);
5411 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5413 switch (fixP->fx_r_type)
5415 case BFD_RELOC_ARM_IMMEDIATE:
5416 newimm = validate_immediate (value);
5417 temp = md_chars_to_number (buf, INSN_SIZE);
5419 /* If the instruction will fail, see if we can fix things up by
5420 changing the opcode. */
5421 if (newimm == (unsigned int) FAIL
5422 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5424 as_bad_where (fixP->fx_file, fixP->fx_line,
5425 _("invalid constant (%lx) after fixup"),
5426 (unsigned long) value);
5427 break;
5430 newimm |= (temp & 0xfffff000);
5431 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5432 break;
5434 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5436 unsigned int highpart = 0;
5437 unsigned int newinsn = 0xe1a00000; /* nop */
5438 newimm = validate_immediate (value);
5439 temp = md_chars_to_number (buf, INSN_SIZE);
5441 /* If the instruction will fail, see if we can fix things up by
5442 changing the opcode. */
5443 if (newimm == (unsigned int) FAIL
5444 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5446 /* No ? OK - try using two ADD instructions to generate the value. */
5447 newimm = validate_immediate_twopart (value, & highpart);
5449 /* Yes - then make sure that the second instruction is also an add. */
5450 if (newimm != (unsigned int) FAIL)
5451 newinsn = temp;
5452 /* Still No ? Try using a negated value. */
5453 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5454 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5455 /* Otherwise - give up. */
5456 else
5458 as_bad_where (fixP->fx_file, fixP->fx_line,
5459 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5460 break;
5463 /* Replace the first operand in the 2nd instruction (which is the PC)
5464 with the destination register. We have already added in the PC in the
5465 first instruction and we do not want to do it again. */
5466 newinsn &= ~ 0xf0000;
5467 newinsn |= ((newinsn & 0x0f000) << 4);
5470 newimm |= (temp & 0xfffff000);
5471 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5473 highpart |= (newinsn & 0xfffff000);
5474 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5476 break;
5478 case BFD_RELOC_ARM_OFFSET_IMM:
5479 sign = value >= 0;
5481 if (value < 0)
5482 value = - value;
5484 if (validate_offset_imm (value, 0) == FAIL)
5486 as_bad_where (fixP->fx_file, fixP->fx_line,
5487 _("bad immediate value for offset (%ld)"), (long) value);
5488 break;
5491 newval = md_chars_to_number (buf, INSN_SIZE);
5492 newval &= 0xff7ff000;
5493 newval |= value | (sign ? INDEX_UP : 0);
5494 md_number_to_chars (buf, newval, INSN_SIZE);
5495 break;
5497 case BFD_RELOC_ARM_OFFSET_IMM8:
5498 case BFD_RELOC_ARM_HWLITERAL:
5499 sign = value >= 0;
5501 if (value < 0)
5502 value = - value;
5504 if (validate_offset_imm (value, 1) == FAIL)
5506 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5507 as_bad_where (fixP->fx_file, fixP->fx_line,
5508 _("invalid literal constant: pool needs to be closer"));
5509 else
5510 as_bad (_("bad immediate value for half-word offset (%ld)"),
5511 (long) value);
5512 break;
5515 newval = md_chars_to_number (buf, INSN_SIZE);
5516 newval &= 0xff7ff0f0;
5517 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5518 md_number_to_chars (buf, newval, INSN_SIZE);
5519 break;
5521 case BFD_RELOC_ARM_LITERAL:
5522 sign = value >= 0;
5524 if (value < 0)
5525 value = - value;
5527 if (validate_offset_imm (value, 0) == FAIL)
5529 as_bad_where (fixP->fx_file, fixP->fx_line,
5530 _("invalid literal constant: pool needs to be closer"));
5531 break;
5534 newval = md_chars_to_number (buf, INSN_SIZE);
5535 newval &= 0xff7ff000;
5536 newval |= value | (sign ? INDEX_UP : 0);
5537 md_number_to_chars (buf, newval, INSN_SIZE);
5538 break;
5540 case BFD_RELOC_ARM_SHIFT_IMM:
5541 newval = md_chars_to_number (buf, INSN_SIZE);
5542 if (((unsigned long) value) > 32
5543 || (value == 32
5544 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5546 as_bad_where (fixP->fx_file, fixP->fx_line,
5547 _("shift expression is too large"));
5548 break;
5551 if (value == 0)
5552 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5553 else if (value == 32)
5554 value = 0;
5555 newval &= 0xfffff07f;
5556 newval |= (value & 0x1f) << 7;
5557 md_number_to_chars (buf, newval , INSN_SIZE);
5558 break;
5560 case BFD_RELOC_ARM_SWI:
5561 if (arm_data->thumb_mode)
5563 if (((unsigned long) value) > 0xff)
5564 as_bad_where (fixP->fx_file, fixP->fx_line,
5565 _("Invalid swi expression"));
5566 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5567 newval |= value;
5568 md_number_to_chars (buf, newval, THUMB_SIZE);
5570 else
5572 if (((unsigned long) value) > 0x00ffffff)
5573 as_bad_where (fixP->fx_file, fixP->fx_line,
5574 _("Invalid swi expression"));
5575 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5576 newval |= value;
5577 md_number_to_chars (buf, newval , INSN_SIZE);
5579 break;
5581 case BFD_RELOC_ARM_MULTI:
5582 if (((unsigned long) value) > 0xffff)
5583 as_bad_where (fixP->fx_file, fixP->fx_line,
5584 _("Invalid expression in load/store multiple"));
5585 newval = value | md_chars_to_number (buf, INSN_SIZE);
5586 md_number_to_chars (buf, newval, INSN_SIZE);
5587 break;
5589 case BFD_RELOC_ARM_PCREL_BRANCH:
5590 newval = md_chars_to_number (buf, INSN_SIZE);
5592 /* Sign-extend a 24-bit number. */
5593 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5595 #ifdef OBJ_ELF
5596 if (! target_oabi)
5597 value = fixP->fx_offset;
5598 #endif
5600 /* We are going to store value (shifted right by two) in the
5601 instruction, in a 24 bit, signed field. Thus we need to check
5602 that none of the top 8 bits of the shifted value (top 7 bits of
5603 the unshifted, unsigned value) are set, or that they are all set. */
5604 if ((value & 0xfe000000UL) != 0
5605 && ((value & 0xfe000000UL) != 0xfe000000UL))
5607 #ifdef OBJ_ELF
5608 /* Normally we would be stuck at this point, since we cannot store
5609 the absolute address that is the destination of the branch in the
5610 24 bits of the branch instruction. If however, we happen to know
5611 that the destination of the branch is in the same section as the
5612 branch instruciton itself, then we can compute the relocation for
5613 ourselves and not have to bother the linker with it.
5615 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5616 because I have not worked out how to do this for OBJ_COFF or
5617 target_oabi. */
5618 if (! target_oabi
5619 && fixP->fx_addsy != NULL
5620 && S_IS_DEFINED (fixP->fx_addsy)
5621 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
5623 /* Get pc relative value to go into the branch. */
5624 value = * val;
5626 /* Permit a backward branch provided that enough bits are set.
5627 Allow a forwards branch, provided that enough bits are clear. */
5628 if ((value & 0xfe000000UL) == 0xfe000000UL
5629 || (value & 0xfe000000UL) == 0)
5630 fixP->fx_done = 1;
5633 if (! fixP->fx_done)
5634 #endif
5635 as_bad_where (fixP->fx_file, fixP->fx_line,
5636 _("gas can't handle same-section branch dest >= 0x04000000"));
5639 value >>= 2;
5640 value += SEXT24 (newval);
5642 if ((value & 0xff000000UL) != 0
5643 && ((value & 0xff000000UL) != 0xff000000UL))
5644 as_bad_where (fixP->fx_file, fixP->fx_line,
5645 _("out of range branch"));
5647 newval = (value & 0x00ffffff) | (newval & 0xff000000);
5648 md_number_to_chars (buf, newval, INSN_SIZE);
5649 break;
5652 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5653 newval = md_chars_to_number (buf, THUMB_SIZE);
5655 addressT diff = (newval & 0xff) << 1;
5656 if (diff & 0x100)
5657 diff |= ~0xff;
5659 value += diff;
5660 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5661 as_bad_where (fixP->fx_file, fixP->fx_line,
5662 _("Branch out of range"));
5663 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5665 md_number_to_chars (buf, newval, THUMB_SIZE);
5666 break;
5668 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5669 newval = md_chars_to_number (buf, THUMB_SIZE);
5671 addressT diff = (newval & 0x7ff) << 1;
5672 if (diff & 0x800)
5673 diff |= ~0x7ff;
5675 value += diff;
5676 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5677 as_bad_where (fixP->fx_file, fixP->fx_line,
5678 _("Branch out of range"));
5679 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5681 md_number_to_chars (buf, newval, THUMB_SIZE);
5682 break;
5684 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5686 offsetT newval2;
5687 addressT diff;
5689 newval = md_chars_to_number (buf, THUMB_SIZE);
5690 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5691 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5692 if (diff & 0x400000)
5693 diff |= ~0x3fffff;
5694 #ifdef OBJ_ELF
5695 value = fixP->fx_offset;
5696 #endif
5697 value += diff;
5698 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5699 as_bad_where (fixP->fx_file, fixP->fx_line,
5700 _("Branch with link out of range"));
5702 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5703 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5704 md_number_to_chars (buf, newval, THUMB_SIZE);
5705 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5707 break;
5709 case BFD_RELOC_8:
5710 if (fixP->fx_done || fixP->fx_pcrel)
5711 md_number_to_chars (buf, value, 1);
5712 #ifdef OBJ_ELF
5713 else if (!target_oabi)
5715 value = fixP->fx_offset;
5716 md_number_to_chars (buf, value, 1);
5718 #endif
5719 break;
5721 case BFD_RELOC_16:
5722 if (fixP->fx_done || fixP->fx_pcrel)
5723 md_number_to_chars (buf, value, 2);
5724 #ifdef OBJ_ELF
5725 else if (!target_oabi)
5727 value = fixP->fx_offset;
5728 md_number_to_chars (buf, value, 2);
5730 #endif
5731 break;
5733 #ifdef OBJ_ELF
5734 case BFD_RELOC_ARM_GOT32:
5735 case BFD_RELOC_ARM_GOTOFF:
5736 md_number_to_chars (buf, 0, 4);
5737 break;
5738 #endif
5740 case BFD_RELOC_RVA:
5741 case BFD_RELOC_32:
5742 if (fixP->fx_done || fixP->fx_pcrel)
5743 md_number_to_chars (buf, value, 4);
5744 #ifdef OBJ_ELF
5745 else if (!target_oabi)
5747 value = fixP->fx_offset;
5748 md_number_to_chars (buf, value, 4);
5750 #endif
5751 break;
5753 #ifdef OBJ_ELF
5754 case BFD_RELOC_ARM_PLT32:
5755 /* It appears the instruction is fully prepared at this point. */
5756 break;
5757 #endif
5759 case BFD_RELOC_ARM_GOTPC:
5760 md_number_to_chars (buf, value, 4);
5761 break;
5763 case BFD_RELOC_ARM_CP_OFF_IMM:
5764 sign = value >= 0;
5765 if (value < -1023 || value > 1023 || (value & 3))
5766 as_bad_where (fixP->fx_file, fixP->fx_line,
5767 _("Illegal value for co-processor offset"));
5768 if (value < 0)
5769 value = -value;
5770 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5771 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5772 md_number_to_chars (buf, newval , INSN_SIZE);
5773 break;
5775 case BFD_RELOC_ARM_THUMB_OFFSET:
5776 newval = md_chars_to_number (buf, THUMB_SIZE);
5777 /* Exactly what ranges, and where the offset is inserted depends on
5778 the type of instruction, we can establish this from the top 4 bits */
5779 switch (newval >> 12)
5781 case 4: /* PC load */
5782 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5783 forced to zero for these loads, so we will need to round
5784 up the offset if the instruction address is not word
5785 aligned (since the final address produced must be, and
5786 we can only describe word-aligned immediate offsets). */
5788 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5789 as_bad_where (fixP->fx_file, fixP->fx_line,
5790 _("Invalid offset, target not word aligned (0x%08X)"),
5791 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5793 if ((value + 2) & ~0x3fe)
5794 as_bad_where (fixP->fx_file, fixP->fx_line,
5795 _("Invalid offset, value too big (0x%08X)"), value);
5797 /* Round up, since pc will be rounded down. */
5798 newval |= (value + 2) >> 2;
5799 break;
5801 case 9: /* SP load/store */
5802 if (value & ~0x3fc)
5803 as_bad_where (fixP->fx_file, fixP->fx_line,
5804 _("Invalid offset, value too big (0x%08X)"), value);
5805 newval |= value >> 2;
5806 break;
5808 case 6: /* Word load/store */
5809 if (value & ~0x7c)
5810 as_bad_where (fixP->fx_file, fixP->fx_line,
5811 _("Invalid offset, value too big (0x%08X)"), value);
5812 newval |= value << 4; /* 6 - 2 */
5813 break;
5815 case 7: /* Byte load/store */
5816 if (value & ~0x1f)
5817 as_bad_where (fixP->fx_file, fixP->fx_line,
5818 _("Invalid offset, value too big (0x%08X)"), value);
5819 newval |= value << 6;
5820 break;
5822 case 8: /* Halfword load/store */
5823 if (value & ~0x3e)
5824 as_bad_where (fixP->fx_file, fixP->fx_line,
5825 _("Invalid offset, value too big (0x%08X)"), value);
5826 newval |= value << 5; /* 6 - 1 */
5827 break;
5829 default:
5830 as_bad_where (fixP->fx_file, fixP->fx_line,
5831 "Unable to process relocation for thumb opcode: %lx",
5832 (unsigned long) newval);
5833 break;
5835 md_number_to_chars (buf, newval, THUMB_SIZE);
5836 break;
5838 case BFD_RELOC_ARM_THUMB_ADD:
5839 /* This is a complicated relocation, since we use it for all of
5840 the following immediate relocations:
5841 3bit ADD/SUB
5842 8bit ADD/SUB
5843 9bit ADD/SUB SP word-aligned
5844 10bit ADD PC/SP word-aligned
5846 The type of instruction being processed is encoded in the
5847 instruction field:
5848 0x8000 SUB
5849 0x00F0 Rd
5850 0x000F Rs
5852 newval = md_chars_to_number (buf, THUMB_SIZE);
5854 int rd = (newval >> 4) & 0xf;
5855 int rs = newval & 0xf;
5856 int subtract = newval & 0x8000;
5858 if (rd == REG_SP)
5860 if (value & ~0x1fc)
5861 as_bad_where (fixP->fx_file, fixP->fx_line,
5862 _("Invalid immediate for stack address calculation"));
5863 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5864 newval |= value >> 2;
5866 else if (rs == REG_PC || rs == REG_SP)
5868 if (subtract ||
5869 value & ~0x3fc)
5870 as_bad_where (fixP->fx_file, fixP->fx_line,
5871 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5872 (unsigned long) value);
5873 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5874 newval |= rd << 8;
5875 newval |= value >> 2;
5877 else if (rs == rd)
5879 if (value & ~0xff)
5880 as_bad_where (fixP->fx_file, fixP->fx_line,
5881 _("Invalid 8bit immediate"));
5882 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5883 newval |= (rd << 8) | value;
5885 else
5887 if (value & ~0x7)
5888 as_bad_where (fixP->fx_file, fixP->fx_line,
5889 _("Invalid 3bit immediate"));
5890 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5891 newval |= rd | (rs << 3) | (value << 6);
5894 md_number_to_chars (buf, newval , THUMB_SIZE);
5895 break;
5897 case BFD_RELOC_ARM_THUMB_IMM:
5898 newval = md_chars_to_number (buf, THUMB_SIZE);
5899 switch (newval >> 11)
5901 case 0x04: /* 8bit immediate MOV */
5902 case 0x05: /* 8bit immediate CMP */
5903 if (value < 0 || value > 255)
5904 as_bad_where (fixP->fx_file, fixP->fx_line,
5905 _("Invalid immediate: %ld is too large"),
5906 (long) value);
5907 newval |= value;
5908 break;
5910 default:
5911 abort ();
5913 md_number_to_chars (buf, newval , THUMB_SIZE);
5914 break;
5916 case BFD_RELOC_ARM_THUMB_SHIFT:
5917 /* 5bit shift value (0..31) */
5918 if (value < 0 || value > 31)
5919 as_bad_where (fixP->fx_file, fixP->fx_line,
5920 _("Illegal Thumb shift value: %ld"), (long) value);
5921 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5922 newval |= value << 6;
5923 md_number_to_chars (buf, newval , THUMB_SIZE);
5924 break;
5926 case BFD_RELOC_VTABLE_INHERIT:
5927 case BFD_RELOC_VTABLE_ENTRY:
5928 fixP->fx_done = 0;
5929 return 1;
5931 case BFD_RELOC_NONE:
5932 default:
5933 as_bad_where (fixP->fx_file, fixP->fx_line,
5934 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5937 return 1;
5940 /* Translate internal representation of relocation info to BFD target
5941 format. */
5942 arelent *
5943 tc_gen_reloc (section, fixp)
5944 asection * section ATTRIBUTE_UNUSED;
5945 fixS * fixp;
5947 arelent * reloc;
5948 bfd_reloc_code_real_type code;
5950 reloc = (arelent *) xmalloc (sizeof (arelent));
5952 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5953 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5954 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5956 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5957 #ifndef OBJ_ELF
5958 if (fixp->fx_pcrel == 0)
5959 reloc->addend = fixp->fx_offset;
5960 else
5961 reloc->addend = fixp->fx_offset = reloc->address;
5962 #else /* OBJ_ELF */
5963 reloc->addend = fixp->fx_offset;
5964 #endif
5966 switch (fixp->fx_r_type)
5968 case BFD_RELOC_8:
5969 if (fixp->fx_pcrel)
5971 code = BFD_RELOC_8_PCREL;
5972 break;
5975 case BFD_RELOC_16:
5976 if (fixp->fx_pcrel)
5978 code = BFD_RELOC_16_PCREL;
5979 break;
5982 case BFD_RELOC_32:
5983 if (fixp->fx_pcrel)
5985 code = BFD_RELOC_32_PCREL;
5986 break;
5989 case BFD_RELOC_ARM_PCREL_BRANCH:
5990 case BFD_RELOC_RVA:
5991 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5992 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5993 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5994 case BFD_RELOC_VTABLE_ENTRY:
5995 case BFD_RELOC_VTABLE_INHERIT:
5996 code = fixp->fx_r_type;
5997 break;
5999 case BFD_RELOC_ARM_LITERAL:
6000 case BFD_RELOC_ARM_HWLITERAL:
6001 /* If this is called then the a literal has been referenced across
6002 a section boundary - possibly due to an implicit dump */
6003 as_bad_where (fixp->fx_file, fixp->fx_line,
6004 _("Literal referenced across section boundary (Implicit dump?)"));
6005 return NULL;
6007 #ifdef OBJ_ELF
6008 case BFD_RELOC_ARM_GOT32:
6009 case BFD_RELOC_ARM_GOTOFF:
6010 case BFD_RELOC_ARM_PLT32:
6011 code = fixp->fx_r_type;
6012 break;
6013 #endif
6015 case BFD_RELOC_ARM_IMMEDIATE:
6016 as_bad_where (fixp->fx_file, fixp->fx_line,
6017 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6018 fixp->fx_r_type);
6019 return NULL;
6021 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6022 as_bad_where (fixp->fx_file, fixp->fx_line,
6023 _("ADRL used for a symbol not defined in the same file"),
6024 fixp->fx_r_type);
6025 return NULL;
6027 case BFD_RELOC_ARM_OFFSET_IMM:
6028 as_bad_where (fixp->fx_file, fixp->fx_line,
6029 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6030 fixp->fx_r_type);
6031 return NULL;
6033 default:
6035 char * type;
6036 switch (fixp->fx_r_type)
6038 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
6039 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
6040 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
6041 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
6042 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
6043 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
6044 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
6045 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
6046 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
6047 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
6048 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
6049 default: type = _("<unknown>"); break;
6051 as_bad_where (fixp->fx_file, fixp->fx_line,
6052 _("Can not represent %s relocation in this object file format (%d)"),
6053 type, fixp->fx_pcrel);
6054 return NULL;
6058 #ifdef OBJ_ELF
6059 if (code == BFD_RELOC_32_PCREL
6060 && GOT_symbol
6061 && fixp->fx_addsy == GOT_symbol)
6063 code = BFD_RELOC_ARM_GOTPC;
6064 reloc->addend = fixp->fx_offset = reloc->address;
6066 #endif
6068 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6070 if (reloc->howto == NULL)
6072 as_bad_where (fixp->fx_file, fixp->fx_line,
6073 _("Can not represent %s relocation in this object file format"),
6074 bfd_get_reloc_code_name (code));
6075 return NULL;
6078 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6079 vtable entry to be used in the relocation's section offset. */
6080 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6081 reloc->address = fixp->fx_offset;
6083 return reloc;
6087 md_estimate_size_before_relax (fragP, segtype)
6088 fragS * fragP ATTRIBUTE_UNUSED;
6089 segT segtype ATTRIBUTE_UNUSED;
6091 as_fatal (_("md_estimate_size_before_relax\n"));
6092 return 1;
6095 static void
6096 output_inst PARAMS ((void))
6098 char * to = NULL;
6100 if (inst.error)
6102 as_bad (inst.error);
6103 return;
6106 to = frag_more (inst.size);
6108 if (thumb_mode && (inst.size > THUMB_SIZE))
6110 assert (inst.size == (2 * THUMB_SIZE));
6111 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6112 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6114 else if (inst.size > INSN_SIZE)
6116 assert (inst.size == (2 * INSN_SIZE));
6117 md_number_to_chars (to, inst.instruction, INSN_SIZE);
6118 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6120 else
6121 md_number_to_chars (to, inst.instruction, inst.size);
6123 if (inst.reloc.type != BFD_RELOC_NONE)
6124 fix_new_arm (frag_now, to - frag_now->fr_literal,
6125 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6126 inst.reloc.type);
6128 return;
6131 void
6132 md_assemble (str)
6133 char * str;
6135 char c;
6136 char * p;
6137 char * q;
6138 char * start;
6140 /* Align the instruction.
6141 This may not be the right thing to do but ... */
6142 /* arm_align (2, 0); */
6143 listing_prev_line (); /* Defined in listing.h */
6145 /* Align the previous label if needed. */
6146 if (last_label_seen != NULL)
6148 symbol_set_frag (last_label_seen, frag_now);
6149 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6150 S_SET_SEGMENT (last_label_seen, now_seg);
6153 memset (&inst, '\0', sizeof (inst));
6154 inst.reloc.type = BFD_RELOC_NONE;
6156 skip_whitespace (str);
6158 /* Scan up to the end of the op-code, which must end in white space or
6159 end of string. */
6160 for (start = p = str; *p != '\0'; p++)
6161 if (*p == ' ')
6162 break;
6164 if (p == str)
6166 as_bad (_("No operator -- statement `%s'\n"), str);
6167 return;
6170 if (thumb_mode)
6172 CONST struct thumb_opcode * opcode;
6174 c = *p;
6175 *p = '\0';
6176 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6177 *p = c;
6179 if (opcode)
6181 /* Check that this instruction is supported for this CPU. */
6182 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
6184 as_bad (_("selected processor does not support this opcode"));
6185 return;
6188 inst.instruction = opcode->value;
6189 inst.size = opcode->size;
6190 (*opcode->parms)(p);
6191 output_inst ();
6192 return;
6195 else
6197 CONST struct asm_opcode * opcode;
6198 unsigned long cond_code;
6200 inst.size = INSN_SIZE;
6201 /* p now points to the end of the opcode, probably white space, but we
6202 have to break the opcode up in case it contains condionals and flags;
6203 keep trying with progressively smaller basic instructions until one
6204 matches, or we run out of opcode. */
6205 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6206 for (; q != str; q--)
6208 c = *q;
6209 *q = '\0';
6210 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6211 *q = c;
6213 if (opcode && opcode->template)
6215 unsigned long flag_bits = 0;
6216 char * r;
6218 /* Check that this instruction is supported for this CPU. */
6219 if ((opcode->variants & cpu_variant) == 0)
6220 goto try_shorter;
6222 inst.instruction = opcode->value;
6223 if (q == p) /* Just a simple opcode. */
6225 if (opcode->comp_suffix)
6227 if (*opcode->comp_suffix != '\0')
6228 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6229 str, opcode->comp_suffix);
6230 else
6231 /* Not a conditional instruction. */
6232 (*opcode->parms)(q, 0);
6234 else
6236 /* A conditional instruction with default condition. */
6237 inst.instruction |= COND_ALWAYS;
6238 (*opcode->parms)(q, 0);
6240 output_inst ();
6241 return;
6244 /* Not just a simple opcode. Check if extra is a conditional. */
6245 r = q;
6246 if (p - r >= 2)
6248 CONST struct asm_cond *cond;
6249 char d = *(r + 2);
6251 *(r + 2) = '\0';
6252 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6253 *(r + 2) = d;
6254 if (cond)
6256 if (cond->value == 0xf0000000)
6257 as_tsktsk (
6258 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6260 cond_code = cond->value;
6261 r += 2;
6263 else
6264 cond_code = COND_ALWAYS;
6266 else
6267 cond_code = COND_ALWAYS;
6269 /* Apply the conditional, or complain it's not allowed. */
6270 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6272 /* Instruction isn't conditional */
6273 if (cond_code != COND_ALWAYS)
6275 as_bad (_("Opcode `%s' is unconditional\n"), str);
6276 return;
6279 else
6280 /* Instruction is conditional: set the condition into it. */
6281 inst.instruction |= cond_code;
6284 /* If there is a compulsory suffix, it should come here, before
6285 any optional flags. */
6286 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
6288 CONST char *s = opcode->comp_suffix;
6290 while (*s)
6292 inst.suffix++;
6293 if (*r == *s)
6294 break;
6295 s++;
6298 if (*s == '\0')
6300 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6301 opcode->comp_suffix);
6302 return;
6305 r++;
6308 /* The remainder, if any should now be flags for the instruction;
6309 Scan these checking each one found with the opcode. */
6310 if (r != p)
6312 char d;
6313 CONST struct asm_flg *flag = opcode->flags;
6315 if (flag)
6317 int flagno;
6319 d = *p;
6320 *p = '\0';
6322 for (flagno = 0; flag[flagno].template; flagno++)
6324 if (streq (r, flag[flagno].template))
6326 flag_bits |= flag[flagno].set_bits;
6327 break;
6331 *p = d;
6332 if (! flag[flagno].template)
6333 goto try_shorter;
6335 else
6336 goto try_shorter;
6339 (*opcode->parms) (p, flag_bits);
6340 output_inst ();
6341 return;
6344 try_shorter:
6349 /* It wasn't an instruction, but it might be a register alias of the form
6350 alias .req reg */
6351 q = p;
6352 skip_whitespace (q);
6354 c = *p;
6355 *p = '\0';
6357 if (*q && !strncmp (q, ".req ", 4))
6359 int reg;
6360 char * copy_of_str = str;
6361 char * r;
6363 q += 4;
6364 skip_whitespace (q);
6366 for (r = q; *r != '\0'; r++)
6367 if (*r == ' ')
6368 break;
6370 if (r != q)
6372 int regnum;
6373 char d = *r;
6375 *r = '\0';
6376 regnum = arm_reg_parse (& q);
6377 *r = d;
6379 reg = arm_reg_parse (& str);
6381 if (reg == FAIL)
6383 if (regnum != FAIL)
6384 insert_reg_alias (str, regnum);
6385 else
6386 as_warn (_("register '%s' does not exist\n"), q);
6388 else if (regnum != FAIL)
6390 if (reg != regnum)
6391 as_warn (_("ignoring redefinition of register alias '%s'"),
6392 copy_of_str );
6394 /* Do not warn about redefinitions to the same alias. */
6396 else
6397 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6398 copy_of_str, q);
6400 else
6401 as_warn (_("ignoring incomplete .req pseuso op"));
6403 *p = c;
6404 return;
6407 *p = c;
6408 as_bad (_("bad instruction `%s'"), start);
6412 * md_parse_option
6413 * Invocation line includes a switch not recognized by the base assembler.
6414 * See if it's a processor-specific option. These are:
6415 * Cpu variants, the arm part is optional:
6416 * -m[arm]1 Currently not supported.
6417 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6418 * -m[arm]3 Arm 3 processor
6419 * -m[arm]6[xx], Arm 6 processors
6420 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6421 * -m[arm]8[10] Arm 8 processors
6422 * -m[arm]9[20][tdmi] Arm 9 processors
6423 * -mstrongarm[110[0]] StrongARM processors
6424 * -m[arm]v[2345[t]] Arm architectures
6425 * -mall All (except the ARM1)
6426 * FP variants:
6427 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6428 * -mfpe-old (No float load/store multiples)
6429 * -mno-fpu Disable all floating point instructions
6430 * Run-time endian selection:
6431 * -EB big endian cpu
6432 * -EL little endian cpu
6433 * ARM Procedure Calling Standard:
6434 * -mapcs-32 32 bit APCS
6435 * -mapcs-26 26 bit APCS
6436 * -mapcs-float Pass floats in float regs
6437 * -mapcs-reentrant Position independent code
6438 * -mthumb-interwork Code supports Arm/Thumb interworking
6439 * -moabi Old ELF ABI
6442 CONST char * md_shortopts = "m:k";
6443 struct option md_longopts[] =
6445 #ifdef ARM_BI_ENDIAN
6446 #define OPTION_EB (OPTION_MD_BASE + 0)
6447 {"EB", no_argument, NULL, OPTION_EB},
6448 #define OPTION_EL (OPTION_MD_BASE + 1)
6449 {"EL", no_argument, NULL, OPTION_EL},
6450 #ifdef OBJ_ELF
6451 #define OPTION_OABI (OPTION_MD_BASE +2)
6452 {"oabi", no_argument, NULL, OPTION_OABI},
6453 #endif
6454 #endif
6455 {NULL, no_argument, NULL, 0}
6457 size_t md_longopts_size = sizeof (md_longopts);
6460 md_parse_option (c, arg)
6461 int c;
6462 char * arg;
6464 char * str = arg;
6466 switch (c)
6468 #ifdef ARM_BI_ENDIAN
6469 case OPTION_EB:
6470 target_big_endian = 1;
6471 break;
6472 case OPTION_EL:
6473 target_big_endian = 0;
6474 break;
6475 #endif
6477 case 'm':
6478 switch (*str)
6480 case 'f':
6481 if (streq (str, "fpa10"))
6482 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6483 else if (streq (str, "fpa11"))
6484 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6485 else if (streq (str, "fpe-old"))
6486 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6487 else
6488 goto bad;
6489 break;
6491 case 'n':
6492 if (streq (str, "no-fpu"))
6493 cpu_variant &= ~FPU_ALL;
6494 break;
6496 #ifdef OBJ_ELF
6497 case 'o':
6498 if (streq (str, "oabi"))
6499 target_oabi = true;
6500 break;
6501 #endif
6503 case 't':
6504 /* Limit assembler to generating only Thumb instructions: */
6505 if (streq (str, "thumb"))
6507 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6508 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6509 thumb_mode = 1;
6511 else if (streq (str, "thumb-interwork"))
6513 if ((cpu_variant & ARM_THUMB) == 0)
6514 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
6515 #if defined OBJ_COFF || defined OBJ_ELF
6516 support_interwork = true;
6517 #endif
6519 else
6520 goto bad;
6521 break;
6523 default:
6524 if (streq (str, "all"))
6526 cpu_variant = ARM_ALL | FPU_ALL;
6527 return 1;
6529 #if defined OBJ_COFF || defined OBJ_ELF
6530 if (! strncmp (str, "apcs-", 5))
6532 /* GCC passes on all command line options starting "-mapcs-..."
6533 to us, so we must parse them here. */
6535 str += 5;
6537 if (streq (str, "32"))
6539 uses_apcs_26 = false;
6540 return 1;
6542 else if (streq (str, "26"))
6544 uses_apcs_26 = true;
6545 return 1;
6547 else if (streq (str, "frame"))
6549 /* Stack frames are being generated - does not affect
6550 linkage of code. */
6551 return 1;
6553 else if (streq (str, "stack-check"))
6555 /* Stack checking is being performed - does not affect
6556 linkage, but does require that the functions
6557 __rt_stkovf_split_small and __rt_stkovf_split_big be
6558 present in the final link. */
6560 return 1;
6562 else if (streq (str, "float"))
6564 /* Floating point arguments are being passed in the floating
6565 point registers. This does affect linking, since this
6566 version of the APCS is incompatible with the version that
6567 passes floating points in the integer registers. */
6569 uses_apcs_float = true;
6570 return 1;
6572 else if (streq (str, "reentrant"))
6574 /* Reentrant code has been generated. This does affect
6575 linking, since there is no point in linking reentrant/
6576 position independent code with absolute position code. */
6577 pic_code = true;
6578 return 1;
6581 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6582 return 0;
6584 #endif
6585 /* Strip off optional "arm" */
6586 if (! strncmp (str, "arm", 3))
6587 str += 3;
6589 switch (*str)
6591 case '1':
6592 if (streq (str, "1"))
6593 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6594 else
6595 goto bad;
6596 break;
6598 case '2':
6599 if (streq (str, "2"))
6600 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6601 else if (streq (str, "250"))
6602 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6603 else
6604 goto bad;
6605 break;
6607 case '3':
6608 if (streq (str, "3"))
6609 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6610 else
6611 goto bad;
6612 break;
6614 case '6':
6615 switch (strtol (str, NULL, 10))
6617 case 6:
6618 case 60:
6619 case 600:
6620 case 610:
6621 case 620:
6622 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6623 break;
6624 default:
6625 goto bad;
6627 break;
6629 case '7':
6630 switch (strtol (str, & str, 10)) /* Eat the processor name */
6632 case 7:
6633 case 70:
6634 case 700:
6635 case 710:
6636 case 720:
6637 case 7100:
6638 case 7500:
6639 break;
6640 default:
6641 goto bad;
6643 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6644 for (; *str; str++)
6646 switch (* str)
6648 case 't':
6649 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6650 break;
6652 case 'm':
6653 cpu_variant |= ARM_LONGMUL;
6654 break;
6656 case 'f': /* fe => fp enabled cpu. */
6657 if (str[1] == 'e')
6658 ++ str;
6659 else
6660 goto bad;
6662 case 'c': /* Left over from 710c processor name. */
6663 case 'd': /* Debug */
6664 case 'i': /* Embedded ICE */
6665 /* Included for completeness in ARM processor naming. */
6666 break;
6668 default:
6669 goto bad;
6672 break;
6674 case '8':
6675 if (streq (str, "8") || streq (str, "810"))
6676 cpu_variant = (cpu_variant & ~ARM_ANY)
6677 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6678 else
6679 goto bad;
6680 break;
6682 case '9':
6683 if (streq (str, "9"))
6684 cpu_variant = (cpu_variant & ~ARM_ANY)
6685 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6686 else if (streq (str, "920"))
6687 cpu_variant = (cpu_variant & ~ARM_ANY)
6688 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6689 else if (streq (str, "920t"))
6690 cpu_variant = (cpu_variant & ~ARM_ANY)
6691 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6692 else if (streq (str, "9tdmi"))
6693 cpu_variant = (cpu_variant & ~ARM_ANY)
6694 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6695 else
6696 goto bad;
6697 break;
6700 case 's':
6701 if (streq (str, "strongarm")
6702 || streq (str, "strongarm110")
6703 || streq (str, "strongarm1100"))
6704 cpu_variant = (cpu_variant & ~ARM_ANY)
6705 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6706 else
6707 goto bad;
6708 break;
6710 case 'v':
6711 /* Select variant based on architecture rather than processor. */
6712 switch (*++str)
6714 case '2':
6715 switch (*++str)
6717 case 'a':
6718 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6719 break;
6720 case 0:
6721 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6722 break;
6723 default:
6724 as_bad (_("Invalid architecture variant -m%s"), arg);
6725 break;
6727 break;
6729 case '3':
6730 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6732 switch (*++str)
6734 case 'm': cpu_variant |= ARM_LONGMUL; break;
6735 case 0: break;
6736 default:
6737 as_bad (_("Invalid architecture variant -m%s"), arg);
6738 break;
6740 break;
6742 case '4':
6743 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6745 switch (*++str)
6747 case 't': cpu_variant |= ARM_THUMB; break;
6748 case 0: break;
6749 default:
6750 as_bad (_("Invalid architecture variant -m%s"), arg);
6751 break;
6753 break;
6755 case '5':
6756 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6757 switch (*++str)
6759 case 't': cpu_variant |= ARM_THUMB; break;
6760 case 'e': cpu_variant |= ARM_EXT_V5E; break;
6761 case 0: break;
6762 default:
6763 as_bad (_("Invalid architecture variant -m%s"), arg);
6764 break;
6766 break;
6768 default:
6769 as_bad (_("Invalid architecture variant -m%s"), arg);
6770 break;
6772 break;
6774 default:
6775 bad:
6776 as_bad (_("Invalid processor variant -m%s"), arg);
6777 return 0;
6780 break;
6782 #if defined OBJ_ELF || defined OBJ_COFF
6783 case 'k':
6784 pic_code = 1;
6785 break;
6786 #endif
6788 default:
6789 return 0;
6792 return 1;
6795 void
6796 md_show_usage (fp)
6797 FILE * fp;
6799 fprintf (fp, _("\
6800 ARM Specific Assembler Options:\n\
6801 -m[arm][<processor name>] select processor variant\n\
6802 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6803 -mthumb only allow Thumb instructions\n\
6804 -mthumb-interwork mark the assembled code as supporting interworking\n\
6805 -mall allow any instruction\n\
6806 -mfpa10, -mfpa11 select floating point architecture\n\
6807 -mfpe-old don't allow floating-point multiple instructions\n\
6808 -mno-fpu don't allow any floating-point instructions.\n\
6809 -k generate PIC code.\n"));
6810 #if defined OBJ_COFF || defined OBJ_ELF
6811 fprintf (fp, _("\
6812 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6813 -mapcs-float floating point args are passed in FP regs\n\
6814 -mapcs-reentrant the code is position independent/reentrant\n"));
6815 #endif
6816 #ifdef OBJ_ELF
6817 fprintf (fp, _("\
6818 -moabi support the old ELF ABI\n"));
6819 #endif
6820 #ifdef ARM_BI_ENDIAN
6821 fprintf (fp, _("\
6822 -EB assemble code for a big endian cpu\n\
6823 -EL assemble code for a little endian cpu\n"));
6824 #endif
6827 /* We need to be able to fix up arbitrary expressions in some statements.
6828 This is so that we can handle symbols that are an arbitrary distance from
6829 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6830 which returns part of an address in a form which will be valid for
6831 a data instruction. We do this by pushing the expression into a symbol
6832 in the expr_section, and creating a fix for that. */
6834 static void
6835 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6836 fragS * frag;
6837 int where;
6838 short int size;
6839 expressionS * exp;
6840 int pc_rel;
6841 int reloc;
6843 fixS * new_fix;
6844 arm_fix_data * arm_data;
6846 switch (exp->X_op)
6848 case O_constant:
6849 case O_symbol:
6850 case O_add:
6851 case O_subtract:
6852 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6853 break;
6855 default:
6856 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6857 pc_rel, reloc);
6858 break;
6861 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6862 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6863 new_fix->tc_fix_data = (PTR) arm_data;
6864 arm_data->thumb_mode = thumb_mode;
6866 return;
6870 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6871 void
6872 cons_fix_new_arm (frag, where, size, exp)
6873 fragS * frag;
6874 int where;
6875 int size;
6876 expressionS * exp;
6878 bfd_reloc_code_real_type type;
6879 int pcrel = 0;
6881 /* Pick a reloc.
6882 FIXME: @@ Should look at CPU word size. */
6883 switch (size)
6885 case 1:
6886 type = BFD_RELOC_8;
6887 break;
6888 case 2:
6889 type = BFD_RELOC_16;
6890 break;
6891 case 4:
6892 default:
6893 type = BFD_RELOC_32;
6894 break;
6895 case 8:
6896 type = BFD_RELOC_64;
6897 break;
6900 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6903 /* A good place to do this, although this was probably not intended
6904 for this kind of use. We need to dump the literal pool before
6905 references are made to a null symbol pointer. */
6906 void
6907 arm_cleanup ()
6909 if (current_poolP == NULL)
6910 return;
6912 subseg_set (text_section, 0); /* Put it at the end of text section. */
6913 s_ltorg (0);
6914 listing_prev_line ();
6917 void
6918 arm_start_line_hook ()
6920 last_label_seen = NULL;
6923 void
6924 arm_frob_label (sym)
6925 symbolS * sym;
6927 last_label_seen = sym;
6929 ARM_SET_THUMB (sym, thumb_mode);
6931 #if defined OBJ_COFF || defined OBJ_ELF
6932 ARM_SET_INTERWORK (sym, support_interwork);
6933 #endif
6935 if (label_is_thumb_function_name)
6937 /* When the address of a Thumb function is taken the bottom
6938 bit of that address should be set. This will allow
6939 interworking between Arm and Thumb functions to work
6940 correctly. */
6942 THUMB_SET_FUNC (sym, 1);
6944 label_is_thumb_function_name = false;
6948 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6949 ARM ones. */
6951 void
6952 arm_adjust_symtab ()
6954 #ifdef OBJ_COFF
6955 symbolS * sym;
6957 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6959 if (ARM_IS_THUMB (sym))
6961 if (THUMB_IS_FUNC (sym))
6963 /* Mark the symbol as a Thumb function. */
6964 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6965 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6966 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6968 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6969 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6970 else
6971 as_bad (_("%s: unexpected function type: %d"),
6972 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6974 else switch (S_GET_STORAGE_CLASS (sym))
6976 case C_EXT:
6977 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6978 break;
6979 case C_STAT:
6980 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6981 break;
6982 case C_LABEL:
6983 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6984 break;
6985 default: /* do nothing */
6986 break;
6990 if (ARM_IS_INTERWORK (sym))
6991 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
6993 #endif
6994 #ifdef OBJ_ELF
6995 symbolS * sym;
6996 char bind;
6998 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
7000 if (ARM_IS_THUMB (sym))
7002 elf_symbol_type * elf_sym;
7004 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
7005 bind = ELF_ST_BIND (elf_sym);
7007 /* If it's a .thumb_func, declare it as so,
7008 otherwise tag label as .code 16. */
7009 if (THUMB_IS_FUNC (sym))
7010 elf_sym->internal_elf_sym.st_info =
7011 ELF_ST_INFO (bind, STT_ARM_TFUNC);
7012 else
7013 elf_sym->internal_elf_sym.st_info =
7014 ELF_ST_INFO (bind, STT_ARM_16BIT);
7017 #endif
7021 arm_data_in_code ()
7023 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
7025 *input_line_pointer = '/';
7026 input_line_pointer += 5;
7027 *input_line_pointer = 0;
7028 return 1;
7031 return 0;
7034 char *
7035 arm_canonicalize_symbol_name (name)
7036 char * name;
7038 int len;
7040 if (thumb_mode && (len = strlen (name)) > 5
7041 && streq (name + len - 5, "/data"))
7042 *(name + len - 5) = 0;
7044 return name;
7047 boolean
7048 arm_validate_fix (fixP)
7049 fixS * fixP;
7051 /* If the destination of the branch is a defined symbol which does not have
7052 the THUMB_FUNC attribute, then we must be calling a function which has
7053 the (interfacearm) attribute. We look for the Thumb entry point to that
7054 function and change the branch to refer to that function instead. */
7055 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
7056 && fixP->fx_addsy != NULL
7057 && S_IS_DEFINED (fixP->fx_addsy)
7058 && ! THUMB_IS_FUNC (fixP->fx_addsy))
7060 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
7061 return true;
7064 return false;
7067 #ifdef OBJ_ELF
7068 /* Relocations against Thumb function names must be left unadjusted,
7069 so that the linker can use this information to correctly set the
7070 bottom bit of their addresses. The MIPS version of this function
7071 also prevents relocations that are mips-16 specific, but I do not
7072 know why it does this.
7074 FIXME:
7075 There is one other problem that ought to be addressed here, but
7076 which currently is not: Taking the address of a label (rather
7077 than a function) and then later jumping to that address. Such
7078 addresses also ought to have their bottom bit set (assuming that
7079 they reside in Thumb code), but at the moment they will not. */
7081 boolean
7082 arm_fix_adjustable (fixP)
7083 fixS * fixP;
7085 if (fixP->fx_addsy == NULL)
7086 return 1;
7088 /* Prevent all adjustments to global symbols. */
7089 if (S_IS_EXTERN (fixP->fx_addsy))
7090 return 0;
7092 if (S_IS_WEAK (fixP->fx_addsy))
7093 return 0;
7095 if (THUMB_IS_FUNC (fixP->fx_addsy)
7096 && fixP->fx_subsy == NULL)
7097 return 0;
7099 /* We need the symbol name for the VTABLE entries */
7100 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7101 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7102 return 0;
7104 return 1;
7107 const char *
7108 elf32_arm_target_format ()
7110 if (target_big_endian)
7111 if (target_oabi)
7112 return "elf32-bigarm-oabi";
7113 else
7114 return "elf32-bigarm";
7115 else
7116 if (target_oabi)
7117 return "elf32-littlearm-oabi";
7118 else
7119 return "elf32-littlearm";
7122 void
7123 armelf_frob_symbol (symp, puntp)
7124 symbolS * symp;
7125 int * puntp;
7127 elf_frob_symbol (symp, puntp);
7131 arm_force_relocation (fixp)
7132 struct fix * fixp;
7134 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7135 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7136 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7137 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
7138 return 1;
7140 return 0;
7143 static bfd_reloc_code_real_type
7144 arm_parse_reloc ()
7146 char id[16];
7147 char * ip;
7148 unsigned int i;
7149 static struct
7151 char * str;
7152 int len;
7153 bfd_reloc_code_real_type reloc;
7155 reloc_map[] =
7157 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7158 MAP ("(got)", BFD_RELOC_ARM_GOT32),
7159 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7160 /* ScottB: Jan 30, 1998 */
7161 /* Added support for parsing "var(PLT)" branch instructions */
7162 /* generated by GCC for PLT relocs */
7163 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
7164 { NULL, 0, BFD_RELOC_UNUSED }
7165 #undef MAP
7168 for (i = 0, ip = input_line_pointer;
7169 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7170 i++, ip++)
7171 id[i] = tolower (*ip);
7173 for (i = 0; reloc_map[i].str; i++)
7174 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7175 break;
7177 input_line_pointer += reloc_map[i].len;
7179 return reloc_map[i].reloc;
7182 static void
7183 s_arm_elf_cons (nbytes)
7184 int nbytes;
7186 expressionS exp;
7188 #ifdef md_flush_pending_output
7189 md_flush_pending_output ();
7190 #endif
7192 if (is_it_end_of_statement ())
7194 demand_empty_rest_of_line ();
7195 return;
7198 #ifdef md_cons_align
7199 md_cons_align (nbytes);
7200 #endif
7204 bfd_reloc_code_real_type reloc;
7206 expression (& exp);
7208 if (exp.X_op == O_symbol
7209 && * input_line_pointer == '('
7210 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7212 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7213 int size = bfd_get_reloc_size (howto);
7215 if (size > nbytes)
7216 as_bad ("%s relocations do not fit in %d bytes",
7217 howto->name, nbytes);
7218 else
7220 register char * p = frag_more ((int) nbytes);
7221 int offset = nbytes - size;
7223 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7224 & exp, 0, reloc);
7227 else
7228 emit_expr (& exp, (unsigned int) nbytes);
7230 while (*input_line_pointer++ == ',');
7232 input_line_pointer--; /* Put terminator back into stream. */
7233 demand_empty_rest_of_line ();
7236 #endif /* OBJ_ELF */