1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
29 /* Need TARGET_CPU. */
40 /* Types of processor to assemble for. */
41 #define ARM_1 0x00000001
42 #define ARM_2 0x00000002
43 #define ARM_3 0x00000004
45 #define ARM_6 0x00000008
46 #define ARM_7 ARM_6 /* Same core instruction set. */
47 #define ARM_8 ARM_6 /* Same core instruction set. */
48 #define ARM_9 ARM_6 /* Same core instruction set. */
49 #define ARM_CPU_MASK 0x0000000f
51 /* The following bitmasks control CPU extensions (ARM7 onwards): */
52 #define ARM_LONGMUL 0x00000010 /* Allow long multiplies. */
53 #define ARM_HALFWORD 0x00000020 /* Allow half word loads. */
54 #define ARM_THUMB 0x00000040 /* Allow BX instruction. */
55 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
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
75 /* Some useful combinations. */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #define CPU_DEFAULT ARM_ALL
88 #define FPU_DEFAULT FPU_ALL
91 #define streq(a, b) (strcmp (a, b) == 0)
92 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
94 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
95 static int target_oabi
= 0;
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure. */
99 static boolean uses_apcs_26
= false;
100 static boolean support_interwork
= false;
101 static boolean uses_apcs_float
= false;
102 static boolean pic_code
= false;
105 /* This array holds the chars that always start a comment. If the
106 pre-processor is disabled, these aren't very useful. */
107 CONST
char comment_chars
[] = "@";
109 /* This array holds the chars that only start a comment at the beginning of
110 a line. If the line seems to have the form '# 123 filename'
111 .line and .file directives will appear in the pre-processed output. */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113 first line of the input file. This is because the compiler outputs
114 #NO_APP at the beginning of its output. */
115 /* Also note that comments like this one will always work. */
116 CONST
char line_comment_chars
[] = "#";
118 CONST
char line_separator_chars
[] = ";";
120 /* Chars that can be used to separate mant
121 from exp in floating point numbers. */
122 CONST
char EXP_CHARS
[] = "eE";
124 /* Chars that mean this number is a floating point constant. */
128 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
130 /* Prefix characters that indicate the start of an immediate
132 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
135 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
136 symbolS
* GOT_symbol
;
139 /* Size of relocation record. */
140 CONST
int md_reloc_size
= 8;
142 /* 0: assemble for ARM,
143 1: assemble for Thumb,
144 2: assemble for Thumb even though target CPU does not support thumb
146 static int thumb_mode
= 0;
148 typedef struct arm_fix
156 unsigned long instruction
;
161 bfd_reloc_code_real_type type
;
178 struct asm_shift_properties
180 enum asm_shift_index index
;
181 unsigned long bit_field
;
182 unsigned int allows_0
: 1;
183 unsigned int allows_32
: 1;
186 static const struct asm_shift_properties shift_properties
[] =
188 { SHIFT_LSL
, 0, 1, 0},
189 { SHIFT_LSR
, 0x20, 0, 1},
190 { SHIFT_ASR
, 0x40, 0, 1},
191 { SHIFT_ROR
, 0x60, 0, 0},
192 { SHIFT_RRX
, 0x60, 0, 0}
195 struct asm_shift_name
198 const struct asm_shift_properties
* properties
;
201 static const struct asm_shift_name shift_names
[] =
203 { "asl", shift_properties
+ SHIFT_LSL
},
204 { "lsl", shift_properties
+ SHIFT_LSL
},
205 { "lsr", shift_properties
+ SHIFT_LSR
},
206 { "asr", shift_properties
+ SHIFT_ASR
},
207 { "ror", shift_properties
+ SHIFT_ROR
},
208 { "rrx", shift_properties
+ SHIFT_RRX
},
209 { "ASL", shift_properties
+ SHIFT_LSL
},
210 { "LSL", shift_properties
+ SHIFT_LSL
},
211 { "LSR", shift_properties
+ SHIFT_LSR
},
212 { "ASR", shift_properties
+ SHIFT_ASR
},
213 { "ROR", shift_properties
+ SHIFT_ROR
},
214 { "RRX", shift_properties
+ SHIFT_RRX
}
217 #define NO_SHIFT_RESTRICT 1
218 #define SHIFT_RESTRICT 0
220 #define NUM_FLOAT_VALS 8
222 CONST
char * fp_const
[] =
224 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
227 /* Number of littlenums required to hold an extended precision number. */
228 #define MAX_LITTLENUMS 6
230 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
240 #define CP_T_X 0x00008000
241 #define CP_T_Y 0x00400000
242 #define CP_T_Pre 0x01000000
243 #define CP_T_UD 0x00800000
244 #define CP_T_WB 0x00200000
246 #define CONDS_BIT (0x00100000)
247 #define LOAD_BIT (0x00100000)
248 #define TRANS_BIT (0x00200000)
252 CONST
char * template;
256 /* This is to save a hash look-up in the common case. */
257 #define COND_ALWAYS 0xe0000000
259 static CONST
struct asm_cond conds
[] =
263 {"cs", 0x20000000}, {"hs", 0x20000000},
264 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
279 /* Warning: If the top bit of the set_bits is set, then the standard
280 instruction bitmask is ignored, and the new bitmask is taken from
284 CONST
char * template; /* Basic flag string. */
285 unsigned long set_bits
; /* Bits to set. */
288 static CONST
struct asm_flg s_flag
[] =
294 static CONST
struct asm_flg ldr_flags
[] =
298 {"bt", 0x00400000 | TRANS_BIT
},
305 static CONST
struct asm_flg str_flags
[] =
309 {"bt", 0x00400000 | TRANS_BIT
},
314 static CONST
struct asm_flg byte_flag
[] =
320 static CONST
struct asm_flg cmp_flags
[] =
327 static CONST
struct asm_flg ldm_flags
[] =
340 static CONST
struct asm_flg stm_flags
[] =
353 static CONST
struct asm_flg lfm_flags
[] =
360 static CONST
struct asm_flg sfm_flags
[] =
367 static CONST
struct asm_flg round_flags
[] =
375 /* The implementation of the FIX instruction is broken on some assemblers,
376 in that it accepts a precision specifier as well as a rounding specifier,
377 despite the fact that this is meaningless. To be more compatible, we
378 accept it as well, though of course it does not set any bits. */
379 static CONST
struct asm_flg fix_flags
[] =
396 static CONST
struct asm_flg except_flag
[] =
402 static CONST
struct asm_flg cplong_flag
[] =
410 CONST
char * template;
415 /* The bit that distnguishes CPSR and SPSR. */
416 #define SPSR_BIT (1 << 22)
418 /* How many bits to shift the PSR_xxx bits up by. */
421 #define PSR_c (1 << 0)
422 #define PSR_x (1 << 1)
423 #define PSR_s (1 << 2)
424 #define PSR_f (1 << 3)
426 static CONST
struct asm_psr psrs
[] =
428 {"CPSR", true, PSR_c
| PSR_f
},
429 {"CPSR_all", true, PSR_c
| PSR_f
},
430 {"SPSR", false, PSR_c
| PSR_f
},
431 {"SPSR_all", false, PSR_c
| PSR_f
},
432 {"CPSR_flg", true, PSR_f
},
433 {"CPSR_f", true, PSR_f
},
434 {"SPSR_flg", false, PSR_f
},
435 {"SPSR_f", false, PSR_f
},
436 {"CPSR_c", true, PSR_c
},
437 {"CPSR_ctl", true, PSR_c
},
438 {"SPSR_c", false, PSR_c
},
439 {"SPSR_ctl", false, PSR_c
},
440 {"CPSR_x", true, PSR_x
},
441 {"CPSR_s", true, PSR_s
},
442 {"SPSR_x", false, PSR_x
},
443 {"SPSR_s", false, PSR_s
},
444 /* Combinations of flags. */
445 {"CPSR_fs", true, PSR_f
| PSR_s
},
446 {"CPSR_fx", true, PSR_f
| PSR_x
},
447 {"CPSR_fc", true, PSR_f
| PSR_c
},
448 {"CPSR_sf", true, PSR_s
| PSR_f
},
449 {"CPSR_sx", true, PSR_s
| PSR_x
},
450 {"CPSR_sc", true, PSR_s
| PSR_c
},
451 {"CPSR_xf", true, PSR_x
| PSR_f
},
452 {"CPSR_xs", true, PSR_x
| PSR_s
},
453 {"CPSR_xc", true, PSR_x
| PSR_c
},
454 {"CPSR_cf", true, PSR_c
| PSR_f
},
455 {"CPSR_cs", true, PSR_c
| PSR_s
},
456 {"CPSR_cx", true, PSR_c
| PSR_x
},
457 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
458 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
459 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
460 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
461 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
462 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
463 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
464 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
465 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
466 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
467 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
468 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
469 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
470 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
471 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
472 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
473 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
474 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
475 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
476 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
477 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
478 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
479 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
480 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
481 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
482 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
483 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
484 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
485 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
486 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
487 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
488 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
489 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
490 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
491 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
492 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
493 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
494 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
495 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
496 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
497 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
498 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
499 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
500 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
501 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
502 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
503 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
504 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
505 {"SPSR_fs", false, PSR_f
| PSR_s
},
506 {"SPSR_fx", false, PSR_f
| PSR_x
},
507 {"SPSR_fc", false, PSR_f
| PSR_c
},
508 {"SPSR_sf", false, PSR_s
| PSR_f
},
509 {"SPSR_sx", false, PSR_s
| PSR_x
},
510 {"SPSR_sc", false, PSR_s
| PSR_c
},
511 {"SPSR_xf", false, PSR_x
| PSR_f
},
512 {"SPSR_xs", false, PSR_x
| PSR_s
},
513 {"SPSR_xc", false, PSR_x
| PSR_c
},
514 {"SPSR_cf", false, PSR_c
| PSR_f
},
515 {"SPSR_cs", false, PSR_c
| PSR_s
},
516 {"SPSR_cx", false, PSR_c
| PSR_x
},
517 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
518 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
519 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
520 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
521 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
522 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
523 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
524 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
525 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
526 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
527 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
528 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
529 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
530 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
531 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
532 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
533 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
534 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
535 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
536 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
537 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
538 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
539 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
540 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
541 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
542 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
543 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
544 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
545 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
546 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
547 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
548 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
549 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
550 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
551 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
552 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
553 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
554 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
555 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
556 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
557 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
558 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
559 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
560 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
561 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
562 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
563 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
564 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
565 /* For backwards compatability with older toolchain we also
566 support lower case versions of some of these flags. */
567 {"cpsr", true, PSR_c
| PSR_f
},
568 {"cpsr_all", true, PSR_c
| PSR_f
},
569 {"spsr", false, PSR_c
| PSR_f
},
570 {"spsr_all", false, PSR_c
| PSR_f
},
571 {"cpsr_flg", true, PSR_f
},
572 {"cpsr_f", true, PSR_f
},
573 {"spsr_flg", false, PSR_f
},
574 {"spsr_f", false, PSR_f
},
575 {"cpsr_c", true, PSR_c
},
576 {"cpsr_ctl", true, PSR_c
},
577 {"spsr_c", false, PSR_c
},
578 {"spsr_ctl", false, PSR_c
}
581 /* Functions called by parser. */
582 /* ARM instructions. */
583 static void do_arit
PARAMS ((char *, unsigned long));
584 static void do_cmp
PARAMS ((char *, unsigned long));
585 static void do_mov
PARAMS ((char *, unsigned long));
586 static void do_ldst
PARAMS ((char *, unsigned long));
587 static void do_ldmstm
PARAMS ((char *, unsigned long));
588 static void do_branch
PARAMS ((char *, unsigned long));
589 static void do_swi
PARAMS ((char *, unsigned long));
590 /* Pseudo Op codes. */
591 static void do_adr
PARAMS ((char *, unsigned long));
592 static void do_adrl
PARAMS ((char *, unsigned long));
593 static void do_nop
PARAMS ((char *, unsigned long));
595 static void do_mul
PARAMS ((char *, unsigned long));
596 static void do_mla
PARAMS ((char *, unsigned long));
598 static void do_swap
PARAMS ((char *, unsigned long));
600 static void do_msr
PARAMS ((char *, unsigned long));
601 static void do_mrs
PARAMS ((char *, unsigned long));
603 static void do_mull
PARAMS ((char *, unsigned long));
605 static void do_bx
PARAMS ((char *, unsigned long));
607 /* Coprocessor Instructions. */
608 static void do_cdp
PARAMS ((char *, unsigned long));
609 static void do_lstc
PARAMS ((char *, unsigned long));
610 static void do_co_reg
PARAMS ((char *, unsigned long));
611 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
612 static void do_fp_ldst
PARAMS ((char *, unsigned long));
613 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
614 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
615 static void do_fp_monadic
PARAMS ((char *, unsigned long));
616 static void do_fp_cmp
PARAMS ((char *, unsigned long));
617 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
618 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
620 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
621 static int arm_reg_parse
PARAMS ((char **));
622 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
623 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
624 static int add_to_lit_pool
PARAMS ((void));
625 static unsigned validate_immediate
PARAMS ((unsigned));
626 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
627 static int validate_offset_imm
PARAMS ((unsigned int, int));
628 static void opcode_select
PARAMS ((int));
629 static void end_of_line
PARAMS ((char *));
630 static int reg_required_here
PARAMS ((char **, int));
631 static int psr_required_here
PARAMS ((char **));
632 static int co_proc_number
PARAMS ((char **));
633 static int cp_opc_expr
PARAMS ((char **, int, int));
634 static int cp_reg_required_here
PARAMS ((char **, int));
635 static int fp_reg_required_here
PARAMS ((char **, int));
636 static int cp_address_offset
PARAMS ((char **));
637 static int cp_address_required_here
PARAMS ((char **));
638 static int my_get_float_expression
PARAMS ((char **));
639 static int skip_past_comma
PARAMS ((char **));
640 static int walk_no_bignums
PARAMS ((symbolS
*));
641 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
642 static int data_op2
PARAMS ((char **));
643 static int fp_op2
PARAMS ((char **));
644 static long reg_list
PARAMS ((char **));
645 static void thumb_load_store
PARAMS ((char *, int, int));
646 static int decode_shift
PARAMS ((char **, int));
647 static int ldst_extend
PARAMS ((char **, int));
648 static void thumb_add_sub
PARAMS ((char *, int));
649 static void insert_reg
PARAMS ((int));
650 static void thumb_shift
PARAMS ((char *, int));
651 static void thumb_mov_compare
PARAMS ((char *, int));
652 static void set_constant_flonums
PARAMS ((void));
653 static valueT md_chars_to_number
PARAMS ((char *, int));
654 static void insert_reg_alias
PARAMS ((char *, int));
655 static void output_inst
PARAMS ((void));
657 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
660 /* ARM instructions take 4bytes in the object file, Thumb instructions
664 /* LONGEST_INST is the longest basic instruction name without conditions or
665 flags. ARM7M has 4 of length 5. */
667 #define LONGEST_INST 5
671 /* Basic string to match. */
672 CONST
char * template;
674 /* Basic instruction code. */
677 /* Compulsory suffix that must follow conds. If "", then the
678 instruction is not conditional and must have no suffix. */
679 CONST
char * comp_suffix
;
681 /* Bits to toggle if flag 'n' set. */
682 CONST
struct asm_flg
* flags
;
684 /* Which CPU variants this exists for. */
685 unsigned long variants
;
687 /* Function to call to parse args. */
688 void (* parms
) PARAMS ((char *, unsigned long));
691 static CONST
struct asm_opcode insns
[] =
693 /* ARM Instructions. */
694 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
695 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
696 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
697 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
698 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
699 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
700 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
701 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
702 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
703 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
704 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
705 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
706 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
707 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
708 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
709 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
710 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
711 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
712 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
713 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
714 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
716 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
717 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
719 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
720 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
724 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
725 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
726 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
728 /* ARM 2 multiplies. */
729 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
730 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
732 /* ARM 3 - swp instructions. */
733 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
735 /* ARM 6 Coprocessor instructions. */
736 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
737 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
738 /* ScottB: our code uses 0x0128f000 for msr.
739 NickC: but this is wrong because the bits 16 through 19 are
740 handled by the PSR_xxx defines above. */
742 /* ARM 7M long multiplies - need signed/unsigned flags! */
743 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
744 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
745 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
746 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
748 /* ARM THUMB interworking. */
749 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
751 /* Floating point instructions. */
752 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
753 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
754 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
755 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
756 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
757 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
758 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
759 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
760 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
761 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
762 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
763 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
764 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
765 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
766 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
767 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
768 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
769 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
770 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
771 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
772 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
773 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
774 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
775 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
776 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
777 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
778 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
779 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
780 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
781 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
782 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
783 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
784 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
785 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
786 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
787 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
788 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
789 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
790 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
791 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
792 be an optional suffix, but part of the instruction. To be compatible,
794 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
795 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
796 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
797 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
799 /* Generic copressor instructions. */
800 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
801 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
802 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
803 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
804 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
807 /* Defines for various bits that we will want to toggle. */
808 #define INST_IMMEDIATE 0x02000000
809 #define OFFSET_REG 0x02000000
810 #define HWOFFSET_IMM 0x00400000
811 #define SHIFT_BY_REG 0x00000010
812 #define PRE_INDEX 0x01000000
813 #define INDEX_UP 0x00800000
814 #define WRITE_BACK 0x00200000
815 #define LDM_TYPE_2_OR_3 0x00400000
817 #define LITERAL_MASK 0xf000f000
818 #define COND_MASK 0xf0000000
819 #define OPCODE_MASK 0xfe1fffff
820 #define DATA_OP_SHIFT 21
822 /* Codes to distinguish the arithmetic instructions. */
833 #define OPCODE_CMP 10
834 #define OPCODE_CMN 11
835 #define OPCODE_ORR 12
836 #define OPCODE_MOV 13
837 #define OPCODE_BIC 14
838 #define OPCODE_MVN 15
840 static void do_t_nop
PARAMS ((char *));
841 static void do_t_arit
PARAMS ((char *));
842 static void do_t_add
PARAMS ((char *));
843 static void do_t_asr
PARAMS ((char *));
844 static void do_t_branch9
PARAMS ((char *));
845 static void do_t_branch12
PARAMS ((char *));
846 static void do_t_branch23
PARAMS ((char *));
847 static void do_t_bx
PARAMS ((char *));
848 static void do_t_compare
PARAMS ((char *));
849 static void do_t_ldmstm
PARAMS ((char *));
850 static void do_t_ldr
PARAMS ((char *));
851 static void do_t_ldrb
PARAMS ((char *));
852 static void do_t_ldrh
PARAMS ((char *));
853 static void do_t_lds
PARAMS ((char *));
854 static void do_t_lsl
PARAMS ((char *));
855 static void do_t_lsr
PARAMS ((char *));
856 static void do_t_mov
PARAMS ((char *));
857 static void do_t_push_pop
PARAMS ((char *));
858 static void do_t_str
PARAMS ((char *));
859 static void do_t_strb
PARAMS ((char *));
860 static void do_t_strh
PARAMS ((char *));
861 static void do_t_sub
PARAMS ((char *));
862 static void do_t_swi
PARAMS ((char *));
863 static void do_t_adr
PARAMS ((char *));
865 #define T_OPCODE_MUL 0x4340
866 #define T_OPCODE_TST 0x4200
867 #define T_OPCODE_CMN 0x42c0
868 #define T_OPCODE_NEG 0x4240
869 #define T_OPCODE_MVN 0x43c0
871 #define T_OPCODE_ADD_R3 0x1800
872 #define T_OPCODE_SUB_R3 0x1a00
873 #define T_OPCODE_ADD_HI 0x4400
874 #define T_OPCODE_ADD_ST 0xb000
875 #define T_OPCODE_SUB_ST 0xb080
876 #define T_OPCODE_ADD_SP 0xa800
877 #define T_OPCODE_ADD_PC 0xa000
878 #define T_OPCODE_ADD_I8 0x3000
879 #define T_OPCODE_SUB_I8 0x3800
880 #define T_OPCODE_ADD_I3 0x1c00
881 #define T_OPCODE_SUB_I3 0x1e00
883 #define T_OPCODE_ASR_R 0x4100
884 #define T_OPCODE_LSL_R 0x4080
885 #define T_OPCODE_LSR_R 0x40c0
886 #define T_OPCODE_ASR_I 0x1000
887 #define T_OPCODE_LSL_I 0x0000
888 #define T_OPCODE_LSR_I 0x0800
890 #define T_OPCODE_MOV_I8 0x2000
891 #define T_OPCODE_CMP_I8 0x2800
892 #define T_OPCODE_CMP_LR 0x4280
893 #define T_OPCODE_MOV_HR 0x4600
894 #define T_OPCODE_CMP_HR 0x4500
896 #define T_OPCODE_LDR_PC 0x4800
897 #define T_OPCODE_LDR_SP 0x9800
898 #define T_OPCODE_STR_SP 0x9000
899 #define T_OPCODE_LDR_IW 0x6800
900 #define T_OPCODE_STR_IW 0x6000
901 #define T_OPCODE_LDR_IH 0x8800
902 #define T_OPCODE_STR_IH 0x8000
903 #define T_OPCODE_LDR_IB 0x7800
904 #define T_OPCODE_STR_IB 0x7000
905 #define T_OPCODE_LDR_RW 0x5800
906 #define T_OPCODE_STR_RW 0x5000
907 #define T_OPCODE_LDR_RH 0x5a00
908 #define T_OPCODE_STR_RH 0x5200
909 #define T_OPCODE_LDR_RB 0x5c00
910 #define T_OPCODE_STR_RB 0x5400
912 #define T_OPCODE_PUSH 0xb400
913 #define T_OPCODE_POP 0xbc00
915 #define T_OPCODE_BRANCH 0xe7fe
917 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
919 #define THUMB_SIZE 2 /* Size of thumb instruction. */
920 #define THUMB_REG_LO 0x1
921 #define THUMB_REG_HI 0x2
922 #define THUMB_REG_ANY 0x3
924 #define THUMB_H1 0x0080
925 #define THUMB_H2 0x0040
932 #define THUMB_COMPARE 1
935 #define THUMB_STORE 1
937 #define THUMB_PP_PC_LR 0x0100
939 /* These three are used for immediate shifts, do not alter. */
941 #define THUMB_HALFWORD 1
946 /* Basic string to match. */
947 CONST
char * template;
949 /* Basic instruction code. */
954 /* Which CPU variants this exists for. */
955 unsigned long variants
;
957 /* Function to call to parse args. */
958 void (* parms
) PARAMS ((char *));
961 static CONST
struct thumb_opcode tinsns
[] =
963 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
964 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
965 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
966 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
967 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
968 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
969 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
970 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
971 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
972 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
973 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
974 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
975 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
976 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
977 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
978 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
979 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
980 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
981 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
982 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
983 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
984 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
985 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
986 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
987 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
988 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
989 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
990 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
991 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
992 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
993 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
994 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
995 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
996 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
997 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
998 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
999 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
1000 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
1001 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
1002 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
1003 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
1004 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
1005 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
1006 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
1007 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
1008 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
1009 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
1010 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
1011 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
1012 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
1013 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
1014 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
1015 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
1016 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
1017 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
1019 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
1020 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
1029 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1030 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1031 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1037 /* These are the standard names. Users can add aliases with .req. */
1038 static CONST
struct reg_entry reg_table
[] =
1040 /* Processor Register Numbers. */
1041 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1042 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1043 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1044 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1045 /* APCS conventions. */
1046 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1047 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1048 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1049 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1050 /* ATPCS additions to APCS conventions. */
1051 {"wr", 7}, {"v8", 11},
1053 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1054 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1055 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1056 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1057 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1058 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1059 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1060 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1061 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1062 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1063 /* ATPCS additions to float register names. */
1064 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1065 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1066 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1067 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1068 /* FIXME: At some point we need to add VFP register names. */
1069 /* Array terminator. */
1073 #define BAD_ARGS _("Bad arguments to instruction")
1074 #define BAD_PC _("r15 not allowed here")
1075 #define BAD_FLAGS _("Instruction should not have flags")
1076 #define BAD_COND _("Instruction is not conditional")
1078 static struct hash_control
* arm_ops_hsh
= NULL
;
1079 static struct hash_control
* arm_tops_hsh
= NULL
;
1080 static struct hash_control
* arm_cond_hsh
= NULL
;
1081 static struct hash_control
* arm_shift_hsh
= NULL
;
1082 static struct hash_control
* arm_reg_hsh
= NULL
;
1083 static struct hash_control
* arm_psr_hsh
= NULL
;
1085 /* This table describes all the machine specific pseudo-ops the assembler
1086 has to support. The fields are:
1087 pseudo-op name without dot
1088 function to call to execute this pseudo-op
1089 Integer arg to pass to the function. */
1091 static void s_req
PARAMS ((int));
1092 static void s_align
PARAMS ((int));
1093 static void s_bss
PARAMS ((int));
1094 static void s_even
PARAMS ((int));
1095 static void s_ltorg
PARAMS ((int));
1096 static void s_arm
PARAMS ((int));
1097 static void s_thumb
PARAMS ((int));
1098 static void s_code
PARAMS ((int));
1099 static void s_force_thumb
PARAMS ((int));
1100 static void s_thumb_func
PARAMS ((int));
1101 static void s_thumb_set
PARAMS ((int));
1102 static void arm_s_text
PARAMS ((int));
1103 static void arm_s_data
PARAMS ((int));
1105 static void arm_s_section
PARAMS ((int));
1106 static void s_arm_elf_cons
PARAMS ((int));
1109 static int my_get_expression
PARAMS ((expressionS
*, char **));
1111 CONST pseudo_typeS md_pseudo_table
[] =
1113 /* Never called becasue '.req' does not start line. */
1114 { "req", s_req
, 0 },
1115 { "bss", s_bss
, 0 },
1116 { "align", s_align
, 0 },
1117 { "arm", s_arm
, 0 },
1118 { "thumb", s_thumb
, 0 },
1119 { "code", s_code
, 0 },
1120 { "force_thumb", s_force_thumb
, 0 },
1121 { "thumb_func", s_thumb_func
, 0 },
1122 { "thumb_set", s_thumb_set
, 0 },
1123 { "even", s_even
, 0 },
1124 { "ltorg", s_ltorg
, 0 },
1125 { "pool", s_ltorg
, 0 },
1126 /* Allow for the effect of section changes. */
1127 { "text", arm_s_text
, 0 },
1128 { "data", arm_s_data
, 0 },
1130 { "section", arm_s_section
, 0 },
1131 { "section.s", arm_s_section
, 0 },
1132 { "sect", arm_s_section
, 0 },
1133 { "sect.s", arm_s_section
, 0 },
1134 { "word", s_arm_elf_cons
, 4 },
1135 { "long", s_arm_elf_cons
, 4 },
1139 { "extend", float_cons
, 'x' },
1140 { "ldouble", float_cons
, 'x' },
1141 { "packed", float_cons
, 'p' },
1145 /* Stuff needed to resolve the label ambiguity
1155 symbolS
* last_label_seen
;
1156 static int label_is_thumb_function_name
= false;
1158 /* Literal stuff. */
1160 #define MAX_LITERAL_POOL_SIZE 1024
1162 typedef struct literalS
1164 struct expressionS exp
;
1165 struct arm_it
* inst
;
1168 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1170 /* Next free entry in the pool. */
1171 int next_literal_pool_place
= 0;
1173 /* Next literal pool number. */
1174 int lit_pool_num
= 1;
1176 symbolS
* current_poolP
= NULL
;
1183 if (current_poolP
== NULL
)
1184 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1185 (valueT
) 0, &zero_address_frag
);
1187 /* Check if this literal value is already in the pool: */
1188 while (lit_count
< next_literal_pool_place
)
1190 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1191 && inst
.reloc
.exp
.X_op
== O_constant
1192 && (literals
[lit_count
].exp
.X_add_number
1193 == inst
.reloc
.exp
.X_add_number
)
1194 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1199 if (lit_count
== next_literal_pool_place
) /* New entry. */
1201 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1203 inst
.error
= _("Literal Pool Overflow");
1207 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1208 lit_count
= next_literal_pool_place
++;
1211 inst
.reloc
.exp
.X_op
= O_symbol
;
1212 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1213 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1218 /* Can't use symbol_new here, so have to create a symbol and then at
1219 a later date assign it a value. Thats what these functions do. */
1222 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1224 CONST
char * name
; /* It is copied, the caller can modify. */
1225 segT segment
; /* Segment identifier (SEG_<something>). */
1226 valueT valu
; /* Symbol value. */
1227 fragS
* frag
; /* Associated fragment. */
1229 unsigned int name_length
;
1230 char * preserved_copy_of_name
;
1232 name_length
= strlen (name
) + 1; /* +1 for \0. */
1233 obstack_grow (¬es
, name
, name_length
);
1234 preserved_copy_of_name
= obstack_finish (¬es
);
1235 #ifdef STRIP_UNDERSCORE
1236 if (preserved_copy_of_name
[0] == '_')
1237 preserved_copy_of_name
++;
1240 #ifdef tc_canonicalize_symbol_name
1241 preserved_copy_of_name
=
1242 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1245 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1247 S_SET_SEGMENT (symbolP
, segment
);
1248 S_SET_VALUE (symbolP
, valu
);
1249 symbol_clear_list_pointers(symbolP
);
1251 symbol_set_frag (symbolP
, frag
);
1253 /* Link to end of symbol chain. */
1255 extern int symbol_table_frozen
;
1256 if (symbol_table_frozen
)
1260 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1262 obj_symbol_new_hook (symbolP
);
1264 #ifdef tc_symbol_new_hook
1265 tc_symbol_new_hook (symbolP
);
1269 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1270 #endif /* DEBUG_SYMS */
1273 /* Check that an immediate is valid.
1274 If so, convert it to the right format. */
1277 validate_immediate (val
)
1283 #define rotate_left(v, n) (v << n | v >> (32 - n))
1285 for (i
= 0; i
< 32; i
+= 2)
1286 if ((a
= rotate_left (val
, i
)) <= 0xff)
1287 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1292 /* Check to see if an immediate can be computed as two seperate immediate
1293 values, added together. We already know that this value cannot be
1294 computed by just one ARM instruction. */
1297 validate_immediate_twopart (val
, highpart
)
1299 unsigned int * highpart
;
1304 for (i
= 0; i
< 32; i
+= 2)
1305 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1311 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1313 else if (a
& 0xff0000)
1317 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1321 assert (a
& 0xff000000);
1322 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1325 return (a
& 0xff) | (i
<< 7);
1332 validate_offset_imm (val
, hwse
)
1336 if ((hwse
&& val
> 255) || val
> 4095)
1343 int a ATTRIBUTE_UNUSED
;
1345 as_bad (_("Invalid syntax for .req directive."));
1350 int ignore ATTRIBUTE_UNUSED
;
1352 /* We don't support putting frags in the BSS segment, we fake it by
1353 marking in_bss, then looking at s_skip for clues. */
1354 subseg_set (bss_section
, 0);
1355 demand_empty_rest_of_line ();
1360 int ignore ATTRIBUTE_UNUSED
;
1362 /* Never make frag if expect extra pass. */
1364 frag_align (1, 0, 0);
1366 record_alignment (now_seg
, 1);
1368 demand_empty_rest_of_line ();
1373 int ignored ATTRIBUTE_UNUSED
;
1378 if (current_poolP
== NULL
)
1381 /* Align pool as you have word accesses.
1382 Only make a frag if we have to. */
1384 frag_align (2, 0, 0);
1386 record_alignment (now_seg
, 2);
1388 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1390 symbol_locate (current_poolP
, sym_name
, now_seg
,
1391 (valueT
) frag_now_fix (), frag_now
);
1392 symbol_table_insert (current_poolP
);
1394 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1396 #if defined OBJ_COFF || defined OBJ_ELF
1397 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1400 while (lit_count
< next_literal_pool_place
)
1401 /* First output the expression in the instruction to the pool. */
1402 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1404 next_literal_pool_place
= 0;
1405 current_poolP
= NULL
;
1408 /* Same as s_align_ptwo but align 0 => align 2. */
1412 int unused ATTRIBUTE_UNUSED
;
1415 register long temp_fill
;
1416 long max_alignment
= 15;
1418 temp
= get_absolute_expression ();
1419 if (temp
> max_alignment
)
1420 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1423 as_bad (_("Alignment negative. 0 assumed."));
1427 if (*input_line_pointer
== ',')
1429 input_line_pointer
++;
1430 temp_fill
= get_absolute_expression ();
1438 /* Only make a frag if we HAVE to. */
1439 if (temp
&& !need_pass_2
)
1440 frag_align (temp
, (int) temp_fill
, 0);
1441 demand_empty_rest_of_line ();
1443 record_alignment (now_seg
, temp
);
1447 s_force_thumb (ignore
)
1448 int ignore ATTRIBUTE_UNUSED
;
1450 /* If we are not already in thumb mode go into it, EVEN if
1451 the target processor does not support thumb instructions.
1452 This is used by gcc/config/arm/lib1funcs.asm for example
1453 to compile interworking support functions even if the
1454 target processor should not support interworking. */
1459 record_alignment (now_seg
, 1);
1462 demand_empty_rest_of_line ();
1466 s_thumb_func (ignore
)
1467 int ignore ATTRIBUTE_UNUSED
;
1472 /* The following label is the name/address of the start of a Thumb function.
1473 We need to know this for the interworking support. */
1474 label_is_thumb_function_name
= true;
1476 demand_empty_rest_of_line ();
1479 /* Perform a .set directive, but also mark the alias as
1480 being a thumb function. */
1486 /* XXX the following is a duplicate of the code for s_set() in read.c
1487 We cannot just call that code as we need to get at the symbol that
1489 register char * name
;
1490 register char delim
;
1491 register char * end_name
;
1492 register symbolS
* symbolP
;
1494 /* Especial apologies for the random logic:
1495 This just grew, and could be parsed much more simply!
1497 name
= input_line_pointer
;
1498 delim
= get_symbol_end ();
1499 end_name
= input_line_pointer
;
1504 if (*input_line_pointer
!= ',')
1507 as_bad (_("Expected comma after name \"%s\""), name
);
1509 ignore_rest_of_line ();
1513 input_line_pointer
++;
1516 if (name
[0] == '.' && name
[1] == '\0')
1518 /* XXX - this should not happen to .thumb_set. */
1522 if ((symbolP
= symbol_find (name
)) == NULL
1523 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1526 /* When doing symbol listings, play games with dummy fragments living
1527 outside the normal fragment chain to record the file and line info
1529 if (listing
& LISTING_SYMBOLS
)
1531 extern struct list_info_struct
* listing_tail
;
1532 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1534 memset (dummy_frag
, 0, sizeof (fragS
));
1535 dummy_frag
->fr_type
= rs_fill
;
1536 dummy_frag
->line
= listing_tail
;
1537 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1538 dummy_frag
->fr_symbol
= symbolP
;
1542 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1545 /* "set" symbols are local unless otherwise specified. */
1546 SF_SET_LOCAL (symbolP
);
1547 #endif /* OBJ_COFF */
1548 } /* Make a new symbol. */
1550 symbol_table_insert (symbolP
);
1555 && S_IS_DEFINED (symbolP
)
1556 && S_GET_SEGMENT (symbolP
) != reg_section
)
1557 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1559 pseudo_set (symbolP
);
1561 demand_empty_rest_of_line ();
1563 /* XXX Now we come to the Thumb specific bit of code. */
1565 THUMB_SET_FUNC (symbolP
, 1);
1566 ARM_SET_THUMB (symbolP
, 1);
1567 #if defined OBJ_ELF || defined OBJ_COFF
1568 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1572 /* If we change section we must dump the literal pool first. */
1578 if (now_seg
!= text_section
)
1582 obj_elf_text (ignore
);
1592 if (flag_readonly_data_in_text
)
1594 if (now_seg
!= text_section
)
1597 else if (now_seg
!= data_section
)
1601 obj_elf_data (ignore
);
1609 arm_s_section (ignore
)
1614 obj_elf_section (ignore
);
1619 opcode_select (width
)
1627 if (! (cpu_variant
& ARM_THUMB
))
1628 as_bad (_("selected processor does not support THUMB opcodes"));
1631 /* No need to force the alignment, since we will have been
1632 coming from ARM mode, which is word-aligned. */
1633 record_alignment (now_seg
, 1);
1640 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1641 as_bad (_("selected processor does not support ARM opcodes"));
1646 frag_align (2, 0, 0);
1648 record_alignment (now_seg
, 1);
1653 as_bad (_("invalid instruction size selected (%d)"), width
);
1659 int ignore ATTRIBUTE_UNUSED
;
1662 demand_empty_rest_of_line ();
1667 int ignore ATTRIBUTE_UNUSED
;
1670 demand_empty_rest_of_line ();
1675 int unused ATTRIBUTE_UNUSED
;
1679 temp
= get_absolute_expression ();
1684 opcode_select (temp
);
1688 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1696 skip_whitespace (str
);
1699 inst
.error
= _("Garbage following instruction");
1703 skip_past_comma (str
)
1706 char * p
= * str
, c
;
1709 while ((c
= *p
) == ' ' || c
== ',')
1712 if (c
== ',' && comma
++)
1720 return comma
? SUCCESS
: FAIL
;
1723 /* A standard register must be given at this point.
1724 SHIFT is the place to put it in inst.instruction.
1725 Restores input start point on error.
1726 Returns the reg#, or FAIL. */
1729 reg_required_here (str
, shift
)
1733 static char buff
[128]; /* XXX */
1735 char * start
= * str
;
1737 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1740 inst
.instruction
|= reg
<< shift
;
1744 /* Restore the start point, we may have got a reg of the wrong class. */
1747 /* In the few cases where we might be able to accept something else
1748 this error can be overridden. */
1749 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1755 static CONST
struct asm_psr
*
1757 register char ** ccp
;
1759 char * start
= * ccp
;
1762 CONST
struct asm_psr
* psr
;
1766 /* Skip to the end of the next word in the input stream. */
1771 while (isalpha (c
) || c
== '_');
1773 /* Terminate the word. */
1776 /* Now locate the word in the psr hash table. */
1777 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1779 /* Restore the input stream. */
1782 /* If we found a valid match, advance the
1783 stream pointer past the end of the word. */
1789 /* Parse the input looking for a PSR flag. */
1792 psr_required_here (str
)
1795 char * start
= * str
;
1796 CONST
struct asm_psr
* psr
;
1798 psr
= arm_psr_parse (str
);
1802 /* If this is the SPSR that is being modified, set the R bit. */
1804 inst
.instruction
|= SPSR_BIT
;
1806 /* Set the psr flags in the MSR instruction. */
1807 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1812 /* In the few cases where we might be able to accept
1813 something else this error can be overridden. */
1814 inst
.error
= _("flag for {c}psr instruction expected");
1816 /* Restore the start point. */
1822 co_proc_number (str
)
1825 int processor
, pchar
;
1827 skip_whitespace (* str
);
1829 /* The data sheet seems to imply that just a number on its own is valid
1830 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1832 if (**str
== 'p' || **str
== 'P')
1836 if (pchar
>= '0' && pchar
<= '9')
1838 processor
= pchar
- '0';
1839 if (**str
>= '0' && **str
<= '9')
1841 processor
= processor
* 10 + *(*str
)++ - '0';
1844 inst
.error
= _("Illegal co-processor number");
1851 inst
.error
= _("Bad or missing co-processor number");
1855 inst
.instruction
|= processor
<< 8;
1860 cp_opc_expr (str
, where
, length
)
1867 skip_whitespace (* str
);
1869 memset (&expr
, '\0', sizeof (expr
));
1871 if (my_get_expression (&expr
, str
))
1873 if (expr
.X_op
!= O_constant
)
1875 inst
.error
= _("bad or missing expression");
1879 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1881 inst
.error
= _("immediate co-processor expression too large");
1885 inst
.instruction
|= expr
.X_add_number
<< where
;
1890 cp_reg_required_here (str
, where
)
1895 char * start
= *str
;
1897 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1900 inst
.instruction
|= reg
<< where
;
1904 /* In the few cases where we might be able to accept something else
1905 this error can be overridden. */
1906 inst
.error
= _("Co-processor register expected");
1908 /* Restore the start point. */
1914 fp_reg_required_here (str
, where
)
1919 char * start
= * str
;
1921 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1924 inst
.instruction
|= reg
<< where
;
1928 /* In the few cases where we might be able to accept something else
1929 this error can be overridden. */
1930 inst
.error
= _("Floating point register expected");
1932 /* Restore the start point. */
1938 cp_address_offset (str
)
1943 skip_whitespace (* str
);
1945 if (! is_immediate_prefix (**str
))
1947 inst
.error
= _("immediate expression expected");
1953 if (my_get_expression (& inst
.reloc
.exp
, str
))
1956 if (inst
.reloc
.exp
.X_op
== O_constant
)
1958 offset
= inst
.reloc
.exp
.X_add_number
;
1962 inst
.error
= _("co-processor address must be word aligned");
1966 if (offset
> 1023 || offset
< -1023)
1968 inst
.error
= _("offset too large");
1973 inst
.instruction
|= INDEX_UP
;
1977 inst
.instruction
|= offset
>> 2;
1980 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1986 cp_address_required_here (str
)
1998 skip_whitespace (p
);
2000 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2003 skip_whitespace (p
);
2009 if (skip_past_comma (& p
) == SUCCESS
)
2012 write_back
= WRITE_BACK
;
2016 inst
.error
= _("pc may not be used in post-increment");
2020 if (cp_address_offset (& p
) == FAIL
)
2024 pre_inc
= PRE_INDEX
| INDEX_UP
;
2028 /* '['Rn, #expr']'[!] */
2030 if (skip_past_comma (& p
) == FAIL
)
2032 inst
.error
= _("pre-indexed expression expected");
2036 pre_inc
= PRE_INDEX
;
2038 if (cp_address_offset (& p
) == FAIL
)
2041 skip_whitespace (p
);
2045 inst
.error
= _("missing ]");
2049 skip_whitespace (p
);
2055 inst
.error
= _("pc may not be used with write-back");
2060 write_back
= WRITE_BACK
;
2066 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2069 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2070 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2071 inst
.reloc
.pc_rel
= 1;
2072 inst
.instruction
|= (REG_PC
<< 16);
2073 pre_inc
= PRE_INDEX
;
2076 inst
.instruction
|= write_back
| pre_inc
;
2084 unsigned long flags
;
2086 /* Do nothing really. */
2087 inst
.instruction
|= flags
; /* This is pointless. */
2095 unsigned long flags
;
2099 /* Only one syntax. */
2100 skip_whitespace (str
);
2102 if (reg_required_here (&str
, 12) == FAIL
)
2104 inst
.error
= BAD_ARGS
;
2108 if (skip_past_comma (&str
) == FAIL
)
2110 inst
.error
= _("comma expected after register name");
2114 skip_whitespace (str
);
2116 if ( strcmp (str
, "CPSR") == 0
2117 || strcmp (str
, "SPSR") == 0
2118 /* Lower case versions for backwards compatability. */
2119 || strcmp (str
, "cpsr") == 0
2120 || strcmp (str
, "spsr") == 0)
2123 /* This is for backwards compatability with older toolchains. */
2124 else if ( strcmp (str
, "cpsr_all") == 0
2125 || strcmp (str
, "spsr_all") == 0)
2129 inst
.error
= _("{C|S}PSR expected");
2133 if (* str
== 's' || * str
== 'S')
2134 inst
.instruction
|= SPSR_BIT
;
2137 inst
.instruction
|= flags
;
2141 /* Two possible forms:
2142 "{C|S}PSR_<field>, Rm",
2143 "{C|S}PSR_f, #expression". */
2148 unsigned long flags
;
2150 skip_whitespace (str
);
2152 if (psr_required_here (& str
) == FAIL
)
2155 if (skip_past_comma (& str
) == FAIL
)
2157 inst
.error
= _("comma missing after psr flags");
2161 skip_whitespace (str
);
2163 if (reg_required_here (& str
, 0) != FAIL
)
2166 inst
.instruction
|= flags
;
2171 if (! is_immediate_prefix (* str
))
2174 _("only a register or immediate value can follow a psr flag");
2181 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2184 _("only a register or immediate value can follow a psr flag");
2188 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2190 inst
.error
= _("can only set flag field with immediate value");
2194 flags
|= INST_IMMEDIATE
;
2196 if (inst
.reloc
.exp
.X_add_symbol
)
2198 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2199 inst
.reloc
.pc_rel
= 0;
2203 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2205 if (value
== (unsigned) FAIL
)
2207 inst
.error
= _("Invalid constant");
2211 inst
.instruction
|= value
;
2215 inst
.instruction
|= flags
;
2219 /* Long Multiply Parser
2220 UMULL RdLo, RdHi, Rm, Rs
2221 SMULL RdLo, RdHi, Rm, Rs
2222 UMLAL RdLo, RdHi, Rm, Rs
2223 SMLAL RdLo, RdHi, Rm, Rs. */
2226 do_mull (str
, flags
)
2228 unsigned long flags
;
2230 int rdlo
, rdhi
, rm
, rs
;
2232 /* Only one format "rdlo, rdhi, rm, rs". */
2233 skip_whitespace (str
);
2235 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2237 inst
.error
= BAD_ARGS
;
2241 if (skip_past_comma (&str
) == FAIL
2242 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2244 inst
.error
= BAD_ARGS
;
2248 if (skip_past_comma (&str
) == FAIL
2249 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2251 inst
.error
= BAD_ARGS
;
2255 /* rdhi, rdlo and rm must all be different. */
2256 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2257 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2259 if (skip_past_comma (&str
) == FAIL
2260 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2262 inst
.error
= BAD_ARGS
;
2266 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2268 inst
.error
= BAD_PC
;
2272 inst
.instruction
|= flags
;
2280 unsigned long flags
;
2284 /* Only one format "rd, rm, rs". */
2285 skip_whitespace (str
);
2287 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2289 inst
.error
= BAD_ARGS
;
2295 inst
.error
= BAD_PC
;
2299 if (skip_past_comma (&str
) == FAIL
2300 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2302 inst
.error
= BAD_ARGS
;
2308 inst
.error
= BAD_PC
;
2313 as_tsktsk (_("rd and rm should be different in mul"));
2315 if (skip_past_comma (&str
) == FAIL
2316 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2318 inst
.error
= BAD_ARGS
;
2324 inst
.error
= BAD_PC
;
2328 inst
.instruction
|= flags
;
2336 unsigned long flags
;
2340 /* Only one format "rd, rm, rs, rn". */
2341 skip_whitespace (str
);
2343 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2345 inst
.error
= BAD_ARGS
;
2351 inst
.error
= BAD_PC
;
2355 if (skip_past_comma (&str
) == FAIL
2356 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2358 inst
.error
= BAD_ARGS
;
2364 inst
.error
= BAD_PC
;
2369 as_tsktsk (_("rd and rm should be different in mla"));
2371 if (skip_past_comma (&str
) == FAIL
2372 || (rd
= reg_required_here (&str
, 8)) == FAIL
2373 || skip_past_comma (&str
) == FAIL
2374 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2376 inst
.error
= BAD_ARGS
;
2380 if (rd
== REG_PC
|| rm
== REG_PC
)
2382 inst
.error
= BAD_PC
;
2386 inst
.instruction
|= flags
;
2391 /* Returns the index into fp_values of a floating point number,
2392 or -1 if not in the table. */
2395 my_get_float_expression (str
)
2398 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2404 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2406 /* Look for a raw floating point number. */
2407 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2408 && is_end_of_line
[(unsigned char) *save_in
])
2410 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2412 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2414 if (words
[j
] != fp_values
[i
][j
])
2418 if (j
== MAX_LITTLENUMS
)
2426 /* Try and parse a more complex expression, this will probably fail
2427 unless the code uses a floating point prefix (eg "0f"). */
2428 save_in
= input_line_pointer
;
2429 input_line_pointer
= *str
;
2430 if (expression (&exp
) == absolute_section
2431 && exp
.X_op
== O_big
2432 && exp
.X_add_number
< 0)
2434 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2436 if (gen_to_words (words
, 5, (long) 15) == 0)
2438 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2440 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2442 if (words
[j
] != fp_values
[i
][j
])
2446 if (j
== MAX_LITTLENUMS
)
2448 *str
= input_line_pointer
;
2449 input_line_pointer
= save_in
;
2456 *str
= input_line_pointer
;
2457 input_line_pointer
= save_in
;
2461 /* Return true if anything in the expression is a bignum. */
2464 walk_no_bignums (sp
)
2467 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2470 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2472 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2473 || (symbol_get_value_expression (sp
)->X_op_symbol
2474 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2481 my_get_expression (ep
, str
)
2488 save_in
= input_line_pointer
;
2489 input_line_pointer
= *str
;
2490 seg
= expression (ep
);
2493 if (seg
!= absolute_section
2494 && seg
!= text_section
2495 && seg
!= data_section
2496 && seg
!= bss_section
2497 && seg
!= undefined_section
)
2499 inst
.error
= _("bad_segment");
2500 *str
= input_line_pointer
;
2501 input_line_pointer
= save_in
;
2506 /* Get rid of any bignums now, so that we don't generate an error for which
2507 we can't establish a line number later on. Big numbers are never valid
2508 in instructions, which is where this routine is always called. */
2509 if (ep
->X_op
== O_big
2510 || (ep
->X_add_symbol
2511 && (walk_no_bignums (ep
->X_add_symbol
)
2513 && walk_no_bignums (ep
->X_op_symbol
)))))
2515 inst
.error
= _("Invalid constant");
2516 *str
= input_line_pointer
;
2517 input_line_pointer
= save_in
;
2521 *str
= input_line_pointer
;
2522 input_line_pointer
= save_in
;
2526 /* UNRESTRICT should be one if <shift> <register> is permitted for this
2530 decode_shift (str
, unrestrict
)
2534 const struct asm_shift_name
* shift
;
2538 skip_whitespace (* str
);
2540 for (p
= * str
; isalpha (* p
); p
++)
2545 inst
.error
= _("Shift expression expected");
2551 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
2556 inst
.error
= _("Shift expression expected");
2560 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
2562 if (shift
->properties
->index
== SHIFT_RRX
)
2565 inst
.instruction
|= shift
->properties
->bit_field
;
2569 skip_whitespace (p
);
2571 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
2573 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
2577 else if (! is_immediate_prefix (* p
))
2579 inst
.error
= (unrestrict
2580 ? _("shift requires register or #expression")
2581 : _("shift requires #expression"));
2589 if (my_get_expression (& inst
.reloc
.exp
, & p
))
2592 /* Validate some simple #expressions. */
2593 if (inst
.reloc
.exp
.X_op
== O_constant
)
2595 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2597 /* Reject operations greater than 32. */
2599 /* Reject a shift of 0 unless the mode allows it. */
2600 || (num
== 0 && shift
->properties
->allows_0
== 0)
2601 /* Reject a shift of 32 unless the mode allows it. */
2602 || (num
== 32 && shift
->properties
->allows_32
== 0)
2605 /* As a special case we allow a shift of zero for
2606 modes that do not support it to be recoded as an
2607 logical shift left of zero (ie nothing). We warn
2608 about this though. */
2611 as_warn (_("Shift of 0 ignored."));
2612 shift
= & shift_names
[0];
2613 assert (shift
->properties
->index
== SHIFT_LSL
);
2617 inst
.error
= _("Invalid immediate shift");
2622 /* Shifts of 32 are encoded as 0, for those shifts that
2627 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
2631 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2632 inst
.reloc
.pc_rel
= 0;
2633 inst
.instruction
|= shift
->properties
->bit_field
;
2640 /* Do those data_ops which can take a negative immediate constant
2641 by altering the instuction. A bit of a hack really.
2645 by inverting the second operand, and
2648 by negating the second operand. */
2651 negate_data_op (instruction
, value
)
2652 unsigned long * instruction
;
2653 unsigned long value
;
2656 unsigned long negated
, inverted
;
2658 negated
= validate_immediate (-value
);
2659 inverted
= validate_immediate (~value
);
2661 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2664 /* First negates. */
2665 case OPCODE_SUB
: /* ADD <-> SUB */
2666 new_inst
= OPCODE_ADD
;
2671 new_inst
= OPCODE_SUB
;
2675 case OPCODE_CMP
: /* CMP <-> CMN */
2676 new_inst
= OPCODE_CMN
;
2681 new_inst
= OPCODE_CMP
;
2685 /* Now Inverted ops. */
2686 case OPCODE_MOV
: /* MOV <-> MVN */
2687 new_inst
= OPCODE_MVN
;
2692 new_inst
= OPCODE_MOV
;
2696 case OPCODE_AND
: /* AND <-> BIC */
2697 new_inst
= OPCODE_BIC
;
2702 new_inst
= OPCODE_AND
;
2706 case OPCODE_ADC
: /* ADC <-> SBC */
2707 new_inst
= OPCODE_SBC
;
2712 new_inst
= OPCODE_ADC
;
2716 /* We cannot do anything. */
2721 if (value
== (unsigned) FAIL
)
2724 *instruction
&= OPCODE_MASK
;
2725 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2736 skip_whitespace (* str
);
2738 if (reg_required_here (str
, 0) != FAIL
)
2740 if (skip_past_comma (str
) == SUCCESS
)
2741 /* Shift operation on register. */
2742 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2748 /* Immediate expression. */
2749 if (is_immediate_prefix (**str
))
2754 if (my_get_expression (&inst
.reloc
.exp
, str
))
2757 if (inst
.reloc
.exp
.X_add_symbol
)
2759 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2760 inst
.reloc
.pc_rel
= 0;
2764 if (skip_past_comma (str
) == SUCCESS
)
2766 /* #x, y -- ie explicit rotation by Y. */
2767 if (my_get_expression (&expr
, str
))
2770 if (expr
.X_op
!= O_constant
)
2772 inst
.error
= _("Constant expression expected");
2776 /* Rotate must be a multiple of 2. */
2777 if (((unsigned) expr
.X_add_number
) > 30
2778 || (expr
.X_add_number
& 1) != 0
2779 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2781 inst
.error
= _("Invalid constant");
2784 inst
.instruction
|= INST_IMMEDIATE
;
2785 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2786 inst
.instruction
|= expr
.X_add_number
<< 7;
2790 /* Implicit rotation, select a suitable one. */
2791 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2795 /* Can't be done. Perhaps the code reads something like
2796 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
2797 if ((value
= negate_data_op (&inst
.instruction
,
2798 inst
.reloc
.exp
.X_add_number
))
2801 inst
.error
= _("Invalid constant");
2806 inst
.instruction
|= value
;
2809 inst
.instruction
|= INST_IMMEDIATE
;
2814 inst
.error
= _("Register or shift expression expected");
2823 skip_whitespace (* str
);
2825 if (fp_reg_required_here (str
, 0) != FAIL
)
2829 /* Immediate expression. */
2830 if (*((*str
)++) == '#')
2836 skip_whitespace (* str
);
2838 /* First try and match exact strings, this is to guarantee
2839 that some formats will work even for cross assembly. */
2841 for (i
= 0; fp_const
[i
]; i
++)
2843 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2847 *str
+= strlen (fp_const
[i
]);
2848 if (is_end_of_line
[(unsigned char) **str
])
2850 inst
.instruction
|= i
+ 8;
2857 /* Just because we didn't get a match doesn't mean that the
2858 constant isn't valid, just that it is in a format that we
2859 don't automatically recognize. Try parsing it with
2860 the standard expression routines. */
2861 if ((i
= my_get_float_expression (str
)) >= 0)
2863 inst
.instruction
|= i
+ 8;
2867 inst
.error
= _("Invalid floating point immediate expression");
2871 _("Floating point register or immediate expression expected");
2877 do_arit (str
, flags
)
2879 unsigned long flags
;
2881 skip_whitespace (str
);
2883 if (reg_required_here (&str
, 12) == FAIL
2884 || skip_past_comma (&str
) == FAIL
2885 || reg_required_here (&str
, 16) == FAIL
2886 || skip_past_comma (&str
) == FAIL
2887 || data_op2 (&str
) == FAIL
)
2890 inst
.error
= BAD_ARGS
;
2894 inst
.instruction
|= flags
;
2902 unsigned long flags
;
2904 /* This is a pseudo-op of the form "adr rd, label" to be converted
2905 into a relative address of the form "add rd, pc, #label-.-8". */
2906 skip_whitespace (str
);
2908 if (reg_required_here (&str
, 12) == FAIL
2909 || skip_past_comma (&str
) == FAIL
2910 || my_get_expression (&inst
.reloc
.exp
, &str
))
2913 inst
.error
= BAD_ARGS
;
2917 /* Frag hacking will turn this into a sub instruction if the offset turns
2918 out to be negative. */
2919 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2920 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2921 inst
.reloc
.pc_rel
= 1;
2922 inst
.instruction
|= flags
;
2928 do_adrl (str
, flags
)
2930 unsigned long flags
;
2932 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2933 into a relative address of the form:
2934 add rd, pc, #low(label-.-8)"
2935 add rd, rd, #high(label-.-8)" */
2937 skip_whitespace (str
);
2939 if (reg_required_here (& str
, 12) == FAIL
2940 || skip_past_comma (& str
) == FAIL
2941 || my_get_expression (& inst
.reloc
.exp
, & str
))
2944 inst
.error
= BAD_ARGS
;
2950 /* Frag hacking will turn this into a sub instruction if the offset turns
2951 out to be negative. */
2952 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2953 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2954 inst
.reloc
.pc_rel
= 1;
2955 inst
.instruction
|= flags
;
2956 inst
.size
= INSN_SIZE
* 2;
2964 unsigned long flags
;
2966 skip_whitespace (str
);
2968 if (reg_required_here (&str
, 16) == FAIL
)
2971 inst
.error
= BAD_ARGS
;
2975 if (skip_past_comma (&str
) == FAIL
2976 || data_op2 (&str
) == FAIL
)
2979 inst
.error
= BAD_ARGS
;
2983 inst
.instruction
|= flags
;
2984 if ((flags
& 0x0000f000) == 0)
2985 inst
.instruction
|= CONDS_BIT
;
2994 unsigned long flags
;
2996 skip_whitespace (str
);
2998 if (reg_required_here (&str
, 12) == FAIL
)
3001 inst
.error
= BAD_ARGS
;
3005 if (skip_past_comma (&str
) == FAIL
3006 || data_op2 (&str
) == FAIL
)
3009 inst
.error
= BAD_ARGS
;
3013 inst
.instruction
|= flags
;
3019 ldst_extend (str
, hwse
)
3030 if (my_get_expression (& inst
.reloc
.exp
, str
))
3033 if (inst
.reloc
.exp
.X_op
== O_constant
)
3035 int value
= inst
.reloc
.exp
.X_add_number
;
3037 if ((hwse
&& (value
< -255 || value
> 255))
3038 || (value
< -4095 || value
> 4095))
3040 inst
.error
= _("address offset too large");
3050 /* Halfword and signextension instructions have the
3051 immediate value split across bits 11..8 and bits 3..0. */
3053 inst
.instruction
|= (add
| HWOFFSET_IMM
3054 | ((value
>> 4) << 8) | (value
& 0xF));
3056 inst
.instruction
|= add
| value
;
3062 inst
.instruction
|= HWOFFSET_IMM
;
3063 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3066 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3067 inst
.reloc
.pc_rel
= 0;
3080 if (reg_required_here (str
, 0) == FAIL
)
3084 inst
.instruction
|= add
;
3087 inst
.instruction
|= add
| OFFSET_REG
;
3088 if (skip_past_comma (str
) == SUCCESS
)
3089 return decode_shift (str
, SHIFT_RESTRICT
);
3097 do_ldst (str
, flags
)
3099 unsigned long flags
;
3106 /* This is not ideal, but it is the simplest way of dealing with the
3107 ARM7T halfword instructions (since they use a different
3108 encoding, but the same mnemonic): */
3109 halfword
= (flags
& 0x80000000) != 0;
3112 /* This is actually a load/store of a halfword, or a
3113 signed-extension load. */
3114 if ((cpu_variant
& ARM_HALFWORD
) == 0)
3117 = _("Processor does not support halfwords or signed bytes");
3121 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
3122 | (flags
& ~COND_MASK
));
3127 skip_whitespace (str
);
3129 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
3132 inst
.error
= BAD_ARGS
;
3136 if (skip_past_comma (& str
) == FAIL
)
3138 inst
.error
= _("Address expected");
3148 skip_whitespace (str
);
3150 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3153 /* Conflicts can occur on stores as well as loads. */
3154 conflict_reg
= (conflict_reg
== reg
);
3156 skip_whitespace (str
);
3162 if (skip_past_comma (&str
) == SUCCESS
)
3164 /* [Rn],... (post inc) */
3165 if (ldst_extend (&str
, halfword
) == FAIL
)
3168 as_warn (_("%s register same as write-back base"),
3169 ((inst
.instruction
& LOAD_BIT
)
3170 ? _("destination") : _("source")));
3176 inst
.instruction
|= HWOFFSET_IMM
;
3178 skip_whitespace (str
);
3183 as_warn (_("%s register same as write-back base"),
3184 ((inst
.instruction
& LOAD_BIT
)
3185 ? _("destination") : _("source")));
3187 inst
.instruction
|= WRITE_BACK
;
3191 if (! (flags
& TRANS_BIT
))
3198 if (skip_past_comma (&str
) == FAIL
)
3200 inst
.error
= _("pre-indexed expression expected");
3205 if (ldst_extend (&str
, halfword
) == FAIL
)
3208 skip_whitespace (str
);
3212 inst
.error
= _("missing ]");
3216 skip_whitespace (str
);
3221 as_warn (_("%s register same as write-back base"),
3222 ((inst
.instruction
& LOAD_BIT
)
3223 ? _("destination") : _("source")));
3225 inst
.instruction
|= WRITE_BACK
;
3229 else if (*str
== '=')
3231 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
3234 skip_whitespace (str
);
3236 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3239 if (inst
.reloc
.exp
.X_op
!= O_constant
3240 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3242 inst
.error
= _("Constant expression expected");
3246 if (inst
.reloc
.exp
.X_op
== O_constant
3247 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3249 /* This can be done with a mov instruction. */
3250 inst
.instruction
&= LITERAL_MASK
;
3251 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3252 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3258 /* Insert into literal pool. */
3259 if (add_to_lit_pool () == FAIL
)
3262 inst
.error
= _("literal pool insertion failed");
3266 /* Change the instruction exp to point to the pool. */
3269 inst
.instruction
|= HWOFFSET_IMM
;
3270 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3273 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3274 inst
.reloc
.pc_rel
= 1;
3275 inst
.instruction
|= (REG_PC
<< 16);
3281 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3286 inst
.instruction
|= HWOFFSET_IMM
;
3287 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3290 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3292 /* PC rel adjust. */
3293 inst
.reloc
.exp
.X_add_number
-= 8;
3295 inst
.reloc
.pc_rel
= 1;
3296 inst
.instruction
|= (REG_PC
<< 16);
3300 if (pre_inc
&& (flags
& TRANS_BIT
))
3301 inst
.error
= _("Pre-increment instruction with translate");
3303 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3312 char * str
= * strp
;
3316 /* We come back here if we get ranges concatenated by '+' or '|'. */
3331 skip_whitespace (str
);
3333 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3342 inst
.error
= _("Bad range in register list");
3346 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3348 if (range
& (1 << i
))
3350 (_("Warning: Duplicated register (r%d) in register list"),
3358 if (range
& (1 << reg
))
3359 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3361 else if (reg
<= cur_reg
)
3362 as_tsktsk (_("Warning: Register range not in ascending order"));
3367 while (skip_past_comma (&str
) != FAIL
3368 || (in_range
= 1, *str
++ == '-'));
3370 skip_whitespace (str
);
3374 inst
.error
= _("Missing `}'");
3382 if (my_get_expression (&expr
, &str
))
3385 if (expr
.X_op
== O_constant
)
3387 if (expr
.X_add_number
3388 != (expr
.X_add_number
& 0x0000ffff))
3390 inst
.error
= _("invalid register mask");
3394 if ((range
& expr
.X_add_number
) != 0)
3396 int regno
= range
& expr
.X_add_number
;
3399 regno
= (1 << regno
) - 1;
3401 (_("Warning: Duplicated register (r%d) in register list"),
3405 range
|= expr
.X_add_number
;
3409 if (inst
.reloc
.type
!= 0)
3411 inst
.error
= _("expression too complex");
3415 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3416 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3417 inst
.reloc
.pc_rel
= 0;
3421 skip_whitespace (str
);
3423 if (*str
== '|' || *str
== '+')
3429 while (another_range
);
3436 do_ldmstm (str
, flags
)
3438 unsigned long flags
;
3443 skip_whitespace (str
);
3445 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3448 if (base_reg
== REG_PC
)
3450 inst
.error
= _("r15 not allowed as base register");
3454 skip_whitespace (str
);
3458 flags
|= WRITE_BACK
;
3462 if (skip_past_comma (&str
) == FAIL
3463 || (range
= reg_list (&str
)) == FAIL
)
3466 inst
.error
= BAD_ARGS
;
3473 flags
|= LDM_TYPE_2_OR_3
;
3476 inst
.instruction
|= flags
| range
;
3484 unsigned long flags
;
3486 skip_whitespace (str
);
3488 /* Allow optional leading '#'. */
3489 if (is_immediate_prefix (*str
))
3492 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3495 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3496 inst
.reloc
.pc_rel
= 0;
3497 inst
.instruction
|= flags
;
3505 do_swap (str
, flags
)
3507 unsigned long flags
;
3511 skip_whitespace (str
);
3513 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3518 inst
.error
= _("r15 not allowed in swap");
3522 if (skip_past_comma (&str
) == FAIL
3523 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3526 inst
.error
= BAD_ARGS
;
3532 inst
.error
= _("r15 not allowed in swap");
3536 if (skip_past_comma (&str
) == FAIL
3539 inst
.error
= BAD_ARGS
;
3543 skip_whitespace (str
);
3545 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3550 inst
.error
= BAD_PC
;
3554 skip_whitespace (str
);
3558 inst
.error
= _("missing ]");
3562 inst
.instruction
|= flags
;
3568 do_branch (str
, flags
)
3570 unsigned long flags ATTRIBUTE_UNUSED
;
3572 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3579 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
3580 required for the instruction. */
3582 /* arm_parse_reloc () works on input_line_pointer.
3583 We actually want to parse the operands to the branch instruction
3584 passed in 'str'. Save the input pointer and restore it later. */
3585 save_in
= input_line_pointer
;
3586 input_line_pointer
= str
;
3587 if (inst
.reloc
.exp
.X_op
== O_symbol
3589 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3591 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3592 inst
.reloc
.pc_rel
= 0;
3593 /* Modify str to point to after parsed operands, otherwise
3594 end_of_line() will complain about the (PLT) left in str. */
3595 str
= input_line_pointer
;
3599 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3600 inst
.reloc
.pc_rel
= 1;
3602 input_line_pointer
= save_in
;
3605 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3606 inst
.reloc
.pc_rel
= 1;
3607 #endif /* OBJ_ELF */
3616 unsigned long flags ATTRIBUTE_UNUSED
;
3620 skip_whitespace (str
);
3622 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3624 inst
.error
= BAD_ARGS
;
3628 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
3630 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
3638 unsigned long flags ATTRIBUTE_UNUSED
;
3640 /* Co-processor data operation.
3641 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3642 skip_whitespace (str
);
3644 if (co_proc_number (&str
) == FAIL
)
3647 inst
.error
= BAD_ARGS
;
3651 if (skip_past_comma (&str
) == FAIL
3652 || cp_opc_expr (&str
, 20,4) == FAIL
)
3655 inst
.error
= BAD_ARGS
;
3659 if (skip_past_comma (&str
) == FAIL
3660 || cp_reg_required_here (&str
, 12) == FAIL
)
3663 inst
.error
= BAD_ARGS
;
3667 if (skip_past_comma (&str
) == FAIL
3668 || cp_reg_required_here (&str
, 16) == FAIL
)
3671 inst
.error
= BAD_ARGS
;
3675 if (skip_past_comma (&str
) == FAIL
3676 || cp_reg_required_here (&str
, 0) == FAIL
)
3679 inst
.error
= BAD_ARGS
;
3683 if (skip_past_comma (&str
) == SUCCESS
)
3685 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3688 inst
.error
= BAD_ARGS
;
3698 do_lstc (str
, flags
)
3700 unsigned long flags
;
3702 /* Co-processor register load/store.
3703 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3705 skip_whitespace (str
);
3707 if (co_proc_number (&str
) == FAIL
)
3710 inst
.error
= BAD_ARGS
;
3714 if (skip_past_comma (&str
) == FAIL
3715 || cp_reg_required_here (&str
, 12) == FAIL
)
3718 inst
.error
= BAD_ARGS
;
3722 if (skip_past_comma (&str
) == FAIL
3723 || cp_address_required_here (&str
) == FAIL
)
3726 inst
.error
= BAD_ARGS
;
3730 inst
.instruction
|= flags
;
3736 do_co_reg (str
, flags
)
3738 unsigned long flags
;
3740 /* Co-processor register transfer.
3741 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3743 skip_whitespace (str
);
3745 if (co_proc_number (&str
) == FAIL
)
3748 inst
.error
= BAD_ARGS
;
3752 if (skip_past_comma (&str
) == FAIL
3753 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3756 inst
.error
= BAD_ARGS
;
3760 if (skip_past_comma (&str
) == FAIL
3761 || reg_required_here (&str
, 12) == FAIL
)
3764 inst
.error
= BAD_ARGS
;
3768 if (skip_past_comma (&str
) == FAIL
3769 || cp_reg_required_here (&str
, 16) == FAIL
)
3772 inst
.error
= BAD_ARGS
;
3776 if (skip_past_comma (&str
) == FAIL
3777 || cp_reg_required_here (&str
, 0) == FAIL
)
3780 inst
.error
= BAD_ARGS
;
3784 if (skip_past_comma (&str
) == SUCCESS
)
3786 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3789 inst
.error
= BAD_ARGS
;
3795 inst
.error
= BAD_COND
;
3803 do_fp_ctrl (str
, flags
)
3805 unsigned long flags ATTRIBUTE_UNUSED
;
3807 /* FP control registers.
3808 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3810 skip_whitespace (str
);
3812 if (reg_required_here (&str
, 12) == FAIL
)
3815 inst
.error
= BAD_ARGS
;
3824 do_fp_ldst (str
, flags
)
3826 unsigned long flags ATTRIBUTE_UNUSED
;
3828 skip_whitespace (str
);
3830 switch (inst
.suffix
)
3835 inst
.instruction
|= CP_T_X
;
3838 inst
.instruction
|= CP_T_Y
;
3841 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3847 if (fp_reg_required_here (&str
, 12) == FAIL
)
3850 inst
.error
= BAD_ARGS
;
3854 if (skip_past_comma (&str
) == FAIL
3855 || cp_address_required_here (&str
) == FAIL
)
3858 inst
.error
= BAD_ARGS
;
3866 do_fp_ldmstm (str
, flags
)
3868 unsigned long flags
;
3872 skip_whitespace (str
);
3874 if (fp_reg_required_here (&str
, 12) == FAIL
)
3877 inst
.error
= BAD_ARGS
;
3881 /* Get Number of registers to transfer. */
3882 if (skip_past_comma (&str
) == FAIL
3883 || my_get_expression (&inst
.reloc
.exp
, &str
))
3886 inst
.error
= _("constant expression expected");
3890 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3892 inst
.error
= _("Constant value required for number of registers");
3896 num_regs
= inst
.reloc
.exp
.X_add_number
;
3898 if (num_regs
< 1 || num_regs
> 4)
3900 inst
.error
= _("number of registers must be in the range [1:4]");
3907 inst
.instruction
|= CP_T_X
;
3910 inst
.instruction
|= CP_T_Y
;
3913 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3927 /* The instruction specified "ea" or "fd", so we can only accept
3928 [Rn]{!}. The instruction does not really support stacking or
3929 unstacking, so we have to emulate these by setting appropriate
3930 bits and offsets. */
3931 if (skip_past_comma (&str
) == FAIL
3935 inst
.error
= BAD_ARGS
;
3940 skip_whitespace (str
);
3942 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3945 skip_whitespace (str
);
3949 inst
.error
= BAD_ARGS
;
3961 _("R15 not allowed as base register with write-back");
3968 if (flags
& CP_T_Pre
)
3970 /* Pre-decrement. */
3971 offset
= 3 * num_regs
;
3977 /* Post-increment. */
3981 offset
= 3 * num_regs
;
3985 /* No write-back, so convert this into a standard pre-increment
3986 instruction -- aesthetically more pleasing. */
3987 flags
= CP_T_Pre
| CP_T_UD
;
3992 inst
.instruction
|= flags
| offset
;
3994 else if (skip_past_comma (&str
) == FAIL
3995 || cp_address_required_here (&str
) == FAIL
)
3998 inst
.error
= BAD_ARGS
;
4006 do_fp_dyadic (str
, flags
)
4008 unsigned long flags
;
4010 skip_whitespace (str
);
4012 switch (inst
.suffix
)
4017 inst
.instruction
|= 0x00000080;
4020 inst
.instruction
|= 0x00080000;
4026 if (fp_reg_required_here (&str
, 12) == FAIL
)
4029 inst
.error
= BAD_ARGS
;
4033 if (skip_past_comma (&str
) == FAIL
4034 || fp_reg_required_here (&str
, 16) == FAIL
)
4037 inst
.error
= BAD_ARGS
;
4041 if (skip_past_comma (&str
) == FAIL
4042 || fp_op2 (&str
) == FAIL
)
4045 inst
.error
= BAD_ARGS
;
4049 inst
.instruction
|= flags
;
4055 do_fp_monadic (str
, flags
)
4057 unsigned long flags
;
4059 skip_whitespace (str
);
4061 switch (inst
.suffix
)
4066 inst
.instruction
|= 0x00000080;
4069 inst
.instruction
|= 0x00080000;
4075 if (fp_reg_required_here (&str
, 12) == FAIL
)
4078 inst
.error
= BAD_ARGS
;
4082 if (skip_past_comma (&str
) == FAIL
4083 || fp_op2 (&str
) == FAIL
)
4086 inst
.error
= BAD_ARGS
;
4090 inst
.instruction
|= flags
;
4096 do_fp_cmp (str
, flags
)
4098 unsigned long flags
;
4100 skip_whitespace (str
);
4102 if (fp_reg_required_here (&str
, 16) == FAIL
)
4105 inst
.error
= BAD_ARGS
;
4109 if (skip_past_comma (&str
) == FAIL
4110 || fp_op2 (&str
) == FAIL
)
4113 inst
.error
= BAD_ARGS
;
4117 inst
.instruction
|= flags
;
4123 do_fp_from_reg (str
, flags
)
4125 unsigned long flags
;
4127 skip_whitespace (str
);
4129 switch (inst
.suffix
)
4134 inst
.instruction
|= 0x00000080;
4137 inst
.instruction
|= 0x00080000;
4143 if (fp_reg_required_here (&str
, 16) == FAIL
)
4146 inst
.error
= BAD_ARGS
;
4150 if (skip_past_comma (&str
) == FAIL
4151 || reg_required_here (&str
, 12) == FAIL
)
4154 inst
.error
= BAD_ARGS
;
4158 inst
.instruction
|= flags
;
4164 do_fp_to_reg (str
, flags
)
4166 unsigned long flags
;
4168 skip_whitespace (str
);
4170 if (reg_required_here (&str
, 12) == FAIL
)
4173 if (skip_past_comma (&str
) == FAIL
4174 || fp_reg_required_here (&str
, 0) == FAIL
)
4177 inst
.error
= BAD_ARGS
;
4181 inst
.instruction
|= flags
;
4186 /* Thumb specific routines. */
4188 /* Parse and validate that a register is of the right form, this saves
4189 repeated checking of this information in many similar cases.
4190 Unlike the 32-bit case we do not insert the register into the opcode
4191 here, since the position is often unknown until the full instruction
4195 thumb_reg (strp
, hi_lo
)
4201 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
4209 inst
.error
= _("lo register required");
4217 inst
.error
= _("hi register required");
4229 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4233 thumb_add_sub (str
, subtract
)
4237 int Rd
, Rs
, Rn
= FAIL
;
4239 skip_whitespace (str
);
4241 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4242 || skip_past_comma (&str
) == FAIL
)
4245 inst
.error
= BAD_ARGS
;
4249 if (is_immediate_prefix (*str
))
4253 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4258 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4261 if (skip_past_comma (&str
) == FAIL
)
4263 /* Two operand format, shuffle the registers
4264 and pretend there are 3. */
4268 else if (is_immediate_prefix (*str
))
4271 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4274 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4278 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4279 for the latter case, EXPR contains the immediate that was found. */
4282 /* All register format. */
4283 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4287 inst
.error
= _("dest and source1 must be the same register");
4291 /* Can't do this for SUB. */
4294 inst
.error
= _("subtract valid only on lo regs");
4298 inst
.instruction
= (T_OPCODE_ADD_HI
4299 | (Rd
> 7 ? THUMB_H1
: 0)
4300 | (Rn
> 7 ? THUMB_H2
: 0));
4301 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4305 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4306 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4311 /* Immediate expression, now things start to get nasty. */
4313 /* First deal with HI regs, only very restricted cases allowed:
4314 Adjusting SP, and using PC or SP to get an address. */
4315 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4316 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4318 inst
.error
= _("invalid Hi register with immediate");
4322 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4324 /* Value isn't known yet, all we can do is store all the fragments
4325 we know about in the instruction and let the reloc hacking
4327 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4328 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4332 int offset
= inst
.reloc
.exp
.X_add_number
;
4342 /* Quick check, in case offset is MIN_INT. */
4345 inst
.error
= _("immediate value out of range");
4354 if (offset
& ~0x1fc)
4356 inst
.error
= _("invalid immediate value for stack adjust");
4359 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4360 inst
.instruction
|= offset
>> 2;
4362 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4365 || (offset
& ~0x3fc))
4367 inst
.error
= _("invalid immediate for address calculation");
4370 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4372 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4378 inst
.error
= _("immediate value out of range");
4381 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4382 inst
.instruction
|= (Rd
<< 8) | offset
;
4388 inst
.error
= _("immediate value out of range");
4391 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4392 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4401 thumb_shift (str
, shift
)
4405 int Rd
, Rs
, Rn
= FAIL
;
4407 skip_whitespace (str
);
4409 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4410 || skip_past_comma (&str
) == FAIL
)
4413 inst
.error
= BAD_ARGS
;
4417 if (is_immediate_prefix (*str
))
4419 /* Two operand immediate format, set Rs to Rd. */
4422 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4427 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4430 if (skip_past_comma (&str
) == FAIL
)
4432 /* Two operand format, shuffle the registers
4433 and pretend there are 3. */
4437 else if (is_immediate_prefix (*str
))
4440 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4443 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4447 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4448 for the latter case, EXPR contains the immediate that was found. */
4454 inst
.error
= _("source1 and dest must be same register");
4460 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4461 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4462 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4465 inst
.instruction
|= Rd
| (Rn
<< 3);
4471 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4472 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4473 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4476 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4478 /* Value isn't known yet, create a dummy reloc and let reloc
4479 hacking fix it up. */
4480 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4484 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4486 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4488 inst
.error
= _("Invalid immediate for shift");
4492 /* Shifts of zero are handled by converting to LSL. */
4493 if (shift_value
== 0)
4494 inst
.instruction
= T_OPCODE_LSL_I
;
4496 /* Shifts of 32 are encoded as a shift of zero. */
4497 if (shift_value
== 32)
4500 inst
.instruction
|= shift_value
<< 6;
4503 inst
.instruction
|= Rd
| (Rs
<< 3);
4510 thumb_mov_compare (str
, move
)
4516 skip_whitespace (str
);
4518 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4519 || skip_past_comma (&str
) == FAIL
)
4522 inst
.error
= BAD_ARGS
;
4526 if (is_immediate_prefix (*str
))
4529 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4532 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4537 if (Rs
< 8 && Rd
< 8)
4539 if (move
== THUMB_MOVE
)
4540 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4541 since a MOV instruction produces unpredictable results. */
4542 inst
.instruction
= T_OPCODE_ADD_I3
;
4544 inst
.instruction
= T_OPCODE_CMP_LR
;
4545 inst
.instruction
|= Rd
| (Rs
<< 3);
4549 if (move
== THUMB_MOVE
)
4550 inst
.instruction
= T_OPCODE_MOV_HR
;
4552 inst
.instruction
= T_OPCODE_CMP_HR
;
4555 inst
.instruction
|= THUMB_H1
;
4558 inst
.instruction
|= THUMB_H2
;
4560 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4567 inst
.error
= _("only lo regs allowed with immediate");
4571 if (move
== THUMB_MOVE
)
4572 inst
.instruction
= T_OPCODE_MOV_I8
;
4574 inst
.instruction
= T_OPCODE_CMP_I8
;
4576 inst
.instruction
|= Rd
<< 8;
4578 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4579 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4582 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4586 inst
.error
= _("invalid immediate");
4590 inst
.instruction
|= value
;
4598 thumb_load_store (str
, load_store
, size
)
4603 int Rd
, Rb
, Ro
= FAIL
;
4605 skip_whitespace (str
);
4607 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4608 || skip_past_comma (&str
) == FAIL
)
4611 inst
.error
= BAD_ARGS
;
4618 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4621 if (skip_past_comma (&str
) != FAIL
)
4623 if (is_immediate_prefix (*str
))
4626 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4629 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4634 inst
.reloc
.exp
.X_op
= O_constant
;
4635 inst
.reloc
.exp
.X_add_number
= 0;
4640 inst
.error
= _("expected ']'");
4645 else if (*str
== '=')
4647 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4650 skip_whitespace (str
);
4652 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4657 if ( inst
.reloc
.exp
.X_op
!= O_constant
4658 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4660 inst
.error
= "Constant expression expected";
4664 if (inst
.reloc
.exp
.X_op
== O_constant
4665 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4667 /* This can be done with a mov instruction. */
4669 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4670 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4674 /* Insert into literal pool. */
4675 if (add_to_lit_pool () == FAIL
)
4678 inst
.error
= "literal pool insertion failed";
4682 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4683 inst
.reloc
.pc_rel
= 1;
4684 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4685 /* Adjust ARM pipeline offset to Thumb. */
4686 inst
.reloc
.exp
.X_add_number
+= 4;
4692 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4695 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4696 inst
.reloc
.pc_rel
= 1;
4697 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
4698 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4703 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4705 if (size
!= THUMB_WORD
)
4707 inst
.error
= _("byte or halfword not valid for base register");
4710 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4712 inst
.error
= _("R15 based store not allowed");
4715 else if (Ro
!= FAIL
)
4717 inst
.error
= _("Invalid base register for register offset");
4722 inst
.instruction
= T_OPCODE_LDR_PC
;
4723 else if (load_store
== THUMB_LOAD
)
4724 inst
.instruction
= T_OPCODE_LDR_SP
;
4726 inst
.instruction
= T_OPCODE_STR_SP
;
4728 inst
.instruction
|= Rd
<< 8;
4729 if (inst
.reloc
.exp
.X_op
== O_constant
)
4731 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4733 if (offset
& ~0x3fc)
4735 inst
.error
= _("invalid offset");
4739 inst
.instruction
|= offset
>> 2;
4742 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4746 inst
.error
= _("invalid base register in load/store");
4749 else if (Ro
== FAIL
)
4751 /* Immediate offset. */
4752 if (size
== THUMB_WORD
)
4753 inst
.instruction
= (load_store
== THUMB_LOAD
4754 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4755 else if (size
== THUMB_HALFWORD
)
4756 inst
.instruction
= (load_store
== THUMB_LOAD
4757 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4759 inst
.instruction
= (load_store
== THUMB_LOAD
4760 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4762 inst
.instruction
|= Rd
| (Rb
<< 3);
4764 if (inst
.reloc
.exp
.X_op
== O_constant
)
4766 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4768 if (offset
& ~(0x1f << size
))
4770 inst
.error
= _("Invalid offset");
4773 inst
.instruction
|= (offset
>> size
) << 6;
4776 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4780 /* Register offset. */
4781 if (size
== THUMB_WORD
)
4782 inst
.instruction
= (load_store
== THUMB_LOAD
4783 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4784 else if (size
== THUMB_HALFWORD
)
4785 inst
.instruction
= (load_store
== THUMB_LOAD
4786 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4788 inst
.instruction
= (load_store
== THUMB_LOAD
4789 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4791 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4806 /* Handle the Format 4 instructions that do not have equivalents in other
4807 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4816 skip_whitespace (str
);
4818 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4819 || skip_past_comma (&str
) == FAIL
4820 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4822 inst
.error
= BAD_ARGS
;
4826 if (skip_past_comma (&str
) != FAIL
)
4828 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4829 (It isn't allowed for CMP either, but that isn't handled by this
4831 if (inst
.instruction
== T_OPCODE_TST
4832 || inst
.instruction
== T_OPCODE_CMN
4833 || inst
.instruction
== T_OPCODE_NEG
4834 || inst
.instruction
== T_OPCODE_MVN
)
4836 inst
.error
= BAD_ARGS
;
4840 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4845 inst
.error
= _("dest and source1 one must be the same register");
4851 if (inst
.instruction
== T_OPCODE_MUL
4853 as_tsktsk (_("Rs and Rd must be different in MUL"));
4855 inst
.instruction
|= Rd
| (Rs
<< 3);
4863 thumb_add_sub (str
, 0);
4870 thumb_shift (str
, THUMB_ASR
);
4877 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4879 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4880 inst
.reloc
.pc_rel
= 1;
4888 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4890 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4891 inst
.reloc
.pc_rel
= 1;
4895 /* Find the real, Thumb encoded start of a Thumb function. */
4898 find_real_start (symbolP
)
4902 const char * name
= S_GET_NAME (symbolP
);
4903 symbolS
* new_target
;
4905 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
4906 #define STUB_NAME ".real_start_of"
4911 /* Names that start with '.' are local labels, not function entry points.
4912 The compiler may generate BL instructions to these labels because it
4913 needs to perform a branch to a far away location. */
4917 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4918 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4920 new_target
= symbol_find (real_start
);
4922 if (new_target
== NULL
)
4924 as_warn ("Failed to find real start of function: %s\n", name
);
4925 new_target
= symbolP
;
4937 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4940 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4941 inst
.reloc
.pc_rel
= 1;
4944 /* If the destination of the branch is a defined symbol which does not have
4945 the THUMB_FUNC attribute, then we must be calling a function which has
4946 the (interfacearm) attribute. We look for the Thumb entry point to that
4947 function and change the branch to refer to that function instead. */
4948 if ( inst
.reloc
.exp
.X_op
== O_symbol
4949 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4950 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4951 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4952 inst
.reloc
.exp
.X_add_symbol
=
4953 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4962 skip_whitespace (str
);
4964 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4967 /* This sets THUMB_H2 from the top bit of reg. */
4968 inst
.instruction
|= reg
<< 3;
4970 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4971 should cause the alignment to be checked once it is known. This is
4972 because BX PC only works if the instruction is word aligned. */
4981 thumb_mov_compare (str
, THUMB_COMPARE
);
4991 skip_whitespace (str
);
4993 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4997 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
5001 if (skip_past_comma (&str
) == FAIL
5002 || (range
= reg_list (&str
)) == FAIL
)
5005 inst
.error
= BAD_ARGS
;
5009 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5011 /* This really doesn't seem worth it. */
5012 inst
.reloc
.type
= BFD_RELOC_NONE
;
5013 inst
.error
= _("Expression too complex");
5019 inst
.error
= _("only lo-regs valid in load/store multiple");
5023 inst
.instruction
|= (Rb
<< 8) | range
;
5031 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
5038 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
5045 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
5054 skip_whitespace (str
);
5056 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5057 || skip_past_comma (&str
) == FAIL
5059 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5060 || skip_past_comma (&str
) == FAIL
5061 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5065 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
5069 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5077 thumb_shift (str
, THUMB_LSL
);
5084 thumb_shift (str
, THUMB_LSR
);
5091 thumb_mov_compare (str
, THUMB_MOVE
);
5100 skip_whitespace (str
);
5102 if ((range
= reg_list (&str
)) == FAIL
)
5105 inst
.error
= BAD_ARGS
;
5109 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5111 /* This really doesn't seem worth it. */
5112 inst
.reloc
.type
= BFD_RELOC_NONE
;
5113 inst
.error
= _("Expression too complex");
5119 if ((inst
.instruction
== T_OPCODE_PUSH
5120 && (range
& ~0xff) == 1 << REG_LR
)
5121 || (inst
.instruction
== T_OPCODE_POP
5122 && (range
& ~0xff) == 1 << REG_PC
))
5124 inst
.instruction
|= THUMB_PP_PC_LR
;
5129 inst
.error
= _("invalid register list to push/pop instruction");
5134 inst
.instruction
|= range
;
5142 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
5149 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
5156 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
5163 thumb_add_sub (str
, 1);
5170 skip_whitespace (str
);
5172 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5175 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5186 /* This is a pseudo-op of the form "adr rd, label" to be converted
5187 into a relative address of the form "add rd, pc, #label-.-4". */
5188 skip_whitespace (str
);
5190 /* Store Rd in temporary location inside instruction. */
5191 if ((reg
= reg_required_here (&str
, 4)) == FAIL
5192 || (reg
> 7) /* For Thumb reg must be r0..r7. */
5193 || skip_past_comma (&str
) == FAIL
5194 || my_get_expression (&inst
.reloc
.exp
, &str
))
5197 inst
.error
= BAD_ARGS
;
5201 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5202 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
5203 inst
.reloc
.pc_rel
= 1;
5204 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
5213 int len
= strlen (reg_table
[entry
].name
) + 2;
5214 char * buf
= (char *) xmalloc (len
);
5215 char * buf2
= (char *) xmalloc (len
);
5218 #ifdef REGISTER_PREFIX
5219 buf
[i
++] = REGISTER_PREFIX
;
5222 strcpy (buf
+ i
, reg_table
[entry
].name
);
5224 for (i
= 0; buf
[i
]; i
++)
5225 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5229 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
5230 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
5234 insert_reg_alias (str
, regnum
)
5238 struct reg_entry
*new =
5239 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
5240 char *name
= xmalloc (strlen (str
) + 1);
5244 new->number
= regnum
;
5246 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5250 set_constant_flonums ()
5254 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5255 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5265 if ( (arm_ops_hsh
= hash_new ()) == NULL
5266 || (arm_tops_hsh
= hash_new ()) == NULL
5267 || (arm_cond_hsh
= hash_new ()) == NULL
5268 || (arm_shift_hsh
= hash_new ()) == NULL
5269 || (arm_reg_hsh
= hash_new ()) == NULL
5270 || (arm_psr_hsh
= hash_new ()) == NULL
)
5271 as_fatal (_("Virtual memory exhausted"));
5273 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5274 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5275 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5276 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5277 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5278 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5279 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
5280 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
5281 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5282 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5284 for (i
= 0; reg_table
[i
].name
; i
++)
5287 set_constant_flonums ();
5289 #if defined OBJ_COFF || defined OBJ_ELF
5291 unsigned int flags
= 0;
5293 /* Set the flags in the private structure. */
5294 if (uses_apcs_26
) flags
|= F_APCS26
;
5295 if (support_interwork
) flags
|= F_INTERWORK
;
5296 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5297 if (pic_code
) flags
|= F_PIC
;
5298 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5300 bfd_set_private_flags (stdoutput
, flags
);
5304 /* Record the CPU type as well. */
5305 switch (cpu_variant
& ARM_CPU_MASK
)
5308 mach
= bfd_mach_arm_2
;
5311 case ARM_3
: /* Also ARM_250. */
5312 mach
= bfd_mach_arm_2a
;
5316 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5317 mach
= bfd_mach_arm_4
;
5320 case ARM_7
: /* Also ARM_6. */
5321 mach
= bfd_mach_arm_3
;
5325 /* Catch special cases. */
5326 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5328 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5329 mach
= bfd_mach_arm_5T
;
5330 else if (cpu_variant
& ARM_EXT_V5
)
5331 mach
= bfd_mach_arm_5
;
5332 else if (cpu_variant
& ARM_THUMB
)
5333 mach
= bfd_mach_arm_4T
;
5334 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5335 mach
= bfd_mach_arm_4
;
5336 else if (cpu_variant
& ARM_LONGMUL
)
5337 mach
= bfd_mach_arm_3M
;
5340 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5343 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5344 for use in the a.out file, and stores them in the array pointed to by buf.
5345 This knows about the endian-ness of the target machine and does
5346 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5347 2 (short) and 4 (long) Floating numbers are put out as a series of
5348 LITTLENUMS (shorts, here at least). */
5351 md_number_to_chars (buf
, val
, n
)
5356 if (target_big_endian
)
5357 number_to_chars_bigendian (buf
, val
, n
);
5359 number_to_chars_littleendian (buf
, val
, n
);
5363 md_chars_to_number (buf
, n
)
5368 unsigned char * where
= (unsigned char *) buf
;
5370 if (target_big_endian
)
5375 result
|= (*where
++ & 255);
5383 result
|= (where
[n
] & 255);
5390 /* Turn a string in input_line_pointer into a floating point constant
5391 of type TYPE, and store the appropriate bytes in *LITP. The number
5392 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5393 returned, or NULL on OK.
5395 Note that fp constants aren't represent in the normal way on the ARM.
5396 In big endian mode, things are as expected. However, in little endian
5397 mode fp constants are big-endian word-wise, and little-endian byte-wise
5398 within the words. For example, (double) 1.1 in big endian mode is
5399 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5400 the byte sequence 99 99 f1 3f 9a 99 99 99.
5402 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5405 md_atof (type
, litP
, sizeP
)
5411 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5443 return _("Bad call to MD_ATOF()");
5446 t
= atof_ieee (input_line_pointer
, type
, words
);
5448 input_line_pointer
= t
;
5451 if (target_big_endian
)
5453 for (i
= 0; i
< prec
; i
++)
5455 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5461 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5462 8 byte float the order is 1 0 3 2. */
5463 for (i
= 0; i
< prec
; i
+= 2)
5465 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5466 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5474 /* The knowledge of the PC's pipeline offset is built into the insns
5478 md_pcrel_from (fixP
)
5482 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5483 && fixP
->fx_subsy
== NULL
)
5486 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5488 /* PC relative addressing on the Thumb is slightly odd
5489 as the bottom two bits of the PC are forced to zero
5490 for the calculation. */
5491 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5495 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5496 so we un-adjust here to compensate for the accomodation. */
5497 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5499 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5503 /* Round up a section size to the appropriate boundary. */
5506 md_section_align (segment
, size
)
5507 segT segment ATTRIBUTE_UNUSED
;
5513 /* Round all sects to multiple of 4. */
5514 return (size
+ 3) & ~3;
5518 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
5519 Otherwise we have no need to default values of symbols. */
5522 md_undefined_symbol (name
)
5523 char * name ATTRIBUTE_UNUSED
;
5526 if (name
[0] == '_' && name
[1] == 'G'
5527 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5531 if (symbol_find (name
))
5532 as_bad ("GOT already in the symbol table");
5534 GOT_symbol
= symbol_new (name
, undefined_section
,
5535 (valueT
) 0, & zero_address_frag
);
5545 /* arm_reg_parse () := if it looks like a register, return its token and
5546 advance the pointer. */
5550 register char ** ccp
;
5552 char * start
= * ccp
;
5555 struct reg_entry
* reg
;
5557 #ifdef REGISTER_PREFIX
5558 if (*start
!= REGISTER_PREFIX
)
5563 #ifdef OPTIONAL_REGISTER_PREFIX
5564 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5568 if (!isalpha (*p
) || !is_name_beginner (*p
))
5572 while (isalpha (c
) || isdigit (c
) || c
== '_')
5576 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5589 md_apply_fix3 (fixP
, val
, seg
)
5594 offsetT value
= * val
;
5596 unsigned int newimm
;
5599 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5600 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5602 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5604 /* Note whether this will delete the relocation. */
5606 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
5607 doesn't work fully.) */
5608 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5611 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5615 /* If this symbol is in a different section then we need to leave it for
5616 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5617 so we have to undo it's effects here. */
5620 if (fixP
->fx_addsy
!= NULL
5621 && S_IS_DEFINED (fixP
->fx_addsy
)
5622 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5625 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5626 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5630 value
+= md_pcrel_from (fixP
);
5634 /* Remember value for emit_reloc. */
5635 fixP
->fx_addnumber
= value
;
5637 switch (fixP
->fx_r_type
)
5639 case BFD_RELOC_ARM_IMMEDIATE
:
5640 newimm
= validate_immediate (value
);
5641 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5643 /* If the instruction will fail, see if we can fix things up by
5644 changing the opcode. */
5645 if (newimm
== (unsigned int) FAIL
5646 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5648 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5649 _("invalid constant (%lx) after fixup"),
5650 (unsigned long) value
);
5654 newimm
|= (temp
& 0xfffff000);
5655 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5658 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5660 unsigned int highpart
= 0;
5661 unsigned int newinsn
= 0xe1a00000; /* nop. */
5662 newimm
= validate_immediate (value
);
5663 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5665 /* If the instruction will fail, see if we can fix things up by
5666 changing the opcode. */
5667 if (newimm
== (unsigned int) FAIL
5668 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5670 /* No ? OK - try using two ADD instructions to generate
5672 newimm
= validate_immediate_twopart (value
, & highpart
);
5674 /* Yes - then make sure that the second instruction is
5676 if (newimm
!= (unsigned int) FAIL
)
5678 /* Still No ? Try using a negated value. */
5679 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
5680 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5681 /* Otherwise - give up. */
5684 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5685 _("Unable to compute ADRL instructions for PC offset of 0x%x"),
5690 /* Replace the first operand in the 2nd instruction (which
5691 is the PC) with the destination register. We have
5692 already added in the PC in the first instruction and we
5693 do not want to do it again. */
5694 newinsn
&= ~ 0xf0000;
5695 newinsn
|= ((newinsn
& 0x0f000) << 4);
5698 newimm
|= (temp
& 0xfffff000);
5699 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5701 highpart
|= (newinsn
& 0xfffff000);
5702 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5706 case BFD_RELOC_ARM_OFFSET_IMM
:
5712 if (validate_offset_imm (value
, 0) == FAIL
)
5714 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5715 _("bad immediate value for offset (%ld)"),
5720 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5721 newval
&= 0xff7ff000;
5722 newval
|= value
| (sign
? INDEX_UP
: 0);
5723 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5726 case BFD_RELOC_ARM_OFFSET_IMM8
:
5727 case BFD_RELOC_ARM_HWLITERAL
:
5733 if (validate_offset_imm (value
, 1) == FAIL
)
5735 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5736 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5737 _("invalid literal constant: pool needs to be closer"));
5739 as_bad (_("bad immediate value for half-word offset (%ld)"),
5744 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5745 newval
&= 0xff7ff0f0;
5746 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5747 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5750 case BFD_RELOC_ARM_LITERAL
:
5756 if (validate_offset_imm (value
, 0) == FAIL
)
5758 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5759 _("invalid literal constant: pool needs to be closer"));
5763 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5764 newval
&= 0xff7ff000;
5765 newval
|= value
| (sign
? INDEX_UP
: 0);
5766 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5769 case BFD_RELOC_ARM_SHIFT_IMM
:
5770 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5771 if (((unsigned long) value
) > 32
5773 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5775 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5776 _("shift expression is too large"));
5781 /* Shifts of zero must be done as lsl. */
5783 else if (value
== 32)
5785 newval
&= 0xfffff07f;
5786 newval
|= (value
& 0x1f) << 7;
5787 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5790 case BFD_RELOC_ARM_SWI
:
5791 if (arm_data
->thumb_mode
)
5793 if (((unsigned long) value
) > 0xff)
5794 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5795 _("Invalid swi expression"));
5796 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5798 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5802 if (((unsigned long) value
) > 0x00ffffff)
5803 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5804 _("Invalid swi expression"));
5805 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5807 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5811 case BFD_RELOC_ARM_MULTI
:
5812 if (((unsigned long) value
) > 0xffff)
5813 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5814 _("Invalid expression in load/store multiple"));
5815 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5816 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5819 case BFD_RELOC_ARM_PCREL_BRANCH
:
5820 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5822 /* Sign-extend a 24-bit number. */
5823 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5827 value
= fixP
->fx_offset
;
5830 /* We are going to store value (shifted right by two) in the
5831 instruction, in a 24 bit, signed field. Thus we need to check
5832 that none of the top 8 bits of the shifted value (top 7 bits of
5833 the unshifted, unsigned value) are set, or that they are all set. */
5834 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5835 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5838 /* Normally we would be stuck at this point, since we cannot store
5839 the absolute address that is the destination of the branch in the
5840 24 bits of the branch instruction. If however, we happen to know
5841 that the destination of the branch is in the same section as the
5842 branch instruciton itself, then we can compute the relocation for
5843 ourselves and not have to bother the linker with it.
5845 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5846 because I have not worked out how to do this for OBJ_COFF or
5849 && fixP
->fx_addsy
!= NULL
5850 && S_IS_DEFINED (fixP
->fx_addsy
)
5851 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5853 /* Get pc relative value to go into the branch. */
5856 /* Permit a backward branch provided that enough bits
5857 are set. Allow a forwards branch, provided that
5858 enough bits are clear. */
5859 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5860 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5864 if (! fixP
->fx_done
)
5866 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5867 _("gas can't handle same-section branch dest >= 0x04000000"));
5871 value
+= SEXT24 (newval
);
5873 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
5874 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5875 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5876 _("out of range branch"));
5878 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5879 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5882 case BFD_RELOC_ARM_PCREL_BLX
:
5885 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5889 value
= fixP
->fx_offset
;
5891 hbit
= (value
>> 1) & 1;
5892 value
= (value
>> 2) & 0x00ffffff;
5893 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5894 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5895 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5899 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
5900 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5902 addressT diff
= (newval
& 0xff) << 1;
5907 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5908 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5909 _("Branch out of range"));
5910 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5912 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5915 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
5916 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5918 addressT diff
= (newval
& 0x7ff) << 1;
5923 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5924 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5925 _("Branch out of range"));
5926 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5928 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5931 case BFD_RELOC_THUMB_PCREL_BLX
:
5932 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5937 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5938 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5939 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5940 if (diff
& 0x400000)
5943 value
= fixP
->fx_offset
;
5946 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5947 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5948 _("Branch with link out of range"));
5950 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5951 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5952 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5953 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5958 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5959 md_number_to_chars (buf
, value
, 1);
5961 else if (!target_oabi
)
5963 value
= fixP
->fx_offset
;
5964 md_number_to_chars (buf
, value
, 1);
5970 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5971 md_number_to_chars (buf
, value
, 2);
5973 else if (!target_oabi
)
5975 value
= fixP
->fx_offset
;
5976 md_number_to_chars (buf
, value
, 2);
5982 case BFD_RELOC_ARM_GOT32
:
5983 case BFD_RELOC_ARM_GOTOFF
:
5984 md_number_to_chars (buf
, 0, 4);
5990 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5991 md_number_to_chars (buf
, value
, 4);
5993 else if (!target_oabi
)
5995 value
= fixP
->fx_offset
;
5996 md_number_to_chars (buf
, value
, 4);
6002 case BFD_RELOC_ARM_PLT32
:
6003 /* It appears the instruction is fully prepared at this point. */
6007 case BFD_RELOC_ARM_GOTPC
:
6008 md_number_to_chars (buf
, value
, 4);
6011 case BFD_RELOC_ARM_CP_OFF_IMM
:
6013 if (value
< -1023 || value
> 1023 || (value
& 3))
6014 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6015 _("Illegal value for co-processor offset"));
6018 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
6019 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
6020 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6023 case BFD_RELOC_ARM_THUMB_OFFSET
:
6024 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6025 /* Exactly what ranges, and where the offset is inserted depends
6026 on the type of instruction, we can establish this from the
6028 switch (newval
>> 12)
6030 case 4: /* PC load. */
6031 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
6032 forced to zero for these loads, so we will need to round
6033 up the offset if the instruction address is not word
6034 aligned (since the final address produced must be, and
6035 we can only describe word-aligned immediate offsets). */
6037 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
6038 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6039 _("Invalid offset, target not word aligned (0x%08X)"),
6040 (unsigned int) (fixP
->fx_frag
->fr_address
6041 + fixP
->fx_where
+ value
));
6043 if ((value
+ 2) & ~0x3fe)
6044 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6045 _("Invalid offset, value too big (0x%08X)"), value
);
6047 /* Round up, since pc will be rounded down. */
6048 newval
|= (value
+ 2) >> 2;
6051 case 9: /* SP load/store. */
6053 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6054 _("Invalid offset, value too big (0x%08X)"), value
);
6055 newval
|= value
>> 2;
6058 case 6: /* Word load/store. */
6060 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6061 _("Invalid offset, value too big (0x%08X)"), value
);
6062 newval
|= value
<< 4; /* 6 - 2. */
6065 case 7: /* Byte load/store. */
6067 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6068 _("Invalid offset, value too big (0x%08X)"), value
);
6069 newval
|= value
<< 6;
6072 case 8: /* Halfword load/store. */
6074 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6075 _("Invalid offset, value too big (0x%08X)"), value
);
6076 newval
|= value
<< 5; /* 6 - 1. */
6080 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6081 "Unable to process relocation for thumb opcode: %lx",
6082 (unsigned long) newval
);
6085 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6088 case BFD_RELOC_ARM_THUMB_ADD
:
6089 /* This is a complicated relocation, since we use it for all of
6090 the following immediate relocations:
6094 9bit ADD/SUB SP word-aligned
6095 10bit ADD PC/SP word-aligned
6097 The type of instruction being processed is encoded in the
6104 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6106 int rd
= (newval
>> 4) & 0xf;
6107 int rs
= newval
& 0xf;
6108 int subtract
= newval
& 0x8000;
6113 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6114 _("Invalid immediate for stack address calculation"));
6115 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6116 newval
|= value
>> 2;
6118 else if (rs
== REG_PC
|| rs
== REG_SP
)
6122 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6123 _("Invalid immediate for address calculation (value = 0x%08lX)"),
6124 (unsigned long) value
);
6125 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
6127 newval
|= value
>> 2;
6132 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6133 _("Invalid 8bit immediate"));
6134 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6135 newval
|= (rd
<< 8) | value
;
6140 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6141 _("Invalid 3bit immediate"));
6142 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6143 newval
|= rd
| (rs
<< 3) | (value
<< 6);
6146 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6149 case BFD_RELOC_ARM_THUMB_IMM
:
6150 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6151 switch (newval
>> 11)
6153 case 0x04: /* 8bit immediate MOV. */
6154 case 0x05: /* 8bit immediate CMP. */
6155 if (value
< 0 || value
> 255)
6156 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6157 _("Invalid immediate: %ld is too large"),
6165 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6168 case BFD_RELOC_ARM_THUMB_SHIFT
:
6169 /* 5bit shift value (0..31). */
6170 if (value
< 0 || value
> 31)
6171 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6172 _("Illegal Thumb shift value: %ld"), (long) value
);
6173 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
6174 newval
|= value
<< 6;
6175 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6178 case BFD_RELOC_VTABLE_INHERIT
:
6179 case BFD_RELOC_VTABLE_ENTRY
:
6183 case BFD_RELOC_NONE
:
6185 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6186 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6192 /* Translate internal representation of relocation info to BFD target
6196 tc_gen_reloc (section
, fixp
)
6197 asection
* section ATTRIBUTE_UNUSED
;
6201 bfd_reloc_code_real_type code
;
6203 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
6205 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6206 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6207 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6209 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
6211 if (fixp
->fx_pcrel
== 0)
6212 reloc
->addend
= fixp
->fx_offset
;
6214 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6216 reloc
->addend
= fixp
->fx_offset
;
6219 switch (fixp
->fx_r_type
)
6224 code
= BFD_RELOC_8_PCREL
;
6231 code
= BFD_RELOC_16_PCREL
;
6238 code
= BFD_RELOC_32_PCREL
;
6242 case BFD_RELOC_ARM_PCREL_BRANCH
:
6243 case BFD_RELOC_ARM_PCREL_BLX
:
6245 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6246 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6247 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6248 case BFD_RELOC_THUMB_PCREL_BLX
:
6249 case BFD_RELOC_VTABLE_ENTRY
:
6250 case BFD_RELOC_VTABLE_INHERIT
:
6251 code
= fixp
->fx_r_type
;
6254 case BFD_RELOC_ARM_LITERAL
:
6255 case BFD_RELOC_ARM_HWLITERAL
:
6256 /* If this is called then the a literal has been referenced across
6257 a section boundary - possibly due to an implicit dump. */
6258 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6259 _("Literal referenced across section boundary (Implicit dump?)"));
6263 case BFD_RELOC_ARM_GOT32
:
6264 case BFD_RELOC_ARM_GOTOFF
:
6265 case BFD_RELOC_ARM_PLT32
:
6266 code
= fixp
->fx_r_type
;
6270 case BFD_RELOC_ARM_IMMEDIATE
:
6271 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6272 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6276 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6277 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6278 _("ADRL used for a symbol not defined in the same file"),
6282 case BFD_RELOC_ARM_OFFSET_IMM
:
6283 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6284 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6292 switch (fixp
->fx_r_type
)
6294 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6295 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6296 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6297 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6298 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6299 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6300 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6301 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6302 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6303 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6304 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6305 default: type
= _("<unknown>"); break;
6307 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6308 _("Can not represent %s relocation in this object file format (%d)"),
6309 type
, fixp
->fx_pcrel
);
6315 if (code
== BFD_RELOC_32_PCREL
6317 && fixp
->fx_addsy
== GOT_symbol
)
6319 code
= BFD_RELOC_ARM_GOTPC
;
6320 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6324 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6326 if (reloc
->howto
== NULL
)
6328 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6329 _("Can not represent %s relocation in this object file format"),
6330 bfd_get_reloc_code_name (code
));
6334 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6335 vtable entry to be used in the relocation's section offset. */
6336 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6337 reloc
->address
= fixp
->fx_offset
;
6343 md_estimate_size_before_relax (fragP
, segtype
)
6344 fragS
* fragP ATTRIBUTE_UNUSED
;
6345 segT segtype ATTRIBUTE_UNUSED
;
6347 as_fatal (_("md_estimate_size_before_relax\n"));
6352 output_inst
PARAMS ((void))
6358 as_bad (inst
.error
);
6362 to
= frag_more (inst
.size
);
6364 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6366 assert (inst
.size
== (2 * THUMB_SIZE
));
6367 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6368 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6370 else if (inst
.size
> INSN_SIZE
)
6372 assert (inst
.size
== (2 * INSN_SIZE
));
6373 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6374 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6377 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6379 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6380 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6381 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6396 /* Align the instruction.
6397 This may not be the right thing to do but ... */
6401 listing_prev_line (); /* Defined in listing.h. */
6403 /* Align the previous label if needed. */
6404 if (last_label_seen
!= NULL
)
6406 symbol_set_frag (last_label_seen
, frag_now
);
6407 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6408 S_SET_SEGMENT (last_label_seen
, now_seg
);
6411 memset (&inst
, '\0', sizeof (inst
));
6412 inst
.reloc
.type
= BFD_RELOC_NONE
;
6414 skip_whitespace (str
);
6416 /* Scan up to the end of the op-code, which must end in white space or
6418 for (start
= p
= str
; *p
!= '\0'; p
++)
6424 as_bad (_("No operator -- statement `%s'\n"), str
);
6430 CONST
struct thumb_opcode
* opcode
;
6434 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6439 /* Check that this instruction is supported for this CPU. */
6440 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6442 as_bad (_("selected processor does not support this opcode"));
6446 inst
.instruction
= opcode
->value
;
6447 inst
.size
= opcode
->size
;
6448 (*opcode
->parms
) (p
);
6455 CONST
struct asm_opcode
* opcode
;
6456 unsigned long cond_code
;
6458 inst
.size
= INSN_SIZE
;
6459 /* P now points to the end of the opcode, probably white space, but we
6460 have to break the opcode up in case it contains condionals and flags;
6461 keep trying with progressively smaller basic instructions until one
6462 matches, or we run out of opcode. */
6463 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6465 for (; q
!= str
; q
--)
6470 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6473 if (opcode
&& opcode
->template)
6475 unsigned long flag_bits
= 0;
6478 /* Check that this instruction is supported for this CPU. */
6479 if ((opcode
->variants
& cpu_variant
) == 0)
6482 inst
.instruction
= opcode
->value
;
6483 if (q
== p
) /* Just a simple opcode. */
6485 if (opcode
->comp_suffix
)
6487 if (*opcode
->comp_suffix
!= '\0')
6488 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6489 str
, opcode
->comp_suffix
);
6491 /* Not a conditional instruction. */
6492 (*opcode
->parms
) (q
, 0);
6496 /* A conditional instruction with default condition. */
6497 inst
.instruction
|= COND_ALWAYS
;
6498 (*opcode
->parms
) (q
, 0);
6504 /* Not just a simple opcode. Check if extra is a
6509 CONST
struct asm_cond
*cond
;
6513 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6517 if (cond
->value
== 0xf0000000)
6519 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6521 cond_code
= cond
->value
;
6525 cond_code
= COND_ALWAYS
;
6528 cond_code
= COND_ALWAYS
;
6530 /* Apply the conditional, or complain it's not allowed. */
6531 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6533 /* Instruction isn't conditional. */
6534 if (cond_code
!= COND_ALWAYS
)
6536 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6541 /* Instruction is conditional: set the condition into it. */
6542 inst
.instruction
|= cond_code
;
6544 /* If there is a compulsory suffix, it should come here
6545 before any optional flags. */
6546 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6548 CONST
char *s
= opcode
->comp_suffix
;
6560 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
6561 str
, opcode
->comp_suffix
);
6568 /* The remainder, if any should now be flags for the instruction;
6569 Scan these checking each one found with the opcode. */
6573 CONST
struct asm_flg
*flag
= opcode
->flags
;
6582 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6584 if (streq (r
, flag
[flagno
].template))
6586 flag_bits
|= flag
[flagno
].set_bits
;
6592 if (! flag
[flagno
].template)
6599 (*opcode
->parms
) (p
, flag_bits
);
6609 /* It wasn't an instruction, but it might be a register alias of the form
6612 skip_whitespace (q
);
6617 if (*q
&& !strncmp (q
, ".req ", 4))
6620 char * copy_of_str
= str
;
6624 skip_whitespace (q
);
6626 for (r
= q
; *r
!= '\0'; r
++)
6636 regnum
= arm_reg_parse (& q
);
6639 reg
= arm_reg_parse (& str
);
6644 insert_reg_alias (str
, regnum
);
6646 as_warn (_("register '%s' does not exist\n"), q
);
6648 else if (regnum
!= FAIL
)
6651 as_warn (_("ignoring redefinition of register alias '%s'"),
6654 /* Do not warn about redefinitions to the same alias. */
6657 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6661 as_warn (_("ignoring incomplete .req pseuso op"));
6668 as_bad (_("bad instruction `%s'"), start
);
6672 Invocation line includes a switch not recognized by the base assembler.
6673 See if it's a processor-specific option. These are:
6674 Cpu variants, the arm part is optional:
6675 -m[arm]1 Currently not supported.
6676 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6677 -m[arm]3 Arm 3 processor
6678 -m[arm]6[xx], Arm 6 processors
6679 -m[arm]7[xx][t][[d]m] Arm 7 processors
6680 -m[arm]8[10] Arm 8 processors
6681 -m[arm]9[20][tdmi] Arm 9 processors
6682 -mstrongarm[110[0]] StrongARM processors
6683 -m[arm]v[2345[t]] Arm architectures
6684 -mall All (except the ARM1)
6686 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6687 -mfpe-old (No float load/store multiples)
6688 -mno-fpu Disable all floating point instructions
6689 Run-time endian selection:
6691 -EL little endian cpu
6692 ARM Procedure Calling Standard:
6693 -mapcs-32 32 bit APCS
6694 -mapcs-26 26 bit APCS
6695 -mapcs-float Pass floats in float regs
6696 -mapcs-reentrant Position independent code
6697 -mthumb-interwork Code supports Arm/Thumb interworking
6698 -moabi Old ELF ABI */
6700 CONST
char * md_shortopts
= "m:k";
6702 struct option md_longopts
[] =
6704 #ifdef ARM_BI_ENDIAN
6705 #define OPTION_EB (OPTION_MD_BASE + 0)
6706 {"EB", no_argument
, NULL
, OPTION_EB
},
6707 #define OPTION_EL (OPTION_MD_BASE + 1)
6708 {"EL", no_argument
, NULL
, OPTION_EL
},
6710 #define OPTION_OABI (OPTION_MD_BASE +2)
6711 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6714 {NULL
, no_argument
, NULL
, 0}
6717 size_t md_longopts_size
= sizeof (md_longopts
);
6720 md_parse_option (c
, arg
)
6728 #ifdef ARM_BI_ENDIAN
6730 target_big_endian
= 1;
6733 target_big_endian
= 0;
6741 if (streq (str
, "fpa10"))
6742 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6743 else if (streq (str
, "fpa11"))
6744 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6745 else if (streq (str
, "fpe-old"))
6746 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6752 if (streq (str
, "no-fpu"))
6753 cpu_variant
&= ~FPU_ALL
;
6758 if (streq (str
, "oabi"))
6764 /* Limit assembler to generating only Thumb instructions: */
6765 if (streq (str
, "thumb"))
6767 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6768 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6771 else if (streq (str
, "thumb-interwork"))
6773 if ((cpu_variant
& ARM_THUMB
) == 0)
6774 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6775 #if defined OBJ_COFF || defined OBJ_ELF
6776 support_interwork
= true;
6784 if (streq (str
, "all"))
6786 cpu_variant
= ARM_ALL
| FPU_ALL
;
6789 #if defined OBJ_COFF || defined OBJ_ELF
6790 if (! strncmp (str
, "apcs-", 5))
6792 /* GCC passes on all command line options starting "-mapcs-..."
6793 to us, so we must parse them here. */
6797 if (streq (str
, "32"))
6799 uses_apcs_26
= false;
6802 else if (streq (str
, "26"))
6804 uses_apcs_26
= true;
6807 else if (streq (str
, "frame"))
6809 /* Stack frames are being generated - does not affect
6813 else if (streq (str
, "stack-check"))
6815 /* Stack checking is being performed - does not affect
6816 linkage, but does require that the functions
6817 __rt_stkovf_split_small and __rt_stkovf_split_big be
6818 present in the final link. */
6822 else if (streq (str
, "float"))
6824 /* Floating point arguments are being passed in the floating
6825 point registers. This does affect linking, since this
6826 version of the APCS is incompatible with the version that
6827 passes floating points in the integer registers. */
6829 uses_apcs_float
= true;
6832 else if (streq (str
, "reentrant"))
6834 /* Reentrant code has been generated. This does affect
6835 linking, since there is no point in linking reentrant/
6836 position independent code with absolute position code. */
6841 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6845 /* Strip off optional "arm". */
6846 if (! strncmp (str
, "arm", 3))
6852 if (streq (str
, "1"))
6853 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6859 if (streq (str
, "2"))
6860 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6861 else if (streq (str
, "250"))
6862 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6868 if (streq (str
, "3"))
6869 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6875 switch (strtol (str
, NULL
, 10))
6882 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6890 /* Eat the processor name. */
6891 switch (strtol (str
, & str
, 10))
6904 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6910 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6914 cpu_variant
|= ARM_LONGMUL
;
6917 case 'f': /* fe => fp enabled cpu. */
6923 case 'c': /* Left over from 710c processor name. */
6924 case 'd': /* Debug. */
6925 case 'i': /* Embedded ICE. */
6926 /* Included for completeness in ARM processor naming. */
6936 if (streq (str
, "8") || streq (str
, "810"))
6937 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6938 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6944 if (streq (str
, "9"))
6945 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6946 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6947 else if (streq (str
, "920"))
6948 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6949 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6950 else if (streq (str
, "920t"))
6951 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6952 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6953 else if (streq (str
, "9tdmi"))
6954 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6955 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6961 if (streq (str
, "strongarm")
6962 || streq (str
, "strongarm110")
6963 || streq (str
, "strongarm1100"))
6964 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6965 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6971 /* Select variant based on architecture rather than
6979 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6982 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6985 as_bad (_("Invalid architecture variant -m%s"), arg
);
6991 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6995 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6998 as_bad (_("Invalid architecture variant -m%s"), arg
);
7004 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
7008 case 't': cpu_variant
|= ARM_THUMB
; break;
7011 as_bad (_("Invalid architecture variant -m%s"), arg
);
7017 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
7020 case 't': cpu_variant
|= ARM_THUMB
; break;
7023 as_bad (_("Invalid architecture variant -m%s"), arg
);
7029 as_bad (_("Invalid architecture variant -m%s"), arg
);
7036 as_bad (_("Invalid processor variant -m%s"), arg
);
7042 #if defined OBJ_ELF || defined OBJ_COFF
7060 ARM Specific Assembler Options:\n\
7061 -m[arm][<processor name>] select processor variant\n\
7062 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
7063 -mthumb only allow Thumb instructions\n\
7064 -mthumb-interwork mark the assembled code as supporting interworking\n\
7065 -mall allow any instruction\n\
7066 -mfpa10, -mfpa11 select floating point architecture\n\
7067 -mfpe-old don't allow floating-point multiple instructions\n\
7068 -mno-fpu don't allow any floating-point instructions.\n\
7069 -k generate PIC code.\n"));
7070 #if defined OBJ_COFF || defined OBJ_ELF
7072 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
7073 -mapcs-float floating point args are passed in FP regs\n\
7074 -mapcs-reentrant the code is position independent/reentrant\n"));
7078 -moabi support the old ELF ABI\n"));
7080 #ifdef ARM_BI_ENDIAN
7082 -EB assemble code for a big endian cpu\n\
7083 -EL assemble code for a little endian cpu\n"));
7087 /* We need to be able to fix up arbitrary expressions in some statements.
7088 This is so that we can handle symbols that are an arbitrary distance from
7089 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
7090 which returns part of an address in a form which will be valid for
7091 a data instruction. We do this by pushing the expression into a symbol
7092 in the expr_section, and creating a fix for that. */
7095 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
7104 arm_fix_data
* arm_data
;
7112 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
7116 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
7121 /* Mark whether the fix is to a THUMB instruction, or an ARM
7123 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
7124 new_fix
->tc_fix_data
= (PTR
) arm_data
;
7125 arm_data
->thumb_mode
= thumb_mode
;
7130 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
7133 cons_fix_new_arm (frag
, where
, size
, exp
)
7139 bfd_reloc_code_real_type type
;
7143 FIXME: @@ Should look at CPU word size. */
7150 type
= BFD_RELOC_16
;
7154 type
= BFD_RELOC_32
;
7157 type
= BFD_RELOC_64
;
7161 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
7164 /* A good place to do this, although this was probably not intended
7165 for this kind of use. We need to dump the literal pool before
7166 references are made to a null symbol pointer. */
7171 if (current_poolP
== NULL
)
7174 /* Put it at the end of text section. */
7175 subseg_set (text_section
, 0);
7177 listing_prev_line ();
7181 arm_start_line_hook ()
7183 last_label_seen
= NULL
;
7187 arm_frob_label (sym
)
7190 last_label_seen
= sym
;
7192 ARM_SET_THUMB (sym
, thumb_mode
);
7194 #if defined OBJ_COFF || defined OBJ_ELF
7195 ARM_SET_INTERWORK (sym
, support_interwork
);
7198 if (label_is_thumb_function_name
)
7200 /* When the address of a Thumb function is taken the bottom
7201 bit of that address should be set. This will allow
7202 interworking between Arm and Thumb functions to work
7205 THUMB_SET_FUNC (sym
, 1);
7207 label_is_thumb_function_name
= false;
7211 /* Adjust the symbol table. This marks Thumb symbols as distinct from
7215 arm_adjust_symtab ()
7220 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7222 if (ARM_IS_THUMB (sym
))
7224 if (THUMB_IS_FUNC (sym
))
7226 /* Mark the symbol as a Thumb function. */
7227 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
7228 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
7229 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
7231 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
7232 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
7234 as_bad (_("%s: unexpected function type: %d"),
7235 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
7237 else switch (S_GET_STORAGE_CLASS (sym
))
7240 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
7243 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7246 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7254 if (ARM_IS_INTERWORK (sym
))
7255 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7262 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7264 if (ARM_IS_THUMB (sym
))
7266 elf_symbol_type
*elf_sym
;
7268 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7269 bind
= ELF_ST_BIND (elf_sym
);
7271 /* If it's a .thumb_func, declare it as so,
7272 otherwise tag label as .code 16. */
7273 if (THUMB_IS_FUNC (sym
))
7274 elf_sym
->internal_elf_sym
.st_info
=
7275 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7277 elf_sym
->internal_elf_sym
.st_info
=
7278 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7287 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7289 *input_line_pointer
= '/';
7290 input_line_pointer
+= 5;
7291 *input_line_pointer
= 0;
7299 arm_canonicalize_symbol_name (name
)
7304 if (thumb_mode
&& (len
= strlen (name
)) > 5
7305 && streq (name
+ len
- 5, "/data"))
7306 *(name
+ len
- 5) = 0;
7312 arm_validate_fix (fixP
)
7315 /* If the destination of the branch is a defined symbol which does not have
7316 the THUMB_FUNC attribute, then we must be calling a function which has
7317 the (interfacearm) attribute. We look for the Thumb entry point to that
7318 function and change the branch to refer to that function instead. */
7319 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7320 && fixP
->fx_addsy
!= NULL
7321 && S_IS_DEFINED (fixP
->fx_addsy
)
7322 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7324 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7332 /* Relocations against Thumb function names must be left unadjusted,
7333 so that the linker can use this information to correctly set the
7334 bottom bit of their addresses. The MIPS version of this function
7335 also prevents relocations that are mips-16 specific, but I do not
7336 know why it does this.
7339 There is one other problem that ought to be addressed here, but
7340 which currently is not: Taking the address of a label (rather
7341 than a function) and then later jumping to that address. Such
7342 addresses also ought to have their bottom bit set (assuming that
7343 they reside in Thumb code), but at the moment they will not. */
7346 arm_fix_adjustable (fixP
)
7349 if (fixP
->fx_addsy
== NULL
)
7352 /* Prevent all adjustments to global symbols. */
7353 if (S_IS_EXTERN (fixP
->fx_addsy
))
7356 if (S_IS_WEAK (fixP
->fx_addsy
))
7359 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7360 && fixP
->fx_subsy
== NULL
)
7363 /* We need the symbol name for the VTABLE entries. */
7364 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7365 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7372 elf32_arm_target_format ()
7374 if (target_big_endian
)
7377 return "elf32-bigarm-oabi";
7379 return "elf32-bigarm";
7384 return "elf32-littlearm-oabi";
7386 return "elf32-littlearm";
7391 armelf_frob_symbol (symp
, puntp
)
7395 elf_frob_symbol (symp
, puntp
);
7399 arm_force_relocation (fixp
)
7402 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7403 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7404 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7405 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7406 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7407 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7413 static bfd_reloc_code_real_type
7423 bfd_reloc_code_real_type reloc
;
7427 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
7428 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7429 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7430 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
7431 branch instructions generated by GCC for PLT relocs. */
7432 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7433 { NULL
, 0, BFD_RELOC_UNUSED
}
7437 for (i
= 0, ip
= input_line_pointer
;
7438 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7440 id
[i
] = tolower (*ip
);
7442 for (i
= 0; reloc_map
[i
].str
; i
++)
7443 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7446 input_line_pointer
+= reloc_map
[i
].len
;
7448 return reloc_map
[i
].reloc
;
7452 s_arm_elf_cons (nbytes
)
7457 #ifdef md_flush_pending_output
7458 md_flush_pending_output ();
7461 if (is_it_end_of_statement ())
7463 demand_empty_rest_of_line ();
7467 #ifdef md_cons_align
7468 md_cons_align (nbytes
);
7473 bfd_reloc_code_real_type reloc
;
7477 if (exp
.X_op
== O_symbol
7478 && *input_line_pointer
== '('
7479 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
7481 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7482 int size
= bfd_get_reloc_size (howto
);
7485 as_bad ("%s relocations do not fit in %d bytes",
7486 howto
->name
, nbytes
);
7489 register char *p
= frag_more ((int) nbytes
);
7490 int offset
= nbytes
- size
;
7492 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7497 emit_expr (&exp
, (unsigned int) nbytes
);
7499 while (*input_line_pointer
++ == ',');
7501 /* Put terminator back into stream. */
7502 input_line_pointer
--;
7503 demand_empty_rest_of_line ();
7506 #endif /* OBJ_ELF */