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. */
38 #include "dwarf2dbg.h"
41 /* Types of processor to assemble for. */
42 #define ARM_1 0x00000001
43 #define ARM_2 0x00000002
44 #define ARM_3 0x00000004
46 #define ARM_6 0x00000008
47 #define ARM_7 ARM_6 /* Same core instruction set. */
48 #define ARM_8 ARM_6 /* Same core instruction set. */
49 #define ARM_9 ARM_6 /* Same core instruction set. */
50 #define ARM_CPU_MASK 0x0000000f
52 /* The following bitmasks control CPU extensions (ARM7 onwards): */
53 #define ARM_LONGMUL 0x00000010 /* Allow long multiplies. */
54 #define ARM_HALFWORD 0x00000020 /* Allow half word loads. */
55 #define ARM_THUMB 0x00000040 /* Allow BX instruction. */
56 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
58 /* Architectures are the sum of the base and extensions. */
59 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
60 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
61 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
62 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
64 /* Some useful combinations: */
65 #define ARM_ANY 0x00ffffff
66 #define ARM_2UP (ARM_ANY - ARM_1)
67 #define ARM_ALL ARM_2UP /* Not arm1 only. */
68 #define ARM_3UP 0x00fffffc
69 #define ARM_6UP 0x00fffff8 /* Includes ARM7. */
71 #define FPU_CORE 0x80000000
72 #define FPU_FPA10 0x40000000
73 #define FPU_FPA11 0x40000000
76 /* Some useful combinations. */
77 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */
78 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */
82 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
84 #define CPU_DEFAULT ARM_ALL
89 #define FPU_DEFAULT FPU_ALL
92 #define streq(a, b) (strcmp (a, b) == 0)
93 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
95 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
96 static int target_oabi
= 0;
98 #if defined OBJ_COFF || defined OBJ_ELF
99 /* Flags stored in private area of BFD structure. */
100 static boolean uses_apcs_26
= false;
101 static boolean support_interwork
= false;
102 static boolean uses_apcs_float
= false;
103 static boolean pic_code
= false;
106 /* This array holds the chars that always start a comment. If the
107 pre-processor is disabled, these aren't very useful. */
108 CONST
char comment_chars
[] = "@";
110 /* This array holds the chars that only start a comment at the beginning of
111 a line. If the line seems to have the form '# 123 filename'
112 .line and .file directives will appear in the pre-processed output. */
113 /* Note that input_file.c hand checks for '#' at the beginning of the
114 first line of the input file. This is because the compiler outputs
115 #NO_APP at the beginning of its output. */
116 /* Also note that comments like this one will always work. */
117 CONST
char line_comment_chars
[] = "#";
119 CONST
char line_separator_chars
[] = ";";
121 /* Chars that can be used to separate mant
122 from exp in floating point numbers. */
123 CONST
char EXP_CHARS
[] = "eE";
125 /* Chars that mean this number is a floating point constant. */
129 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
131 /* Prefix characters that indicate the start of an immediate
133 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
136 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
137 symbolS
* GOT_symbol
;
140 /* Size of relocation record. */
141 CONST
int md_reloc_size
= 8;
143 /* 0: assemble for ARM,
144 1: assemble for Thumb,
145 2: assemble for Thumb even though target CPU does not support thumb
147 static int thumb_mode
= 0;
149 typedef struct arm_fix
157 unsigned long instruction
;
162 bfd_reloc_code_real_type type
;
179 struct asm_shift_properties
181 enum asm_shift_index index
;
182 unsigned long bit_field
;
183 unsigned int allows_0
: 1;
184 unsigned int allows_32
: 1;
187 static const struct asm_shift_properties shift_properties
[] =
189 { SHIFT_LSL
, 0, 1, 0},
190 { SHIFT_LSR
, 0x20, 0, 1},
191 { SHIFT_ASR
, 0x40, 0, 1},
192 { SHIFT_ROR
, 0x60, 0, 0},
193 { SHIFT_RRX
, 0x60, 0, 0}
196 struct asm_shift_name
199 const struct asm_shift_properties
* properties
;
202 static const struct asm_shift_name shift_names
[] =
204 { "asl", shift_properties
+ SHIFT_LSL
},
205 { "lsl", shift_properties
+ SHIFT_LSL
},
206 { "lsr", shift_properties
+ SHIFT_LSR
},
207 { "asr", shift_properties
+ SHIFT_ASR
},
208 { "ror", shift_properties
+ SHIFT_ROR
},
209 { "rrx", shift_properties
+ SHIFT_RRX
},
210 { "ASL", shift_properties
+ SHIFT_LSL
},
211 { "LSL", shift_properties
+ SHIFT_LSL
},
212 { "LSR", shift_properties
+ SHIFT_LSR
},
213 { "ASR", shift_properties
+ SHIFT_ASR
},
214 { "ROR", shift_properties
+ SHIFT_ROR
},
215 { "RRX", shift_properties
+ SHIFT_RRX
}
218 #define NO_SHIFT_RESTRICT 1
219 #define SHIFT_RESTRICT 0
221 #define NUM_FLOAT_VALS 8
223 CONST
char * fp_const
[] =
225 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
228 /* Number of littlenums required to hold an extended precision number. */
229 #define MAX_LITTLENUMS 6
231 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
241 #define CP_T_X 0x00008000
242 #define CP_T_Y 0x00400000
243 #define CP_T_Pre 0x01000000
244 #define CP_T_UD 0x00800000
245 #define CP_T_WB 0x00200000
247 #define CONDS_BIT (0x00100000)
248 #define LOAD_BIT (0x00100000)
249 #define TRANS_BIT (0x00200000)
253 CONST
char * template;
257 /* This is to save a hash look-up in the common case. */
258 #define COND_ALWAYS 0xe0000000
260 static CONST
struct asm_cond conds
[] =
264 {"cs", 0x20000000}, {"hs", 0x20000000},
265 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
280 /* Warning: If the top bit of the set_bits is set, then the standard
281 instruction bitmask is ignored, and the new bitmask is taken from
285 CONST
char * template; /* Basic flag string. */
286 unsigned long set_bits
; /* Bits to set. */
289 static CONST
struct asm_flg s_flag
[] =
295 static CONST
struct asm_flg ldr_flags
[] =
299 {"bt", 0x00400000 | TRANS_BIT
},
306 static CONST
struct asm_flg str_flags
[] =
310 {"bt", 0x00400000 | TRANS_BIT
},
315 static CONST
struct asm_flg byte_flag
[] =
321 static CONST
struct asm_flg cmp_flags
[] =
328 static CONST
struct asm_flg ldm_flags
[] =
341 static CONST
struct asm_flg stm_flags
[] =
354 static CONST
struct asm_flg lfm_flags
[] =
361 static CONST
struct asm_flg sfm_flags
[] =
368 static CONST
struct asm_flg round_flags
[] =
376 /* The implementation of the FIX instruction is broken on some assemblers,
377 in that it accepts a precision specifier as well as a rounding specifier,
378 despite the fact that this is meaningless. To be more compatible, we
379 accept it as well, though of course it does not set any bits. */
380 static CONST
struct asm_flg fix_flags
[] =
397 static CONST
struct asm_flg except_flag
[] =
403 static CONST
struct asm_flg cplong_flag
[] =
411 CONST
char * template;
416 /* The bit that distnguishes CPSR and SPSR. */
417 #define SPSR_BIT (1 << 22)
419 /* How many bits to shift the PSR_xxx bits up by. */
422 #define PSR_c (1 << 0)
423 #define PSR_x (1 << 1)
424 #define PSR_s (1 << 2)
425 #define PSR_f (1 << 3)
427 static CONST
struct asm_psr psrs
[] =
429 {"CPSR", true, PSR_c
| PSR_f
},
430 {"CPSR_all", true, PSR_c
| PSR_f
},
431 {"SPSR", false, PSR_c
| PSR_f
},
432 {"SPSR_all", false, PSR_c
| PSR_f
},
433 {"CPSR_flg", true, PSR_f
},
434 {"CPSR_f", true, PSR_f
},
435 {"SPSR_flg", false, PSR_f
},
436 {"SPSR_f", false, PSR_f
},
437 {"CPSR_c", true, PSR_c
},
438 {"CPSR_ctl", true, PSR_c
},
439 {"SPSR_c", false, PSR_c
},
440 {"SPSR_ctl", false, PSR_c
},
441 {"CPSR_x", true, PSR_x
},
442 {"CPSR_s", true, PSR_s
},
443 {"SPSR_x", false, PSR_x
},
444 {"SPSR_s", false, PSR_s
},
445 /* Combinations of flags. */
446 {"CPSR_fs", true, PSR_f
| PSR_s
},
447 {"CPSR_fx", true, PSR_f
| PSR_x
},
448 {"CPSR_fc", true, PSR_f
| PSR_c
},
449 {"CPSR_sf", true, PSR_s
| PSR_f
},
450 {"CPSR_sx", true, PSR_s
| PSR_x
},
451 {"CPSR_sc", true, PSR_s
| PSR_c
},
452 {"CPSR_xf", true, PSR_x
| PSR_f
},
453 {"CPSR_xs", true, PSR_x
| PSR_s
},
454 {"CPSR_xc", true, PSR_x
| PSR_c
},
455 {"CPSR_cf", true, PSR_c
| PSR_f
},
456 {"CPSR_cs", true, PSR_c
| PSR_s
},
457 {"CPSR_cx", true, PSR_c
| PSR_x
},
458 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
459 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
460 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
461 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
462 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
463 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
464 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
465 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
466 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
467 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
468 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
469 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
470 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
471 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
472 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
473 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
474 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
475 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
476 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
477 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
478 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
479 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
480 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
481 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
482 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
483 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
484 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
485 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
486 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
487 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
488 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
489 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
490 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
491 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
492 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
493 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
494 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
495 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
496 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
497 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
498 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
499 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
500 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
501 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
502 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
503 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
504 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
505 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
506 {"SPSR_fs", false, PSR_f
| PSR_s
},
507 {"SPSR_fx", false, PSR_f
| PSR_x
},
508 {"SPSR_fc", false, PSR_f
| PSR_c
},
509 {"SPSR_sf", false, PSR_s
| PSR_f
},
510 {"SPSR_sx", false, PSR_s
| PSR_x
},
511 {"SPSR_sc", false, PSR_s
| PSR_c
},
512 {"SPSR_xf", false, PSR_x
| PSR_f
},
513 {"SPSR_xs", false, PSR_x
| PSR_s
},
514 {"SPSR_xc", false, PSR_x
| PSR_c
},
515 {"SPSR_cf", false, PSR_c
| PSR_f
},
516 {"SPSR_cs", false, PSR_c
| PSR_s
},
517 {"SPSR_cx", false, PSR_c
| PSR_x
},
518 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
519 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
520 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
521 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
522 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
523 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
524 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
525 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
526 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
527 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
528 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
529 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
530 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
531 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
532 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
533 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
534 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
535 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
536 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
537 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
538 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
539 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
540 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
541 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
542 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
543 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
544 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
545 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
546 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
547 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
548 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
549 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
550 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
551 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
552 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
553 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
554 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
555 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
556 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
557 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
558 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
559 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
560 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
561 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
562 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
563 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
564 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
565 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
568 /* Functions called by parser. */
569 /* ARM instructions. */
570 static void do_arit
PARAMS ((char *, unsigned long));
571 static void do_cmp
PARAMS ((char *, unsigned long));
572 static void do_mov
PARAMS ((char *, unsigned long));
573 static void do_ldst
PARAMS ((char *, unsigned long));
574 static void do_ldmstm
PARAMS ((char *, unsigned long));
575 static void do_branch
PARAMS ((char *, unsigned long));
576 static void do_swi
PARAMS ((char *, unsigned long));
577 /* Pseudo Op codes. */
578 static void do_adr
PARAMS ((char *, unsigned long));
579 static void do_adrl
PARAMS ((char *, unsigned long));
580 static void do_nop
PARAMS ((char *, unsigned long));
582 static void do_mul
PARAMS ((char *, unsigned long));
583 static void do_mla
PARAMS ((char *, unsigned long));
585 static void do_swap
PARAMS ((char *, unsigned long));
587 static void do_msr
PARAMS ((char *, unsigned long));
588 static void do_mrs
PARAMS ((char *, unsigned long));
590 static void do_mull
PARAMS ((char *, unsigned long));
592 static void do_bx
PARAMS ((char *, unsigned long));
594 /* Coprocessor Instructions. */
595 static void do_cdp
PARAMS ((char *, unsigned long));
596 static void do_lstc
PARAMS ((char *, unsigned long));
597 static void do_co_reg
PARAMS ((char *, unsigned long));
598 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
599 static void do_fp_ldst
PARAMS ((char *, unsigned long));
600 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
601 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
602 static void do_fp_monadic
PARAMS ((char *, unsigned long));
603 static void do_fp_cmp
PARAMS ((char *, unsigned long));
604 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
605 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
607 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
608 static int arm_reg_parse
PARAMS ((char **));
609 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
610 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
611 static int add_to_lit_pool
PARAMS ((void));
612 static unsigned validate_immediate
PARAMS ((unsigned));
613 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
614 static int validate_offset_imm
PARAMS ((unsigned int, int));
615 static void opcode_select
PARAMS ((int));
616 static void end_of_line
PARAMS ((char *));
617 static int reg_required_here
PARAMS ((char **, int));
618 static int psr_required_here
PARAMS ((char **));
619 static int co_proc_number
PARAMS ((char **));
620 static int cp_opc_expr
PARAMS ((char **, int, int));
621 static int cp_reg_required_here
PARAMS ((char **, int));
622 static int fp_reg_required_here
PARAMS ((char **, int));
623 static int cp_address_offset
PARAMS ((char **));
624 static int cp_address_required_here
PARAMS ((char **));
625 static int my_get_float_expression
PARAMS ((char **));
626 static int skip_past_comma
PARAMS ((char **));
627 static int walk_no_bignums
PARAMS ((symbolS
*));
628 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
629 static int data_op2
PARAMS ((char **));
630 static int fp_op2
PARAMS ((char **));
631 static long reg_list
PARAMS ((char **));
632 static void thumb_load_store
PARAMS ((char *, int, int));
633 static int decode_shift
PARAMS ((char **, int));
634 static int ldst_extend
PARAMS ((char **, int));
635 static void thumb_add_sub
PARAMS ((char *, int));
636 static void insert_reg
PARAMS ((int));
637 static void thumb_shift
PARAMS ((char *, int));
638 static void thumb_mov_compare
PARAMS ((char *, int));
639 static void set_constant_flonums
PARAMS ((void));
640 static valueT md_chars_to_number
PARAMS ((char *, int));
641 static void insert_reg_alias
PARAMS ((char *, int));
642 static void output_inst
PARAMS ((void));
644 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
647 /* ARM instructions take 4bytes in the object file, Thumb instructions
651 /* LONGEST_INST is the longest basic instruction name without conditions or
652 flags. ARM7M has 4 of length 5. */
654 #define LONGEST_INST 5
658 /* Basic string to match. */
659 CONST
char * template;
661 /* Basic instruction code. */
664 /* Compulsory suffix that must follow conds. If "", then the
665 instruction is not conditional and must have no suffix. */
666 CONST
char * comp_suffix
;
668 /* Bits to toggle if flag 'n' set. */
669 CONST
struct asm_flg
* flags
;
671 /* Which CPU variants this exists for. */
672 unsigned long variants
;
674 /* Function to call to parse args. */
675 void (* parms
) PARAMS ((char *, unsigned long));
678 static CONST
struct asm_opcode insns
[] =
680 /* ARM Instructions. */
681 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
682 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
683 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
684 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
685 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
686 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
687 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
688 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
689 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
690 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
691 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
692 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
693 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
694 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
695 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
696 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
697 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
698 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
699 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
700 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
701 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
703 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
704 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
706 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
707 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
711 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
712 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
713 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
715 /* ARM 2 multiplies. */
716 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
717 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
719 /* ARM 3 - swp instructions. */
720 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
722 /* ARM 6 Coprocessor instructions. */
723 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
724 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
725 /* ScottB: our code uses 0x0128f000 for msr.
726 NickC: but this is wrong because the bits 16 through 19 are
727 handled by the PSR_xxx defines above. */
729 /* ARM 7M long multiplies - need signed/unsigned flags! */
730 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
731 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
732 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
733 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
735 /* ARM THUMB interworking. */
736 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
738 /* Floating point instructions. */
739 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
740 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
741 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
742 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
743 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
744 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
745 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
746 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
747 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
748 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
749 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
750 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
751 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
752 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
753 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
754 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
755 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
756 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
757 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
758 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
759 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
760 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
761 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
762 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
763 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
764 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
765 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
766 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
767 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
768 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
769 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
770 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
771 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
772 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
773 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
774 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
775 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
776 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
777 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
778 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
779 be an optional suffix, but part of the instruction. To be compatible,
781 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
782 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
783 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
784 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
786 /* Generic copressor instructions. */
787 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
788 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
789 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
790 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
791 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
794 /* Defines for various bits that we will want to toggle. */
795 #define INST_IMMEDIATE 0x02000000
796 #define OFFSET_REG 0x02000000
797 #define HWOFFSET_IMM 0x00400000
798 #define SHIFT_BY_REG 0x00000010
799 #define PRE_INDEX 0x01000000
800 #define INDEX_UP 0x00800000
801 #define WRITE_BACK 0x00200000
802 #define LDM_TYPE_2_OR_3 0x00400000
804 #define LITERAL_MASK 0xf000f000
805 #define COND_MASK 0xf0000000
806 #define OPCODE_MASK 0xfe1fffff
807 #define DATA_OP_SHIFT 21
809 /* Codes to distinguish the arithmetic instructions. */
820 #define OPCODE_CMP 10
821 #define OPCODE_CMN 11
822 #define OPCODE_ORR 12
823 #define OPCODE_MOV 13
824 #define OPCODE_BIC 14
825 #define OPCODE_MVN 15
827 static void do_t_nop
PARAMS ((char *));
828 static void do_t_arit
PARAMS ((char *));
829 static void do_t_add
PARAMS ((char *));
830 static void do_t_asr
PARAMS ((char *));
831 static void do_t_branch9
PARAMS ((char *));
832 static void do_t_branch12
PARAMS ((char *));
833 static void do_t_branch23
PARAMS ((char *));
834 static void do_t_bx
PARAMS ((char *));
835 static void do_t_compare
PARAMS ((char *));
836 static void do_t_ldmstm
PARAMS ((char *));
837 static void do_t_ldr
PARAMS ((char *));
838 static void do_t_ldrb
PARAMS ((char *));
839 static void do_t_ldrh
PARAMS ((char *));
840 static void do_t_lds
PARAMS ((char *));
841 static void do_t_lsl
PARAMS ((char *));
842 static void do_t_lsr
PARAMS ((char *));
843 static void do_t_mov
PARAMS ((char *));
844 static void do_t_push_pop
PARAMS ((char *));
845 static void do_t_str
PARAMS ((char *));
846 static void do_t_strb
PARAMS ((char *));
847 static void do_t_strh
PARAMS ((char *));
848 static void do_t_sub
PARAMS ((char *));
849 static void do_t_swi
PARAMS ((char *));
850 static void do_t_adr
PARAMS ((char *));
852 #define T_OPCODE_MUL 0x4340
853 #define T_OPCODE_TST 0x4200
854 #define T_OPCODE_CMN 0x42c0
855 #define T_OPCODE_NEG 0x4240
856 #define T_OPCODE_MVN 0x43c0
858 #define T_OPCODE_ADD_R3 0x1800
859 #define T_OPCODE_SUB_R3 0x1a00
860 #define T_OPCODE_ADD_HI 0x4400
861 #define T_OPCODE_ADD_ST 0xb000
862 #define T_OPCODE_SUB_ST 0xb080
863 #define T_OPCODE_ADD_SP 0xa800
864 #define T_OPCODE_ADD_PC 0xa000
865 #define T_OPCODE_ADD_I8 0x3000
866 #define T_OPCODE_SUB_I8 0x3800
867 #define T_OPCODE_ADD_I3 0x1c00
868 #define T_OPCODE_SUB_I3 0x1e00
870 #define T_OPCODE_ASR_R 0x4100
871 #define T_OPCODE_LSL_R 0x4080
872 #define T_OPCODE_LSR_R 0x40c0
873 #define T_OPCODE_ASR_I 0x1000
874 #define T_OPCODE_LSL_I 0x0000
875 #define T_OPCODE_LSR_I 0x0800
877 #define T_OPCODE_MOV_I8 0x2000
878 #define T_OPCODE_CMP_I8 0x2800
879 #define T_OPCODE_CMP_LR 0x4280
880 #define T_OPCODE_MOV_HR 0x4600
881 #define T_OPCODE_CMP_HR 0x4500
883 #define T_OPCODE_LDR_PC 0x4800
884 #define T_OPCODE_LDR_SP 0x9800
885 #define T_OPCODE_STR_SP 0x9000
886 #define T_OPCODE_LDR_IW 0x6800
887 #define T_OPCODE_STR_IW 0x6000
888 #define T_OPCODE_LDR_IH 0x8800
889 #define T_OPCODE_STR_IH 0x8000
890 #define T_OPCODE_LDR_IB 0x7800
891 #define T_OPCODE_STR_IB 0x7000
892 #define T_OPCODE_LDR_RW 0x5800
893 #define T_OPCODE_STR_RW 0x5000
894 #define T_OPCODE_LDR_RH 0x5a00
895 #define T_OPCODE_STR_RH 0x5200
896 #define T_OPCODE_LDR_RB 0x5c00
897 #define T_OPCODE_STR_RB 0x5400
899 #define T_OPCODE_PUSH 0xb400
900 #define T_OPCODE_POP 0xbc00
902 #define T_OPCODE_BRANCH 0xe7fe
904 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
906 #define THUMB_SIZE 2 /* Size of thumb instruction. */
907 #define THUMB_REG_LO 0x1
908 #define THUMB_REG_HI 0x2
909 #define THUMB_REG_ANY 0x3
911 #define THUMB_H1 0x0080
912 #define THUMB_H2 0x0040
919 #define THUMB_COMPARE 1
922 #define THUMB_STORE 1
924 #define THUMB_PP_PC_LR 0x0100
926 /* These three are used for immediate shifts, do not alter. */
928 #define THUMB_HALFWORD 1
933 /* Basic string to match. */
934 CONST
char * template;
936 /* Basic instruction code. */
941 /* Which CPU variants this exists for. */
942 unsigned long variants
;
944 /* Function to call to parse args. */
945 void (* parms
) PARAMS ((char *));
948 static CONST
struct thumb_opcode tinsns
[] =
950 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
951 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
952 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
953 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
954 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
955 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
956 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
957 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
958 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
959 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
960 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
961 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
962 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
963 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
964 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
965 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
966 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
967 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
968 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
969 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
970 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
971 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
972 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
973 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
974 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
975 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
976 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
977 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
978 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
979 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
980 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
981 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
982 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
983 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
984 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
985 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
986 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
987 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
988 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
989 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
990 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
991 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
992 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
993 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
994 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
995 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
996 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
997 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
998 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
999 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
1000 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
1001 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
1002 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
1003 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
1004 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
1006 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
1007 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
1016 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1017 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1018 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1024 /* These are the standard names. Users can add aliases with .req. */
1025 static CONST
struct reg_entry reg_table
[] =
1027 /* Processor Register Numbers. */
1028 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1029 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1030 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1031 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1032 /* APCS conventions. */
1033 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1034 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1035 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1036 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1037 /* ATPCS additions to APCS conventions. */
1038 {"wr", 7}, {"v8", 11},
1040 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1041 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1042 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1043 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1044 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1045 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1046 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1047 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1048 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1049 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1050 /* ATPCS additions to float register names. */
1051 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1052 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1053 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1054 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1055 /* FIXME: At some point we need to add VFP register names. */
1056 /* Array terminator. */
1060 #define BAD_ARGS _("Bad arguments to instruction")
1061 #define BAD_PC _("r15 not allowed here")
1062 #define BAD_FLAGS _("Instruction should not have flags")
1063 #define BAD_COND _("Instruction is not conditional")
1065 static struct hash_control
* arm_ops_hsh
= NULL
;
1066 static struct hash_control
* arm_tops_hsh
= NULL
;
1067 static struct hash_control
* arm_cond_hsh
= NULL
;
1068 static struct hash_control
* arm_shift_hsh
= NULL
;
1069 static struct hash_control
* arm_reg_hsh
= NULL
;
1070 static struct hash_control
* arm_psr_hsh
= NULL
;
1072 /* This table describes all the machine specific pseudo-ops the assembler
1073 has to support. The fields are:
1074 pseudo-op name without dot
1075 function to call to execute this pseudo-op
1076 Integer arg to pass to the function. */
1078 static void s_req
PARAMS ((int));
1079 static void s_align
PARAMS ((int));
1080 static void s_bss
PARAMS ((int));
1081 static void s_even
PARAMS ((int));
1082 static void s_ltorg
PARAMS ((int));
1083 static void s_arm
PARAMS ((int));
1084 static void s_thumb
PARAMS ((int));
1085 static void s_code
PARAMS ((int));
1086 static void s_force_thumb
PARAMS ((int));
1087 static void s_thumb_func
PARAMS ((int));
1088 static void s_thumb_set
PARAMS ((int));
1089 static void arm_s_text
PARAMS ((int));
1090 static void arm_s_data
PARAMS ((int));
1092 static void arm_s_section
PARAMS ((int));
1093 static void s_arm_elf_cons
PARAMS ((int));
1096 static int my_get_expression
PARAMS ((expressionS
*, char **));
1098 CONST pseudo_typeS md_pseudo_table
[] =
1100 /* Never called becasue '.req' does not start line. */
1101 { "req", s_req
, 0 },
1102 { "bss", s_bss
, 0 },
1103 { "align", s_align
, 0 },
1104 { "arm", s_arm
, 0 },
1105 { "thumb", s_thumb
, 0 },
1106 { "code", s_code
, 0 },
1107 { "force_thumb", s_force_thumb
, 0 },
1108 { "thumb_func", s_thumb_func
, 0 },
1109 { "thumb_set", s_thumb_set
, 0 },
1110 { "even", s_even
, 0 },
1111 { "ltorg", s_ltorg
, 0 },
1112 { "pool", s_ltorg
, 0 },
1113 /* Allow for the effect of section changes. */
1114 { "text", arm_s_text
, 0 },
1115 { "data", arm_s_data
, 0 },
1117 { "section", arm_s_section
, 0 },
1118 { "section.s", arm_s_section
, 0 },
1119 { "sect", arm_s_section
, 0 },
1120 { "sect.s", arm_s_section
, 0 },
1121 { "word", s_arm_elf_cons
, 4 },
1122 { "long", s_arm_elf_cons
, 4 },
1126 { "extend", float_cons
, 'x' },
1127 { "ldouble", float_cons
, 'x' },
1128 { "packed", float_cons
, 'p' },
1132 /* Stuff needed to resolve the label ambiguity
1142 symbolS
* last_label_seen
;
1143 static int label_is_thumb_function_name
= false;
1145 /* Literal stuff. */
1147 #define MAX_LITERAL_POOL_SIZE 1024
1149 typedef struct literalS
1151 struct expressionS exp
;
1152 struct arm_it
* inst
;
1155 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1157 /* Next free entry in the pool. */
1158 int next_literal_pool_place
= 0;
1160 /* Next literal pool number. */
1161 int lit_pool_num
= 1;
1163 symbolS
* current_poolP
= NULL
;
1170 if (current_poolP
== NULL
)
1171 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1172 (valueT
) 0, &zero_address_frag
);
1174 /* Check if this literal value is already in the pool: */
1175 while (lit_count
< next_literal_pool_place
)
1177 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1178 && inst
.reloc
.exp
.X_op
== O_constant
1179 && (literals
[lit_count
].exp
.X_add_number
1180 == inst
.reloc
.exp
.X_add_number
)
1181 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1186 if (lit_count
== next_literal_pool_place
) /* New entry. */
1188 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1190 inst
.error
= _("Literal Pool Overflow");
1194 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1195 lit_count
= next_literal_pool_place
++;
1198 inst
.reloc
.exp
.X_op
= O_symbol
;
1199 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1200 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1205 /* Can't use symbol_new here, so have to create a symbol and then at
1206 a later date assign it a value. Thats what these functions do. */
1209 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1211 CONST
char * name
; /* It is copied, the caller can modify. */
1212 segT segment
; /* Segment identifier (SEG_<something>). */
1213 valueT valu
; /* Symbol value. */
1214 fragS
* frag
; /* Associated fragment. */
1216 unsigned int name_length
;
1217 char * preserved_copy_of_name
;
1219 name_length
= strlen (name
) + 1; /* +1 for \0. */
1220 obstack_grow (¬es
, name
, name_length
);
1221 preserved_copy_of_name
= obstack_finish (¬es
);
1222 #ifdef STRIP_UNDERSCORE
1223 if (preserved_copy_of_name
[0] == '_')
1224 preserved_copy_of_name
++;
1227 #ifdef tc_canonicalize_symbol_name
1228 preserved_copy_of_name
=
1229 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1232 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1234 S_SET_SEGMENT (symbolP
, segment
);
1235 S_SET_VALUE (symbolP
, valu
);
1236 symbol_clear_list_pointers(symbolP
);
1238 symbol_set_frag (symbolP
, frag
);
1240 /* Link to end of symbol chain. */
1242 extern int symbol_table_frozen
;
1243 if (symbol_table_frozen
)
1247 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1249 obj_symbol_new_hook (symbolP
);
1251 #ifdef tc_symbol_new_hook
1252 tc_symbol_new_hook (symbolP
);
1256 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1257 #endif /* DEBUG_SYMS */
1260 /* Check that an immediate is valid.
1261 If so, convert it to the right format. */
1264 validate_immediate (val
)
1270 #define rotate_left(v, n) (v << n | v >> (32 - n))
1272 for (i
= 0; i
< 32; i
+= 2)
1273 if ((a
= rotate_left (val
, i
)) <= 0xff)
1274 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1279 /* Check to see if an immediate can be computed as two seperate immediate
1280 values, added together. We already know that this value cannot be
1281 computed by just one ARM instruction. */
1284 validate_immediate_twopart (val
, highpart
)
1286 unsigned int * highpart
;
1291 for (i
= 0; i
< 32; i
+= 2)
1292 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1298 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1300 else if (a
& 0xff0000)
1304 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1308 assert (a
& 0xff000000);
1309 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1312 return (a
& 0xff) | (i
<< 7);
1319 validate_offset_imm (val
, hwse
)
1323 if ((hwse
&& val
> 255) || val
> 4095)
1330 int a ATTRIBUTE_UNUSED
;
1332 as_bad (_("Invalid syntax for .req directive."));
1337 int ignore ATTRIBUTE_UNUSED
;
1339 /* We don't support putting frags in the BSS segment, we fake it by
1340 marking in_bss, then looking at s_skip for clues. */
1341 subseg_set (bss_section
, 0);
1342 demand_empty_rest_of_line ();
1347 int ignore ATTRIBUTE_UNUSED
;
1349 /* Never make frag if expect extra pass. */
1351 frag_align (1, 0, 0);
1353 record_alignment (now_seg
, 1);
1355 demand_empty_rest_of_line ();
1360 int ignored ATTRIBUTE_UNUSED
;
1365 if (current_poolP
== NULL
)
1368 /* Align pool as you have word accesses.
1369 Only make a frag if we have to. */
1371 frag_align (2, 0, 0);
1373 record_alignment (now_seg
, 2);
1375 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1377 symbol_locate (current_poolP
, sym_name
, now_seg
,
1378 (valueT
) frag_now_fix (), frag_now
);
1379 symbol_table_insert (current_poolP
);
1381 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1383 #if defined OBJ_COFF || defined OBJ_ELF
1384 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1387 while (lit_count
< next_literal_pool_place
)
1388 /* First output the expression in the instruction to the pool. */
1389 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1391 next_literal_pool_place
= 0;
1392 current_poolP
= NULL
;
1395 /* Same as s_align_ptwo but align 0 => align 2. */
1399 int unused ATTRIBUTE_UNUSED
;
1402 register long temp_fill
;
1403 long max_alignment
= 15;
1405 temp
= get_absolute_expression ();
1406 if (temp
> max_alignment
)
1407 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1410 as_bad (_("Alignment negative. 0 assumed."));
1414 if (*input_line_pointer
== ',')
1416 input_line_pointer
++;
1417 temp_fill
= get_absolute_expression ();
1425 /* Only make a frag if we HAVE to. */
1426 if (temp
&& !need_pass_2
)
1427 frag_align (temp
, (int) temp_fill
, 0);
1428 demand_empty_rest_of_line ();
1430 record_alignment (now_seg
, temp
);
1434 s_force_thumb (ignore
)
1435 int ignore ATTRIBUTE_UNUSED
;
1437 /* If we are not already in thumb mode go into it, EVEN if
1438 the target processor does not support thumb instructions.
1439 This is used by gcc/config/arm/lib1funcs.asm for example
1440 to compile interworking support functions even if the
1441 target processor should not support interworking. */
1446 record_alignment (now_seg
, 1);
1449 demand_empty_rest_of_line ();
1453 s_thumb_func (ignore
)
1454 int ignore ATTRIBUTE_UNUSED
;
1459 /* The following label is the name/address of the start of a Thumb function.
1460 We need to know this for the interworking support. */
1461 label_is_thumb_function_name
= true;
1463 demand_empty_rest_of_line ();
1466 /* Perform a .set directive, but also mark the alias as
1467 being a thumb function. */
1473 /* XXX the following is a duplicate of the code for s_set() in read.c
1474 We cannot just call that code as we need to get at the symbol that
1476 register char * name
;
1477 register char delim
;
1478 register char * end_name
;
1479 register symbolS
* symbolP
;
1481 /* Especial apologies for the random logic:
1482 This just grew, and could be parsed much more simply!
1484 name
= input_line_pointer
;
1485 delim
= get_symbol_end ();
1486 end_name
= input_line_pointer
;
1491 if (*input_line_pointer
!= ',')
1494 as_bad (_("Expected comma after name \"%s\""), name
);
1496 ignore_rest_of_line ();
1500 input_line_pointer
++;
1503 if (name
[0] == '.' && name
[1] == '\0')
1505 /* XXX - this should not happen to .thumb_set. */
1509 if ((symbolP
= symbol_find (name
)) == NULL
1510 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1513 /* When doing symbol listings, play games with dummy fragments living
1514 outside the normal fragment chain to record the file and line info
1516 if (listing
& LISTING_SYMBOLS
)
1518 extern struct list_info_struct
* listing_tail
;
1519 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1521 memset (dummy_frag
, 0, sizeof (fragS
));
1522 dummy_frag
->fr_type
= rs_fill
;
1523 dummy_frag
->line
= listing_tail
;
1524 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1525 dummy_frag
->fr_symbol
= symbolP
;
1529 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1532 /* "set" symbols are local unless otherwise specified. */
1533 SF_SET_LOCAL (symbolP
);
1534 #endif /* OBJ_COFF */
1535 } /* Make a new symbol. */
1537 symbol_table_insert (symbolP
);
1542 && S_IS_DEFINED (symbolP
)
1543 && S_GET_SEGMENT (symbolP
) != reg_section
)
1544 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1546 pseudo_set (symbolP
);
1548 demand_empty_rest_of_line ();
1550 /* XXX Now we come to the Thumb specific bit of code. */
1552 THUMB_SET_FUNC (symbolP
, 1);
1553 ARM_SET_THUMB (symbolP
, 1);
1554 #if defined OBJ_ELF || defined OBJ_COFF
1555 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1559 /* If we change section we must dump the literal pool first. */
1565 if (now_seg
!= text_section
)
1569 obj_elf_text (ignore
);
1579 if (flag_readonly_data_in_text
)
1581 if (now_seg
!= text_section
)
1584 else if (now_seg
!= data_section
)
1588 obj_elf_data (ignore
);
1596 arm_s_section (ignore
)
1601 obj_elf_section (ignore
);
1606 opcode_select (width
)
1614 if (! (cpu_variant
& ARM_THUMB
))
1615 as_bad (_("selected processor does not support THUMB opcodes"));
1618 /* No need to force the alignment, since we will have been
1619 coming from ARM mode, which is word-aligned. */
1620 record_alignment (now_seg
, 1);
1627 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1628 as_bad (_("selected processor does not support ARM opcodes"));
1633 frag_align (2, 0, 0);
1635 record_alignment (now_seg
, 1);
1640 as_bad (_("invalid instruction size selected (%d)"), width
);
1646 int ignore ATTRIBUTE_UNUSED
;
1649 demand_empty_rest_of_line ();
1654 int ignore ATTRIBUTE_UNUSED
;
1657 demand_empty_rest_of_line ();
1662 int unused ATTRIBUTE_UNUSED
;
1666 temp
= get_absolute_expression ();
1671 opcode_select (temp
);
1675 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1683 skip_whitespace (str
);
1686 inst
.error
= _("Garbage following instruction");
1690 skip_past_comma (str
)
1693 char * p
= * str
, c
;
1696 while ((c
= *p
) == ' ' || c
== ',')
1699 if (c
== ',' && comma
++)
1707 return comma
? SUCCESS
: FAIL
;
1710 /* A standard register must be given at this point.
1711 SHIFT is the place to put it in inst.instruction.
1712 Restores input start point on error.
1713 Returns the reg#, or FAIL. */
1716 reg_required_here (str
, shift
)
1720 static char buff
[128]; /* XXX */
1722 char * start
= * str
;
1724 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1727 inst
.instruction
|= reg
<< shift
;
1731 /* Restore the start point, we may have got a reg of the wrong class. */
1734 /* In the few cases where we might be able to accept something else
1735 this error can be overridden. */
1736 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1742 static CONST
struct asm_psr
*
1744 register char ** ccp
;
1746 char * start
= * ccp
;
1749 CONST
struct asm_psr
* psr
;
1753 /* Skip to the end of the next word in the input stream. */
1758 while (isalpha (c
) || c
== '_');
1760 /* Terminate the word. */
1763 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1764 feature for ease of use and backwards compatibility. */
1765 if (!strncmp (start
, "cpsr", 4))
1766 strncpy (start
, "CPSR", 4);
1767 else if (!strncmp (start
, "spsr", 4))
1768 strncpy (start
, "SPSR", 4);
1770 /* Now locate the word in the psr hash table. */
1771 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1773 /* Restore the input stream. */
1776 /* If we found a valid match, advance the
1777 stream pointer past the end of the word. */
1783 /* Parse the input looking for a PSR flag. */
1786 psr_required_here (str
)
1789 char * start
= * str
;
1790 CONST
struct asm_psr
* psr
;
1792 psr
= arm_psr_parse (str
);
1796 /* If this is the SPSR that is being modified, set the R bit. */
1798 inst
.instruction
|= SPSR_BIT
;
1800 /* Set the psr flags in the MSR instruction. */
1801 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1806 /* In the few cases where we might be able to accept
1807 something else this error can be overridden. */
1808 inst
.error
= _("flag for {c}psr instruction expected");
1810 /* Restore the start point. */
1816 co_proc_number (str
)
1819 int processor
, pchar
;
1821 skip_whitespace (* str
);
1823 /* The data sheet seems to imply that just a number on its own is valid
1824 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1826 if (**str
== 'p' || **str
== 'P')
1830 if (pchar
>= '0' && pchar
<= '9')
1832 processor
= pchar
- '0';
1833 if (**str
>= '0' && **str
<= '9')
1835 processor
= processor
* 10 + *(*str
)++ - '0';
1838 inst
.error
= _("Illegal co-processor number");
1845 inst
.error
= _("Bad or missing co-processor number");
1849 inst
.instruction
|= processor
<< 8;
1854 cp_opc_expr (str
, where
, length
)
1861 skip_whitespace (* str
);
1863 memset (&expr
, '\0', sizeof (expr
));
1865 if (my_get_expression (&expr
, str
))
1867 if (expr
.X_op
!= O_constant
)
1869 inst
.error
= _("bad or missing expression");
1873 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1875 inst
.error
= _("immediate co-processor expression too large");
1879 inst
.instruction
|= expr
.X_add_number
<< where
;
1884 cp_reg_required_here (str
, where
)
1889 char * start
= *str
;
1891 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1894 inst
.instruction
|= reg
<< where
;
1898 /* In the few cases where we might be able to accept something else
1899 this error can be overridden. */
1900 inst
.error
= _("Co-processor register expected");
1902 /* Restore the start point. */
1908 fp_reg_required_here (str
, where
)
1913 char * start
= * str
;
1915 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1918 inst
.instruction
|= reg
<< where
;
1922 /* In the few cases where we might be able to accept something else
1923 this error can be overridden. */
1924 inst
.error
= _("Floating point register expected");
1926 /* Restore the start point. */
1932 cp_address_offset (str
)
1937 skip_whitespace (* str
);
1939 if (! is_immediate_prefix (**str
))
1941 inst
.error
= _("immediate expression expected");
1947 if (my_get_expression (& inst
.reloc
.exp
, str
))
1950 if (inst
.reloc
.exp
.X_op
== O_constant
)
1952 offset
= inst
.reloc
.exp
.X_add_number
;
1956 inst
.error
= _("co-processor address must be word aligned");
1960 if (offset
> 1023 || offset
< -1023)
1962 inst
.error
= _("offset too large");
1967 inst
.instruction
|= INDEX_UP
;
1971 inst
.instruction
|= offset
>> 2;
1974 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1980 cp_address_required_here (str
)
1992 skip_whitespace (p
);
1994 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1997 skip_whitespace (p
);
2003 if (skip_past_comma (& p
) == SUCCESS
)
2006 write_back
= WRITE_BACK
;
2010 inst
.error
= _("pc may not be used in post-increment");
2014 if (cp_address_offset (& p
) == FAIL
)
2018 pre_inc
= PRE_INDEX
| INDEX_UP
;
2022 /* '['Rn, #expr']'[!] */
2024 if (skip_past_comma (& p
) == FAIL
)
2026 inst
.error
= _("pre-indexed expression expected");
2030 pre_inc
= PRE_INDEX
;
2032 if (cp_address_offset (& p
) == FAIL
)
2035 skip_whitespace (p
);
2039 inst
.error
= _("missing ]");
2043 skip_whitespace (p
);
2049 inst
.error
= _("pc may not be used with write-back");
2054 write_back
= WRITE_BACK
;
2060 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2063 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2064 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2065 inst
.reloc
.pc_rel
= 1;
2066 inst
.instruction
|= (REG_PC
<< 16);
2067 pre_inc
= PRE_INDEX
;
2070 inst
.instruction
|= write_back
| pre_inc
;
2078 unsigned long flags
;
2080 /* Do nothing really. */
2081 inst
.instruction
|= flags
; /* This is pointless. */
2089 unsigned long flags
;
2093 /* Only one syntax. */
2094 skip_whitespace (str
);
2096 if (reg_required_here (&str
, 12) == FAIL
)
2098 inst
.error
= BAD_ARGS
;
2102 if (skip_past_comma (&str
) == FAIL
)
2104 inst
.error
= _("comma expected after register name");
2108 skip_whitespace (str
);
2110 if ( strcmp (str
, "CPSR") == 0
2111 || strcmp (str
, "SPSR") == 0
2112 /* Lower case versions for backwards compatability. */
2113 || strcmp (str
, "cpsr") == 0
2114 || strcmp (str
, "spsr") == 0)
2117 /* This is for backwards compatability with older toolchains. */
2118 else if ( strcmp (str
, "cpsr_all") == 0
2119 || strcmp (str
, "spsr_all") == 0)
2123 inst
.error
= _("{C|S}PSR expected");
2127 if (* str
== 's' || * str
== 'S')
2128 inst
.instruction
|= SPSR_BIT
;
2131 inst
.instruction
|= flags
;
2135 /* Two possible forms:
2136 "{C|S}PSR_<field>, Rm",
2137 "{C|S}PSR_f, #expression". */
2142 unsigned long flags
;
2144 skip_whitespace (str
);
2146 if (psr_required_here (& str
) == FAIL
)
2149 if (skip_past_comma (& str
) == FAIL
)
2151 inst
.error
= _("comma missing after psr flags");
2155 skip_whitespace (str
);
2157 if (reg_required_here (& str
, 0) != FAIL
)
2160 inst
.instruction
|= flags
;
2165 if (! is_immediate_prefix (* str
))
2168 _("only a register or immediate value can follow a psr flag");
2175 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2178 _("only a register or immediate value can follow a psr flag");
2182 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2184 inst
.error
= _("only flag field of psr can be set with immediate value");
2188 flags
|= INST_IMMEDIATE
;
2190 if (inst
.reloc
.exp
.X_add_symbol
)
2192 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2193 inst
.reloc
.pc_rel
= 0;
2197 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2199 if (value
== (unsigned) FAIL
)
2201 inst
.error
= _("Invalid constant");
2205 inst
.instruction
|= value
;
2209 inst
.instruction
|= flags
;
2213 /* Long Multiply Parser
2214 UMULL RdLo, RdHi, Rm, Rs
2215 SMULL RdLo, RdHi, Rm, Rs
2216 UMLAL RdLo, RdHi, Rm, Rs
2217 SMLAL RdLo, RdHi, Rm, Rs. */
2220 do_mull (str
, flags
)
2222 unsigned long flags
;
2224 int rdlo
, rdhi
, rm
, rs
;
2226 /* Only one format "rdlo, rdhi, rm, rs". */
2227 skip_whitespace (str
);
2229 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2231 inst
.error
= BAD_ARGS
;
2235 if (skip_past_comma (&str
) == FAIL
2236 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2238 inst
.error
= BAD_ARGS
;
2242 if (skip_past_comma (&str
) == FAIL
2243 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2245 inst
.error
= BAD_ARGS
;
2249 /* rdhi, rdlo and rm must all be different. */
2250 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2251 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2253 if (skip_past_comma (&str
) == FAIL
2254 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2256 inst
.error
= BAD_ARGS
;
2260 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2262 inst
.error
= BAD_PC
;
2266 inst
.instruction
|= flags
;
2274 unsigned long flags
;
2278 /* Only one format "rd, rm, rs". */
2279 skip_whitespace (str
);
2281 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2283 inst
.error
= BAD_ARGS
;
2289 inst
.error
= BAD_PC
;
2293 if (skip_past_comma (&str
) == FAIL
2294 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2296 inst
.error
= BAD_ARGS
;
2302 inst
.error
= BAD_PC
;
2307 as_tsktsk (_("rd and rm should be different in mul"));
2309 if (skip_past_comma (&str
) == FAIL
2310 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2312 inst
.error
= BAD_ARGS
;
2318 inst
.error
= BAD_PC
;
2322 inst
.instruction
|= flags
;
2330 unsigned long flags
;
2334 /* Only one format "rd, rm, rs, rn". */
2335 skip_whitespace (str
);
2337 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2339 inst
.error
= BAD_ARGS
;
2345 inst
.error
= BAD_PC
;
2349 if (skip_past_comma (&str
) == FAIL
2350 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2352 inst
.error
= BAD_ARGS
;
2358 inst
.error
= BAD_PC
;
2363 as_tsktsk (_("rd and rm should be different in mla"));
2365 if (skip_past_comma (&str
) == FAIL
2366 || (rd
= reg_required_here (&str
, 8)) == FAIL
2367 || skip_past_comma (&str
) == FAIL
2368 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2370 inst
.error
= BAD_ARGS
;
2374 if (rd
== REG_PC
|| rm
== REG_PC
)
2376 inst
.error
= BAD_PC
;
2380 inst
.instruction
|= flags
;
2385 /* Returns the index into fp_values of a floating point number,
2386 or -1 if not in the table. */
2389 my_get_float_expression (str
)
2392 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2398 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2400 /* Look for a raw floating point number. */
2401 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2402 && is_end_of_line
[(unsigned char) *save_in
])
2404 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2406 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2408 if (words
[j
] != fp_values
[i
][j
])
2412 if (j
== MAX_LITTLENUMS
)
2420 /* Try and parse a more complex expression, this will probably fail
2421 unless the code uses a floating point prefix (eg "0f"). */
2422 save_in
= input_line_pointer
;
2423 input_line_pointer
= *str
;
2424 if (expression (&exp
) == absolute_section
2425 && exp
.X_op
== O_big
2426 && exp
.X_add_number
< 0)
2428 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2430 if (gen_to_words (words
, 5, (long) 15) == 0)
2432 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2434 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2436 if (words
[j
] != fp_values
[i
][j
])
2440 if (j
== MAX_LITTLENUMS
)
2442 *str
= input_line_pointer
;
2443 input_line_pointer
= save_in
;
2450 *str
= input_line_pointer
;
2451 input_line_pointer
= save_in
;
2455 /* Return true if anything in the expression is a bignum. */
2458 walk_no_bignums (sp
)
2461 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2464 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2466 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2467 || (symbol_get_value_expression (sp
)->X_op_symbol
2468 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2475 my_get_expression (ep
, str
)
2482 save_in
= input_line_pointer
;
2483 input_line_pointer
= *str
;
2484 seg
= expression (ep
);
2487 if (seg
!= absolute_section
2488 && seg
!= text_section
2489 && seg
!= data_section
2490 && seg
!= bss_section
2491 && seg
!= undefined_section
)
2493 inst
.error
= _("bad_segment");
2494 *str
= input_line_pointer
;
2495 input_line_pointer
= save_in
;
2500 /* Get rid of any bignums now, so that we don't generate an error for which
2501 we can't establish a line number later on. Big numbers are never valid
2502 in instructions, which is where this routine is always called. */
2503 if (ep
->X_op
== O_big
2504 || (ep
->X_add_symbol
2505 && (walk_no_bignums (ep
->X_add_symbol
)
2507 && walk_no_bignums (ep
->X_op_symbol
)))))
2509 inst
.error
= _("Invalid constant");
2510 *str
= input_line_pointer
;
2511 input_line_pointer
= save_in
;
2515 *str
= input_line_pointer
;
2516 input_line_pointer
= save_in
;
2520 /* UNRESTRICT should be one if <shift> <register> is permitted for this
2524 decode_shift (str
, unrestrict
)
2528 const struct asm_shift_name
* shift
;
2532 skip_whitespace (* str
);
2534 for (p
= * str
; isalpha (* p
); p
++)
2539 inst
.error
= _("Shift expression expected");
2545 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
2550 inst
.error
= _("Shift expression expected");
2554 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
2556 if (shift
->properties
->index
== SHIFT_RRX
)
2559 inst
.instruction
|= shift
->properties
->bit_field
;
2563 skip_whitespace (p
);
2565 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
2567 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
2571 else if (! is_immediate_prefix (* p
))
2573 inst
.error
= (unrestrict
2574 ? _("shift requires register or #expression")
2575 : _("shift requires #expression"));
2583 if (my_get_expression (& inst
.reloc
.exp
, & p
))
2586 /* Validate some simple #expressions. */
2587 if (inst
.reloc
.exp
.X_op
== O_constant
)
2589 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2591 /* Reject operations greater than 32. */
2593 /* Reject a shift of 0 unless the mode allows it. */
2594 || (num
== 0 && shift
->properties
->allows_0
== 0)
2595 /* Reject a shift of 32 unless the mode allows it. */
2596 || (num
== 32 && shift
->properties
->allows_32
== 0)
2599 /* As a special case we allow a shift of zero for
2600 modes that do not support it to be recoded as an
2601 logical shift left of zero (ie nothing). We warn
2602 about this though. */
2605 as_warn (_("Shift of 0 ignored."));
2606 shift
= & shift_names
[0];
2607 assert (shift
->properties
->index
== SHIFT_LSL
);
2611 inst
.error
= _("Invalid immediate shift");
2616 /* Shifts of 32 are encoded as 0, for those shifts that
2621 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
2625 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2626 inst
.reloc
.pc_rel
= 0;
2627 inst
.instruction
|= shift
->properties
->bit_field
;
2634 /* Do those data_ops which can take a negative immediate constant
2635 by altering the instuction. A bit of a hack really.
2639 by inverting the second operand, and
2642 by negating the second operand. */
2645 negate_data_op (instruction
, value
)
2646 unsigned long * instruction
;
2647 unsigned long value
;
2650 unsigned long negated
, inverted
;
2652 negated
= validate_immediate (-value
);
2653 inverted
= validate_immediate (~value
);
2655 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2658 /* First negates. */
2659 case OPCODE_SUB
: /* ADD <-> SUB */
2660 new_inst
= OPCODE_ADD
;
2665 new_inst
= OPCODE_SUB
;
2669 case OPCODE_CMP
: /* CMP <-> CMN */
2670 new_inst
= OPCODE_CMN
;
2675 new_inst
= OPCODE_CMP
;
2679 /* Now Inverted ops. */
2680 case OPCODE_MOV
: /* MOV <-> MVN */
2681 new_inst
= OPCODE_MVN
;
2686 new_inst
= OPCODE_MOV
;
2690 case OPCODE_AND
: /* AND <-> BIC */
2691 new_inst
= OPCODE_BIC
;
2696 new_inst
= OPCODE_AND
;
2700 case OPCODE_ADC
: /* ADC <-> SBC */
2701 new_inst
= OPCODE_SBC
;
2706 new_inst
= OPCODE_ADC
;
2710 /* We cannot do anything. */
2715 if (value
== (unsigned) FAIL
)
2718 *instruction
&= OPCODE_MASK
;
2719 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2730 skip_whitespace (* str
);
2732 if (reg_required_here (str
, 0) != FAIL
)
2734 if (skip_past_comma (str
) == SUCCESS
)
2735 /* Shift operation on register. */
2736 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2742 /* Immediate expression. */
2743 if (is_immediate_prefix (**str
))
2748 if (my_get_expression (&inst
.reloc
.exp
, str
))
2751 if (inst
.reloc
.exp
.X_add_symbol
)
2753 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2754 inst
.reloc
.pc_rel
= 0;
2758 if (skip_past_comma (str
) == SUCCESS
)
2760 /* #x, y -- ie explicit rotation by Y. */
2761 if (my_get_expression (&expr
, str
))
2764 if (expr
.X_op
!= O_constant
)
2766 inst
.error
= _("Constant expression expected");
2770 /* Rotate must be a multiple of 2. */
2771 if (((unsigned) expr
.X_add_number
) > 30
2772 || (expr
.X_add_number
& 1) != 0
2773 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2775 inst
.error
= _("Invalid constant");
2778 inst
.instruction
|= INST_IMMEDIATE
;
2779 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2780 inst
.instruction
|= expr
.X_add_number
<< 7;
2784 /* Implicit rotation, select a suitable one. */
2785 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2789 /* Can't be done. Perhaps the code reads something like
2790 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
2791 if ((value
= negate_data_op (&inst
.instruction
,
2792 inst
.reloc
.exp
.X_add_number
))
2795 inst
.error
= _("Invalid constant");
2800 inst
.instruction
|= value
;
2803 inst
.instruction
|= INST_IMMEDIATE
;
2808 inst
.error
= _("Register or shift expression expected");
2817 skip_whitespace (* str
);
2819 if (fp_reg_required_here (str
, 0) != FAIL
)
2823 /* Immediate expression. */
2824 if (*((*str
)++) == '#')
2830 skip_whitespace (* str
);
2832 /* First try and match exact strings, this is to guarantee
2833 that some formats will work even for cross assembly. */
2835 for (i
= 0; fp_const
[i
]; i
++)
2837 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2841 *str
+= strlen (fp_const
[i
]);
2842 if (is_end_of_line
[(unsigned char) **str
])
2844 inst
.instruction
|= i
+ 8;
2851 /* Just because we didn't get a match doesn't mean that the
2852 constant isn't valid, just that it is in a format that we
2853 don't automatically recognize. Try parsing it with
2854 the standard expression routines. */
2855 if ((i
= my_get_float_expression (str
)) >= 0)
2857 inst
.instruction
|= i
+ 8;
2861 inst
.error
= _("Invalid floating point immediate expression");
2865 _("Floating point register or immediate expression expected");
2871 do_arit (str
, flags
)
2873 unsigned long flags
;
2875 skip_whitespace (str
);
2877 if (reg_required_here (&str
, 12) == FAIL
2878 || skip_past_comma (&str
) == FAIL
2879 || reg_required_here (&str
, 16) == FAIL
2880 || skip_past_comma (&str
) == FAIL
2881 || data_op2 (&str
) == FAIL
)
2884 inst
.error
= BAD_ARGS
;
2888 inst
.instruction
|= flags
;
2896 unsigned long flags
;
2898 /* This is a pseudo-op of the form "adr rd, label" to be converted
2899 into a relative address of the form "add rd, pc, #label-.-8". */
2900 skip_whitespace (str
);
2902 if (reg_required_here (&str
, 12) == FAIL
2903 || skip_past_comma (&str
) == FAIL
2904 || my_get_expression (&inst
.reloc
.exp
, &str
))
2907 inst
.error
= BAD_ARGS
;
2911 /* Frag hacking will turn this into a sub instruction if the offset turns
2912 out to be negative. */
2913 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2914 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2915 inst
.reloc
.pc_rel
= 1;
2916 inst
.instruction
|= flags
;
2922 do_adrl (str
, flags
)
2924 unsigned long flags
;
2926 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2927 into a relative address of the form:
2928 add rd, pc, #low(label-.-8)"
2929 add rd, rd, #high(label-.-8)" */
2931 skip_whitespace (str
);
2933 if (reg_required_here (& str
, 12) == FAIL
2934 || skip_past_comma (& str
) == FAIL
2935 || my_get_expression (& inst
.reloc
.exp
, & str
))
2938 inst
.error
= BAD_ARGS
;
2944 /* Frag hacking will turn this into a sub instruction if the offset turns
2945 out to be negative. */
2946 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2947 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2948 inst
.reloc
.pc_rel
= 1;
2949 inst
.instruction
|= flags
;
2950 inst
.size
= INSN_SIZE
* 2;
2958 unsigned long flags
;
2960 skip_whitespace (str
);
2962 if (reg_required_here (&str
, 16) == FAIL
)
2965 inst
.error
= BAD_ARGS
;
2969 if (skip_past_comma (&str
) == FAIL
2970 || data_op2 (&str
) == FAIL
)
2973 inst
.error
= BAD_ARGS
;
2977 inst
.instruction
|= flags
;
2978 if ((flags
& 0x0000f000) == 0)
2979 inst
.instruction
|= CONDS_BIT
;
2988 unsigned long flags
;
2990 skip_whitespace (str
);
2992 if (reg_required_here (&str
, 12) == FAIL
)
2995 inst
.error
= BAD_ARGS
;
2999 if (skip_past_comma (&str
) == FAIL
3000 || data_op2 (&str
) == FAIL
)
3003 inst
.error
= BAD_ARGS
;
3007 inst
.instruction
|= flags
;
3013 ldst_extend (str
, hwse
)
3024 if (my_get_expression (& inst
.reloc
.exp
, str
))
3027 if (inst
.reloc
.exp
.X_op
== O_constant
)
3029 int value
= inst
.reloc
.exp
.X_add_number
;
3031 if ((hwse
&& (value
< -255 || value
> 255))
3032 || (value
< -4095 || value
> 4095))
3034 inst
.error
= _("address offset too large");
3044 /* Halfword and signextension instructions have the
3045 immediate value split across bits 11..8 and bits 3..0. */
3047 inst
.instruction
|= (add
| HWOFFSET_IMM
3048 | ((value
>> 4) << 8) | (value
& 0xF));
3050 inst
.instruction
|= add
| value
;
3056 inst
.instruction
|= HWOFFSET_IMM
;
3057 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3060 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3061 inst
.reloc
.pc_rel
= 0;
3074 if (reg_required_here (str
, 0) == FAIL
)
3078 inst
.instruction
|= add
;
3081 inst
.instruction
|= add
| OFFSET_REG
;
3082 if (skip_past_comma (str
) == SUCCESS
)
3083 return decode_shift (str
, SHIFT_RESTRICT
);
3091 do_ldst (str
, flags
)
3093 unsigned long flags
;
3100 /* This is not ideal, but it is the simplest way of dealing with the
3101 ARM7T halfword instructions (since they use a different
3102 encoding, but the same mnemonic): */
3103 halfword
= (flags
& 0x80000000) != 0;
3106 /* This is actually a load/store of a halfword, or a
3107 signed-extension load. */
3108 if ((cpu_variant
& ARM_HALFWORD
) == 0)
3111 = _("Processor does not support halfwords or signed bytes");
3115 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
3116 | (flags
& ~COND_MASK
));
3121 skip_whitespace (str
);
3123 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
3126 inst
.error
= BAD_ARGS
;
3130 if (skip_past_comma (& str
) == FAIL
)
3132 inst
.error
= _("Address expected");
3142 skip_whitespace (str
);
3144 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3147 /* Conflicts can occur on stores as well as loads. */
3148 conflict_reg
= (conflict_reg
== reg
);
3150 skip_whitespace (str
);
3156 if (skip_past_comma (&str
) == SUCCESS
)
3158 /* [Rn],... (post inc) */
3159 if (ldst_extend (&str
, halfword
) == FAIL
)
3162 as_warn (_("%s register same as write-back base"),
3163 ((inst
.instruction
& LOAD_BIT
)
3164 ? _("destination") : _("source")));
3170 inst
.instruction
|= HWOFFSET_IMM
;
3172 skip_whitespace (str
);
3177 as_warn (_("%s register same as write-back base"),
3178 ((inst
.instruction
& LOAD_BIT
)
3179 ? _("destination") : _("source")));
3181 inst
.instruction
|= WRITE_BACK
;
3185 if (! (flags
& TRANS_BIT
))
3192 if (skip_past_comma (&str
) == FAIL
)
3194 inst
.error
= _("pre-indexed expression expected");
3199 if (ldst_extend (&str
, halfword
) == FAIL
)
3202 skip_whitespace (str
);
3206 inst
.error
= _("missing ]");
3210 skip_whitespace (str
);
3215 as_warn (_("%s register same as write-back base"),
3216 ((inst
.instruction
& LOAD_BIT
)
3217 ? _("destination") : _("source")));
3219 inst
.instruction
|= WRITE_BACK
;
3223 else if (*str
== '=')
3225 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
3228 skip_whitespace (str
);
3230 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3233 if (inst
.reloc
.exp
.X_op
!= O_constant
3234 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3236 inst
.error
= _("Constant expression expected");
3240 if (inst
.reloc
.exp
.X_op
== O_constant
3241 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3243 /* This can be done with a mov instruction. */
3244 inst
.instruction
&= LITERAL_MASK
;
3245 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3246 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3252 /* Insert into literal pool. */
3253 if (add_to_lit_pool () == FAIL
)
3256 inst
.error
= _("literal pool insertion failed");
3260 /* Change the instruction exp to point to the pool. */
3263 inst
.instruction
|= HWOFFSET_IMM
;
3264 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3267 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3268 inst
.reloc
.pc_rel
= 1;
3269 inst
.instruction
|= (REG_PC
<< 16);
3275 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3280 inst
.instruction
|= HWOFFSET_IMM
;
3281 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3284 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3286 /* PC rel adjust. */
3287 inst
.reloc
.exp
.X_add_number
-= 8;
3289 inst
.reloc
.pc_rel
= 1;
3290 inst
.instruction
|= (REG_PC
<< 16);
3294 if (pre_inc
&& (flags
& TRANS_BIT
))
3295 inst
.error
= _("Pre-increment instruction with translate");
3297 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3306 char * str
= * strp
;
3310 /* We come back here if we get ranges concatenated by '+' or '|'. */
3325 skip_whitespace (str
);
3327 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3336 inst
.error
= _("Bad range in register list");
3340 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3342 if (range
& (1 << i
))
3344 (_("Warning: Duplicated register (r%d) in register list"),
3352 if (range
& (1 << reg
))
3353 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3355 else if (reg
<= cur_reg
)
3356 as_tsktsk (_("Warning: Register range not in ascending order"));
3361 while (skip_past_comma (&str
) != FAIL
3362 || (in_range
= 1, *str
++ == '-'));
3364 skip_whitespace (str
);
3368 inst
.error
= _("Missing `}'");
3376 if (my_get_expression (&expr
, &str
))
3379 if (expr
.X_op
== O_constant
)
3381 if (expr
.X_add_number
3382 != (expr
.X_add_number
& 0x0000ffff))
3384 inst
.error
= _("invalid register mask");
3388 if ((range
& expr
.X_add_number
) != 0)
3390 int regno
= range
& expr
.X_add_number
;
3393 regno
= (1 << regno
) - 1;
3395 (_("Warning: Duplicated register (r%d) in register list"),
3399 range
|= expr
.X_add_number
;
3403 if (inst
.reloc
.type
!= 0)
3405 inst
.error
= _("expression too complex");
3409 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3410 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3411 inst
.reloc
.pc_rel
= 0;
3415 skip_whitespace (str
);
3417 if (*str
== '|' || *str
== '+')
3423 while (another_range
);
3430 do_ldmstm (str
, flags
)
3432 unsigned long flags
;
3437 skip_whitespace (str
);
3439 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3442 if (base_reg
== REG_PC
)
3444 inst
.error
= _("r15 not allowed as base register");
3448 skip_whitespace (str
);
3452 flags
|= WRITE_BACK
;
3456 if (skip_past_comma (&str
) == FAIL
3457 || (range
= reg_list (&str
)) == FAIL
)
3460 inst
.error
= BAD_ARGS
;
3467 flags
|= LDM_TYPE_2_OR_3
;
3470 inst
.instruction
|= flags
| range
;
3478 unsigned long flags
;
3480 skip_whitespace (str
);
3482 /* Allow optional leading '#'. */
3483 if (is_immediate_prefix (*str
))
3486 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3489 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3490 inst
.reloc
.pc_rel
= 0;
3491 inst
.instruction
|= flags
;
3499 do_swap (str
, flags
)
3501 unsigned long flags
;
3505 skip_whitespace (str
);
3507 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3512 inst
.error
= _("r15 not allowed in swap");
3516 if (skip_past_comma (&str
) == FAIL
3517 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3520 inst
.error
= BAD_ARGS
;
3526 inst
.error
= _("r15 not allowed in swap");
3530 if (skip_past_comma (&str
) == FAIL
3533 inst
.error
= BAD_ARGS
;
3537 skip_whitespace (str
);
3539 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3544 inst
.error
= BAD_PC
;
3548 skip_whitespace (str
);
3552 inst
.error
= _("missing ]");
3556 inst
.instruction
|= flags
;
3562 do_branch (str
, flags
)
3564 unsigned long flags ATTRIBUTE_UNUSED
;
3566 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3573 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
3574 required for the instruction. */
3576 /* arm_parse_reloc () works on input_line_pointer.
3577 We actually want to parse the operands to the branch instruction
3578 passed in 'str'. Save the input pointer and restore it later. */
3579 save_in
= input_line_pointer
;
3580 input_line_pointer
= str
;
3581 if (inst
.reloc
.exp
.X_op
== O_symbol
3583 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3585 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3586 inst
.reloc
.pc_rel
= 0;
3587 /* Modify str to point to after parsed operands, otherwise
3588 end_of_line() will complain about the (PLT) left in str. */
3589 str
= input_line_pointer
;
3593 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3594 inst
.reloc
.pc_rel
= 1;
3596 input_line_pointer
= save_in
;
3599 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3600 inst
.reloc
.pc_rel
= 1;
3601 #endif /* OBJ_ELF */
3610 unsigned long flags ATTRIBUTE_UNUSED
;
3614 skip_whitespace (str
);
3616 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3618 inst
.error
= BAD_ARGS
;
3622 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
3624 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
3632 unsigned long flags ATTRIBUTE_UNUSED
;
3634 /* Co-processor data operation.
3635 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3636 skip_whitespace (str
);
3638 if (co_proc_number (&str
) == FAIL
)
3641 inst
.error
= BAD_ARGS
;
3645 if (skip_past_comma (&str
) == FAIL
3646 || cp_opc_expr (&str
, 20,4) == FAIL
)
3649 inst
.error
= BAD_ARGS
;
3653 if (skip_past_comma (&str
) == FAIL
3654 || cp_reg_required_here (&str
, 12) == FAIL
)
3657 inst
.error
= BAD_ARGS
;
3661 if (skip_past_comma (&str
) == FAIL
3662 || cp_reg_required_here (&str
, 16) == FAIL
)
3665 inst
.error
= BAD_ARGS
;
3669 if (skip_past_comma (&str
) == FAIL
3670 || cp_reg_required_here (&str
, 0) == FAIL
)
3673 inst
.error
= BAD_ARGS
;
3677 if (skip_past_comma (&str
) == SUCCESS
)
3679 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3682 inst
.error
= BAD_ARGS
;
3692 do_lstc (str
, flags
)
3694 unsigned long flags
;
3696 /* Co-processor register load/store.
3697 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3699 skip_whitespace (str
);
3701 if (co_proc_number (&str
) == FAIL
)
3704 inst
.error
= BAD_ARGS
;
3708 if (skip_past_comma (&str
) == FAIL
3709 || cp_reg_required_here (&str
, 12) == FAIL
)
3712 inst
.error
= BAD_ARGS
;
3716 if (skip_past_comma (&str
) == FAIL
3717 || cp_address_required_here (&str
) == FAIL
)
3720 inst
.error
= BAD_ARGS
;
3724 inst
.instruction
|= flags
;
3730 do_co_reg (str
, flags
)
3732 unsigned long flags
;
3734 /* Co-processor register transfer.
3735 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3737 skip_whitespace (str
);
3739 if (co_proc_number (&str
) == FAIL
)
3742 inst
.error
= BAD_ARGS
;
3746 if (skip_past_comma (&str
) == FAIL
3747 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3750 inst
.error
= BAD_ARGS
;
3754 if (skip_past_comma (&str
) == FAIL
3755 || reg_required_here (&str
, 12) == FAIL
)
3758 inst
.error
= BAD_ARGS
;
3762 if (skip_past_comma (&str
) == FAIL
3763 || cp_reg_required_here (&str
, 16) == FAIL
)
3766 inst
.error
= BAD_ARGS
;
3770 if (skip_past_comma (&str
) == FAIL
3771 || cp_reg_required_here (&str
, 0) == FAIL
)
3774 inst
.error
= BAD_ARGS
;
3778 if (skip_past_comma (&str
) == SUCCESS
)
3780 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3783 inst
.error
= BAD_ARGS
;
3789 inst
.error
= BAD_COND
;
3797 do_fp_ctrl (str
, flags
)
3799 unsigned long flags ATTRIBUTE_UNUSED
;
3801 /* FP control registers.
3802 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3804 skip_whitespace (str
);
3806 if (reg_required_here (&str
, 12) == FAIL
)
3809 inst
.error
= BAD_ARGS
;
3818 do_fp_ldst (str
, flags
)
3820 unsigned long flags ATTRIBUTE_UNUSED
;
3822 skip_whitespace (str
);
3824 switch (inst
.suffix
)
3829 inst
.instruction
|= CP_T_X
;
3832 inst
.instruction
|= CP_T_Y
;
3835 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3841 if (fp_reg_required_here (&str
, 12) == FAIL
)
3844 inst
.error
= BAD_ARGS
;
3848 if (skip_past_comma (&str
) == FAIL
3849 || cp_address_required_here (&str
) == FAIL
)
3852 inst
.error
= BAD_ARGS
;
3860 do_fp_ldmstm (str
, flags
)
3862 unsigned long flags
;
3866 skip_whitespace (str
);
3868 if (fp_reg_required_here (&str
, 12) == FAIL
)
3871 inst
.error
= BAD_ARGS
;
3875 /* Get Number of registers to transfer. */
3876 if (skip_past_comma (&str
) == FAIL
3877 || my_get_expression (&inst
.reloc
.exp
, &str
))
3880 inst
.error
= _("constant expression expected");
3884 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3886 inst
.error
= _("Constant value required for number of registers");
3890 num_regs
= inst
.reloc
.exp
.X_add_number
;
3892 if (num_regs
< 1 || num_regs
> 4)
3894 inst
.error
= _("number of registers must be in the range [1:4]");
3901 inst
.instruction
|= CP_T_X
;
3904 inst
.instruction
|= CP_T_Y
;
3907 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3921 /* The instruction specified "ea" or "fd", so we can only accept
3922 [Rn]{!}. The instruction does not really support stacking or
3923 unstacking, so we have to emulate these by setting appropriate
3924 bits and offsets. */
3925 if (skip_past_comma (&str
) == FAIL
3929 inst
.error
= BAD_ARGS
;
3934 skip_whitespace (str
);
3936 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3939 skip_whitespace (str
);
3943 inst
.error
= BAD_ARGS
;
3955 _("R15 not allowed as base register with write-back");
3962 if (flags
& CP_T_Pre
)
3964 /* Pre-decrement. */
3965 offset
= 3 * num_regs
;
3971 /* Post-increment. */
3975 offset
= 3 * num_regs
;
3979 /* No write-back, so convert this into a standard pre-increment
3980 instruction -- aesthetically more pleasing. */
3981 flags
= CP_T_Pre
| CP_T_UD
;
3986 inst
.instruction
|= flags
| offset
;
3988 else if (skip_past_comma (&str
) == FAIL
3989 || cp_address_required_here (&str
) == FAIL
)
3992 inst
.error
= BAD_ARGS
;
4000 do_fp_dyadic (str
, flags
)
4002 unsigned long flags
;
4004 skip_whitespace (str
);
4006 switch (inst
.suffix
)
4011 inst
.instruction
|= 0x00000080;
4014 inst
.instruction
|= 0x00080000;
4020 if (fp_reg_required_here (&str
, 12) == FAIL
)
4023 inst
.error
= BAD_ARGS
;
4027 if (skip_past_comma (&str
) == FAIL
4028 || fp_reg_required_here (&str
, 16) == FAIL
)
4031 inst
.error
= BAD_ARGS
;
4035 if (skip_past_comma (&str
) == FAIL
4036 || fp_op2 (&str
) == FAIL
)
4039 inst
.error
= BAD_ARGS
;
4043 inst
.instruction
|= flags
;
4049 do_fp_monadic (str
, flags
)
4051 unsigned long flags
;
4053 skip_whitespace (str
);
4055 switch (inst
.suffix
)
4060 inst
.instruction
|= 0x00000080;
4063 inst
.instruction
|= 0x00080000;
4069 if (fp_reg_required_here (&str
, 12) == FAIL
)
4072 inst
.error
= BAD_ARGS
;
4076 if (skip_past_comma (&str
) == FAIL
4077 || fp_op2 (&str
) == FAIL
)
4080 inst
.error
= BAD_ARGS
;
4084 inst
.instruction
|= flags
;
4090 do_fp_cmp (str
, flags
)
4092 unsigned long flags
;
4094 skip_whitespace (str
);
4096 if (fp_reg_required_here (&str
, 16) == FAIL
)
4099 inst
.error
= BAD_ARGS
;
4103 if (skip_past_comma (&str
) == FAIL
4104 || fp_op2 (&str
) == FAIL
)
4107 inst
.error
= BAD_ARGS
;
4111 inst
.instruction
|= flags
;
4117 do_fp_from_reg (str
, flags
)
4119 unsigned long flags
;
4121 skip_whitespace (str
);
4123 switch (inst
.suffix
)
4128 inst
.instruction
|= 0x00000080;
4131 inst
.instruction
|= 0x00080000;
4137 if (fp_reg_required_here (&str
, 16) == FAIL
)
4140 inst
.error
= BAD_ARGS
;
4144 if (skip_past_comma (&str
) == FAIL
4145 || reg_required_here (&str
, 12) == FAIL
)
4148 inst
.error
= BAD_ARGS
;
4152 inst
.instruction
|= flags
;
4158 do_fp_to_reg (str
, flags
)
4160 unsigned long flags
;
4162 skip_whitespace (str
);
4164 if (reg_required_here (&str
, 12) == FAIL
)
4167 if (skip_past_comma (&str
) == FAIL
4168 || fp_reg_required_here (&str
, 0) == FAIL
)
4171 inst
.error
= BAD_ARGS
;
4175 inst
.instruction
|= flags
;
4180 /* Thumb specific routines. */
4182 /* Parse and validate that a register is of the right form, this saves
4183 repeated checking of this information in many similar cases.
4184 Unlike the 32-bit case we do not insert the register into the opcode
4185 here, since the position is often unknown until the full instruction
4189 thumb_reg (strp
, hi_lo
)
4195 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
4203 inst
.error
= _("lo register required");
4211 inst
.error
= _("hi register required");
4223 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4227 thumb_add_sub (str
, subtract
)
4231 int Rd
, Rs
, Rn
= FAIL
;
4233 skip_whitespace (str
);
4235 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4236 || skip_past_comma (&str
) == FAIL
)
4239 inst
.error
= BAD_ARGS
;
4243 if (is_immediate_prefix (*str
))
4247 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4252 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4255 if (skip_past_comma (&str
) == FAIL
)
4257 /* Two operand format, shuffle the registers
4258 and pretend there are 3. */
4262 else if (is_immediate_prefix (*str
))
4265 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4268 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4272 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4273 for the latter case, EXPR contains the immediate that was found. */
4276 /* All register format. */
4277 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4281 inst
.error
= _("dest and source1 must be the same register");
4285 /* Can't do this for SUB. */
4288 inst
.error
= _("subtract valid only on lo regs");
4292 inst
.instruction
= (T_OPCODE_ADD_HI
4293 | (Rd
> 7 ? THUMB_H1
: 0)
4294 | (Rn
> 7 ? THUMB_H2
: 0));
4295 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4299 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4300 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4305 /* Immediate expression, now things start to get nasty. */
4307 /* First deal with HI regs, only very restricted cases allowed:
4308 Adjusting SP, and using PC or SP to get an address. */
4309 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4310 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4312 inst
.error
= _("invalid Hi register with immediate");
4316 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4318 /* Value isn't known yet, all we can do is store all the fragments
4319 we know about in the instruction and let the reloc hacking
4321 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4322 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4326 int offset
= inst
.reloc
.exp
.X_add_number
;
4336 /* Quick check, in case offset is MIN_INT. */
4339 inst
.error
= _("immediate value out of range");
4348 if (offset
& ~0x1fc)
4350 inst
.error
= _("invalid immediate value for stack adjust");
4353 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4354 inst
.instruction
|= offset
>> 2;
4356 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4359 || (offset
& ~0x3fc))
4361 inst
.error
= _("invalid immediate for address calculation");
4364 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4366 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4372 inst
.error
= _("immediate value out of range");
4375 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4376 inst
.instruction
|= (Rd
<< 8) | offset
;
4382 inst
.error
= _("immediate value out of range");
4385 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4386 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4395 thumb_shift (str
, shift
)
4399 int Rd
, Rs
, Rn
= FAIL
;
4401 skip_whitespace (str
);
4403 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4404 || skip_past_comma (&str
) == FAIL
)
4407 inst
.error
= BAD_ARGS
;
4411 if (is_immediate_prefix (*str
))
4413 /* Two operand immediate format, set Rs to Rd. */
4416 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4421 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4424 if (skip_past_comma (&str
) == FAIL
)
4426 /* Two operand format, shuffle the registers
4427 and pretend there are 3. */
4431 else if (is_immediate_prefix (*str
))
4434 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4437 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4441 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4442 for the latter case, EXPR contains the immediate that was found. */
4448 inst
.error
= _("source1 and dest must be same register");
4454 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4455 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4456 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4459 inst
.instruction
|= Rd
| (Rn
<< 3);
4465 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4466 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4467 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4470 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4472 /* Value isn't known yet, create a dummy reloc and let reloc
4473 hacking fix it up. */
4474 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4478 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4480 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4482 inst
.error
= _("Invalid immediate for shift");
4486 /* Shifts of zero are handled by converting to LSL. */
4487 if (shift_value
== 0)
4488 inst
.instruction
= T_OPCODE_LSL_I
;
4490 /* Shifts of 32 are encoded as a shift of zero. */
4491 if (shift_value
== 32)
4494 inst
.instruction
|= shift_value
<< 6;
4497 inst
.instruction
|= Rd
| (Rs
<< 3);
4504 thumb_mov_compare (str
, move
)
4510 skip_whitespace (str
);
4512 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4513 || skip_past_comma (&str
) == FAIL
)
4516 inst
.error
= BAD_ARGS
;
4520 if (is_immediate_prefix (*str
))
4523 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4526 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4531 if (Rs
< 8 && Rd
< 8)
4533 if (move
== THUMB_MOVE
)
4534 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4535 since a MOV instruction produces unpredictable results. */
4536 inst
.instruction
= T_OPCODE_ADD_I3
;
4538 inst
.instruction
= T_OPCODE_CMP_LR
;
4539 inst
.instruction
|= Rd
| (Rs
<< 3);
4543 if (move
== THUMB_MOVE
)
4544 inst
.instruction
= T_OPCODE_MOV_HR
;
4546 inst
.instruction
= T_OPCODE_CMP_HR
;
4549 inst
.instruction
|= THUMB_H1
;
4552 inst
.instruction
|= THUMB_H2
;
4554 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4561 inst
.error
= _("only lo regs allowed with immediate");
4565 if (move
== THUMB_MOVE
)
4566 inst
.instruction
= T_OPCODE_MOV_I8
;
4568 inst
.instruction
= T_OPCODE_CMP_I8
;
4570 inst
.instruction
|= Rd
<< 8;
4572 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4573 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4576 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4580 inst
.error
= _("invalid immediate");
4584 inst
.instruction
|= value
;
4592 thumb_load_store (str
, load_store
, size
)
4597 int Rd
, Rb
, Ro
= FAIL
;
4599 skip_whitespace (str
);
4601 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4602 || skip_past_comma (&str
) == FAIL
)
4605 inst
.error
= BAD_ARGS
;
4612 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4615 if (skip_past_comma (&str
) != FAIL
)
4617 if (is_immediate_prefix (*str
))
4620 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4623 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4628 inst
.reloc
.exp
.X_op
= O_constant
;
4629 inst
.reloc
.exp
.X_add_number
= 0;
4634 inst
.error
= _("expected ']'");
4639 else if (*str
== '=')
4641 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4644 skip_whitespace (str
);
4646 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4651 if ( inst
.reloc
.exp
.X_op
!= O_constant
4652 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4654 inst
.error
= "Constant expression expected";
4658 if (inst
.reloc
.exp
.X_op
== O_constant
4659 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4661 /* This can be done with a mov instruction. */
4663 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4664 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4668 /* Insert into literal pool. */
4669 if (add_to_lit_pool () == FAIL
)
4672 inst
.error
= "literal pool insertion failed";
4676 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4677 inst
.reloc
.pc_rel
= 1;
4678 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4679 /* Adjust ARM pipeline offset to Thumb. */
4680 inst
.reloc
.exp
.X_add_number
+= 4;
4686 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4689 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4690 inst
.reloc
.pc_rel
= 1;
4691 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
4692 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4697 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4699 if (size
!= THUMB_WORD
)
4701 inst
.error
= _("byte or halfword not valid for base register");
4704 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4706 inst
.error
= _("R15 based store not allowed");
4709 else if (Ro
!= FAIL
)
4711 inst
.error
= _("Invalid base register for register offset");
4716 inst
.instruction
= T_OPCODE_LDR_PC
;
4717 else if (load_store
== THUMB_LOAD
)
4718 inst
.instruction
= T_OPCODE_LDR_SP
;
4720 inst
.instruction
= T_OPCODE_STR_SP
;
4722 inst
.instruction
|= Rd
<< 8;
4723 if (inst
.reloc
.exp
.X_op
== O_constant
)
4725 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4727 if (offset
& ~0x3fc)
4729 inst
.error
= _("invalid offset");
4733 inst
.instruction
|= offset
>> 2;
4736 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4740 inst
.error
= _("invalid base register in load/store");
4743 else if (Ro
== FAIL
)
4745 /* Immediate offset. */
4746 if (size
== THUMB_WORD
)
4747 inst
.instruction
= (load_store
== THUMB_LOAD
4748 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4749 else if (size
== THUMB_HALFWORD
)
4750 inst
.instruction
= (load_store
== THUMB_LOAD
4751 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4753 inst
.instruction
= (load_store
== THUMB_LOAD
4754 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4756 inst
.instruction
|= Rd
| (Rb
<< 3);
4758 if (inst
.reloc
.exp
.X_op
== O_constant
)
4760 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4762 if (offset
& ~(0x1f << size
))
4764 inst
.error
= _("Invalid offset");
4767 inst
.instruction
|= (offset
>> size
) << 6;
4770 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4774 /* Register offset. */
4775 if (size
== THUMB_WORD
)
4776 inst
.instruction
= (load_store
== THUMB_LOAD
4777 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4778 else if (size
== THUMB_HALFWORD
)
4779 inst
.instruction
= (load_store
== THUMB_LOAD
4780 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4782 inst
.instruction
= (load_store
== THUMB_LOAD
4783 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4785 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4800 /* Handle the Format 4 instructions that do not have equivalents in other
4801 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4810 skip_whitespace (str
);
4812 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4813 || skip_past_comma (&str
) == FAIL
4814 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4816 inst
.error
= BAD_ARGS
;
4820 if (skip_past_comma (&str
) != FAIL
)
4822 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4823 (It isn't allowed for CMP either, but that isn't handled by this
4825 if (inst
.instruction
== T_OPCODE_TST
4826 || inst
.instruction
== T_OPCODE_CMN
4827 || inst
.instruction
== T_OPCODE_NEG
4828 || inst
.instruction
== T_OPCODE_MVN
)
4830 inst
.error
= BAD_ARGS
;
4834 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4839 inst
.error
= _("dest and source1 one must be the same register");
4845 if (inst
.instruction
== T_OPCODE_MUL
4847 as_tsktsk (_("Rs and Rd must be different in MUL"));
4849 inst
.instruction
|= Rd
| (Rs
<< 3);
4857 thumb_add_sub (str
, 0);
4864 thumb_shift (str
, THUMB_ASR
);
4871 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4873 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4874 inst
.reloc
.pc_rel
= 1;
4882 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4884 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4885 inst
.reloc
.pc_rel
= 1;
4889 /* Find the real, Thumb encoded start of a Thumb function. */
4892 find_real_start (symbolP
)
4896 const char * name
= S_GET_NAME (symbolP
);
4897 symbolS
* new_target
;
4899 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
4900 #define STUB_NAME ".real_start_of"
4905 /* Names that start with '.' are local labels, not function entry points.
4906 The compiler may generate BL instructions to these labels because it
4907 needs to perform a branch to a far away location. */
4911 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4912 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4914 new_target
= symbol_find (real_start
);
4916 if (new_target
== NULL
)
4918 as_warn ("Failed to find real start of function: %s\n", name
);
4919 new_target
= symbolP
;
4931 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4934 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4935 inst
.reloc
.pc_rel
= 1;
4938 /* If the destination of the branch is a defined symbol which does not have
4939 the THUMB_FUNC attribute, then we must be calling a function which has
4940 the (interfacearm) attribute. We look for the Thumb entry point to that
4941 function and change the branch to refer to that function instead. */
4942 if ( inst
.reloc
.exp
.X_op
== O_symbol
4943 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4944 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4945 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4946 inst
.reloc
.exp
.X_add_symbol
=
4947 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4956 skip_whitespace (str
);
4958 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4961 /* This sets THUMB_H2 from the top bit of reg. */
4962 inst
.instruction
|= reg
<< 3;
4964 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4965 should cause the alignment to be checked once it is known. This is
4966 because BX PC only works if the instruction is word aligned. */
4975 thumb_mov_compare (str
, THUMB_COMPARE
);
4985 skip_whitespace (str
);
4987 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4991 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4995 if (skip_past_comma (&str
) == FAIL
4996 || (range
= reg_list (&str
)) == FAIL
)
4999 inst
.error
= BAD_ARGS
;
5003 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5005 /* This really doesn't seem worth it. */
5006 inst
.reloc
.type
= BFD_RELOC_NONE
;
5007 inst
.error
= _("Expression too complex");
5013 inst
.error
= _("only lo-regs valid in load/store multiple");
5017 inst
.instruction
|= (Rb
<< 8) | range
;
5025 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
5032 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
5039 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
5048 skip_whitespace (str
);
5050 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5051 || skip_past_comma (&str
) == FAIL
5053 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5054 || skip_past_comma (&str
) == FAIL
5055 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5059 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
5063 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5071 thumb_shift (str
, THUMB_LSL
);
5078 thumb_shift (str
, THUMB_LSR
);
5085 thumb_mov_compare (str
, THUMB_MOVE
);
5094 skip_whitespace (str
);
5096 if ((range
= reg_list (&str
)) == FAIL
)
5099 inst
.error
= BAD_ARGS
;
5103 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5105 /* This really doesn't seem worth it. */
5106 inst
.reloc
.type
= BFD_RELOC_NONE
;
5107 inst
.error
= _("Expression too complex");
5113 if ((inst
.instruction
== T_OPCODE_PUSH
5114 && (range
& ~0xff) == 1 << REG_LR
)
5115 || (inst
.instruction
== T_OPCODE_POP
5116 && (range
& ~0xff) == 1 << REG_PC
))
5118 inst
.instruction
|= THUMB_PP_PC_LR
;
5123 inst
.error
= _("invalid register list to push/pop instruction");
5128 inst
.instruction
|= range
;
5136 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
5143 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
5150 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
5157 thumb_add_sub (str
, 1);
5164 skip_whitespace (str
);
5166 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5169 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5180 /* This is a pseudo-op of the form "adr rd, label" to be converted
5181 into a relative address of the form "add rd, pc, #label-.-4". */
5182 skip_whitespace (str
);
5184 /* Store Rd in temporary location inside instruction. */
5185 if ((reg
= reg_required_here (&str
, 4)) == FAIL
5186 || (reg
> 7) /* For Thumb reg must be r0..r7. */
5187 || skip_past_comma (&str
) == FAIL
5188 || my_get_expression (&inst
.reloc
.exp
, &str
))
5191 inst
.error
= BAD_ARGS
;
5195 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5196 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
5197 inst
.reloc
.pc_rel
= 1;
5198 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
5207 int len
= strlen (reg_table
[entry
].name
) + 2;
5208 char * buf
= (char *) xmalloc (len
);
5209 char * buf2
= (char *) xmalloc (len
);
5212 #ifdef REGISTER_PREFIX
5213 buf
[i
++] = REGISTER_PREFIX
;
5216 strcpy (buf
+ i
, reg_table
[entry
].name
);
5218 for (i
= 0; buf
[i
]; i
++)
5219 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5223 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
5224 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
5228 insert_reg_alias (str
, regnum
)
5232 struct reg_entry
*new =
5233 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
5234 char *name
= xmalloc (strlen (str
) + 1);
5238 new->number
= regnum
;
5240 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5244 set_constant_flonums ()
5248 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5249 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5259 if ( (arm_ops_hsh
= hash_new ()) == NULL
5260 || (arm_tops_hsh
= hash_new ()) == NULL
5261 || (arm_cond_hsh
= hash_new ()) == NULL
5262 || (arm_shift_hsh
= hash_new ()) == NULL
5263 || (arm_reg_hsh
= hash_new ()) == NULL
5264 || (arm_psr_hsh
= hash_new ()) == NULL
)
5265 as_fatal (_("Virtual memory exhausted"));
5267 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5268 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5269 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5270 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5271 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5272 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5273 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
5274 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
5275 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5276 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5278 for (i
= 0; reg_table
[i
].name
; i
++)
5281 set_constant_flonums ();
5283 #if defined OBJ_COFF || defined OBJ_ELF
5285 unsigned int flags
= 0;
5287 /* Set the flags in the private structure. */
5288 if (uses_apcs_26
) flags
|= F_APCS26
;
5289 if (support_interwork
) flags
|= F_INTERWORK
;
5290 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5291 if (pic_code
) flags
|= F_PIC
;
5292 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5294 bfd_set_private_flags (stdoutput
, flags
);
5298 /* Record the CPU type as well. */
5299 switch (cpu_variant
& ARM_CPU_MASK
)
5302 mach
= bfd_mach_arm_2
;
5305 case ARM_3
: /* Also ARM_250. */
5306 mach
= bfd_mach_arm_2a
;
5310 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5311 mach
= bfd_mach_arm_4
;
5314 case ARM_7
: /* Also ARM_6. */
5315 mach
= bfd_mach_arm_3
;
5319 /* Catch special cases. */
5320 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5322 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5323 mach
= bfd_mach_arm_5T
;
5324 else if (cpu_variant
& ARM_EXT_V5
)
5325 mach
= bfd_mach_arm_5
;
5326 else if (cpu_variant
& ARM_THUMB
)
5327 mach
= bfd_mach_arm_4T
;
5328 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5329 mach
= bfd_mach_arm_4
;
5330 else if (cpu_variant
& ARM_LONGMUL
)
5331 mach
= bfd_mach_arm_3M
;
5334 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5337 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5338 for use in the a.out file, and stores them in the array pointed to by buf.
5339 This knows about the endian-ness of the target machine and does
5340 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5341 2 (short) and 4 (long) Floating numbers are put out as a series of
5342 LITTLENUMS (shorts, here at least). */
5345 md_number_to_chars (buf
, val
, n
)
5350 if (target_big_endian
)
5351 number_to_chars_bigendian (buf
, val
, n
);
5353 number_to_chars_littleendian (buf
, val
, n
);
5357 md_chars_to_number (buf
, n
)
5362 unsigned char * where
= (unsigned char *) buf
;
5364 if (target_big_endian
)
5369 result
|= (*where
++ & 255);
5377 result
|= (where
[n
] & 255);
5384 /* Turn a string in input_line_pointer into a floating point constant
5385 of type TYPE, and store the appropriate bytes in *LITP. The number
5386 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5387 returned, or NULL on OK.
5389 Note that fp constants aren't represent in the normal way on the ARM.
5390 In big endian mode, things are as expected. However, in little endian
5391 mode fp constants are big-endian word-wise, and little-endian byte-wise
5392 within the words. For example, (double) 1.1 in big endian mode is
5393 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5394 the byte sequence 99 99 f1 3f 9a 99 99 99.
5396 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5399 md_atof (type
, litP
, sizeP
)
5405 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5437 return _("Bad call to MD_ATOF()");
5440 t
= atof_ieee (input_line_pointer
, type
, words
);
5442 input_line_pointer
= t
;
5445 if (target_big_endian
)
5447 for (i
= 0; i
< prec
; i
++)
5449 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5455 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5456 8 byte float the order is 1 0 3 2. */
5457 for (i
= 0; i
< prec
; i
+= 2)
5459 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5460 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5468 /* The knowledge of the PC's pipeline offset is built into the insns
5472 md_pcrel_from (fixP
)
5476 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5477 && fixP
->fx_subsy
== NULL
)
5480 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5482 /* PC relative addressing on the Thumb is slightly odd
5483 as the bottom two bits of the PC are forced to zero
5484 for the calculation. */
5485 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5489 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5490 so we un-adjust here to compensate for the accomodation. */
5491 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5493 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5497 /* Round up a section size to the appropriate boundary. */
5500 md_section_align (segment
, size
)
5501 segT segment ATTRIBUTE_UNUSED
;
5507 /* Round all sects to multiple of 4. */
5508 return (size
+ 3) & ~3;
5512 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
5513 Otherwise we have no need to default values of symbols. */
5516 md_undefined_symbol (name
)
5517 char * name ATTRIBUTE_UNUSED
;
5520 if (name
[0] == '_' && name
[1] == 'G'
5521 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5525 if (symbol_find (name
))
5526 as_bad ("GOT already in the symbol table");
5528 GOT_symbol
= symbol_new (name
, undefined_section
,
5529 (valueT
) 0, & zero_address_frag
);
5539 /* arm_reg_parse () := if it looks like a register, return its token and
5540 advance the pointer. */
5544 register char ** ccp
;
5546 char * start
= * ccp
;
5549 struct reg_entry
* reg
;
5551 #ifdef REGISTER_PREFIX
5552 if (*start
!= REGISTER_PREFIX
)
5557 #ifdef OPTIONAL_REGISTER_PREFIX
5558 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5562 if (!isalpha (*p
) || !is_name_beginner (*p
))
5566 while (isalpha (c
) || isdigit (c
) || c
== '_')
5570 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5583 md_apply_fix3 (fixP
, val
, seg
)
5588 offsetT value
= * val
;
5590 unsigned int newimm
;
5593 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5594 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5596 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5598 /* Note whether this will delete the relocation. */
5600 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
5601 doesn't work fully.) */
5602 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5605 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5609 /* If this symbol is in a different section then we need to leave it for
5610 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5611 so we have to undo it's effects here. */
5614 if (fixP
->fx_addsy
!= NULL
5615 && S_IS_DEFINED (fixP
->fx_addsy
)
5616 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5619 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5620 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5624 value
+= md_pcrel_from (fixP
);
5628 /* Remember value for emit_reloc. */
5629 fixP
->fx_addnumber
= value
;
5631 switch (fixP
->fx_r_type
)
5633 case BFD_RELOC_ARM_IMMEDIATE
:
5634 newimm
= validate_immediate (value
);
5635 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5637 /* If the instruction will fail, see if we can fix things up by
5638 changing the opcode. */
5639 if (newimm
== (unsigned int) FAIL
5640 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5642 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5643 _("invalid constant (%lx) after fixup"),
5644 (unsigned long) value
);
5648 newimm
|= (temp
& 0xfffff000);
5649 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5652 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5654 unsigned int highpart
= 0;
5655 unsigned int newinsn
= 0xe1a00000; /* nop. */
5656 newimm
= validate_immediate (value
);
5657 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5659 /* If the instruction will fail, see if we can fix things up by
5660 changing the opcode. */
5661 if (newimm
== (unsigned int) FAIL
5662 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5664 /* No ? OK - try using two ADD instructions to generate
5666 newimm
= validate_immediate_twopart (value
, & highpart
);
5668 /* Yes - then make sure that the second instruction is
5670 if (newimm
!= (unsigned int) FAIL
)
5672 /* Still No ? Try using a negated value. */
5673 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
5674 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5675 /* Otherwise - give up. */
5678 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5679 _("Unable to compute ADRL instructions for PC offset of 0x%x"),
5684 /* Replace the first operand in the 2nd instruction (which
5685 is the PC) with the destination register. We have
5686 already added in the PC in the first instruction and we
5687 do not want to do it again. */
5688 newinsn
&= ~ 0xf0000;
5689 newinsn
|= ((newinsn
& 0x0f000) << 4);
5692 newimm
|= (temp
& 0xfffff000);
5693 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5695 highpart
|= (newinsn
& 0xfffff000);
5696 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5700 case BFD_RELOC_ARM_OFFSET_IMM
:
5706 if (validate_offset_imm (value
, 0) == FAIL
)
5708 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5709 _("bad immediate value for offset (%ld)"),
5714 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5715 newval
&= 0xff7ff000;
5716 newval
|= value
| (sign
? INDEX_UP
: 0);
5717 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5720 case BFD_RELOC_ARM_OFFSET_IMM8
:
5721 case BFD_RELOC_ARM_HWLITERAL
:
5727 if (validate_offset_imm (value
, 1) == FAIL
)
5729 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5730 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5731 _("invalid literal constant: pool needs to be closer"));
5733 as_bad (_("bad immediate value for half-word offset (%ld)"),
5738 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5739 newval
&= 0xff7ff0f0;
5740 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5741 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5744 case BFD_RELOC_ARM_LITERAL
:
5750 if (validate_offset_imm (value
, 0) == FAIL
)
5752 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5753 _("invalid literal constant: pool needs to be closer"));
5757 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5758 newval
&= 0xff7ff000;
5759 newval
|= value
| (sign
? INDEX_UP
: 0);
5760 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5763 case BFD_RELOC_ARM_SHIFT_IMM
:
5764 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5765 if (((unsigned long) value
) > 32
5767 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5769 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5770 _("shift expression is too large"));
5775 /* Shifts of zero must be done as lsl. */
5777 else if (value
== 32)
5779 newval
&= 0xfffff07f;
5780 newval
|= (value
& 0x1f) << 7;
5781 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5784 case BFD_RELOC_ARM_SWI
:
5785 if (arm_data
->thumb_mode
)
5787 if (((unsigned long) value
) > 0xff)
5788 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5789 _("Invalid swi expression"));
5790 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5792 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5796 if (((unsigned long) value
) > 0x00ffffff)
5797 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5798 _("Invalid swi expression"));
5799 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5801 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5805 case BFD_RELOC_ARM_MULTI
:
5806 if (((unsigned long) value
) > 0xffff)
5807 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5808 _("Invalid expression in load/store multiple"));
5809 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5810 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5813 case BFD_RELOC_ARM_PCREL_BRANCH
:
5814 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5816 /* Sign-extend a 24-bit number. */
5817 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5821 value
= fixP
->fx_offset
;
5824 /* We are going to store value (shifted right by two) in the
5825 instruction, in a 24 bit, signed field. Thus we need to check
5826 that none of the top 8 bits of the shifted value (top 7 bits of
5827 the unshifted, unsigned value) are set, or that they are all set. */
5828 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5829 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5832 /* Normally we would be stuck at this point, since we cannot store
5833 the absolute address that is the destination of the branch in the
5834 24 bits of the branch instruction. If however, we happen to know
5835 that the destination of the branch is in the same section as the
5836 branch instruciton itself, then we can compute the relocation for
5837 ourselves and not have to bother the linker with it.
5839 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5840 because I have not worked out how to do this for OBJ_COFF or
5843 && fixP
->fx_addsy
!= NULL
5844 && S_IS_DEFINED (fixP
->fx_addsy
)
5845 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5847 /* Get pc relative value to go into the branch. */
5850 /* Permit a backward branch provided that enough bits
5851 are set. Allow a forwards branch, provided that
5852 enough bits are clear. */
5853 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5854 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5858 if (! fixP
->fx_done
)
5860 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5861 _("gas can't handle same-section branch dest >= 0x04000000"));
5865 value
+= SEXT24 (newval
);
5867 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
5868 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5869 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5870 _("out of range branch"));
5872 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5873 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5876 case BFD_RELOC_ARM_PCREL_BLX
:
5879 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5883 value
= fixP
->fx_offset
;
5885 hbit
= (value
>> 1) & 1;
5886 value
= (value
>> 2) & 0x00ffffff;
5887 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5888 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5889 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5893 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
5894 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5896 addressT diff
= (newval
& 0xff) << 1;
5901 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5902 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5903 _("Branch out of range"));
5904 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5906 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5909 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
5910 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5912 addressT diff
= (newval
& 0x7ff) << 1;
5917 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5918 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5919 _("Branch out of range"));
5920 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5922 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5925 case BFD_RELOC_THUMB_PCREL_BLX
:
5926 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5931 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5932 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5933 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5934 if (diff
& 0x400000)
5937 value
= fixP
->fx_offset
;
5940 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5941 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5942 _("Branch with link out of range"));
5944 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5945 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5946 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5947 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5952 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5953 md_number_to_chars (buf
, value
, 1);
5955 else if (!target_oabi
)
5957 value
= fixP
->fx_offset
;
5958 md_number_to_chars (buf
, value
, 1);
5964 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5965 md_number_to_chars (buf
, value
, 2);
5967 else if (!target_oabi
)
5969 value
= fixP
->fx_offset
;
5970 md_number_to_chars (buf
, value
, 2);
5976 case BFD_RELOC_ARM_GOT32
:
5977 case BFD_RELOC_ARM_GOTOFF
:
5978 md_number_to_chars (buf
, 0, 4);
5984 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5985 md_number_to_chars (buf
, value
, 4);
5987 else if (!target_oabi
)
5989 value
= fixP
->fx_offset
;
5990 md_number_to_chars (buf
, value
, 4);
5996 case BFD_RELOC_ARM_PLT32
:
5997 /* It appears the instruction is fully prepared at this point. */
6001 case BFD_RELOC_ARM_GOTPC
:
6002 md_number_to_chars (buf
, value
, 4);
6005 case BFD_RELOC_ARM_CP_OFF_IMM
:
6007 if (value
< -1023 || value
> 1023 || (value
& 3))
6008 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6009 _("Illegal value for co-processor offset"));
6012 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
6013 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
6014 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6017 case BFD_RELOC_ARM_THUMB_OFFSET
:
6018 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6019 /* Exactly what ranges, and where the offset is inserted depends
6020 on the type of instruction, we can establish this from the
6022 switch (newval
>> 12)
6024 case 4: /* PC load. */
6025 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
6026 forced to zero for these loads, so we will need to round
6027 up the offset if the instruction address is not word
6028 aligned (since the final address produced must be, and
6029 we can only describe word-aligned immediate offsets). */
6031 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
6032 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6033 _("Invalid offset, target not word aligned (0x%08X)"),
6034 (unsigned int) (fixP
->fx_frag
->fr_address
6035 + fixP
->fx_where
+ value
));
6037 if ((value
+ 2) & ~0x3fe)
6038 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6039 _("Invalid offset, value too big (0x%08X)"), value
);
6041 /* Round up, since pc will be rounded down. */
6042 newval
|= (value
+ 2) >> 2;
6045 case 9: /* SP load/store. */
6047 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6048 _("Invalid offset, value too big (0x%08X)"), value
);
6049 newval
|= value
>> 2;
6052 case 6: /* Word load/store. */
6054 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6055 _("Invalid offset, value too big (0x%08X)"), value
);
6056 newval
|= value
<< 4; /* 6 - 2. */
6059 case 7: /* Byte load/store. */
6061 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6062 _("Invalid offset, value too big (0x%08X)"), value
);
6063 newval
|= value
<< 6;
6066 case 8: /* Halfword load/store. */
6068 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6069 _("Invalid offset, value too big (0x%08X)"), value
);
6070 newval
|= value
<< 5; /* 6 - 1. */
6074 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6075 "Unable to process relocation for thumb opcode: %lx",
6076 (unsigned long) newval
);
6079 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6082 case BFD_RELOC_ARM_THUMB_ADD
:
6083 /* This is a complicated relocation, since we use it for all of
6084 the following immediate relocations:
6088 9bit ADD/SUB SP word-aligned
6089 10bit ADD PC/SP word-aligned
6091 The type of instruction being processed is encoded in the
6098 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6100 int rd
= (newval
>> 4) & 0xf;
6101 int rs
= newval
& 0xf;
6102 int subtract
= newval
& 0x8000;
6107 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6108 _("Invalid immediate for stack address calculation"));
6109 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6110 newval
|= value
>> 2;
6112 else if (rs
== REG_PC
|| rs
== REG_SP
)
6116 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6117 _("Invalid immediate for address calculation (value = 0x%08lX)"),
6118 (unsigned long) value
);
6119 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
6121 newval
|= value
>> 2;
6126 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6127 _("Invalid 8bit immediate"));
6128 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6129 newval
|= (rd
<< 8) | value
;
6134 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6135 _("Invalid 3bit immediate"));
6136 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6137 newval
|= rd
| (rs
<< 3) | (value
<< 6);
6140 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6143 case BFD_RELOC_ARM_THUMB_IMM
:
6144 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6145 switch (newval
>> 11)
6147 case 0x04: /* 8bit immediate MOV. */
6148 case 0x05: /* 8bit immediate CMP. */
6149 if (value
< 0 || value
> 255)
6150 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6151 _("Invalid immediate: %ld is too large"),
6159 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6162 case BFD_RELOC_ARM_THUMB_SHIFT
:
6163 /* 5bit shift value (0..31). */
6164 if (value
< 0 || value
> 31)
6165 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6166 _("Illegal Thumb shift value: %ld"), (long) value
);
6167 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
6168 newval
|= value
<< 6;
6169 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6172 case BFD_RELOC_VTABLE_INHERIT
:
6173 case BFD_RELOC_VTABLE_ENTRY
:
6177 case BFD_RELOC_NONE
:
6179 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6180 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6186 /* Translate internal representation of relocation info to BFD target
6190 tc_gen_reloc (section
, fixp
)
6191 asection
* section ATTRIBUTE_UNUSED
;
6195 bfd_reloc_code_real_type code
;
6197 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
6199 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6200 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6201 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6203 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
6205 if (fixp
->fx_pcrel
== 0)
6206 reloc
->addend
= fixp
->fx_offset
;
6208 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6210 reloc
->addend
= fixp
->fx_offset
;
6213 switch (fixp
->fx_r_type
)
6218 code
= BFD_RELOC_8_PCREL
;
6225 code
= BFD_RELOC_16_PCREL
;
6232 code
= BFD_RELOC_32_PCREL
;
6236 case BFD_RELOC_ARM_PCREL_BRANCH
:
6237 case BFD_RELOC_ARM_PCREL_BLX
:
6239 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6240 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6241 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6242 case BFD_RELOC_THUMB_PCREL_BLX
:
6243 case BFD_RELOC_VTABLE_ENTRY
:
6244 case BFD_RELOC_VTABLE_INHERIT
:
6245 code
= fixp
->fx_r_type
;
6248 case BFD_RELOC_ARM_LITERAL
:
6249 case BFD_RELOC_ARM_HWLITERAL
:
6250 /* If this is called then the a literal has been referenced across
6251 a section boundary - possibly due to an implicit dump. */
6252 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6253 _("Literal referenced across section boundary (Implicit dump?)"));
6257 case BFD_RELOC_ARM_GOT32
:
6258 case BFD_RELOC_ARM_GOTOFF
:
6259 case BFD_RELOC_ARM_PLT32
:
6260 code
= fixp
->fx_r_type
;
6264 case BFD_RELOC_ARM_IMMEDIATE
:
6265 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6266 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6270 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6271 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6272 _("ADRL used for a symbol not defined in the same file"),
6276 case BFD_RELOC_ARM_OFFSET_IMM
:
6277 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6278 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6286 switch (fixp
->fx_r_type
)
6288 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6289 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6290 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6291 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6292 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6293 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6294 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6295 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6296 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6297 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6298 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6299 default: type
= _("<unknown>"); break;
6301 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6302 _("Can not represent %s relocation in this object file format (%d)"),
6303 type
, fixp
->fx_pcrel
);
6309 if (code
== BFD_RELOC_32_PCREL
6311 && fixp
->fx_addsy
== GOT_symbol
)
6313 code
= BFD_RELOC_ARM_GOTPC
;
6314 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6318 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6320 if (reloc
->howto
== NULL
)
6322 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6323 _("Can not represent %s relocation in this object file format"),
6324 bfd_get_reloc_code_name (code
));
6328 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6329 vtable entry to be used in the relocation's section offset. */
6330 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6331 reloc
->address
= fixp
->fx_offset
;
6337 md_estimate_size_before_relax (fragP
, segtype
)
6338 fragS
* fragP ATTRIBUTE_UNUSED
;
6339 segT segtype ATTRIBUTE_UNUSED
;
6341 as_fatal (_("md_estimate_size_before_relax\n"));
6346 output_inst
PARAMS ((void))
6352 as_bad (inst
.error
);
6356 to
= frag_more (inst
.size
);
6358 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6360 assert (inst
.size
== (2 * THUMB_SIZE
));
6361 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6362 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6364 else if (inst
.size
> INSN_SIZE
)
6366 assert (inst
.size
== (2 * INSN_SIZE
));
6367 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6368 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6371 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6373 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6374 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6375 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6379 dwarf2_emit_insn (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))
6619 #ifdef IGNORE_OPCODE_CASE
6620 str
= original_case_string
;
6625 skip_whitespace (q
);
6627 for (r
= q
; *r
!= '\0'; r
++)
6637 regnum
= arm_reg_parse (& q
);
6640 reg
= arm_reg_parse (& str
);
6645 insert_reg_alias (str
, regnum
);
6647 as_warn (_("register '%s' does not exist\n"), q
);
6649 else if (regnum
!= FAIL
)
6652 as_warn (_("ignoring redefinition of register alias '%s'"),
6655 /* Do not warn about redefinitions to the same alias. */
6658 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6662 as_warn (_("ignoring incomplete .req pseuso op"));
6669 as_bad (_("bad instruction `%s'"), start
);
6673 Invocation line includes a switch not recognized by the base assembler.
6674 See if it's a processor-specific option. These are:
6675 Cpu variants, the arm part is optional:
6676 -m[arm]1 Currently not supported.
6677 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6678 -m[arm]3 Arm 3 processor
6679 -m[arm]6[xx], Arm 6 processors
6680 -m[arm]7[xx][t][[d]m] Arm 7 processors
6681 -m[arm]8[10] Arm 8 processors
6682 -m[arm]9[20][tdmi] Arm 9 processors
6683 -mstrongarm[110[0]] StrongARM processors
6684 -m[arm]v[2345[t]] Arm architectures
6685 -mall All (except the ARM1)
6687 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6688 -mfpe-old (No float load/store multiples)
6689 -mno-fpu Disable all floating point instructions
6690 Run-time endian selection:
6692 -EL little endian cpu
6693 ARM Procedure Calling Standard:
6694 -mapcs-32 32 bit APCS
6695 -mapcs-26 26 bit APCS
6696 -mapcs-float Pass floats in float regs
6697 -mapcs-reentrant Position independent code
6698 -mthumb-interwork Code supports Arm/Thumb interworking
6699 -moabi Old ELF ABI */
6701 CONST
char * md_shortopts
= "m:k";
6703 struct option md_longopts
[] =
6705 #ifdef ARM_BI_ENDIAN
6706 #define OPTION_EB (OPTION_MD_BASE + 0)
6707 {"EB", no_argument
, NULL
, OPTION_EB
},
6708 #define OPTION_EL (OPTION_MD_BASE + 1)
6709 {"EL", no_argument
, NULL
, OPTION_EL
},
6711 #define OPTION_OABI (OPTION_MD_BASE +2)
6712 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6715 {NULL
, no_argument
, NULL
, 0}
6718 size_t md_longopts_size
= sizeof (md_longopts
);
6721 md_parse_option (c
, arg
)
6729 #ifdef ARM_BI_ENDIAN
6731 target_big_endian
= 1;
6734 target_big_endian
= 0;
6742 if (streq (str
, "fpa10"))
6743 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6744 else if (streq (str
, "fpa11"))
6745 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6746 else if (streq (str
, "fpe-old"))
6747 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6753 if (streq (str
, "no-fpu"))
6754 cpu_variant
&= ~FPU_ALL
;
6759 if (streq (str
, "oabi"))
6765 /* Limit assembler to generating only Thumb instructions: */
6766 if (streq (str
, "thumb"))
6768 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6769 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6772 else if (streq (str
, "thumb-interwork"))
6774 if ((cpu_variant
& ARM_THUMB
) == 0)
6775 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6776 #if defined OBJ_COFF || defined OBJ_ELF
6777 support_interwork
= true;
6785 if (streq (str
, "all"))
6787 cpu_variant
= ARM_ALL
| FPU_ALL
;
6790 #if defined OBJ_COFF || defined OBJ_ELF
6791 if (! strncmp (str
, "apcs-", 5))
6793 /* GCC passes on all command line options starting "-mapcs-..."
6794 to us, so we must parse them here. */
6798 if (streq (str
, "32"))
6800 uses_apcs_26
= false;
6803 else if (streq (str
, "26"))
6805 uses_apcs_26
= true;
6808 else if (streq (str
, "frame"))
6810 /* Stack frames are being generated - does not affect
6814 else if (streq (str
, "stack-check"))
6816 /* Stack checking is being performed - does not affect
6817 linkage, but does require that the functions
6818 __rt_stkovf_split_small and __rt_stkovf_split_big be
6819 present in the final link. */
6823 else if (streq (str
, "float"))
6825 /* Floating point arguments are being passed in the floating
6826 point registers. This does affect linking, since this
6827 version of the APCS is incompatible with the version that
6828 passes floating points in the integer registers. */
6830 uses_apcs_float
= true;
6833 else if (streq (str
, "reentrant"))
6835 /* Reentrant code has been generated. This does affect
6836 linking, since there is no point in linking reentrant/
6837 position independent code with absolute position code. */
6842 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6846 /* Strip off optional "arm". */
6847 if (! strncmp (str
, "arm", 3))
6853 if (streq (str
, "1"))
6854 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6860 if (streq (str
, "2"))
6861 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6862 else if (streq (str
, "250"))
6863 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6869 if (streq (str
, "3"))
6870 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6876 switch (strtol (str
, NULL
, 10))
6883 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6891 /* Eat the processor name. */
6892 switch (strtol (str
, & str
, 10))
6905 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6911 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6915 cpu_variant
|= ARM_LONGMUL
;
6918 case 'f': /* fe => fp enabled cpu. */
6924 case 'c': /* Left over from 710c processor name. */
6925 case 'd': /* Debug. */
6926 case 'i': /* Embedded ICE. */
6927 /* Included for completeness in ARM processor naming. */
6937 if (streq (str
, "8") || streq (str
, "810"))
6938 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6939 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6945 if (streq (str
, "9"))
6946 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6947 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6948 else if (streq (str
, "920"))
6949 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6950 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6951 else if (streq (str
, "920t"))
6952 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6953 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6954 else if (streq (str
, "9tdmi"))
6955 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6956 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6962 if (streq (str
, "strongarm")
6963 || streq (str
, "strongarm110")
6964 || streq (str
, "strongarm1100"))
6965 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6966 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6972 /* Select variant based on architecture rather than
6980 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6983 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6986 as_bad (_("Invalid architecture variant -m%s"), arg
);
6992 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6996 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6999 as_bad (_("Invalid architecture variant -m%s"), arg
);
7005 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
7009 case 't': cpu_variant
|= ARM_THUMB
; break;
7012 as_bad (_("Invalid architecture variant -m%s"), arg
);
7018 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
7021 case 't': cpu_variant
|= ARM_THUMB
; break;
7024 as_bad (_("Invalid architecture variant -m%s"), arg
);
7030 as_bad (_("Invalid architecture variant -m%s"), arg
);
7037 as_bad (_("Invalid processor variant -m%s"), arg
);
7043 #if defined OBJ_ELF || defined OBJ_COFF
7061 ARM Specific Assembler Options:\n\
7062 -m[arm][<processor name>] select processor variant\n\
7063 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
7064 -mthumb only allow Thumb instructions\n\
7065 -mthumb-interwork mark the assembled code as supporting interworking\n\
7066 -mall allow any instruction\n\
7067 -mfpa10, -mfpa11 select floating point architecture\n\
7068 -mfpe-old don't allow floating-point multiple instructions\n\
7069 -mno-fpu don't allow any floating-point instructions.\n\
7070 -k generate PIC code.\n"));
7071 #if defined OBJ_COFF || defined OBJ_ELF
7073 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
7074 -mapcs-float floating point args are passed in FP regs\n\
7075 -mapcs-reentrant the code is position independent/reentrant\n"));
7079 -moabi support the old ELF ABI\n"));
7081 #ifdef ARM_BI_ENDIAN
7083 -EB assemble code for a big endian cpu\n\
7084 -EL assemble code for a little endian cpu\n"));
7088 /* We need to be able to fix up arbitrary expressions in some statements.
7089 This is so that we can handle symbols that are an arbitrary distance from
7090 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
7091 which returns part of an address in a form which will be valid for
7092 a data instruction. We do this by pushing the expression into a symbol
7093 in the expr_section, and creating a fix for that. */
7096 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
7105 arm_fix_data
* arm_data
;
7113 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
7117 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
7122 /* Mark whether the fix is to a THUMB instruction, or an ARM
7124 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
7125 new_fix
->tc_fix_data
= (PTR
) arm_data
;
7126 arm_data
->thumb_mode
= thumb_mode
;
7131 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
7134 cons_fix_new_arm (frag
, where
, size
, exp
)
7140 bfd_reloc_code_real_type type
;
7144 FIXME: @@ Should look at CPU word size. */
7151 type
= BFD_RELOC_16
;
7155 type
= BFD_RELOC_32
;
7158 type
= BFD_RELOC_64
;
7162 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
7165 /* A good place to do this, although this was probably not intended
7166 for this kind of use. We need to dump the literal pool before
7167 references are made to a null symbol pointer. */
7172 if (current_poolP
== NULL
)
7175 /* Put it at the end of text section. */
7176 subseg_set (text_section
, 0);
7178 listing_prev_line ();
7182 arm_start_line_hook ()
7184 last_label_seen
= NULL
;
7188 arm_frob_label (sym
)
7191 last_label_seen
= sym
;
7193 ARM_SET_THUMB (sym
, thumb_mode
);
7195 #if defined OBJ_COFF || defined OBJ_ELF
7196 ARM_SET_INTERWORK (sym
, support_interwork
);
7199 if (label_is_thumb_function_name
)
7201 /* When the address of a Thumb function is taken the bottom
7202 bit of that address should be set. This will allow
7203 interworking between Arm and Thumb functions to work
7206 THUMB_SET_FUNC (sym
, 1);
7208 label_is_thumb_function_name
= false;
7212 /* Adjust the symbol table. This marks Thumb symbols as distinct from
7216 arm_adjust_symtab ()
7221 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7223 if (ARM_IS_THUMB (sym
))
7225 if (THUMB_IS_FUNC (sym
))
7227 /* Mark the symbol as a Thumb function. */
7228 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
7229 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
7230 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
7232 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
7233 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
7235 as_bad (_("%s: unexpected function type: %d"),
7236 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
7238 else switch (S_GET_STORAGE_CLASS (sym
))
7241 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
7244 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7247 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7255 if (ARM_IS_INTERWORK (sym
))
7256 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7263 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7265 if (ARM_IS_THUMB (sym
))
7267 elf_symbol_type
* elf_sym
;
7269 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7270 bind
= ELF_ST_BIND (elf_sym
);
7272 /* If it's a .thumb_func, declare it as so,
7273 otherwise tag label as .code 16. */
7274 if (THUMB_IS_FUNC (sym
))
7275 elf_sym
->internal_elf_sym
.st_info
=
7276 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7278 elf_sym
->internal_elf_sym
.st_info
=
7279 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7288 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7290 *input_line_pointer
= '/';
7291 input_line_pointer
+= 5;
7292 *input_line_pointer
= 0;
7300 arm_canonicalize_symbol_name (name
)
7305 if (thumb_mode
&& (len
= strlen (name
)) > 5
7306 && streq (name
+ len
- 5, "/data"))
7307 *(name
+ len
- 5) = 0;
7313 arm_validate_fix (fixP
)
7316 /* If the destination of the branch is a defined symbol which does not have
7317 the THUMB_FUNC attribute, then we must be calling a function which has
7318 the (interfacearm) attribute. We look for the Thumb entry point to that
7319 function and change the branch to refer to that function instead. */
7320 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7321 && fixP
->fx_addsy
!= NULL
7322 && S_IS_DEFINED (fixP
->fx_addsy
)
7323 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7325 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7333 /* Relocations against Thumb function names must be left unadjusted,
7334 so that the linker can use this information to correctly set the
7335 bottom bit of their addresses. The MIPS version of this function
7336 also prevents relocations that are mips-16 specific, but I do not
7337 know why it does this.
7340 There is one other problem that ought to be addressed here, but
7341 which currently is not: Taking the address of a label (rather
7342 than a function) and then later jumping to that address. Such
7343 addresses also ought to have their bottom bit set (assuming that
7344 they reside in Thumb code), but at the moment they will not. */
7347 arm_fix_adjustable (fixP
)
7350 if (fixP
->fx_addsy
== NULL
)
7353 /* Prevent all adjustments to global symbols. */
7354 if (S_IS_EXTERN (fixP
->fx_addsy
))
7357 if (S_IS_WEAK (fixP
->fx_addsy
))
7360 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7361 && fixP
->fx_subsy
== NULL
)
7364 /* We need the symbol name for the VTABLE entries. */
7365 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7366 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7373 elf32_arm_target_format ()
7375 if (target_big_endian
)
7378 return "elf32-bigarm-oabi";
7380 return "elf32-bigarm";
7385 return "elf32-littlearm-oabi";
7387 return "elf32-littlearm";
7392 armelf_frob_symbol (symp
, puntp
)
7396 elf_frob_symbol (symp
, puntp
);
7400 arm_force_relocation (fixp
)
7403 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7404 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7405 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7406 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7407 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7408 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7414 static bfd_reloc_code_real_type
7424 bfd_reloc_code_real_type reloc
;
7428 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
7429 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7430 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7431 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
7432 branch instructions generated by GCC for PLT relocs. */
7433 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7434 { NULL
, 0, BFD_RELOC_UNUSED
}
7438 for (i
= 0, ip
= input_line_pointer
;
7439 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7441 id
[i
] = tolower (*ip
);
7443 for (i
= 0; reloc_map
[i
].str
; i
++)
7444 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7447 input_line_pointer
+= reloc_map
[i
].len
;
7449 return reloc_map
[i
].reloc
;
7453 s_arm_elf_cons (nbytes
)
7458 #ifdef md_flush_pending_output
7459 md_flush_pending_output ();
7462 if (is_it_end_of_statement ())
7464 demand_empty_rest_of_line ();
7468 #ifdef md_cons_align
7469 md_cons_align (nbytes
);
7474 bfd_reloc_code_real_type reloc
;
7478 if (exp
.X_op
== O_symbol
7479 && * input_line_pointer
== '('
7480 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
7482 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7483 int size
= bfd_get_reloc_size (howto
);
7486 as_bad ("%s relocations do not fit in %d bytes",
7487 howto
->name
, nbytes
);
7490 register char *p
= frag_more ((int) nbytes
);
7491 int offset
= nbytes
- size
;
7493 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7498 emit_expr (&exp
, (unsigned int) nbytes
);
7500 while (*input_line_pointer
++ == ',');
7502 /* Put terminator back into stream. */
7503 input_line_pointer
--;
7504 demand_empty_rest_of_line ();
7507 #endif /* OBJ_ELF */