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
},
567 /* Functions called by parser. */
568 /* ARM instructions. */
569 static void do_arit
PARAMS ((char *, unsigned long));
570 static void do_cmp
PARAMS ((char *, unsigned long));
571 static void do_mov
PARAMS ((char *, unsigned long));
572 static void do_ldst
PARAMS ((char *, unsigned long));
573 static void do_ldmstm
PARAMS ((char *, unsigned long));
574 static void do_branch
PARAMS ((char *, unsigned long));
575 static void do_swi
PARAMS ((char *, unsigned long));
576 /* Pseudo Op codes. */
577 static void do_adr
PARAMS ((char *, unsigned long));
578 static void do_adrl
PARAMS ((char *, unsigned long));
579 static void do_nop
PARAMS ((char *, unsigned long));
581 static void do_mul
PARAMS ((char *, unsigned long));
582 static void do_mla
PARAMS ((char *, unsigned long));
584 static void do_swap
PARAMS ((char *, unsigned long));
586 static void do_msr
PARAMS ((char *, unsigned long));
587 static void do_mrs
PARAMS ((char *, unsigned long));
589 static void do_mull
PARAMS ((char *, unsigned long));
591 static void do_bx
PARAMS ((char *, unsigned long));
593 /* Coprocessor Instructions. */
594 static void do_cdp
PARAMS ((char *, unsigned long));
595 static void do_lstc
PARAMS ((char *, unsigned long));
596 static void do_co_reg
PARAMS ((char *, unsigned long));
597 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
598 static void do_fp_ldst
PARAMS ((char *, unsigned long));
599 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
600 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
601 static void do_fp_monadic
PARAMS ((char *, unsigned long));
602 static void do_fp_cmp
PARAMS ((char *, unsigned long));
603 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
604 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
606 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
607 static int arm_reg_parse
PARAMS ((char **));
608 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
609 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
610 static int add_to_lit_pool
PARAMS ((void));
611 static unsigned validate_immediate
PARAMS ((unsigned));
612 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
613 static int validate_offset_imm
PARAMS ((unsigned int, int));
614 static void opcode_select
PARAMS ((int));
615 static void end_of_line
PARAMS ((char *));
616 static int reg_required_here
PARAMS ((char **, int));
617 static int psr_required_here
PARAMS ((char **));
618 static int co_proc_number
PARAMS ((char **));
619 static int cp_opc_expr
PARAMS ((char **, int, int));
620 static int cp_reg_required_here
PARAMS ((char **, int));
621 static int fp_reg_required_here
PARAMS ((char **, int));
622 static int cp_address_offset
PARAMS ((char **));
623 static int cp_address_required_here
PARAMS ((char **));
624 static int my_get_float_expression
PARAMS ((char **));
625 static int skip_past_comma
PARAMS ((char **));
626 static int walk_no_bignums
PARAMS ((symbolS
*));
627 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
628 static int data_op2
PARAMS ((char **));
629 static int fp_op2
PARAMS ((char **));
630 static long reg_list
PARAMS ((char **));
631 static void thumb_load_store
PARAMS ((char *, int, int));
632 static int decode_shift
PARAMS ((char **, int));
633 static int ldst_extend
PARAMS ((char **, int));
634 static void thumb_add_sub
PARAMS ((char *, int));
635 static void insert_reg
PARAMS ((int));
636 static void thumb_shift
PARAMS ((char *, int));
637 static void thumb_mov_compare
PARAMS ((char *, int));
638 static void set_constant_flonums
PARAMS ((void));
639 static valueT md_chars_to_number
PARAMS ((char *, int));
640 static void insert_reg_alias
PARAMS ((char *, int));
641 static void output_inst
PARAMS ((void));
643 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
646 /* ARM instructions take 4bytes in the object file, Thumb instructions
650 /* LONGEST_INST is the longest basic instruction name without conditions or
651 flags. ARM7M has 4 of length 5. */
653 #define LONGEST_INST 5
657 /* Basic string to match. */
658 CONST
char * template;
660 /* Basic instruction code. */
663 /* Compulsory suffix that must follow conds. If "", then the
664 instruction is not conditional and must have no suffix. */
665 CONST
char * comp_suffix
;
667 /* Bits to toggle if flag 'n' set. */
668 CONST
struct asm_flg
* flags
;
670 /* Which CPU variants this exists for. */
671 unsigned long variants
;
673 /* Function to call to parse args. */
674 void (* parms
) PARAMS ((char *, unsigned long));
677 static CONST
struct asm_opcode insns
[] =
679 /* ARM Instructions. */
680 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
681 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
682 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
683 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
684 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
685 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
686 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
687 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
688 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
689 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
690 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
691 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
692 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
693 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
694 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
695 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
696 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
697 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
698 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
699 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
700 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
702 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
703 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
705 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
706 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
710 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
711 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
712 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
714 /* ARM 2 multiplies. */
715 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
716 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
718 /* ARM 3 - swp instructions. */
719 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
721 /* ARM 6 Coprocessor instructions. */
722 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
723 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
724 /* ScottB: our code uses 0x0128f000 for msr.
725 NickC: but this is wrong because the bits 16 through 19 are
726 handled by the PSR_xxx defines above. */
728 /* ARM 7M long multiplies - need signed/unsigned flags! */
729 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
730 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
731 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
732 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
734 /* ARM THUMB interworking. */
735 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
737 /* Floating point instructions. */
738 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
739 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
740 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
741 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
742 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
743 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
744 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
745 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
746 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
747 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
748 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
749 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
750 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
751 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
752 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
753 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
754 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
755 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
756 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
757 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
758 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
759 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
760 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
761 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
762 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
763 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
764 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
765 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
766 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
767 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
768 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
769 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
770 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
771 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
772 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
773 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
774 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
775 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
776 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
777 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
778 be an optional suffix, but part of the instruction. To be compatible,
780 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
781 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
782 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
783 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
785 /* Generic copressor instructions. */
786 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
787 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
788 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
789 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
790 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
793 /* Defines for various bits that we will want to toggle. */
794 #define INST_IMMEDIATE 0x02000000
795 #define OFFSET_REG 0x02000000
796 #define HWOFFSET_IMM 0x00400000
797 #define SHIFT_BY_REG 0x00000010
798 #define PRE_INDEX 0x01000000
799 #define INDEX_UP 0x00800000
800 #define WRITE_BACK 0x00200000
801 #define LDM_TYPE_2_OR_3 0x00400000
803 #define LITERAL_MASK 0xf000f000
804 #define COND_MASK 0xf0000000
805 #define OPCODE_MASK 0xfe1fffff
806 #define DATA_OP_SHIFT 21
808 /* Codes to distinguish the arithmetic instructions. */
819 #define OPCODE_CMP 10
820 #define OPCODE_CMN 11
821 #define OPCODE_ORR 12
822 #define OPCODE_MOV 13
823 #define OPCODE_BIC 14
824 #define OPCODE_MVN 15
826 static void do_t_nop
PARAMS ((char *));
827 static void do_t_arit
PARAMS ((char *));
828 static void do_t_add
PARAMS ((char *));
829 static void do_t_asr
PARAMS ((char *));
830 static void do_t_branch9
PARAMS ((char *));
831 static void do_t_branch12
PARAMS ((char *));
832 static void do_t_branch23
PARAMS ((char *));
833 static void do_t_bx
PARAMS ((char *));
834 static void do_t_compare
PARAMS ((char *));
835 static void do_t_ldmstm
PARAMS ((char *));
836 static void do_t_ldr
PARAMS ((char *));
837 static void do_t_ldrb
PARAMS ((char *));
838 static void do_t_ldrh
PARAMS ((char *));
839 static void do_t_lds
PARAMS ((char *));
840 static void do_t_lsl
PARAMS ((char *));
841 static void do_t_lsr
PARAMS ((char *));
842 static void do_t_mov
PARAMS ((char *));
843 static void do_t_push_pop
PARAMS ((char *));
844 static void do_t_str
PARAMS ((char *));
845 static void do_t_strb
PARAMS ((char *));
846 static void do_t_strh
PARAMS ((char *));
847 static void do_t_sub
PARAMS ((char *));
848 static void do_t_swi
PARAMS ((char *));
849 static void do_t_adr
PARAMS ((char *));
851 #define T_OPCODE_MUL 0x4340
852 #define T_OPCODE_TST 0x4200
853 #define T_OPCODE_CMN 0x42c0
854 #define T_OPCODE_NEG 0x4240
855 #define T_OPCODE_MVN 0x43c0
857 #define T_OPCODE_ADD_R3 0x1800
858 #define T_OPCODE_SUB_R3 0x1a00
859 #define T_OPCODE_ADD_HI 0x4400
860 #define T_OPCODE_ADD_ST 0xb000
861 #define T_OPCODE_SUB_ST 0xb080
862 #define T_OPCODE_ADD_SP 0xa800
863 #define T_OPCODE_ADD_PC 0xa000
864 #define T_OPCODE_ADD_I8 0x3000
865 #define T_OPCODE_SUB_I8 0x3800
866 #define T_OPCODE_ADD_I3 0x1c00
867 #define T_OPCODE_SUB_I3 0x1e00
869 #define T_OPCODE_ASR_R 0x4100
870 #define T_OPCODE_LSL_R 0x4080
871 #define T_OPCODE_LSR_R 0x40c0
872 #define T_OPCODE_ASR_I 0x1000
873 #define T_OPCODE_LSL_I 0x0000
874 #define T_OPCODE_LSR_I 0x0800
876 #define T_OPCODE_MOV_I8 0x2000
877 #define T_OPCODE_CMP_I8 0x2800
878 #define T_OPCODE_CMP_LR 0x4280
879 #define T_OPCODE_MOV_HR 0x4600
880 #define T_OPCODE_CMP_HR 0x4500
882 #define T_OPCODE_LDR_PC 0x4800
883 #define T_OPCODE_LDR_SP 0x9800
884 #define T_OPCODE_STR_SP 0x9000
885 #define T_OPCODE_LDR_IW 0x6800
886 #define T_OPCODE_STR_IW 0x6000
887 #define T_OPCODE_LDR_IH 0x8800
888 #define T_OPCODE_STR_IH 0x8000
889 #define T_OPCODE_LDR_IB 0x7800
890 #define T_OPCODE_STR_IB 0x7000
891 #define T_OPCODE_LDR_RW 0x5800
892 #define T_OPCODE_STR_RW 0x5000
893 #define T_OPCODE_LDR_RH 0x5a00
894 #define T_OPCODE_STR_RH 0x5200
895 #define T_OPCODE_LDR_RB 0x5c00
896 #define T_OPCODE_STR_RB 0x5400
898 #define T_OPCODE_PUSH 0xb400
899 #define T_OPCODE_POP 0xbc00
901 #define T_OPCODE_BRANCH 0xe7fe
903 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
905 #define THUMB_SIZE 2 /* Size of thumb instruction. */
906 #define THUMB_REG_LO 0x1
907 #define THUMB_REG_HI 0x2
908 #define THUMB_REG_ANY 0x3
910 #define THUMB_H1 0x0080
911 #define THUMB_H2 0x0040
918 #define THUMB_COMPARE 1
921 #define THUMB_STORE 1
923 #define THUMB_PP_PC_LR 0x0100
925 /* These three are used for immediate shifts, do not alter. */
927 #define THUMB_HALFWORD 1
932 /* Basic string to match. */
933 CONST
char * template;
935 /* Basic instruction code. */
940 /* Which CPU variants this exists for. */
941 unsigned long variants
;
943 /* Function to call to parse args. */
944 void (* parms
) PARAMS ((char *));
947 static CONST
struct thumb_opcode tinsns
[] =
949 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
950 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
951 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
952 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
953 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
954 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
955 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
956 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
957 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
958 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
959 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
960 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
961 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
962 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
963 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
964 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
965 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
966 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
967 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
968 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
969 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
970 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
971 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
972 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
973 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
974 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
975 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
976 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
977 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
978 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
979 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
980 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
981 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
982 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
983 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
984 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
985 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
986 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
987 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
988 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
989 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
990 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
991 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
992 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
993 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
994 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
995 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
996 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
997 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
998 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
999 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
1000 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
1001 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
1002 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
1003 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
1005 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
1006 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
1015 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1016 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1017 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1023 /* These are the standard names. Users can add aliases with .req. */
1024 static CONST
struct reg_entry reg_table
[] =
1026 /* Processor Register Numbers. */
1027 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1028 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1029 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1030 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1031 /* APCS conventions. */
1032 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1033 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1034 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1035 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1036 /* ATPCS additions to APCS conventions. */
1037 {"wr", 7}, {"v8", 11},
1039 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1040 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1041 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1042 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1043 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1044 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1045 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1046 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1047 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1048 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1049 /* ATPCS additions to float register names. */
1050 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1051 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1052 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1053 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1054 /* FIXME: At some point we need to add VFP register names. */
1055 /* Array terminator. */
1059 #define BAD_ARGS _("Bad arguments to instruction")
1060 #define BAD_PC _("r15 not allowed here")
1061 #define BAD_FLAGS _("Instruction should not have flags")
1062 #define BAD_COND _("Instruction is not conditional")
1064 static struct hash_control
* arm_ops_hsh
= NULL
;
1065 static struct hash_control
* arm_tops_hsh
= NULL
;
1066 static struct hash_control
* arm_cond_hsh
= NULL
;
1067 static struct hash_control
* arm_shift_hsh
= NULL
;
1068 static struct hash_control
* arm_reg_hsh
= NULL
;
1069 static struct hash_control
* arm_psr_hsh
= NULL
;
1071 /* This table describes all the machine specific pseudo-ops the assembler
1072 has to support. The fields are:
1073 pseudo-op name without dot
1074 function to call to execute this pseudo-op
1075 Integer arg to pass to the function. */
1077 static void s_req
PARAMS ((int));
1078 static void s_align
PARAMS ((int));
1079 static void s_bss
PARAMS ((int));
1080 static void s_even
PARAMS ((int));
1081 static void s_ltorg
PARAMS ((int));
1082 static void s_arm
PARAMS ((int));
1083 static void s_thumb
PARAMS ((int));
1084 static void s_code
PARAMS ((int));
1085 static void s_force_thumb
PARAMS ((int));
1086 static void s_thumb_func
PARAMS ((int));
1087 static void s_thumb_set
PARAMS ((int));
1088 static void arm_s_text
PARAMS ((int));
1089 static void arm_s_data
PARAMS ((int));
1091 static void arm_s_section
PARAMS ((int));
1092 static void s_arm_elf_cons
PARAMS ((int));
1095 static int my_get_expression
PARAMS ((expressionS
*, char **));
1097 CONST pseudo_typeS md_pseudo_table
[] =
1099 /* Never called becasue '.req' does not start line. */
1100 { "req", s_req
, 0 },
1101 { "bss", s_bss
, 0 },
1102 { "align", s_align
, 0 },
1103 { "arm", s_arm
, 0 },
1104 { "thumb", s_thumb
, 0 },
1105 { "code", s_code
, 0 },
1106 { "force_thumb", s_force_thumb
, 0 },
1107 { "thumb_func", s_thumb_func
, 0 },
1108 { "thumb_set", s_thumb_set
, 0 },
1109 { "even", s_even
, 0 },
1110 { "ltorg", s_ltorg
, 0 },
1111 { "pool", s_ltorg
, 0 },
1112 /* Allow for the effect of section changes. */
1113 { "text", arm_s_text
, 0 },
1114 { "data", arm_s_data
, 0 },
1116 { "section", arm_s_section
, 0 },
1117 { "section.s", arm_s_section
, 0 },
1118 { "sect", arm_s_section
, 0 },
1119 { "sect.s", arm_s_section
, 0 },
1120 { "word", s_arm_elf_cons
, 4 },
1121 { "long", s_arm_elf_cons
, 4 },
1125 { "extend", float_cons
, 'x' },
1126 { "ldouble", float_cons
, 'x' },
1127 { "packed", float_cons
, 'p' },
1131 /* Stuff needed to resolve the label ambiguity
1141 symbolS
* last_label_seen
;
1142 static int label_is_thumb_function_name
= false;
1144 /* Literal stuff. */
1146 #define MAX_LITERAL_POOL_SIZE 1024
1148 typedef struct literalS
1150 struct expressionS exp
;
1151 struct arm_it
* inst
;
1154 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1156 /* Next free entry in the pool. */
1157 int next_literal_pool_place
= 0;
1159 /* Next literal pool number. */
1160 int lit_pool_num
= 1;
1162 symbolS
* current_poolP
= NULL
;
1169 if (current_poolP
== NULL
)
1170 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1171 (valueT
) 0, &zero_address_frag
);
1173 /* Check if this literal value is already in the pool: */
1174 while (lit_count
< next_literal_pool_place
)
1176 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1177 && inst
.reloc
.exp
.X_op
== O_constant
1178 && (literals
[lit_count
].exp
.X_add_number
1179 == inst
.reloc
.exp
.X_add_number
)
1180 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1185 if (lit_count
== next_literal_pool_place
) /* New entry. */
1187 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1189 inst
.error
= _("Literal Pool Overflow");
1193 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1194 lit_count
= next_literal_pool_place
++;
1197 inst
.reloc
.exp
.X_op
= O_symbol
;
1198 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1199 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1204 /* Can't use symbol_new here, so have to create a symbol and then at
1205 a later date assign it a value. Thats what these functions do. */
1208 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1210 CONST
char * name
; /* It is copied, the caller can modify. */
1211 segT segment
; /* Segment identifier (SEG_<something>). */
1212 valueT valu
; /* Symbol value. */
1213 fragS
* frag
; /* Associated fragment. */
1215 unsigned int name_length
;
1216 char * preserved_copy_of_name
;
1218 name_length
= strlen (name
) + 1; /* +1 for \0. */
1219 obstack_grow (¬es
, name
, name_length
);
1220 preserved_copy_of_name
= obstack_finish (¬es
);
1221 #ifdef STRIP_UNDERSCORE
1222 if (preserved_copy_of_name
[0] == '_')
1223 preserved_copy_of_name
++;
1226 #ifdef tc_canonicalize_symbol_name
1227 preserved_copy_of_name
=
1228 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1231 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1233 S_SET_SEGMENT (symbolP
, segment
);
1234 S_SET_VALUE (symbolP
, valu
);
1235 symbol_clear_list_pointers(symbolP
);
1237 symbol_set_frag (symbolP
, frag
);
1239 /* Link to end of symbol chain. */
1241 extern int symbol_table_frozen
;
1242 if (symbol_table_frozen
)
1246 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1248 obj_symbol_new_hook (symbolP
);
1250 #ifdef tc_symbol_new_hook
1251 tc_symbol_new_hook (symbolP
);
1255 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1256 #endif /* DEBUG_SYMS */
1259 /* Check that an immediate is valid.
1260 If so, convert it to the right format. */
1263 validate_immediate (val
)
1269 #define rotate_left(v, n) (v << n | v >> (32 - n))
1271 for (i
= 0; i
< 32; i
+= 2)
1272 if ((a
= rotate_left (val
, i
)) <= 0xff)
1273 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1278 /* Check to see if an immediate can be computed as two seperate immediate
1279 values, added together. We already know that this value cannot be
1280 computed by just one ARM instruction. */
1283 validate_immediate_twopart (val
, highpart
)
1285 unsigned int * highpart
;
1290 for (i
= 0; i
< 32; i
+= 2)
1291 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1297 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1299 else if (a
& 0xff0000)
1303 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1307 assert (a
& 0xff000000);
1308 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1311 return (a
& 0xff) | (i
<< 7);
1318 validate_offset_imm (val
, hwse
)
1322 if ((hwse
&& val
> 255) || val
> 4095)
1329 int a ATTRIBUTE_UNUSED
;
1331 as_bad (_("Invalid syntax for .req directive."));
1336 int ignore ATTRIBUTE_UNUSED
;
1338 /* We don't support putting frags in the BSS segment, we fake it by
1339 marking in_bss, then looking at s_skip for clues. */
1340 subseg_set (bss_section
, 0);
1341 demand_empty_rest_of_line ();
1346 int ignore ATTRIBUTE_UNUSED
;
1348 /* Never make frag if expect extra pass. */
1350 frag_align (1, 0, 0);
1352 record_alignment (now_seg
, 1);
1354 demand_empty_rest_of_line ();
1359 int ignored ATTRIBUTE_UNUSED
;
1364 if (current_poolP
== NULL
)
1367 /* Align pool as you have word accesses.
1368 Only make a frag if we have to. */
1370 frag_align (2, 0, 0);
1372 record_alignment (now_seg
, 2);
1374 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1376 symbol_locate (current_poolP
, sym_name
, now_seg
,
1377 (valueT
) frag_now_fix (), frag_now
);
1378 symbol_table_insert (current_poolP
);
1380 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1382 #if defined OBJ_COFF || defined OBJ_ELF
1383 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1386 while (lit_count
< next_literal_pool_place
)
1387 /* First output the expression in the instruction to the pool. */
1388 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1390 next_literal_pool_place
= 0;
1391 current_poolP
= NULL
;
1394 /* Same as s_align_ptwo but align 0 => align 2. */
1398 int unused ATTRIBUTE_UNUSED
;
1401 register long temp_fill
;
1402 long max_alignment
= 15;
1404 temp
= get_absolute_expression ();
1405 if (temp
> max_alignment
)
1406 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1409 as_bad (_("Alignment negative. 0 assumed."));
1413 if (*input_line_pointer
== ',')
1415 input_line_pointer
++;
1416 temp_fill
= get_absolute_expression ();
1424 /* Only make a frag if we HAVE to. */
1425 if (temp
&& !need_pass_2
)
1426 frag_align (temp
, (int) temp_fill
, 0);
1427 demand_empty_rest_of_line ();
1429 record_alignment (now_seg
, temp
);
1433 s_force_thumb (ignore
)
1434 int ignore ATTRIBUTE_UNUSED
;
1436 /* If we are not already in thumb mode go into it, EVEN if
1437 the target processor does not support thumb instructions.
1438 This is used by gcc/config/arm/lib1funcs.asm for example
1439 to compile interworking support functions even if the
1440 target processor should not support interworking. */
1445 record_alignment (now_seg
, 1);
1448 demand_empty_rest_of_line ();
1452 s_thumb_func (ignore
)
1453 int ignore ATTRIBUTE_UNUSED
;
1458 /* The following label is the name/address of the start of a Thumb function.
1459 We need to know this for the interworking support. */
1460 label_is_thumb_function_name
= true;
1462 demand_empty_rest_of_line ();
1465 /* Perform a .set directive, but also mark the alias as
1466 being a thumb function. */
1472 /* XXX the following is a duplicate of the code for s_set() in read.c
1473 We cannot just call that code as we need to get at the symbol that
1475 register char * name
;
1476 register char delim
;
1477 register char * end_name
;
1478 register symbolS
* symbolP
;
1480 /* Especial apologies for the random logic:
1481 This just grew, and could be parsed much more simply!
1483 name
= input_line_pointer
;
1484 delim
= get_symbol_end ();
1485 end_name
= input_line_pointer
;
1490 if (*input_line_pointer
!= ',')
1493 as_bad (_("Expected comma after name \"%s\""), name
);
1495 ignore_rest_of_line ();
1499 input_line_pointer
++;
1502 if (name
[0] == '.' && name
[1] == '\0')
1504 /* XXX - this should not happen to .thumb_set. */
1508 if ((symbolP
= symbol_find (name
)) == NULL
1509 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1512 /* When doing symbol listings, play games with dummy fragments living
1513 outside the normal fragment chain to record the file and line info
1515 if (listing
& LISTING_SYMBOLS
)
1517 extern struct list_info_struct
* listing_tail
;
1518 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1520 memset (dummy_frag
, 0, sizeof (fragS
));
1521 dummy_frag
->fr_type
= rs_fill
;
1522 dummy_frag
->line
= listing_tail
;
1523 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1524 dummy_frag
->fr_symbol
= symbolP
;
1528 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1531 /* "set" symbols are local unless otherwise specified. */
1532 SF_SET_LOCAL (symbolP
);
1533 #endif /* OBJ_COFF */
1534 } /* Make a new symbol. */
1536 symbol_table_insert (symbolP
);
1541 && S_IS_DEFINED (symbolP
)
1542 && S_GET_SEGMENT (symbolP
) != reg_section
)
1543 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1545 pseudo_set (symbolP
);
1547 demand_empty_rest_of_line ();
1549 /* XXX Now we come to the Thumb specific bit of code. */
1551 THUMB_SET_FUNC (symbolP
, 1);
1552 ARM_SET_THUMB (symbolP
, 1);
1553 #if defined OBJ_ELF || defined OBJ_COFF
1554 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1558 /* If we change section we must dump the literal pool first. */
1564 if (now_seg
!= text_section
)
1568 obj_elf_text (ignore
);
1578 if (flag_readonly_data_in_text
)
1580 if (now_seg
!= text_section
)
1583 else if (now_seg
!= data_section
)
1587 obj_elf_data (ignore
);
1595 arm_s_section (ignore
)
1600 obj_elf_section (ignore
);
1605 opcode_select (width
)
1613 if (! (cpu_variant
& ARM_THUMB
))
1614 as_bad (_("selected processor does not support THUMB opcodes"));
1617 /* No need to force the alignment, since we will have been
1618 coming from ARM mode, which is word-aligned. */
1619 record_alignment (now_seg
, 1);
1626 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1627 as_bad (_("selected processor does not support ARM opcodes"));
1632 frag_align (2, 0, 0);
1634 record_alignment (now_seg
, 1);
1639 as_bad (_("invalid instruction size selected (%d)"), width
);
1645 int ignore ATTRIBUTE_UNUSED
;
1648 demand_empty_rest_of_line ();
1653 int ignore ATTRIBUTE_UNUSED
;
1656 demand_empty_rest_of_line ();
1661 int unused ATTRIBUTE_UNUSED
;
1665 temp
= get_absolute_expression ();
1670 opcode_select (temp
);
1674 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1682 skip_whitespace (str
);
1685 inst
.error
= _("Garbage following instruction");
1689 skip_past_comma (str
)
1692 char * p
= * str
, c
;
1695 while ((c
= *p
) == ' ' || c
== ',')
1698 if (c
== ',' && comma
++)
1706 return comma
? SUCCESS
: FAIL
;
1709 /* A standard register must be given at this point.
1710 SHIFT is the place to put it in inst.instruction.
1711 Restores input start point on error.
1712 Returns the reg#, or FAIL. */
1715 reg_required_here (str
, shift
)
1719 static char buff
[128]; /* XXX */
1721 char * start
= * str
;
1723 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1726 inst
.instruction
|= reg
<< shift
;
1730 /* Restore the start point, we may have got a reg of the wrong class. */
1733 /* In the few cases where we might be able to accept something else
1734 this error can be overridden. */
1735 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1741 static CONST
struct asm_psr
*
1743 register char ** ccp
;
1745 char * start
= * ccp
;
1748 CONST
struct asm_psr
* psr
;
1752 /* Skip to the end of the next word in the input stream. */
1757 while (isalpha (c
) || c
== '_');
1759 /* Terminate the word. */
1762 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1763 feature for ease of use and backwards compatibility. */
1764 if (!strncmp (start
, "cpsr", 4))
1765 strncpy (start
, "CPSR", 4);
1766 else if (!strncmp (start
, "spsr", 4))
1767 strncpy (start
, "SPSR", 4);
1769 /* Now locate the word in the psr hash table. */
1770 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1772 /* Restore the input stream. */
1775 /* If we found a valid match, advance the
1776 stream pointer past the end of the word. */
1782 /* Parse the input looking for a PSR flag. */
1785 psr_required_here (str
)
1788 char * start
= * str
;
1789 CONST
struct asm_psr
* psr
;
1791 psr
= arm_psr_parse (str
);
1795 /* If this is the SPSR that is being modified, set the R bit. */
1797 inst
.instruction
|= SPSR_BIT
;
1799 /* Set the psr flags in the MSR instruction. */
1800 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1805 /* In the few cases where we might be able to accept
1806 something else this error can be overridden. */
1807 inst
.error
= _("flag for {c}psr instruction expected");
1809 /* Restore the start point. */
1815 co_proc_number (str
)
1818 int processor
, pchar
;
1820 skip_whitespace (* str
);
1822 /* The data sheet seems to imply that just a number on its own is valid
1823 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1825 if (**str
== 'p' || **str
== 'P')
1829 if (pchar
>= '0' && pchar
<= '9')
1831 processor
= pchar
- '0';
1832 if (**str
>= '0' && **str
<= '9')
1834 processor
= processor
* 10 + *(*str
)++ - '0';
1837 inst
.error
= _("Illegal co-processor number");
1844 inst
.error
= _("Bad or missing co-processor number");
1848 inst
.instruction
|= processor
<< 8;
1853 cp_opc_expr (str
, where
, length
)
1860 skip_whitespace (* str
);
1862 memset (&expr
, '\0', sizeof (expr
));
1864 if (my_get_expression (&expr
, str
))
1866 if (expr
.X_op
!= O_constant
)
1868 inst
.error
= _("bad or missing expression");
1872 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1874 inst
.error
= _("immediate co-processor expression too large");
1878 inst
.instruction
|= expr
.X_add_number
<< where
;
1883 cp_reg_required_here (str
, where
)
1888 char * start
= *str
;
1890 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1893 inst
.instruction
|= reg
<< where
;
1897 /* In the few cases where we might be able to accept something else
1898 this error can be overridden. */
1899 inst
.error
= _("Co-processor register expected");
1901 /* Restore the start point. */
1907 fp_reg_required_here (str
, where
)
1912 char * start
= * str
;
1914 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1917 inst
.instruction
|= reg
<< where
;
1921 /* In the few cases where we might be able to accept something else
1922 this error can be overridden. */
1923 inst
.error
= _("Floating point register expected");
1925 /* Restore the start point. */
1931 cp_address_offset (str
)
1936 skip_whitespace (* str
);
1938 if (! is_immediate_prefix (**str
))
1940 inst
.error
= _("immediate expression expected");
1946 if (my_get_expression (& inst
.reloc
.exp
, str
))
1949 if (inst
.reloc
.exp
.X_op
== O_constant
)
1951 offset
= inst
.reloc
.exp
.X_add_number
;
1955 inst
.error
= _("co-processor address must be word aligned");
1959 if (offset
> 1023 || offset
< -1023)
1961 inst
.error
= _("offset too large");
1966 inst
.instruction
|= INDEX_UP
;
1970 inst
.instruction
|= offset
>> 2;
1973 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1979 cp_address_required_here (str
)
1991 skip_whitespace (p
);
1993 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1996 skip_whitespace (p
);
2002 if (skip_past_comma (& p
) == SUCCESS
)
2005 write_back
= WRITE_BACK
;
2009 inst
.error
= _("pc may not be used in post-increment");
2013 if (cp_address_offset (& p
) == FAIL
)
2017 pre_inc
= PRE_INDEX
| INDEX_UP
;
2021 /* '['Rn, #expr']'[!] */
2023 if (skip_past_comma (& p
) == FAIL
)
2025 inst
.error
= _("pre-indexed expression expected");
2029 pre_inc
= PRE_INDEX
;
2031 if (cp_address_offset (& p
) == FAIL
)
2034 skip_whitespace (p
);
2038 inst
.error
= _("missing ]");
2042 skip_whitespace (p
);
2048 inst
.error
= _("pc may not be used with write-back");
2053 write_back
= WRITE_BACK
;
2059 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2062 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2063 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2064 inst
.reloc
.pc_rel
= 1;
2065 inst
.instruction
|= (REG_PC
<< 16);
2066 pre_inc
= PRE_INDEX
;
2069 inst
.instruction
|= write_back
| pre_inc
;
2077 unsigned long flags
;
2079 /* Do nothing really. */
2080 inst
.instruction
|= flags
; /* This is pointless. */
2088 unsigned long flags
;
2092 /* Only one syntax. */
2093 skip_whitespace (str
);
2095 if (reg_required_here (&str
, 12) == FAIL
)
2097 inst
.error
= BAD_ARGS
;
2101 if (skip_past_comma (&str
) == FAIL
)
2103 inst
.error
= _("comma expected after register name");
2107 skip_whitespace (str
);
2109 if ( strcmp (str
, "CPSR") == 0
2110 || strcmp (str
, "SPSR") == 0
2111 /* Lower case versions for backwards compatability. */
2112 || strcmp (str
, "cpsr") == 0
2113 || strcmp (str
, "spsr") == 0)
2116 /* This is for backwards compatability with older toolchains. */
2117 else if ( strcmp (str
, "cpsr_all") == 0
2118 || strcmp (str
, "spsr_all") == 0)
2122 inst
.error
= _("{C|S}PSR expected");
2126 if (* str
== 's' || * str
== 'S')
2127 inst
.instruction
|= SPSR_BIT
;
2130 inst
.instruction
|= flags
;
2134 /* Two possible forms:
2135 "{C|S}PSR_<field>, Rm",
2136 "{C|S}PSR_f, #expression". */
2141 unsigned long flags
;
2143 skip_whitespace (str
);
2145 if (psr_required_here (& str
) == FAIL
)
2148 if (skip_past_comma (& str
) == FAIL
)
2150 inst
.error
= _("comma missing after psr flags");
2154 skip_whitespace (str
);
2156 if (reg_required_here (& str
, 0) != FAIL
)
2159 inst
.instruction
|= flags
;
2164 if (! is_immediate_prefix (* str
))
2167 _("only a register or immediate value can follow a psr flag");
2174 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2177 _("only a register or immediate value can follow a psr flag");
2181 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2183 inst
.error
= _("can only set flag field with immediate value");
2187 flags
|= INST_IMMEDIATE
;
2189 if (inst
.reloc
.exp
.X_add_symbol
)
2191 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2192 inst
.reloc
.pc_rel
= 0;
2196 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2198 if (value
== (unsigned) FAIL
)
2200 inst
.error
= _("Invalid constant");
2204 inst
.instruction
|= value
;
2208 inst
.instruction
|= flags
;
2212 /* Long Multiply Parser
2213 UMULL RdLo, RdHi, Rm, Rs
2214 SMULL RdLo, RdHi, Rm, Rs
2215 UMLAL RdLo, RdHi, Rm, Rs
2216 SMLAL RdLo, RdHi, Rm, Rs. */
2219 do_mull (str
, flags
)
2221 unsigned long flags
;
2223 int rdlo
, rdhi
, rm
, rs
;
2225 /* Only one format "rdlo, rdhi, rm, rs". */
2226 skip_whitespace (str
);
2228 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2230 inst
.error
= BAD_ARGS
;
2234 if (skip_past_comma (&str
) == FAIL
2235 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2237 inst
.error
= BAD_ARGS
;
2241 if (skip_past_comma (&str
) == FAIL
2242 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2244 inst
.error
= BAD_ARGS
;
2248 /* rdhi, rdlo and rm must all be different. */
2249 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2250 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2252 if (skip_past_comma (&str
) == FAIL
2253 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2255 inst
.error
= BAD_ARGS
;
2259 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2261 inst
.error
= BAD_PC
;
2265 inst
.instruction
|= flags
;
2273 unsigned long flags
;
2277 /* Only one format "rd, rm, rs". */
2278 skip_whitespace (str
);
2280 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2282 inst
.error
= BAD_ARGS
;
2288 inst
.error
= BAD_PC
;
2292 if (skip_past_comma (&str
) == FAIL
2293 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2295 inst
.error
= BAD_ARGS
;
2301 inst
.error
= BAD_PC
;
2306 as_tsktsk (_("rd and rm should be different in mul"));
2308 if (skip_past_comma (&str
) == FAIL
2309 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2311 inst
.error
= BAD_ARGS
;
2317 inst
.error
= BAD_PC
;
2321 inst
.instruction
|= flags
;
2329 unsigned long flags
;
2333 /* Only one format "rd, rm, rs, rn". */
2334 skip_whitespace (str
);
2336 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2338 inst
.error
= BAD_ARGS
;
2344 inst
.error
= BAD_PC
;
2348 if (skip_past_comma (&str
) == FAIL
2349 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2351 inst
.error
= BAD_ARGS
;
2357 inst
.error
= BAD_PC
;
2362 as_tsktsk (_("rd and rm should be different in mla"));
2364 if (skip_past_comma (&str
) == FAIL
2365 || (rd
= reg_required_here (&str
, 8)) == FAIL
2366 || skip_past_comma (&str
) == FAIL
2367 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2369 inst
.error
= BAD_ARGS
;
2373 if (rd
== REG_PC
|| rm
== REG_PC
)
2375 inst
.error
= BAD_PC
;
2379 inst
.instruction
|= flags
;
2384 /* Returns the index into fp_values of a floating point number,
2385 or -1 if not in the table. */
2388 my_get_float_expression (str
)
2391 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2397 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2399 /* Look for a raw floating point number. */
2400 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2401 && is_end_of_line
[(unsigned char) *save_in
])
2403 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2405 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2407 if (words
[j
] != fp_values
[i
][j
])
2411 if (j
== MAX_LITTLENUMS
)
2419 /* Try and parse a more complex expression, this will probably fail
2420 unless the code uses a floating point prefix (eg "0f"). */
2421 save_in
= input_line_pointer
;
2422 input_line_pointer
= *str
;
2423 if (expression (&exp
) == absolute_section
2424 && exp
.X_op
== O_big
2425 && exp
.X_add_number
< 0)
2427 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2429 if (gen_to_words (words
, 5, (long) 15) == 0)
2431 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2433 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2435 if (words
[j
] != fp_values
[i
][j
])
2439 if (j
== MAX_LITTLENUMS
)
2441 *str
= input_line_pointer
;
2442 input_line_pointer
= save_in
;
2449 *str
= input_line_pointer
;
2450 input_line_pointer
= save_in
;
2454 /* Return true if anything in the expression is a bignum. */
2457 walk_no_bignums (sp
)
2460 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2463 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2465 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2466 || (symbol_get_value_expression (sp
)->X_op_symbol
2467 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2474 my_get_expression (ep
, str
)
2481 save_in
= input_line_pointer
;
2482 input_line_pointer
= *str
;
2483 seg
= expression (ep
);
2486 if (seg
!= absolute_section
2487 && seg
!= text_section
2488 && seg
!= data_section
2489 && seg
!= bss_section
2490 && seg
!= undefined_section
)
2492 inst
.error
= _("bad_segment");
2493 *str
= input_line_pointer
;
2494 input_line_pointer
= save_in
;
2499 /* Get rid of any bignums now, so that we don't generate an error for which
2500 we can't establish a line number later on. Big numbers are never valid
2501 in instructions, which is where this routine is always called. */
2502 if (ep
->X_op
== O_big
2503 || (ep
->X_add_symbol
2504 && (walk_no_bignums (ep
->X_add_symbol
)
2506 && walk_no_bignums (ep
->X_op_symbol
)))))
2508 inst
.error
= _("Invalid constant");
2509 *str
= input_line_pointer
;
2510 input_line_pointer
= save_in
;
2514 *str
= input_line_pointer
;
2515 input_line_pointer
= save_in
;
2519 /* UNRESTRICT should be one if <shift> <register> is permitted for this
2523 decode_shift (str
, unrestrict
)
2527 const struct asm_shift_name
* shift
;
2531 skip_whitespace (* str
);
2533 for (p
= * str
; isalpha (* p
); p
++)
2538 inst
.error
= _("Shift expression expected");
2544 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
2549 inst
.error
= _("Shift expression expected");
2553 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
2555 if (shift
->properties
->index
== SHIFT_RRX
)
2558 inst
.instruction
|= shift
->properties
->bit_field
;
2562 skip_whitespace (p
);
2564 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
2566 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
2570 else if (! is_immediate_prefix (* p
))
2572 inst
.error
= (unrestrict
2573 ? _("shift requires register or #expression")
2574 : _("shift requires #expression"));
2582 if (my_get_expression (& inst
.reloc
.exp
, & p
))
2585 /* Validate some simple #expressions. */
2586 if (inst
.reloc
.exp
.X_op
== O_constant
)
2588 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2590 /* Reject operations greater than 32. */
2592 /* Reject a shift of 0 unless the mode allows it. */
2593 || (num
== 0 && shift
->properties
->allows_0
== 0)
2594 /* Reject a shift of 32 unless the mode allows it. */
2595 || (num
== 32 && shift
->properties
->allows_32
== 0)
2598 /* As a special case we allow a shift of zero for
2599 modes that do not support it to be recoded as an
2600 logical shift left of zero (ie nothing). We warn
2601 about this though. */
2604 as_warn (_("Shift of 0 ignored."));
2605 shift
= & shift_names
[0];
2606 assert (shift
->properties
->index
== SHIFT_LSL
);
2610 inst
.error
= _("Invalid immediate shift");
2615 /* Shifts of 32 are encoded as 0, for those shifts that
2620 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
2624 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2625 inst
.reloc
.pc_rel
= 0;
2626 inst
.instruction
|= shift
->properties
->bit_field
;
2633 /* Do those data_ops which can take a negative immediate constant
2634 by altering the instuction. A bit of a hack really.
2638 by inverting the second operand, and
2641 by negating the second operand. */
2644 negate_data_op (instruction
, value
)
2645 unsigned long * instruction
;
2646 unsigned long value
;
2649 unsigned long negated
, inverted
;
2651 negated
= validate_immediate (-value
);
2652 inverted
= validate_immediate (~value
);
2654 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2657 /* First negates. */
2658 case OPCODE_SUB
: /* ADD <-> SUB */
2659 new_inst
= OPCODE_ADD
;
2664 new_inst
= OPCODE_SUB
;
2668 case OPCODE_CMP
: /* CMP <-> CMN */
2669 new_inst
= OPCODE_CMN
;
2674 new_inst
= OPCODE_CMP
;
2678 /* Now Inverted ops. */
2679 case OPCODE_MOV
: /* MOV <-> MVN */
2680 new_inst
= OPCODE_MVN
;
2685 new_inst
= OPCODE_MOV
;
2689 case OPCODE_AND
: /* AND <-> BIC */
2690 new_inst
= OPCODE_BIC
;
2695 new_inst
= OPCODE_AND
;
2699 case OPCODE_ADC
: /* ADC <-> SBC */
2700 new_inst
= OPCODE_SBC
;
2705 new_inst
= OPCODE_ADC
;
2709 /* We cannot do anything. */
2714 if (value
== (unsigned) FAIL
)
2717 *instruction
&= OPCODE_MASK
;
2718 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2729 skip_whitespace (* str
);
2731 if (reg_required_here (str
, 0) != FAIL
)
2733 if (skip_past_comma (str
) == SUCCESS
)
2734 /* Shift operation on register. */
2735 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2741 /* Immediate expression. */
2742 if (is_immediate_prefix (**str
))
2747 if (my_get_expression (&inst
.reloc
.exp
, str
))
2750 if (inst
.reloc
.exp
.X_add_symbol
)
2752 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2753 inst
.reloc
.pc_rel
= 0;
2757 if (skip_past_comma (str
) == SUCCESS
)
2759 /* #x, y -- ie explicit rotation by Y. */
2760 if (my_get_expression (&expr
, str
))
2763 if (expr
.X_op
!= O_constant
)
2765 inst
.error
= _("Constant expression expected");
2769 /* Rotate must be a multiple of 2. */
2770 if (((unsigned) expr
.X_add_number
) > 30
2771 || (expr
.X_add_number
& 1) != 0
2772 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2774 inst
.error
= _("Invalid constant");
2777 inst
.instruction
|= INST_IMMEDIATE
;
2778 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2779 inst
.instruction
|= expr
.X_add_number
<< 7;
2783 /* Implicit rotation, select a suitable one. */
2784 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2788 /* Can't be done. Perhaps the code reads something like
2789 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
2790 if ((value
= negate_data_op (&inst
.instruction
,
2791 inst
.reloc
.exp
.X_add_number
))
2794 inst
.error
= _("Invalid constant");
2799 inst
.instruction
|= value
;
2802 inst
.instruction
|= INST_IMMEDIATE
;
2807 inst
.error
= _("Register or shift expression expected");
2816 skip_whitespace (* str
);
2818 if (fp_reg_required_here (str
, 0) != FAIL
)
2822 /* Immediate expression. */
2823 if (*((*str
)++) == '#')
2829 skip_whitespace (* str
);
2831 /* First try and match exact strings, this is to guarantee
2832 that some formats will work even for cross assembly. */
2834 for (i
= 0; fp_const
[i
]; i
++)
2836 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2840 *str
+= strlen (fp_const
[i
]);
2841 if (is_end_of_line
[(unsigned char) **str
])
2843 inst
.instruction
|= i
+ 8;
2850 /* Just because we didn't get a match doesn't mean that the
2851 constant isn't valid, just that it is in a format that we
2852 don't automatically recognize. Try parsing it with
2853 the standard expression routines. */
2854 if ((i
= my_get_float_expression (str
)) >= 0)
2856 inst
.instruction
|= i
+ 8;
2860 inst
.error
= _("Invalid floating point immediate expression");
2864 _("Floating point register or immediate expression expected");
2870 do_arit (str
, flags
)
2872 unsigned long flags
;
2874 skip_whitespace (str
);
2876 if (reg_required_here (&str
, 12) == FAIL
2877 || skip_past_comma (&str
) == FAIL
2878 || reg_required_here (&str
, 16) == FAIL
2879 || skip_past_comma (&str
) == FAIL
2880 || data_op2 (&str
) == FAIL
)
2883 inst
.error
= BAD_ARGS
;
2887 inst
.instruction
|= flags
;
2895 unsigned long flags
;
2897 /* This is a pseudo-op of the form "adr rd, label" to be converted
2898 into a relative address of the form "add rd, pc, #label-.-8". */
2899 skip_whitespace (str
);
2901 if (reg_required_here (&str
, 12) == FAIL
2902 || skip_past_comma (&str
) == FAIL
2903 || my_get_expression (&inst
.reloc
.exp
, &str
))
2906 inst
.error
= BAD_ARGS
;
2910 /* Frag hacking will turn this into a sub instruction if the offset turns
2911 out to be negative. */
2912 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2913 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2914 inst
.reloc
.pc_rel
= 1;
2915 inst
.instruction
|= flags
;
2921 do_adrl (str
, flags
)
2923 unsigned long flags
;
2925 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2926 into a relative address of the form:
2927 add rd, pc, #low(label-.-8)"
2928 add rd, rd, #high(label-.-8)" */
2930 skip_whitespace (str
);
2932 if (reg_required_here (& str
, 12) == FAIL
2933 || skip_past_comma (& str
) == FAIL
2934 || my_get_expression (& inst
.reloc
.exp
, & str
))
2937 inst
.error
= BAD_ARGS
;
2943 /* Frag hacking will turn this into a sub instruction if the offset turns
2944 out to be negative. */
2945 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2946 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2947 inst
.reloc
.pc_rel
= 1;
2948 inst
.instruction
|= flags
;
2949 inst
.size
= INSN_SIZE
* 2;
2957 unsigned long flags
;
2959 skip_whitespace (str
);
2961 if (reg_required_here (&str
, 16) == FAIL
)
2964 inst
.error
= BAD_ARGS
;
2968 if (skip_past_comma (&str
) == FAIL
2969 || data_op2 (&str
) == FAIL
)
2972 inst
.error
= BAD_ARGS
;
2976 inst
.instruction
|= flags
;
2977 if ((flags
& 0x0000f000) == 0)
2978 inst
.instruction
|= CONDS_BIT
;
2987 unsigned long flags
;
2989 skip_whitespace (str
);
2991 if (reg_required_here (&str
, 12) == FAIL
)
2994 inst
.error
= BAD_ARGS
;
2998 if (skip_past_comma (&str
) == FAIL
2999 || data_op2 (&str
) == FAIL
)
3002 inst
.error
= BAD_ARGS
;
3006 inst
.instruction
|= flags
;
3012 ldst_extend (str
, hwse
)
3023 if (my_get_expression (& inst
.reloc
.exp
, str
))
3026 if (inst
.reloc
.exp
.X_op
== O_constant
)
3028 int value
= inst
.reloc
.exp
.X_add_number
;
3030 if ((hwse
&& (value
< -255 || value
> 255))
3031 || (value
< -4095 || value
> 4095))
3033 inst
.error
= _("address offset too large");
3043 /* Halfword and signextension instructions have the
3044 immediate value split across bits 11..8 and bits 3..0. */
3046 inst
.instruction
|= (add
| HWOFFSET_IMM
3047 | ((value
>> 4) << 8) | (value
& 0xF));
3049 inst
.instruction
|= add
| value
;
3055 inst
.instruction
|= HWOFFSET_IMM
;
3056 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3059 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3060 inst
.reloc
.pc_rel
= 0;
3073 if (reg_required_here (str
, 0) == FAIL
)
3077 inst
.instruction
|= add
;
3080 inst
.instruction
|= add
| OFFSET_REG
;
3081 if (skip_past_comma (str
) == SUCCESS
)
3082 return decode_shift (str
, SHIFT_RESTRICT
);
3090 do_ldst (str
, flags
)
3092 unsigned long flags
;
3099 /* This is not ideal, but it is the simplest way of dealing with the
3100 ARM7T halfword instructions (since they use a different
3101 encoding, but the same mnemonic): */
3102 halfword
= (flags
& 0x80000000) != 0;
3105 /* This is actually a load/store of a halfword, or a
3106 signed-extension load. */
3107 if ((cpu_variant
& ARM_HALFWORD
) == 0)
3110 = _("Processor does not support halfwords or signed bytes");
3114 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
3115 | (flags
& ~COND_MASK
));
3120 skip_whitespace (str
);
3122 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
3125 inst
.error
= BAD_ARGS
;
3129 if (skip_past_comma (& str
) == FAIL
)
3131 inst
.error
= _("Address expected");
3141 skip_whitespace (str
);
3143 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3146 /* Conflicts can occur on stores as well as loads. */
3147 conflict_reg
= (conflict_reg
== reg
);
3149 skip_whitespace (str
);
3155 if (skip_past_comma (&str
) == SUCCESS
)
3157 /* [Rn],... (post inc) */
3158 if (ldst_extend (&str
, halfword
) == FAIL
)
3161 as_warn (_("%s register same as write-back base"),
3162 ((inst
.instruction
& LOAD_BIT
)
3163 ? _("destination") : _("source")));
3169 inst
.instruction
|= HWOFFSET_IMM
;
3171 skip_whitespace (str
);
3176 as_warn (_("%s register same as write-back base"),
3177 ((inst
.instruction
& LOAD_BIT
)
3178 ? _("destination") : _("source")));
3180 inst
.instruction
|= WRITE_BACK
;
3184 if (! (flags
& TRANS_BIT
))
3191 if (skip_past_comma (&str
) == FAIL
)
3193 inst
.error
= _("pre-indexed expression expected");
3198 if (ldst_extend (&str
, halfword
) == FAIL
)
3201 skip_whitespace (str
);
3205 inst
.error
= _("missing ]");
3209 skip_whitespace (str
);
3214 as_warn (_("%s register same as write-back base"),
3215 ((inst
.instruction
& LOAD_BIT
)
3216 ? _("destination") : _("source")));
3218 inst
.instruction
|= WRITE_BACK
;
3222 else if (*str
== '=')
3224 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
3227 skip_whitespace (str
);
3229 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3232 if (inst
.reloc
.exp
.X_op
!= O_constant
3233 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3235 inst
.error
= _("Constant expression expected");
3239 if (inst
.reloc
.exp
.X_op
== O_constant
3240 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3242 /* This can be done with a mov instruction. */
3243 inst
.instruction
&= LITERAL_MASK
;
3244 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3245 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3251 /* Insert into literal pool. */
3252 if (add_to_lit_pool () == FAIL
)
3255 inst
.error
= _("literal pool insertion failed");
3259 /* Change the instruction exp to point to the pool. */
3262 inst
.instruction
|= HWOFFSET_IMM
;
3263 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3266 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3267 inst
.reloc
.pc_rel
= 1;
3268 inst
.instruction
|= (REG_PC
<< 16);
3274 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3279 inst
.instruction
|= HWOFFSET_IMM
;
3280 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3283 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3285 /* PC rel adjust. */
3286 inst
.reloc
.exp
.X_add_number
-= 8;
3288 inst
.reloc
.pc_rel
= 1;
3289 inst
.instruction
|= (REG_PC
<< 16);
3293 if (pre_inc
&& (flags
& TRANS_BIT
))
3294 inst
.error
= _("Pre-increment instruction with translate");
3296 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3305 char * str
= * strp
;
3309 /* We come back here if we get ranges concatenated by '+' or '|'. */
3324 skip_whitespace (str
);
3326 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3335 inst
.error
= _("Bad range in register list");
3339 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3341 if (range
& (1 << i
))
3343 (_("Warning: Duplicated register (r%d) in register list"),
3351 if (range
& (1 << reg
))
3352 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3354 else if (reg
<= cur_reg
)
3355 as_tsktsk (_("Warning: Register range not in ascending order"));
3360 while (skip_past_comma (&str
) != FAIL
3361 || (in_range
= 1, *str
++ == '-'));
3363 skip_whitespace (str
);
3367 inst
.error
= _("Missing `}'");
3375 if (my_get_expression (&expr
, &str
))
3378 if (expr
.X_op
== O_constant
)
3380 if (expr
.X_add_number
3381 != (expr
.X_add_number
& 0x0000ffff))
3383 inst
.error
= _("invalid register mask");
3387 if ((range
& expr
.X_add_number
) != 0)
3389 int regno
= range
& expr
.X_add_number
;
3392 regno
= (1 << regno
) - 1;
3394 (_("Warning: Duplicated register (r%d) in register list"),
3398 range
|= expr
.X_add_number
;
3402 if (inst
.reloc
.type
!= 0)
3404 inst
.error
= _("expression too complex");
3408 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3409 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3410 inst
.reloc
.pc_rel
= 0;
3414 skip_whitespace (str
);
3416 if (*str
== '|' || *str
== '+')
3422 while (another_range
);
3429 do_ldmstm (str
, flags
)
3431 unsigned long flags
;
3436 skip_whitespace (str
);
3438 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3441 if (base_reg
== REG_PC
)
3443 inst
.error
= _("r15 not allowed as base register");
3447 skip_whitespace (str
);
3451 flags
|= WRITE_BACK
;
3455 if (skip_past_comma (&str
) == FAIL
3456 || (range
= reg_list (&str
)) == FAIL
)
3459 inst
.error
= BAD_ARGS
;
3466 flags
|= LDM_TYPE_2_OR_3
;
3469 inst
.instruction
|= flags
| range
;
3477 unsigned long flags
;
3479 skip_whitespace (str
);
3481 /* Allow optional leading '#'. */
3482 if (is_immediate_prefix (*str
))
3485 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3488 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3489 inst
.reloc
.pc_rel
= 0;
3490 inst
.instruction
|= flags
;
3498 do_swap (str
, flags
)
3500 unsigned long flags
;
3504 skip_whitespace (str
);
3506 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3511 inst
.error
= _("r15 not allowed in swap");
3515 if (skip_past_comma (&str
) == FAIL
3516 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3519 inst
.error
= BAD_ARGS
;
3525 inst
.error
= _("r15 not allowed in swap");
3529 if (skip_past_comma (&str
) == FAIL
3532 inst
.error
= BAD_ARGS
;
3536 skip_whitespace (str
);
3538 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3543 inst
.error
= BAD_PC
;
3547 skip_whitespace (str
);
3551 inst
.error
= _("missing ]");
3555 inst
.instruction
|= flags
;
3561 do_branch (str
, flags
)
3563 unsigned long flags ATTRIBUTE_UNUSED
;
3565 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3572 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
3573 required for the instruction. */
3575 /* arm_parse_reloc () works on input_line_pointer.
3576 We actually want to parse the operands to the branch instruction
3577 passed in 'str'. Save the input pointer and restore it later. */
3578 save_in
= input_line_pointer
;
3579 input_line_pointer
= str
;
3580 if (inst
.reloc
.exp
.X_op
== O_symbol
3582 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3584 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3585 inst
.reloc
.pc_rel
= 0;
3586 /* Modify str to point to after parsed operands, otherwise
3587 end_of_line() will complain about the (PLT) left in str. */
3588 str
= input_line_pointer
;
3592 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3593 inst
.reloc
.pc_rel
= 1;
3595 input_line_pointer
= save_in
;
3598 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3599 inst
.reloc
.pc_rel
= 1;
3600 #endif /* OBJ_ELF */
3609 unsigned long flags ATTRIBUTE_UNUSED
;
3613 skip_whitespace (str
);
3615 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3617 inst
.error
= BAD_ARGS
;
3621 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
3623 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
3631 unsigned long flags ATTRIBUTE_UNUSED
;
3633 /* Co-processor data operation.
3634 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3635 skip_whitespace (str
);
3637 if (co_proc_number (&str
) == FAIL
)
3640 inst
.error
= BAD_ARGS
;
3644 if (skip_past_comma (&str
) == FAIL
3645 || cp_opc_expr (&str
, 20,4) == FAIL
)
3648 inst
.error
= BAD_ARGS
;
3652 if (skip_past_comma (&str
) == FAIL
3653 || cp_reg_required_here (&str
, 12) == FAIL
)
3656 inst
.error
= BAD_ARGS
;
3660 if (skip_past_comma (&str
) == FAIL
3661 || cp_reg_required_here (&str
, 16) == FAIL
)
3664 inst
.error
= BAD_ARGS
;
3668 if (skip_past_comma (&str
) == FAIL
3669 || cp_reg_required_here (&str
, 0) == FAIL
)
3672 inst
.error
= BAD_ARGS
;
3676 if (skip_past_comma (&str
) == SUCCESS
)
3678 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3681 inst
.error
= BAD_ARGS
;
3691 do_lstc (str
, flags
)
3693 unsigned long flags
;
3695 /* Co-processor register load/store.
3696 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3698 skip_whitespace (str
);
3700 if (co_proc_number (&str
) == FAIL
)
3703 inst
.error
= BAD_ARGS
;
3707 if (skip_past_comma (&str
) == FAIL
3708 || cp_reg_required_here (&str
, 12) == FAIL
)
3711 inst
.error
= BAD_ARGS
;
3715 if (skip_past_comma (&str
) == FAIL
3716 || cp_address_required_here (&str
) == FAIL
)
3719 inst
.error
= BAD_ARGS
;
3723 inst
.instruction
|= flags
;
3729 do_co_reg (str
, flags
)
3731 unsigned long flags
;
3733 /* Co-processor register transfer.
3734 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3736 skip_whitespace (str
);
3738 if (co_proc_number (&str
) == FAIL
)
3741 inst
.error
= BAD_ARGS
;
3745 if (skip_past_comma (&str
) == FAIL
3746 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3749 inst
.error
= BAD_ARGS
;
3753 if (skip_past_comma (&str
) == FAIL
3754 || reg_required_here (&str
, 12) == FAIL
)
3757 inst
.error
= BAD_ARGS
;
3761 if (skip_past_comma (&str
) == FAIL
3762 || cp_reg_required_here (&str
, 16) == FAIL
)
3765 inst
.error
= BAD_ARGS
;
3769 if (skip_past_comma (&str
) == FAIL
3770 || cp_reg_required_here (&str
, 0) == FAIL
)
3773 inst
.error
= BAD_ARGS
;
3777 if (skip_past_comma (&str
) == SUCCESS
)
3779 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3782 inst
.error
= BAD_ARGS
;
3788 inst
.error
= BAD_COND
;
3796 do_fp_ctrl (str
, flags
)
3798 unsigned long flags ATTRIBUTE_UNUSED
;
3800 /* FP control registers.
3801 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3803 skip_whitespace (str
);
3805 if (reg_required_here (&str
, 12) == FAIL
)
3808 inst
.error
= BAD_ARGS
;
3817 do_fp_ldst (str
, flags
)
3819 unsigned long flags ATTRIBUTE_UNUSED
;
3821 skip_whitespace (str
);
3823 switch (inst
.suffix
)
3828 inst
.instruction
|= CP_T_X
;
3831 inst
.instruction
|= CP_T_Y
;
3834 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3840 if (fp_reg_required_here (&str
, 12) == FAIL
)
3843 inst
.error
= BAD_ARGS
;
3847 if (skip_past_comma (&str
) == FAIL
3848 || cp_address_required_here (&str
) == FAIL
)
3851 inst
.error
= BAD_ARGS
;
3859 do_fp_ldmstm (str
, flags
)
3861 unsigned long flags
;
3865 skip_whitespace (str
);
3867 if (fp_reg_required_here (&str
, 12) == FAIL
)
3870 inst
.error
= BAD_ARGS
;
3874 /* Get Number of registers to transfer. */
3875 if (skip_past_comma (&str
) == FAIL
3876 || my_get_expression (&inst
.reloc
.exp
, &str
))
3879 inst
.error
= _("constant expression expected");
3883 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3885 inst
.error
= _("Constant value required for number of registers");
3889 num_regs
= inst
.reloc
.exp
.X_add_number
;
3891 if (num_regs
< 1 || num_regs
> 4)
3893 inst
.error
= _("number of registers must be in the range [1:4]");
3900 inst
.instruction
|= CP_T_X
;
3903 inst
.instruction
|= CP_T_Y
;
3906 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3920 /* The instruction specified "ea" or "fd", so we can only accept
3921 [Rn]{!}. The instruction does not really support stacking or
3922 unstacking, so we have to emulate these by setting appropriate
3923 bits and offsets. */
3924 if (skip_past_comma (&str
) == FAIL
3928 inst
.error
= BAD_ARGS
;
3933 skip_whitespace (str
);
3935 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3938 skip_whitespace (str
);
3942 inst
.error
= BAD_ARGS
;
3954 _("R15 not allowed as base register with write-back");
3961 if (flags
& CP_T_Pre
)
3963 /* Pre-decrement. */
3964 offset
= 3 * num_regs
;
3970 /* Post-increment. */
3974 offset
= 3 * num_regs
;
3978 /* No write-back, so convert this into a standard pre-increment
3979 instruction -- aesthetically more pleasing. */
3980 flags
= CP_T_Pre
| CP_T_UD
;
3985 inst
.instruction
|= flags
| offset
;
3987 else if (skip_past_comma (&str
) == FAIL
3988 || cp_address_required_here (&str
) == FAIL
)
3991 inst
.error
= BAD_ARGS
;
3999 do_fp_dyadic (str
, flags
)
4001 unsigned long flags
;
4003 skip_whitespace (str
);
4005 switch (inst
.suffix
)
4010 inst
.instruction
|= 0x00000080;
4013 inst
.instruction
|= 0x00080000;
4019 if (fp_reg_required_here (&str
, 12) == FAIL
)
4022 inst
.error
= BAD_ARGS
;
4026 if (skip_past_comma (&str
) == FAIL
4027 || fp_reg_required_here (&str
, 16) == FAIL
)
4030 inst
.error
= BAD_ARGS
;
4034 if (skip_past_comma (&str
) == FAIL
4035 || fp_op2 (&str
) == FAIL
)
4038 inst
.error
= BAD_ARGS
;
4042 inst
.instruction
|= flags
;
4048 do_fp_monadic (str
, flags
)
4050 unsigned long flags
;
4052 skip_whitespace (str
);
4054 switch (inst
.suffix
)
4059 inst
.instruction
|= 0x00000080;
4062 inst
.instruction
|= 0x00080000;
4068 if (fp_reg_required_here (&str
, 12) == FAIL
)
4071 inst
.error
= BAD_ARGS
;
4075 if (skip_past_comma (&str
) == FAIL
4076 || fp_op2 (&str
) == FAIL
)
4079 inst
.error
= BAD_ARGS
;
4083 inst
.instruction
|= flags
;
4089 do_fp_cmp (str
, flags
)
4091 unsigned long flags
;
4093 skip_whitespace (str
);
4095 if (fp_reg_required_here (&str
, 16) == FAIL
)
4098 inst
.error
= BAD_ARGS
;
4102 if (skip_past_comma (&str
) == FAIL
4103 || fp_op2 (&str
) == FAIL
)
4106 inst
.error
= BAD_ARGS
;
4110 inst
.instruction
|= flags
;
4116 do_fp_from_reg (str
, flags
)
4118 unsigned long flags
;
4120 skip_whitespace (str
);
4122 switch (inst
.suffix
)
4127 inst
.instruction
|= 0x00000080;
4130 inst
.instruction
|= 0x00080000;
4136 if (fp_reg_required_here (&str
, 16) == FAIL
)
4139 inst
.error
= BAD_ARGS
;
4143 if (skip_past_comma (&str
) == FAIL
4144 || reg_required_here (&str
, 12) == FAIL
)
4147 inst
.error
= BAD_ARGS
;
4151 inst
.instruction
|= flags
;
4157 do_fp_to_reg (str
, flags
)
4159 unsigned long flags
;
4161 skip_whitespace (str
);
4163 if (reg_required_here (&str
, 12) == FAIL
)
4166 if (skip_past_comma (&str
) == FAIL
4167 || fp_reg_required_here (&str
, 0) == FAIL
)
4170 inst
.error
= BAD_ARGS
;
4174 inst
.instruction
|= flags
;
4179 /* Thumb specific routines. */
4181 /* Parse and validate that a register is of the right form, this saves
4182 repeated checking of this information in many similar cases.
4183 Unlike the 32-bit case we do not insert the register into the opcode
4184 here, since the position is often unknown until the full instruction
4188 thumb_reg (strp
, hi_lo
)
4194 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
4202 inst
.error
= _("lo register required");
4210 inst
.error
= _("hi register required");
4222 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4226 thumb_add_sub (str
, subtract
)
4230 int Rd
, Rs
, Rn
= FAIL
;
4232 skip_whitespace (str
);
4234 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4235 || skip_past_comma (&str
) == FAIL
)
4238 inst
.error
= BAD_ARGS
;
4242 if (is_immediate_prefix (*str
))
4246 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4251 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4254 if (skip_past_comma (&str
) == FAIL
)
4256 /* Two operand format, shuffle the registers
4257 and pretend there are 3. */
4261 else if (is_immediate_prefix (*str
))
4264 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4267 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4271 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4272 for the latter case, EXPR contains the immediate that was found. */
4275 /* All register format. */
4276 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4280 inst
.error
= _("dest and source1 must be the same register");
4284 /* Can't do this for SUB. */
4287 inst
.error
= _("subtract valid only on lo regs");
4291 inst
.instruction
= (T_OPCODE_ADD_HI
4292 | (Rd
> 7 ? THUMB_H1
: 0)
4293 | (Rn
> 7 ? THUMB_H2
: 0));
4294 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4298 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4299 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4304 /* Immediate expression, now things start to get nasty. */
4306 /* First deal with HI regs, only very restricted cases allowed:
4307 Adjusting SP, and using PC or SP to get an address. */
4308 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4309 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4311 inst
.error
= _("invalid Hi register with immediate");
4315 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4317 /* Value isn't known yet, all we can do is store all the fragments
4318 we know about in the instruction and let the reloc hacking
4320 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4321 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4325 int offset
= inst
.reloc
.exp
.X_add_number
;
4335 /* Quick check, in case offset is MIN_INT. */
4338 inst
.error
= _("immediate value out of range");
4347 if (offset
& ~0x1fc)
4349 inst
.error
= _("invalid immediate value for stack adjust");
4352 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4353 inst
.instruction
|= offset
>> 2;
4355 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4358 || (offset
& ~0x3fc))
4360 inst
.error
= _("invalid immediate for address calculation");
4363 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4365 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4371 inst
.error
= _("immediate value out of range");
4374 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4375 inst
.instruction
|= (Rd
<< 8) | offset
;
4381 inst
.error
= _("immediate value out of range");
4384 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4385 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4394 thumb_shift (str
, shift
)
4398 int Rd
, Rs
, Rn
= FAIL
;
4400 skip_whitespace (str
);
4402 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4403 || skip_past_comma (&str
) == FAIL
)
4406 inst
.error
= BAD_ARGS
;
4410 if (is_immediate_prefix (*str
))
4412 /* Two operand immediate format, set Rs to Rd. */
4415 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4420 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4423 if (skip_past_comma (&str
) == FAIL
)
4425 /* Two operand format, shuffle the registers
4426 and pretend there are 3. */
4430 else if (is_immediate_prefix (*str
))
4433 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4436 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4440 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4441 for the latter case, EXPR contains the immediate that was found. */
4447 inst
.error
= _("source1 and dest must be same register");
4453 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4454 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4455 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4458 inst
.instruction
|= Rd
| (Rn
<< 3);
4464 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4465 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4466 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4469 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4471 /* Value isn't known yet, create a dummy reloc and let reloc
4472 hacking fix it up. */
4473 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4477 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4479 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4481 inst
.error
= _("Invalid immediate for shift");
4485 /* Shifts of zero are handled by converting to LSL. */
4486 if (shift_value
== 0)
4487 inst
.instruction
= T_OPCODE_LSL_I
;
4489 /* Shifts of 32 are encoded as a shift of zero. */
4490 if (shift_value
== 32)
4493 inst
.instruction
|= shift_value
<< 6;
4496 inst
.instruction
|= Rd
| (Rs
<< 3);
4503 thumb_mov_compare (str
, move
)
4509 skip_whitespace (str
);
4511 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4512 || skip_past_comma (&str
) == FAIL
)
4515 inst
.error
= BAD_ARGS
;
4519 if (is_immediate_prefix (*str
))
4522 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4525 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4530 if (Rs
< 8 && Rd
< 8)
4532 if (move
== THUMB_MOVE
)
4533 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4534 since a MOV instruction produces unpredictable results. */
4535 inst
.instruction
= T_OPCODE_ADD_I3
;
4537 inst
.instruction
= T_OPCODE_CMP_LR
;
4538 inst
.instruction
|= Rd
| (Rs
<< 3);
4542 if (move
== THUMB_MOVE
)
4543 inst
.instruction
= T_OPCODE_MOV_HR
;
4545 inst
.instruction
= T_OPCODE_CMP_HR
;
4548 inst
.instruction
|= THUMB_H1
;
4551 inst
.instruction
|= THUMB_H2
;
4553 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4560 inst
.error
= _("only lo regs allowed with immediate");
4564 if (move
== THUMB_MOVE
)
4565 inst
.instruction
= T_OPCODE_MOV_I8
;
4567 inst
.instruction
= T_OPCODE_CMP_I8
;
4569 inst
.instruction
|= Rd
<< 8;
4571 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4572 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4575 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4579 inst
.error
= _("invalid immediate");
4583 inst
.instruction
|= value
;
4591 thumb_load_store (str
, load_store
, size
)
4596 int Rd
, Rb
, Ro
= FAIL
;
4598 skip_whitespace (str
);
4600 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4601 || skip_past_comma (&str
) == FAIL
)
4604 inst
.error
= BAD_ARGS
;
4611 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4614 if (skip_past_comma (&str
) != FAIL
)
4616 if (is_immediate_prefix (*str
))
4619 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4622 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4627 inst
.reloc
.exp
.X_op
= O_constant
;
4628 inst
.reloc
.exp
.X_add_number
= 0;
4633 inst
.error
= _("expected ']'");
4638 else if (*str
== '=')
4640 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4643 skip_whitespace (str
);
4645 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4650 if ( inst
.reloc
.exp
.X_op
!= O_constant
4651 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4653 inst
.error
= "Constant expression expected";
4657 if (inst
.reloc
.exp
.X_op
== O_constant
4658 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4660 /* This can be done with a mov instruction. */
4662 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4663 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4667 /* Insert into literal pool. */
4668 if (add_to_lit_pool () == FAIL
)
4671 inst
.error
= "literal pool insertion failed";
4675 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4676 inst
.reloc
.pc_rel
= 1;
4677 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4678 /* Adjust ARM pipeline offset to Thumb. */
4679 inst
.reloc
.exp
.X_add_number
+= 4;
4685 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4688 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4689 inst
.reloc
.pc_rel
= 1;
4690 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
4691 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4696 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4698 if (size
!= THUMB_WORD
)
4700 inst
.error
= _("byte or halfword not valid for base register");
4703 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4705 inst
.error
= _("R15 based store not allowed");
4708 else if (Ro
!= FAIL
)
4710 inst
.error
= _("Invalid base register for register offset");
4715 inst
.instruction
= T_OPCODE_LDR_PC
;
4716 else if (load_store
== THUMB_LOAD
)
4717 inst
.instruction
= T_OPCODE_LDR_SP
;
4719 inst
.instruction
= T_OPCODE_STR_SP
;
4721 inst
.instruction
|= Rd
<< 8;
4722 if (inst
.reloc
.exp
.X_op
== O_constant
)
4724 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4726 if (offset
& ~0x3fc)
4728 inst
.error
= _("invalid offset");
4732 inst
.instruction
|= offset
>> 2;
4735 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4739 inst
.error
= _("invalid base register in load/store");
4742 else if (Ro
== FAIL
)
4744 /* Immediate offset. */
4745 if (size
== THUMB_WORD
)
4746 inst
.instruction
= (load_store
== THUMB_LOAD
4747 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4748 else if (size
== THUMB_HALFWORD
)
4749 inst
.instruction
= (load_store
== THUMB_LOAD
4750 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4752 inst
.instruction
= (load_store
== THUMB_LOAD
4753 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4755 inst
.instruction
|= Rd
| (Rb
<< 3);
4757 if (inst
.reloc
.exp
.X_op
== O_constant
)
4759 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4761 if (offset
& ~(0x1f << size
))
4763 inst
.error
= _("Invalid offset");
4766 inst
.instruction
|= (offset
>> size
) << 6;
4769 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4773 /* Register offset. */
4774 if (size
== THUMB_WORD
)
4775 inst
.instruction
= (load_store
== THUMB_LOAD
4776 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4777 else if (size
== THUMB_HALFWORD
)
4778 inst
.instruction
= (load_store
== THUMB_LOAD
4779 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4781 inst
.instruction
= (load_store
== THUMB_LOAD
4782 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4784 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4799 /* Handle the Format 4 instructions that do not have equivalents in other
4800 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4809 skip_whitespace (str
);
4811 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4812 || skip_past_comma (&str
) == FAIL
4813 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4815 inst
.error
= BAD_ARGS
;
4819 if (skip_past_comma (&str
) != FAIL
)
4821 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4822 (It isn't allowed for CMP either, but that isn't handled by this
4824 if (inst
.instruction
== T_OPCODE_TST
4825 || inst
.instruction
== T_OPCODE_CMN
4826 || inst
.instruction
== T_OPCODE_NEG
4827 || inst
.instruction
== T_OPCODE_MVN
)
4829 inst
.error
= BAD_ARGS
;
4833 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4838 inst
.error
= _("dest and source1 one must be the same register");
4844 if (inst
.instruction
== T_OPCODE_MUL
4846 as_tsktsk (_("Rs and Rd must be different in MUL"));
4848 inst
.instruction
|= Rd
| (Rs
<< 3);
4856 thumb_add_sub (str
, 0);
4863 thumb_shift (str
, THUMB_ASR
);
4870 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4872 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4873 inst
.reloc
.pc_rel
= 1;
4881 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4883 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4884 inst
.reloc
.pc_rel
= 1;
4888 /* Find the real, Thumb encoded start of a Thumb function. */
4891 find_real_start (symbolP
)
4895 const char * name
= S_GET_NAME (symbolP
);
4896 symbolS
* new_target
;
4898 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
4899 #define STUB_NAME ".real_start_of"
4904 /* Names that start with '.' are local labels, not function entry points.
4905 The compiler may generate BL instructions to these labels because it
4906 needs to perform a branch to a far away location. */
4910 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4911 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4913 new_target
= symbol_find (real_start
);
4915 if (new_target
== NULL
)
4917 as_warn ("Failed to find real start of function: %s\n", name
);
4918 new_target
= symbolP
;
4930 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4933 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4934 inst
.reloc
.pc_rel
= 1;
4937 /* If the destination of the branch is a defined symbol which does not have
4938 the THUMB_FUNC attribute, then we must be calling a function which has
4939 the (interfacearm) attribute. We look for the Thumb entry point to that
4940 function and change the branch to refer to that function instead. */
4941 if ( inst
.reloc
.exp
.X_op
== O_symbol
4942 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4943 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4944 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4945 inst
.reloc
.exp
.X_add_symbol
=
4946 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4955 skip_whitespace (str
);
4957 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4960 /* This sets THUMB_H2 from the top bit of reg. */
4961 inst
.instruction
|= reg
<< 3;
4963 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4964 should cause the alignment to be checked once it is known. This is
4965 because BX PC only works if the instruction is word aligned. */
4974 thumb_mov_compare (str
, THUMB_COMPARE
);
4984 skip_whitespace (str
);
4986 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4990 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4994 if (skip_past_comma (&str
) == FAIL
4995 || (range
= reg_list (&str
)) == FAIL
)
4998 inst
.error
= BAD_ARGS
;
5002 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5004 /* This really doesn't seem worth it. */
5005 inst
.reloc
.type
= BFD_RELOC_NONE
;
5006 inst
.error
= _("Expression too complex");
5012 inst
.error
= _("only lo-regs valid in load/store multiple");
5016 inst
.instruction
|= (Rb
<< 8) | range
;
5024 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
5031 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
5038 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
5047 skip_whitespace (str
);
5049 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5050 || skip_past_comma (&str
) == FAIL
5052 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5053 || skip_past_comma (&str
) == FAIL
5054 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5058 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
5062 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5070 thumb_shift (str
, THUMB_LSL
);
5077 thumb_shift (str
, THUMB_LSR
);
5084 thumb_mov_compare (str
, THUMB_MOVE
);
5093 skip_whitespace (str
);
5095 if ((range
= reg_list (&str
)) == FAIL
)
5098 inst
.error
= BAD_ARGS
;
5102 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5104 /* This really doesn't seem worth it. */
5105 inst
.reloc
.type
= BFD_RELOC_NONE
;
5106 inst
.error
= _("Expression too complex");
5112 if ((inst
.instruction
== T_OPCODE_PUSH
5113 && (range
& ~0xff) == 1 << REG_LR
)
5114 || (inst
.instruction
== T_OPCODE_POP
5115 && (range
& ~0xff) == 1 << REG_PC
))
5117 inst
.instruction
|= THUMB_PP_PC_LR
;
5122 inst
.error
= _("invalid register list to push/pop instruction");
5127 inst
.instruction
|= range
;
5135 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
5142 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
5149 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
5156 thumb_add_sub (str
, 1);
5163 skip_whitespace (str
);
5165 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5168 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5179 /* This is a pseudo-op of the form "adr rd, label" to be converted
5180 into a relative address of the form "add rd, pc, #label-.-4". */
5181 skip_whitespace (str
);
5183 /* Store Rd in temporary location inside instruction. */
5184 if ((reg
= reg_required_here (&str
, 4)) == FAIL
5185 || (reg
> 7) /* For Thumb reg must be r0..r7. */
5186 || skip_past_comma (&str
) == FAIL
5187 || my_get_expression (&inst
.reloc
.exp
, &str
))
5190 inst
.error
= BAD_ARGS
;
5194 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5195 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
5196 inst
.reloc
.pc_rel
= 1;
5197 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
5206 int len
= strlen (reg_table
[entry
].name
) + 2;
5207 char * buf
= (char *) xmalloc (len
);
5208 char * buf2
= (char *) xmalloc (len
);
5211 #ifdef REGISTER_PREFIX
5212 buf
[i
++] = REGISTER_PREFIX
;
5215 strcpy (buf
+ i
, reg_table
[entry
].name
);
5217 for (i
= 0; buf
[i
]; i
++)
5218 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5222 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
5223 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
5227 insert_reg_alias (str
, regnum
)
5231 struct reg_entry
*new =
5232 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
5233 char *name
= xmalloc (strlen (str
) + 1);
5237 new->number
= regnum
;
5239 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5243 set_constant_flonums ()
5247 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5248 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5258 if ( (arm_ops_hsh
= hash_new ()) == NULL
5259 || (arm_tops_hsh
= hash_new ()) == NULL
5260 || (arm_cond_hsh
= hash_new ()) == NULL
5261 || (arm_shift_hsh
= hash_new ()) == NULL
5262 || (arm_reg_hsh
= hash_new ()) == NULL
5263 || (arm_psr_hsh
= hash_new ()) == NULL
)
5264 as_fatal (_("Virtual memory exhausted"));
5266 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5267 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5268 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5269 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5270 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5271 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5272 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
5273 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
5274 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5275 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5277 for (i
= 0; reg_table
[i
].name
; i
++)
5280 set_constant_flonums ();
5282 #if defined OBJ_COFF || defined OBJ_ELF
5284 unsigned int flags
= 0;
5286 /* Set the flags in the private structure. */
5287 if (uses_apcs_26
) flags
|= F_APCS26
;
5288 if (support_interwork
) flags
|= F_INTERWORK
;
5289 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5290 if (pic_code
) flags
|= F_PIC
;
5291 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5293 bfd_set_private_flags (stdoutput
, flags
);
5297 /* Record the CPU type as well. */
5298 switch (cpu_variant
& ARM_CPU_MASK
)
5301 mach
= bfd_mach_arm_2
;
5304 case ARM_3
: /* Also ARM_250. */
5305 mach
= bfd_mach_arm_2a
;
5309 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5310 mach
= bfd_mach_arm_4
;
5313 case ARM_7
: /* Also ARM_6. */
5314 mach
= bfd_mach_arm_3
;
5318 /* Catch special cases. */
5319 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5321 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5322 mach
= bfd_mach_arm_5T
;
5323 else if (cpu_variant
& ARM_EXT_V5
)
5324 mach
= bfd_mach_arm_5
;
5325 else if (cpu_variant
& ARM_THUMB
)
5326 mach
= bfd_mach_arm_4T
;
5327 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5328 mach
= bfd_mach_arm_4
;
5329 else if (cpu_variant
& ARM_LONGMUL
)
5330 mach
= bfd_mach_arm_3M
;
5333 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5336 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5337 for use in the a.out file, and stores them in the array pointed to by buf.
5338 This knows about the endian-ness of the target machine and does
5339 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5340 2 (short) and 4 (long) Floating numbers are put out as a series of
5341 LITTLENUMS (shorts, here at least). */
5344 md_number_to_chars (buf
, val
, n
)
5349 if (target_big_endian
)
5350 number_to_chars_bigendian (buf
, val
, n
);
5352 number_to_chars_littleendian (buf
, val
, n
);
5356 md_chars_to_number (buf
, n
)
5361 unsigned char * where
= (unsigned char *) buf
;
5363 if (target_big_endian
)
5368 result
|= (*where
++ & 255);
5376 result
|= (where
[n
] & 255);
5383 /* Turn a string in input_line_pointer into a floating point constant
5384 of type TYPE, and store the appropriate bytes in *LITP. The number
5385 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5386 returned, or NULL on OK.
5388 Note that fp constants aren't represent in the normal way on the ARM.
5389 In big endian mode, things are as expected. However, in little endian
5390 mode fp constants are big-endian word-wise, and little-endian byte-wise
5391 within the words. For example, (double) 1.1 in big endian mode is
5392 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5393 the byte sequence 99 99 f1 3f 9a 99 99 99.
5395 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5398 md_atof (type
, litP
, sizeP
)
5404 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5436 return _("Bad call to MD_ATOF()");
5439 t
= atof_ieee (input_line_pointer
, type
, words
);
5441 input_line_pointer
= t
;
5444 if (target_big_endian
)
5446 for (i
= 0; i
< prec
; i
++)
5448 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5454 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5455 8 byte float the order is 1 0 3 2. */
5456 for (i
= 0; i
< prec
; i
+= 2)
5458 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5459 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5467 /* The knowledge of the PC's pipeline offset is built into the insns
5471 md_pcrel_from (fixP
)
5475 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5476 && fixP
->fx_subsy
== NULL
)
5479 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5481 /* PC relative addressing on the Thumb is slightly odd
5482 as the bottom two bits of the PC are forced to zero
5483 for the calculation. */
5484 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5488 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5489 so we un-adjust here to compensate for the accomodation. */
5490 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5492 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5496 /* Round up a section size to the appropriate boundary. */
5499 md_section_align (segment
, size
)
5500 segT segment ATTRIBUTE_UNUSED
;
5506 /* Round all sects to multiple of 4. */
5507 return (size
+ 3) & ~3;
5511 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
5512 Otherwise we have no need to default values of symbols. */
5515 md_undefined_symbol (name
)
5516 char * name ATTRIBUTE_UNUSED
;
5519 if (name
[0] == '_' && name
[1] == 'G'
5520 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5524 if (symbol_find (name
))
5525 as_bad ("GOT already in the symbol table");
5527 GOT_symbol
= symbol_new (name
, undefined_section
,
5528 (valueT
) 0, & zero_address_frag
);
5538 /* arm_reg_parse () := if it looks like a register, return its token and
5539 advance the pointer. */
5543 register char ** ccp
;
5545 char * start
= * ccp
;
5548 struct reg_entry
* reg
;
5550 #ifdef REGISTER_PREFIX
5551 if (*start
!= REGISTER_PREFIX
)
5556 #ifdef OPTIONAL_REGISTER_PREFIX
5557 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5561 if (!isalpha (*p
) || !is_name_beginner (*p
))
5565 while (isalpha (c
) || isdigit (c
) || c
== '_')
5569 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5582 md_apply_fix3 (fixP
, val
, seg
)
5587 offsetT value
= * val
;
5589 unsigned int newimm
;
5592 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5593 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5595 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5597 /* Note whether this will delete the relocation. */
5599 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
5600 doesn't work fully.) */
5601 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5604 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5608 /* If this symbol is in a different section then we need to leave it for
5609 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5610 so we have to undo it's effects here. */
5613 if (fixP
->fx_addsy
!= NULL
5614 && S_IS_DEFINED (fixP
->fx_addsy
)
5615 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5618 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5619 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5623 value
+= md_pcrel_from (fixP
);
5627 /* Remember value for emit_reloc. */
5628 fixP
->fx_addnumber
= value
;
5630 switch (fixP
->fx_r_type
)
5632 case BFD_RELOC_ARM_IMMEDIATE
:
5633 newimm
= validate_immediate (value
);
5634 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5636 /* If the instruction will fail, see if we can fix things up by
5637 changing the opcode. */
5638 if (newimm
== (unsigned int) FAIL
5639 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5641 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5642 _("invalid constant (%lx) after fixup"),
5643 (unsigned long) value
);
5647 newimm
|= (temp
& 0xfffff000);
5648 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5651 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5653 unsigned int highpart
= 0;
5654 unsigned int newinsn
= 0xe1a00000; /* nop. */
5655 newimm
= validate_immediate (value
);
5656 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5658 /* If the instruction will fail, see if we can fix things up by
5659 changing the opcode. */
5660 if (newimm
== (unsigned int) FAIL
5661 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5663 /* No ? OK - try using two ADD instructions to generate
5665 newimm
= validate_immediate_twopart (value
, & highpart
);
5667 /* Yes - then make sure that the second instruction is
5669 if (newimm
!= (unsigned int) FAIL
)
5671 /* Still No ? Try using a negated value. */
5672 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
5673 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5674 /* Otherwise - give up. */
5677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5678 _("Unable to compute ADRL instructions for PC offset of 0x%x"),
5683 /* Replace the first operand in the 2nd instruction (which
5684 is the PC) with the destination register. We have
5685 already added in the PC in the first instruction and we
5686 do not want to do it again. */
5687 newinsn
&= ~ 0xf0000;
5688 newinsn
|= ((newinsn
& 0x0f000) << 4);
5691 newimm
|= (temp
& 0xfffff000);
5692 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5694 highpart
|= (newinsn
& 0xfffff000);
5695 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5699 case BFD_RELOC_ARM_OFFSET_IMM
:
5705 if (validate_offset_imm (value
, 0) == FAIL
)
5707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5708 _("bad immediate value for offset (%ld)"),
5713 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5714 newval
&= 0xff7ff000;
5715 newval
|= value
| (sign
? INDEX_UP
: 0);
5716 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5719 case BFD_RELOC_ARM_OFFSET_IMM8
:
5720 case BFD_RELOC_ARM_HWLITERAL
:
5726 if (validate_offset_imm (value
, 1) == FAIL
)
5728 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5729 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5730 _("invalid literal constant: pool needs to be closer"));
5732 as_bad (_("bad immediate value for half-word offset (%ld)"),
5737 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5738 newval
&= 0xff7ff0f0;
5739 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5740 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5743 case BFD_RELOC_ARM_LITERAL
:
5749 if (validate_offset_imm (value
, 0) == FAIL
)
5751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5752 _("invalid literal constant: pool needs to be closer"));
5756 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5757 newval
&= 0xff7ff000;
5758 newval
|= value
| (sign
? INDEX_UP
: 0);
5759 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5762 case BFD_RELOC_ARM_SHIFT_IMM
:
5763 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5764 if (((unsigned long) value
) > 32
5766 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5768 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5769 _("shift expression is too large"));
5774 /* Shifts of zero must be done as lsl. */
5776 else if (value
== 32)
5778 newval
&= 0xfffff07f;
5779 newval
|= (value
& 0x1f) << 7;
5780 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5783 case BFD_RELOC_ARM_SWI
:
5784 if (arm_data
->thumb_mode
)
5786 if (((unsigned long) value
) > 0xff)
5787 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5788 _("Invalid swi expression"));
5789 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5791 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5795 if (((unsigned long) value
) > 0x00ffffff)
5796 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5797 _("Invalid swi expression"));
5798 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5800 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5804 case BFD_RELOC_ARM_MULTI
:
5805 if (((unsigned long) value
) > 0xffff)
5806 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5807 _("Invalid expression in load/store multiple"));
5808 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5809 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5812 case BFD_RELOC_ARM_PCREL_BRANCH
:
5813 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5815 /* Sign-extend a 24-bit number. */
5816 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5820 value
= fixP
->fx_offset
;
5823 /* We are going to store value (shifted right by two) in the
5824 instruction, in a 24 bit, signed field. Thus we need to check
5825 that none of the top 8 bits of the shifted value (top 7 bits of
5826 the unshifted, unsigned value) are set, or that they are all set. */
5827 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5828 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5831 /* Normally we would be stuck at this point, since we cannot store
5832 the absolute address that is the destination of the branch in the
5833 24 bits of the branch instruction. If however, we happen to know
5834 that the destination of the branch is in the same section as the
5835 branch instruciton itself, then we can compute the relocation for
5836 ourselves and not have to bother the linker with it.
5838 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5839 because I have not worked out how to do this for OBJ_COFF or
5842 && fixP
->fx_addsy
!= NULL
5843 && S_IS_DEFINED (fixP
->fx_addsy
)
5844 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5846 /* Get pc relative value to go into the branch. */
5849 /* Permit a backward branch provided that enough bits
5850 are set. Allow a forwards branch, provided that
5851 enough bits are clear. */
5852 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5853 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5857 if (! fixP
->fx_done
)
5859 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5860 _("gas can't handle same-section branch dest >= 0x04000000"));
5864 value
+= SEXT24 (newval
);
5866 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
5867 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5868 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5869 _("out of range branch"));
5871 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5872 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5875 case BFD_RELOC_ARM_PCREL_BLX
:
5878 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5882 value
= fixP
->fx_offset
;
5884 hbit
= (value
>> 1) & 1;
5885 value
= (value
>> 2) & 0x00ffffff;
5886 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5887 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5888 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5892 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
5893 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5895 addressT diff
= (newval
& 0xff) << 1;
5900 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5901 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5902 _("Branch out of range"));
5903 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5905 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5908 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
5909 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5911 addressT diff
= (newval
& 0x7ff) << 1;
5916 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5917 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5918 _("Branch out of range"));
5919 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5921 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5924 case BFD_RELOC_THUMB_PCREL_BLX
:
5925 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5930 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5931 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5932 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5933 if (diff
& 0x400000)
5936 value
= fixP
->fx_offset
;
5939 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5940 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5941 _("Branch with link out of range"));
5943 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5944 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5945 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5946 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5951 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5952 md_number_to_chars (buf
, value
, 1);
5954 else if (!target_oabi
)
5956 value
= fixP
->fx_offset
;
5957 md_number_to_chars (buf
, value
, 1);
5963 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5964 md_number_to_chars (buf
, value
, 2);
5966 else if (!target_oabi
)
5968 value
= fixP
->fx_offset
;
5969 md_number_to_chars (buf
, value
, 2);
5975 case BFD_RELOC_ARM_GOT32
:
5976 case BFD_RELOC_ARM_GOTOFF
:
5977 md_number_to_chars (buf
, 0, 4);
5983 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5984 md_number_to_chars (buf
, value
, 4);
5986 else if (!target_oabi
)
5988 value
= fixP
->fx_offset
;
5989 md_number_to_chars (buf
, value
, 4);
5995 case BFD_RELOC_ARM_PLT32
:
5996 /* It appears the instruction is fully prepared at this point. */
6000 case BFD_RELOC_ARM_GOTPC
:
6001 md_number_to_chars (buf
, value
, 4);
6004 case BFD_RELOC_ARM_CP_OFF_IMM
:
6006 if (value
< -1023 || value
> 1023 || (value
& 3))
6007 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6008 _("Illegal value for co-processor offset"));
6011 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
6012 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
6013 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6016 case BFD_RELOC_ARM_THUMB_OFFSET
:
6017 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6018 /* Exactly what ranges, and where the offset is inserted depends
6019 on the type of instruction, we can establish this from the
6021 switch (newval
>> 12)
6023 case 4: /* PC load. */
6024 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
6025 forced to zero for these loads, so we will need to round
6026 up the offset if the instruction address is not word
6027 aligned (since the final address produced must be, and
6028 we can only describe word-aligned immediate offsets). */
6030 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
6031 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6032 _("Invalid offset, target not word aligned (0x%08X)"),
6033 (unsigned int) (fixP
->fx_frag
->fr_address
6034 + fixP
->fx_where
+ value
));
6036 if ((value
+ 2) & ~0x3fe)
6037 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6038 _("Invalid offset, value too big (0x%08X)"), value
);
6040 /* Round up, since pc will be rounded down. */
6041 newval
|= (value
+ 2) >> 2;
6044 case 9: /* SP load/store. */
6046 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6047 _("Invalid offset, value too big (0x%08X)"), value
);
6048 newval
|= value
>> 2;
6051 case 6: /* Word load/store. */
6053 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6054 _("Invalid offset, value too big (0x%08X)"), value
);
6055 newval
|= value
<< 4; /* 6 - 2. */
6058 case 7: /* Byte load/store. */
6060 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6061 _("Invalid offset, value too big (0x%08X)"), value
);
6062 newval
|= value
<< 6;
6065 case 8: /* Halfword load/store. */
6067 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6068 _("Invalid offset, value too big (0x%08X)"), value
);
6069 newval
|= value
<< 5; /* 6 - 1. */
6073 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6074 "Unable to process relocation for thumb opcode: %lx",
6075 (unsigned long) newval
);
6078 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6081 case BFD_RELOC_ARM_THUMB_ADD
:
6082 /* This is a complicated relocation, since we use it for all of
6083 the following immediate relocations:
6087 9bit ADD/SUB SP word-aligned
6088 10bit ADD PC/SP word-aligned
6090 The type of instruction being processed is encoded in the
6097 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6099 int rd
= (newval
>> 4) & 0xf;
6100 int rs
= newval
& 0xf;
6101 int subtract
= newval
& 0x8000;
6106 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6107 _("Invalid immediate for stack address calculation"));
6108 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6109 newval
|= value
>> 2;
6111 else if (rs
== REG_PC
|| rs
== REG_SP
)
6115 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6116 _("Invalid immediate for address calculation (value = 0x%08lX)"),
6117 (unsigned long) value
);
6118 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
6120 newval
|= value
>> 2;
6125 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6126 _("Invalid 8bit immediate"));
6127 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6128 newval
|= (rd
<< 8) | value
;
6133 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6134 _("Invalid 3bit immediate"));
6135 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6136 newval
|= rd
| (rs
<< 3) | (value
<< 6);
6139 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6142 case BFD_RELOC_ARM_THUMB_IMM
:
6143 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6144 switch (newval
>> 11)
6146 case 0x04: /* 8bit immediate MOV. */
6147 case 0x05: /* 8bit immediate CMP. */
6148 if (value
< 0 || value
> 255)
6149 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6150 _("Invalid immediate: %ld is too large"),
6158 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6161 case BFD_RELOC_ARM_THUMB_SHIFT
:
6162 /* 5bit shift value (0..31). */
6163 if (value
< 0 || value
> 31)
6164 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6165 _("Illegal Thumb shift value: %ld"), (long) value
);
6166 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
6167 newval
|= value
<< 6;
6168 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6171 case BFD_RELOC_VTABLE_INHERIT
:
6172 case BFD_RELOC_VTABLE_ENTRY
:
6176 case BFD_RELOC_NONE
:
6178 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6179 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6185 /* Translate internal representation of relocation info to BFD target
6189 tc_gen_reloc (section
, fixp
)
6190 asection
* section ATTRIBUTE_UNUSED
;
6194 bfd_reloc_code_real_type code
;
6196 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
6198 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6199 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6200 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6202 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
6204 if (fixp
->fx_pcrel
== 0)
6205 reloc
->addend
= fixp
->fx_offset
;
6207 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6209 reloc
->addend
= fixp
->fx_offset
;
6212 switch (fixp
->fx_r_type
)
6217 code
= BFD_RELOC_8_PCREL
;
6224 code
= BFD_RELOC_16_PCREL
;
6231 code
= BFD_RELOC_32_PCREL
;
6235 case BFD_RELOC_ARM_PCREL_BRANCH
:
6236 case BFD_RELOC_ARM_PCREL_BLX
:
6238 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6239 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6240 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6241 case BFD_RELOC_THUMB_PCREL_BLX
:
6242 case BFD_RELOC_VTABLE_ENTRY
:
6243 case BFD_RELOC_VTABLE_INHERIT
:
6244 code
= fixp
->fx_r_type
;
6247 case BFD_RELOC_ARM_LITERAL
:
6248 case BFD_RELOC_ARM_HWLITERAL
:
6249 /* If this is called then the a literal has been referenced across
6250 a section boundary - possibly due to an implicit dump. */
6251 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6252 _("Literal referenced across section boundary (Implicit dump?)"));
6256 case BFD_RELOC_ARM_GOT32
:
6257 case BFD_RELOC_ARM_GOTOFF
:
6258 case BFD_RELOC_ARM_PLT32
:
6259 code
= fixp
->fx_r_type
;
6263 case BFD_RELOC_ARM_IMMEDIATE
:
6264 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6265 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6269 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6270 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6271 _("ADRL used for a symbol not defined in the same file"),
6275 case BFD_RELOC_ARM_OFFSET_IMM
:
6276 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6277 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6285 switch (fixp
->fx_r_type
)
6287 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6288 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6289 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6290 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6291 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6292 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6293 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6294 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6295 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6296 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6297 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6298 default: type
= _("<unknown>"); break;
6300 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6301 _("Can not represent %s relocation in this object file format (%d)"),
6302 type
, fixp
->fx_pcrel
);
6308 if (code
== BFD_RELOC_32_PCREL
6310 && fixp
->fx_addsy
== GOT_symbol
)
6312 code
= BFD_RELOC_ARM_GOTPC
;
6313 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6317 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6319 if (reloc
->howto
== NULL
)
6321 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6322 _("Can not represent %s relocation in this object file format"),
6323 bfd_get_reloc_code_name (code
));
6327 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6328 vtable entry to be used in the relocation's section offset. */
6329 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6330 reloc
->address
= fixp
->fx_offset
;
6336 md_estimate_size_before_relax (fragP
, segtype
)
6337 fragS
* fragP ATTRIBUTE_UNUSED
;
6338 segT segtype ATTRIBUTE_UNUSED
;
6340 as_fatal (_("md_estimate_size_before_relax\n"));
6345 output_inst
PARAMS ((void))
6351 as_bad (inst
.error
);
6355 to
= frag_more (inst
.size
);
6357 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6359 assert (inst
.size
== (2 * THUMB_SIZE
));
6360 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6361 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6363 else if (inst
.size
> INSN_SIZE
)
6365 assert (inst
.size
== (2 * INSN_SIZE
));
6366 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6367 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6370 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6372 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6373 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6374 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6377 if (debug_type
== DEBUG_DWARF2
)
6378 dwarf2_generate_asm_lineno (inst
.size
);
6392 /* Align the instruction.
6393 This may not be the right thing to do but ... */
6397 listing_prev_line (); /* Defined in listing.h. */
6399 /* Align the previous label if needed. */
6400 if (last_label_seen
!= NULL
)
6402 symbol_set_frag (last_label_seen
, frag_now
);
6403 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6404 S_SET_SEGMENT (last_label_seen
, now_seg
);
6407 memset (&inst
, '\0', sizeof (inst
));
6408 inst
.reloc
.type
= BFD_RELOC_NONE
;
6410 skip_whitespace (str
);
6412 /* Scan up to the end of the op-code, which must end in white space or
6414 for (start
= p
= str
; *p
!= '\0'; p
++)
6420 as_bad (_("No operator -- statement `%s'\n"), str
);
6426 CONST
struct thumb_opcode
* opcode
;
6430 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6435 /* Check that this instruction is supported for this CPU. */
6436 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6438 as_bad (_("selected processor does not support this opcode"));
6442 inst
.instruction
= opcode
->value
;
6443 inst
.size
= opcode
->size
;
6444 (*opcode
->parms
) (p
);
6451 CONST
struct asm_opcode
* opcode
;
6452 unsigned long cond_code
;
6454 inst
.size
= INSN_SIZE
;
6455 /* P now points to the end of the opcode, probably white space, but we
6456 have to break the opcode up in case it contains condionals and flags;
6457 keep trying with progressively smaller basic instructions until one
6458 matches, or we run out of opcode. */
6459 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6461 for (; q
!= str
; q
--)
6466 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6469 if (opcode
&& opcode
->template)
6471 unsigned long flag_bits
= 0;
6474 /* Check that this instruction is supported for this CPU. */
6475 if ((opcode
->variants
& cpu_variant
) == 0)
6478 inst
.instruction
= opcode
->value
;
6479 if (q
== p
) /* Just a simple opcode. */
6481 if (opcode
->comp_suffix
)
6483 if (*opcode
->comp_suffix
!= '\0')
6484 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6485 str
, opcode
->comp_suffix
);
6487 /* Not a conditional instruction. */
6488 (*opcode
->parms
) (q
, 0);
6492 /* A conditional instruction with default condition. */
6493 inst
.instruction
|= COND_ALWAYS
;
6494 (*opcode
->parms
) (q
, 0);
6500 /* Not just a simple opcode. Check if extra is a
6505 CONST
struct asm_cond
*cond
;
6509 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6513 if (cond
->value
== 0xf0000000)
6515 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6517 cond_code
= cond
->value
;
6521 cond_code
= COND_ALWAYS
;
6524 cond_code
= COND_ALWAYS
;
6526 /* Apply the conditional, or complain it's not allowed. */
6527 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6529 /* Instruction isn't conditional. */
6530 if (cond_code
!= COND_ALWAYS
)
6532 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6537 /* Instruction is conditional: set the condition into it. */
6538 inst
.instruction
|= cond_code
;
6540 /* If there is a compulsory suffix, it should come here
6541 before any optional flags. */
6542 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6544 CONST
char *s
= opcode
->comp_suffix
;
6556 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
6557 str
, opcode
->comp_suffix
);
6564 /* The remainder, if any should now be flags for the instruction;
6565 Scan these checking each one found with the opcode. */
6569 CONST
struct asm_flg
*flag
= opcode
->flags
;
6578 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6580 if (streq (r
, flag
[flagno
].template))
6582 flag_bits
|= flag
[flagno
].set_bits
;
6588 if (! flag
[flagno
].template)
6595 (*opcode
->parms
) (p
, flag_bits
);
6605 /* It wasn't an instruction, but it might be a register alias of the form
6608 skip_whitespace (q
);
6613 if (*q
&& !strncmp (q
, ".req ", 4))
6616 char * copy_of_str
= str
;
6620 skip_whitespace (q
);
6622 for (r
= q
; *r
!= '\0'; r
++)
6632 regnum
= arm_reg_parse (& q
);
6635 reg
= arm_reg_parse (& str
);
6640 insert_reg_alias (str
, regnum
);
6642 as_warn (_("register '%s' does not exist\n"), q
);
6644 else if (regnum
!= FAIL
)
6647 as_warn (_("ignoring redefinition of register alias '%s'"),
6650 /* Do not warn about redefinitions to the same alias. */
6653 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6657 as_warn (_("ignoring incomplete .req pseuso op"));
6664 as_bad (_("bad instruction `%s'"), start
);
6668 Invocation line includes a switch not recognized by the base assembler.
6669 See if it's a processor-specific option. These are:
6670 Cpu variants, the arm part is optional:
6671 -m[arm]1 Currently not supported.
6672 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6673 -m[arm]3 Arm 3 processor
6674 -m[arm]6[xx], Arm 6 processors
6675 -m[arm]7[xx][t][[d]m] Arm 7 processors
6676 -m[arm]8[10] Arm 8 processors
6677 -m[arm]9[20][tdmi] Arm 9 processors
6678 -mstrongarm[110[0]] StrongARM processors
6679 -m[arm]v[2345[t]] Arm architectures
6680 -mall All (except the ARM1)
6682 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6683 -mfpe-old (No float load/store multiples)
6684 -mno-fpu Disable all floating point instructions
6685 Run-time endian selection:
6687 -EL little endian cpu
6688 ARM Procedure Calling Standard:
6689 -mapcs-32 32 bit APCS
6690 -mapcs-26 26 bit APCS
6691 -mapcs-float Pass floats in float regs
6692 -mapcs-reentrant Position independent code
6693 -mthumb-interwork Code supports Arm/Thumb interworking
6694 -moabi Old ELF ABI */
6696 CONST
char * md_shortopts
= "m:k";
6698 struct option md_longopts
[] =
6700 #ifdef ARM_BI_ENDIAN
6701 #define OPTION_EB (OPTION_MD_BASE + 0)
6702 {"EB", no_argument
, NULL
, OPTION_EB
},
6703 #define OPTION_EL (OPTION_MD_BASE + 1)
6704 {"EL", no_argument
, NULL
, OPTION_EL
},
6706 #define OPTION_OABI (OPTION_MD_BASE +2)
6707 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6710 {NULL
, no_argument
, NULL
, 0}
6713 size_t md_longopts_size
= sizeof (md_longopts
);
6716 md_parse_option (c
, arg
)
6724 #ifdef ARM_BI_ENDIAN
6726 target_big_endian
= 1;
6729 target_big_endian
= 0;
6737 if (streq (str
, "fpa10"))
6738 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6739 else if (streq (str
, "fpa11"))
6740 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6741 else if (streq (str
, "fpe-old"))
6742 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6748 if (streq (str
, "no-fpu"))
6749 cpu_variant
&= ~FPU_ALL
;
6754 if (streq (str
, "oabi"))
6760 /* Limit assembler to generating only Thumb instructions: */
6761 if (streq (str
, "thumb"))
6763 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6764 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6767 else if (streq (str
, "thumb-interwork"))
6769 if ((cpu_variant
& ARM_THUMB
) == 0)
6770 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6771 #if defined OBJ_COFF || defined OBJ_ELF
6772 support_interwork
= true;
6780 if (streq (str
, "all"))
6782 cpu_variant
= ARM_ALL
| FPU_ALL
;
6785 #if defined OBJ_COFF || defined OBJ_ELF
6786 if (! strncmp (str
, "apcs-", 5))
6788 /* GCC passes on all command line options starting "-mapcs-..."
6789 to us, so we must parse them here. */
6793 if (streq (str
, "32"))
6795 uses_apcs_26
= false;
6798 else if (streq (str
, "26"))
6800 uses_apcs_26
= true;
6803 else if (streq (str
, "frame"))
6805 /* Stack frames are being generated - does not affect
6809 else if (streq (str
, "stack-check"))
6811 /* Stack checking is being performed - does not affect
6812 linkage, but does require that the functions
6813 __rt_stkovf_split_small and __rt_stkovf_split_big be
6814 present in the final link. */
6818 else if (streq (str
, "float"))
6820 /* Floating point arguments are being passed in the floating
6821 point registers. This does affect linking, since this
6822 version of the APCS is incompatible with the version that
6823 passes floating points in the integer registers. */
6825 uses_apcs_float
= true;
6828 else if (streq (str
, "reentrant"))
6830 /* Reentrant code has been generated. This does affect
6831 linking, since there is no point in linking reentrant/
6832 position independent code with absolute position code. */
6837 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6841 /* Strip off optional "arm". */
6842 if (! strncmp (str
, "arm", 3))
6848 if (streq (str
, "1"))
6849 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6855 if (streq (str
, "2"))
6856 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6857 else if (streq (str
, "250"))
6858 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6864 if (streq (str
, "3"))
6865 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6871 switch (strtol (str
, NULL
, 10))
6878 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6886 /* Eat the processor name. */
6887 switch (strtol (str
, & str
, 10))
6900 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6906 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6910 cpu_variant
|= ARM_LONGMUL
;
6913 case 'f': /* fe => fp enabled cpu. */
6919 case 'c': /* Left over from 710c processor name. */
6920 case 'd': /* Debug. */
6921 case 'i': /* Embedded ICE. */
6922 /* Included for completeness in ARM processor naming. */
6932 if (streq (str
, "8") || streq (str
, "810"))
6933 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6934 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6940 if (streq (str
, "9"))
6941 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6942 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6943 else if (streq (str
, "920"))
6944 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6945 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6946 else if (streq (str
, "920t"))
6947 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6948 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6949 else if (streq (str
, "9tdmi"))
6950 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6951 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6957 if (streq (str
, "strongarm")
6958 || streq (str
, "strongarm110")
6959 || streq (str
, "strongarm1100"))
6960 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6961 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6967 /* Select variant based on architecture rather than
6975 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6978 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6981 as_bad (_("Invalid architecture variant -m%s"), arg
);
6987 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6991 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6994 as_bad (_("Invalid architecture variant -m%s"), arg
);
7000 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
7004 case 't': cpu_variant
|= ARM_THUMB
; break;
7007 as_bad (_("Invalid architecture variant -m%s"), arg
);
7013 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
7016 case 't': cpu_variant
|= ARM_THUMB
; break;
7019 as_bad (_("Invalid architecture variant -m%s"), arg
);
7025 as_bad (_("Invalid architecture variant -m%s"), arg
);
7032 as_bad (_("Invalid processor variant -m%s"), arg
);
7038 #if defined OBJ_ELF || defined OBJ_COFF
7056 ARM Specific Assembler Options:\n\
7057 -m[arm][<processor name>] select processor variant\n\
7058 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
7059 -mthumb only allow Thumb instructions\n\
7060 -mthumb-interwork mark the assembled code as supporting interworking\n\
7061 -mall allow any instruction\n\
7062 -mfpa10, -mfpa11 select floating point architecture\n\
7063 -mfpe-old don't allow floating-point multiple instructions\n\
7064 -mno-fpu don't allow any floating-point instructions.\n\
7065 -k generate PIC code.\n"));
7066 #if defined OBJ_COFF || defined OBJ_ELF
7068 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
7069 -mapcs-float floating point args are passed in FP regs\n\
7070 -mapcs-reentrant the code is position independent/reentrant\n"));
7074 -moabi support the old ELF ABI\n"));
7076 #ifdef ARM_BI_ENDIAN
7078 -EB assemble code for a big endian cpu\n\
7079 -EL assemble code for a little endian cpu\n"));
7083 /* We need to be able to fix up arbitrary expressions in some statements.
7084 This is so that we can handle symbols that are an arbitrary distance from
7085 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
7086 which returns part of an address in a form which will be valid for
7087 a data instruction. We do this by pushing the expression into a symbol
7088 in the expr_section, and creating a fix for that. */
7091 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
7100 arm_fix_data
* arm_data
;
7108 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
7112 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
7117 /* Mark whether the fix is to a THUMB instruction, or an ARM
7119 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
7120 new_fix
->tc_fix_data
= (PTR
) arm_data
;
7121 arm_data
->thumb_mode
= thumb_mode
;
7126 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
7129 cons_fix_new_arm (frag
, where
, size
, exp
)
7135 bfd_reloc_code_real_type type
;
7139 FIXME: @@ Should look at CPU word size. */
7146 type
= BFD_RELOC_16
;
7150 type
= BFD_RELOC_32
;
7153 type
= BFD_RELOC_64
;
7157 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
7160 /* A good place to do this, although this was probably not intended
7161 for this kind of use. We need to dump the literal pool before
7162 references are made to a null symbol pointer. */
7167 if (current_poolP
== NULL
)
7170 /* Put it at the end of text section. */
7171 subseg_set (text_section
, 0);
7173 listing_prev_line ();
7177 arm_start_line_hook ()
7179 last_label_seen
= NULL
;
7183 arm_frob_label (sym
)
7186 last_label_seen
= sym
;
7188 ARM_SET_THUMB (sym
, thumb_mode
);
7190 #if defined OBJ_COFF || defined OBJ_ELF
7191 ARM_SET_INTERWORK (sym
, support_interwork
);
7194 if (label_is_thumb_function_name
)
7196 /* When the address of a Thumb function is taken the bottom
7197 bit of that address should be set. This will allow
7198 interworking between Arm and Thumb functions to work
7201 THUMB_SET_FUNC (sym
, 1);
7203 label_is_thumb_function_name
= false;
7207 /* Adjust the symbol table. This marks Thumb symbols as distinct from
7211 arm_adjust_symtab ()
7216 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7218 if (ARM_IS_THUMB (sym
))
7220 if (THUMB_IS_FUNC (sym
))
7222 /* Mark the symbol as a Thumb function. */
7223 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
7224 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
7225 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
7227 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
7228 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
7230 as_bad (_("%s: unexpected function type: %d"),
7231 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
7233 else switch (S_GET_STORAGE_CLASS (sym
))
7236 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
7239 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7242 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7250 if (ARM_IS_INTERWORK (sym
))
7251 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7258 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7260 if (ARM_IS_THUMB (sym
))
7262 elf_symbol_type
* elf_sym
;
7264 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7265 bind
= ELF_ST_BIND (elf_sym
);
7267 /* If it's a .thumb_func, declare it as so,
7268 otherwise tag label as .code 16. */
7269 if (THUMB_IS_FUNC (sym
))
7270 elf_sym
->internal_elf_sym
.st_info
=
7271 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7273 elf_sym
->internal_elf_sym
.st_info
=
7274 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7283 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7285 *input_line_pointer
= '/';
7286 input_line_pointer
+= 5;
7287 *input_line_pointer
= 0;
7295 arm_canonicalize_symbol_name (name
)
7300 if (thumb_mode
&& (len
= strlen (name
)) > 5
7301 && streq (name
+ len
- 5, "/data"))
7302 *(name
+ len
- 5) = 0;
7308 arm_validate_fix (fixP
)
7311 /* If the destination of the branch is a defined symbol which does not have
7312 the THUMB_FUNC attribute, then we must be calling a function which has
7313 the (interfacearm) attribute. We look for the Thumb entry point to that
7314 function and change the branch to refer to that function instead. */
7315 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7316 && fixP
->fx_addsy
!= NULL
7317 && S_IS_DEFINED (fixP
->fx_addsy
)
7318 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7320 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7328 /* Relocations against Thumb function names must be left unadjusted,
7329 so that the linker can use this information to correctly set the
7330 bottom bit of their addresses. The MIPS version of this function
7331 also prevents relocations that are mips-16 specific, but I do not
7332 know why it does this.
7335 There is one other problem that ought to be addressed here, but
7336 which currently is not: Taking the address of a label (rather
7337 than a function) and then later jumping to that address. Such
7338 addresses also ought to have their bottom bit set (assuming that
7339 they reside in Thumb code), but at the moment they will not. */
7342 arm_fix_adjustable (fixP
)
7345 if (fixP
->fx_addsy
== NULL
)
7348 /* Prevent all adjustments to global symbols. */
7349 if (S_IS_EXTERN (fixP
->fx_addsy
))
7352 if (S_IS_WEAK (fixP
->fx_addsy
))
7355 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7356 && fixP
->fx_subsy
== NULL
)
7359 /* We need the symbol name for the VTABLE entries. */
7360 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7361 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7368 elf32_arm_target_format ()
7370 if (target_big_endian
)
7373 return "elf32-bigarm-oabi";
7375 return "elf32-bigarm";
7380 return "elf32-littlearm-oabi";
7382 return "elf32-littlearm";
7387 armelf_frob_symbol (symp
, puntp
)
7391 elf_frob_symbol (symp
, puntp
);
7395 arm_force_relocation (fixp
)
7398 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7399 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7400 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7401 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7402 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7403 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7409 static bfd_reloc_code_real_type
7419 bfd_reloc_code_real_type reloc
;
7423 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
7424 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7425 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7426 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
7427 branch instructions generated by GCC for PLT relocs. */
7428 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7429 { NULL
, 0, BFD_RELOC_UNUSED
}
7433 for (i
= 0, ip
= input_line_pointer
;
7434 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7436 id
[i
] = tolower (*ip
);
7438 for (i
= 0; reloc_map
[i
].str
; i
++)
7439 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7442 input_line_pointer
+= reloc_map
[i
].len
;
7444 return reloc_map
[i
].reloc
;
7448 s_arm_elf_cons (nbytes
)
7453 #ifdef md_flush_pending_output
7454 md_flush_pending_output ();
7457 if (is_it_end_of_statement ())
7459 demand_empty_rest_of_line ();
7463 #ifdef md_cons_align
7464 md_cons_align (nbytes
);
7469 bfd_reloc_code_real_type reloc
;
7473 if (exp
.X_op
== O_symbol
7474 && * input_line_pointer
== '('
7475 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
7477 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7478 int size
= bfd_get_reloc_size (howto
);
7481 as_bad ("%s relocations do not fit in %d bytes",
7482 howto
->name
, nbytes
);
7485 register char *p
= frag_more ((int) nbytes
);
7486 int offset
= nbytes
- size
;
7488 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7493 emit_expr (&exp
, (unsigned int) nbytes
);
7495 while (*input_line_pointer
++ == ',');
7497 /* Put terminator back into stream. */
7498 input_line_pointer
--;
7499 demand_empty_rest_of_line ();
7502 /* Stuff to do after assembling all of the source file. */
7505 arm_end_of_source ()
7507 if (debug_type
== DEBUG_DWARF2
)
7511 #endif /* OBJ_ELF */