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 },
1123 { "file", dwarf2_directive_file
, 0 },
1124 { "loc", dwarf2_directive_loc
, 0 },
1128 { "extend", float_cons
, 'x' },
1129 { "ldouble", float_cons
, 'x' },
1130 { "packed", float_cons
, 'p' },
1134 /* Stuff needed to resolve the label ambiguity
1144 symbolS
* last_label_seen
;
1145 static int label_is_thumb_function_name
= false;
1147 /* Literal stuff. */
1149 #define MAX_LITERAL_POOL_SIZE 1024
1151 typedef struct literalS
1153 struct expressionS exp
;
1154 struct arm_it
* inst
;
1157 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1159 /* Next free entry in the pool. */
1160 int next_literal_pool_place
= 0;
1162 /* Next literal pool number. */
1163 int lit_pool_num
= 1;
1165 symbolS
* current_poolP
= NULL
;
1172 if (current_poolP
== NULL
)
1173 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1174 (valueT
) 0, &zero_address_frag
);
1176 /* Check if this literal value is already in the pool: */
1177 while (lit_count
< next_literal_pool_place
)
1179 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1180 && inst
.reloc
.exp
.X_op
== O_constant
1181 && (literals
[lit_count
].exp
.X_add_number
1182 == inst
.reloc
.exp
.X_add_number
)
1183 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1188 if (lit_count
== next_literal_pool_place
) /* New entry. */
1190 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1192 inst
.error
= _("Literal Pool Overflow");
1196 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1197 lit_count
= next_literal_pool_place
++;
1200 inst
.reloc
.exp
.X_op
= O_symbol
;
1201 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1202 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1207 /* Can't use symbol_new here, so have to create a symbol and then at
1208 a later date assign it a value. Thats what these functions do. */
1211 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1213 CONST
char * name
; /* It is copied, the caller can modify. */
1214 segT segment
; /* Segment identifier (SEG_<something>). */
1215 valueT valu
; /* Symbol value. */
1216 fragS
* frag
; /* Associated fragment. */
1218 unsigned int name_length
;
1219 char * preserved_copy_of_name
;
1221 name_length
= strlen (name
) + 1; /* +1 for \0. */
1222 obstack_grow (¬es
, name
, name_length
);
1223 preserved_copy_of_name
= obstack_finish (¬es
);
1224 #ifdef STRIP_UNDERSCORE
1225 if (preserved_copy_of_name
[0] == '_')
1226 preserved_copy_of_name
++;
1229 #ifdef tc_canonicalize_symbol_name
1230 preserved_copy_of_name
=
1231 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1234 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1236 S_SET_SEGMENT (symbolP
, segment
);
1237 S_SET_VALUE (symbolP
, valu
);
1238 symbol_clear_list_pointers(symbolP
);
1240 symbol_set_frag (symbolP
, frag
);
1242 /* Link to end of symbol chain. */
1244 extern int symbol_table_frozen
;
1245 if (symbol_table_frozen
)
1249 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1251 obj_symbol_new_hook (symbolP
);
1253 #ifdef tc_symbol_new_hook
1254 tc_symbol_new_hook (symbolP
);
1258 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1259 #endif /* DEBUG_SYMS */
1262 /* Check that an immediate is valid.
1263 If so, convert it to the right format. */
1266 validate_immediate (val
)
1272 #define rotate_left(v, n) (v << n | v >> (32 - n))
1274 for (i
= 0; i
< 32; i
+= 2)
1275 if ((a
= rotate_left (val
, i
)) <= 0xff)
1276 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1281 /* Check to see if an immediate can be computed as two seperate immediate
1282 values, added together. We already know that this value cannot be
1283 computed by just one ARM instruction. */
1286 validate_immediate_twopart (val
, highpart
)
1288 unsigned int * highpart
;
1293 for (i
= 0; i
< 32; i
+= 2)
1294 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1300 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1302 else if (a
& 0xff0000)
1306 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1310 assert (a
& 0xff000000);
1311 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1314 return (a
& 0xff) | (i
<< 7);
1321 validate_offset_imm (val
, hwse
)
1325 if ((hwse
&& val
> 255) || val
> 4095)
1332 int a ATTRIBUTE_UNUSED
;
1334 as_bad (_("Invalid syntax for .req directive."));
1339 int ignore ATTRIBUTE_UNUSED
;
1341 /* We don't support putting frags in the BSS segment, we fake it by
1342 marking in_bss, then looking at s_skip for clues. */
1343 subseg_set (bss_section
, 0);
1344 demand_empty_rest_of_line ();
1349 int ignore ATTRIBUTE_UNUSED
;
1351 /* Never make frag if expect extra pass. */
1353 frag_align (1, 0, 0);
1355 record_alignment (now_seg
, 1);
1357 demand_empty_rest_of_line ();
1362 int ignored ATTRIBUTE_UNUSED
;
1367 if (current_poolP
== NULL
)
1370 /* Align pool as you have word accesses.
1371 Only make a frag if we have to. */
1373 frag_align (2, 0, 0);
1375 record_alignment (now_seg
, 2);
1377 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1379 symbol_locate (current_poolP
, sym_name
, now_seg
,
1380 (valueT
) frag_now_fix (), frag_now
);
1381 symbol_table_insert (current_poolP
);
1383 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1385 #if defined OBJ_COFF || defined OBJ_ELF
1386 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1389 while (lit_count
< next_literal_pool_place
)
1390 /* First output the expression in the instruction to the pool. */
1391 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1393 next_literal_pool_place
= 0;
1394 current_poolP
= NULL
;
1397 /* Same as s_align_ptwo but align 0 => align 2. */
1401 int unused ATTRIBUTE_UNUSED
;
1404 register long temp_fill
;
1405 long max_alignment
= 15;
1407 temp
= get_absolute_expression ();
1408 if (temp
> max_alignment
)
1409 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1412 as_bad (_("Alignment negative. 0 assumed."));
1416 if (*input_line_pointer
== ',')
1418 input_line_pointer
++;
1419 temp_fill
= get_absolute_expression ();
1427 /* Only make a frag if we HAVE to. */
1428 if (temp
&& !need_pass_2
)
1429 frag_align (temp
, (int) temp_fill
, 0);
1430 demand_empty_rest_of_line ();
1432 record_alignment (now_seg
, temp
);
1436 s_force_thumb (ignore
)
1437 int ignore ATTRIBUTE_UNUSED
;
1439 /* If we are not already in thumb mode go into it, EVEN if
1440 the target processor does not support thumb instructions.
1441 This is used by gcc/config/arm/lib1funcs.asm for example
1442 to compile interworking support functions even if the
1443 target processor should not support interworking. */
1448 record_alignment (now_seg
, 1);
1451 demand_empty_rest_of_line ();
1455 s_thumb_func (ignore
)
1456 int ignore ATTRIBUTE_UNUSED
;
1461 /* The following label is the name/address of the start of a Thumb function.
1462 We need to know this for the interworking support. */
1463 label_is_thumb_function_name
= true;
1465 demand_empty_rest_of_line ();
1468 /* Perform a .set directive, but also mark the alias as
1469 being a thumb function. */
1475 /* XXX the following is a duplicate of the code for s_set() in read.c
1476 We cannot just call that code as we need to get at the symbol that
1478 register char * name
;
1479 register char delim
;
1480 register char * end_name
;
1481 register symbolS
* symbolP
;
1483 /* Especial apologies for the random logic:
1484 This just grew, and could be parsed much more simply!
1486 name
= input_line_pointer
;
1487 delim
= get_symbol_end ();
1488 end_name
= input_line_pointer
;
1493 if (*input_line_pointer
!= ',')
1496 as_bad (_("Expected comma after name \"%s\""), name
);
1498 ignore_rest_of_line ();
1502 input_line_pointer
++;
1505 if (name
[0] == '.' && name
[1] == '\0')
1507 /* XXX - this should not happen to .thumb_set. */
1511 if ((symbolP
= symbol_find (name
)) == NULL
1512 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1515 /* When doing symbol listings, play games with dummy fragments living
1516 outside the normal fragment chain to record the file and line info
1518 if (listing
& LISTING_SYMBOLS
)
1520 extern struct list_info_struct
* listing_tail
;
1521 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1523 memset (dummy_frag
, 0, sizeof (fragS
));
1524 dummy_frag
->fr_type
= rs_fill
;
1525 dummy_frag
->line
= listing_tail
;
1526 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1527 dummy_frag
->fr_symbol
= symbolP
;
1531 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1534 /* "set" symbols are local unless otherwise specified. */
1535 SF_SET_LOCAL (symbolP
);
1536 #endif /* OBJ_COFF */
1537 } /* Make a new symbol. */
1539 symbol_table_insert (symbolP
);
1544 && S_IS_DEFINED (symbolP
)
1545 && S_GET_SEGMENT (symbolP
) != reg_section
)
1546 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1548 pseudo_set (symbolP
);
1550 demand_empty_rest_of_line ();
1552 /* XXX Now we come to the Thumb specific bit of code. */
1554 THUMB_SET_FUNC (symbolP
, 1);
1555 ARM_SET_THUMB (symbolP
, 1);
1556 #if defined OBJ_ELF || defined OBJ_COFF
1557 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1561 /* If we change section we must dump the literal pool first. */
1567 if (now_seg
!= text_section
)
1571 obj_elf_text (ignore
);
1581 if (flag_readonly_data_in_text
)
1583 if (now_seg
!= text_section
)
1586 else if (now_seg
!= data_section
)
1590 obj_elf_data (ignore
);
1598 arm_s_section (ignore
)
1603 obj_elf_section (ignore
);
1608 opcode_select (width
)
1616 if (! (cpu_variant
& ARM_THUMB
))
1617 as_bad (_("selected processor does not support THUMB opcodes"));
1620 /* No need to force the alignment, since we will have been
1621 coming from ARM mode, which is word-aligned. */
1622 record_alignment (now_seg
, 1);
1629 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1630 as_bad (_("selected processor does not support ARM opcodes"));
1635 frag_align (2, 0, 0);
1637 record_alignment (now_seg
, 1);
1642 as_bad (_("invalid instruction size selected (%d)"), width
);
1648 int ignore ATTRIBUTE_UNUSED
;
1651 demand_empty_rest_of_line ();
1656 int ignore ATTRIBUTE_UNUSED
;
1659 demand_empty_rest_of_line ();
1664 int unused ATTRIBUTE_UNUSED
;
1668 temp
= get_absolute_expression ();
1673 opcode_select (temp
);
1677 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1685 skip_whitespace (str
);
1688 inst
.error
= _("Garbage following instruction");
1692 skip_past_comma (str
)
1695 char * p
= * str
, c
;
1698 while ((c
= *p
) == ' ' || c
== ',')
1701 if (c
== ',' && comma
++)
1709 return comma
? SUCCESS
: FAIL
;
1712 /* A standard register must be given at this point.
1713 SHIFT is the place to put it in inst.instruction.
1714 Restores input start point on error.
1715 Returns the reg#, or FAIL. */
1718 reg_required_here (str
, shift
)
1722 static char buff
[128]; /* XXX */
1724 char * start
= * str
;
1726 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1729 inst
.instruction
|= reg
<< shift
;
1733 /* Restore the start point, we may have got a reg of the wrong class. */
1736 /* In the few cases where we might be able to accept something else
1737 this error can be overridden. */
1738 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1744 static CONST
struct asm_psr
*
1746 register char ** ccp
;
1748 char * start
= * ccp
;
1751 CONST
struct asm_psr
* psr
;
1755 /* Skip to the end of the next word in the input stream. */
1760 while (isalpha (c
) || c
== '_');
1762 /* Terminate the word. */
1765 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1766 feature for ease of use and backwards compatibility. */
1767 if (!strncmp (start
, "cpsr", 4))
1768 strncpy (start
, "CPSR", 4);
1769 else if (!strncmp (start
, "spsr", 4))
1770 strncpy (start
, "SPSR", 4);
1772 /* Now locate the word in the psr hash table. */
1773 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1775 /* Restore the input stream. */
1778 /* If we found a valid match, advance the
1779 stream pointer past the end of the word. */
1785 /* Parse the input looking for a PSR flag. */
1788 psr_required_here (str
)
1791 char * start
= * str
;
1792 CONST
struct asm_psr
* psr
;
1794 psr
= arm_psr_parse (str
);
1798 /* If this is the SPSR that is being modified, set the R bit. */
1800 inst
.instruction
|= SPSR_BIT
;
1802 /* Set the psr flags in the MSR instruction. */
1803 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1808 /* In the few cases where we might be able to accept
1809 something else this error can be overridden. */
1810 inst
.error
= _("flag for {c}psr instruction expected");
1812 /* Restore the start point. */
1818 co_proc_number (str
)
1821 int processor
, pchar
;
1823 skip_whitespace (* str
);
1825 /* The data sheet seems to imply that just a number on its own is valid
1826 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1828 if (**str
== 'p' || **str
== 'P')
1832 if (pchar
>= '0' && pchar
<= '9')
1834 processor
= pchar
- '0';
1835 if (**str
>= '0' && **str
<= '9')
1837 processor
= processor
* 10 + *(*str
)++ - '0';
1840 inst
.error
= _("Illegal co-processor number");
1847 inst
.error
= _("Bad or missing co-processor number");
1851 inst
.instruction
|= processor
<< 8;
1856 cp_opc_expr (str
, where
, length
)
1863 skip_whitespace (* str
);
1865 memset (&expr
, '\0', sizeof (expr
));
1867 if (my_get_expression (&expr
, str
))
1869 if (expr
.X_op
!= O_constant
)
1871 inst
.error
= _("bad or missing expression");
1875 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1877 inst
.error
= _("immediate co-processor expression too large");
1881 inst
.instruction
|= expr
.X_add_number
<< where
;
1886 cp_reg_required_here (str
, where
)
1891 char * start
= *str
;
1893 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1896 inst
.instruction
|= reg
<< where
;
1900 /* In the few cases where we might be able to accept something else
1901 this error can be overridden. */
1902 inst
.error
= _("Co-processor register expected");
1904 /* Restore the start point. */
1910 fp_reg_required_here (str
, where
)
1915 char * start
= * str
;
1917 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1920 inst
.instruction
|= reg
<< where
;
1924 /* In the few cases where we might be able to accept something else
1925 this error can be overridden. */
1926 inst
.error
= _("Floating point register expected");
1928 /* Restore the start point. */
1934 cp_address_offset (str
)
1939 skip_whitespace (* str
);
1941 if (! is_immediate_prefix (**str
))
1943 inst
.error
= _("immediate expression expected");
1949 if (my_get_expression (& inst
.reloc
.exp
, str
))
1952 if (inst
.reloc
.exp
.X_op
== O_constant
)
1954 offset
= inst
.reloc
.exp
.X_add_number
;
1958 inst
.error
= _("co-processor address must be word aligned");
1962 if (offset
> 1023 || offset
< -1023)
1964 inst
.error
= _("offset too large");
1969 inst
.instruction
|= INDEX_UP
;
1973 inst
.instruction
|= offset
>> 2;
1976 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1982 cp_address_required_here (str
)
1994 skip_whitespace (p
);
1996 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1999 skip_whitespace (p
);
2005 if (skip_past_comma (& p
) == SUCCESS
)
2008 write_back
= WRITE_BACK
;
2012 inst
.error
= _("pc may not be used in post-increment");
2016 if (cp_address_offset (& p
) == FAIL
)
2020 pre_inc
= PRE_INDEX
| INDEX_UP
;
2024 /* '['Rn, #expr']'[!] */
2026 if (skip_past_comma (& p
) == FAIL
)
2028 inst
.error
= _("pre-indexed expression expected");
2032 pre_inc
= PRE_INDEX
;
2034 if (cp_address_offset (& p
) == FAIL
)
2037 skip_whitespace (p
);
2041 inst
.error
= _("missing ]");
2045 skip_whitespace (p
);
2051 inst
.error
= _("pc may not be used with write-back");
2056 write_back
= WRITE_BACK
;
2062 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2065 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2066 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2067 inst
.reloc
.pc_rel
= 1;
2068 inst
.instruction
|= (REG_PC
<< 16);
2069 pre_inc
= PRE_INDEX
;
2072 inst
.instruction
|= write_back
| pre_inc
;
2080 unsigned long flags
;
2082 /* Do nothing really. */
2083 inst
.instruction
|= flags
; /* This is pointless. */
2091 unsigned long flags
;
2095 /* Only one syntax. */
2096 skip_whitespace (str
);
2098 if (reg_required_here (&str
, 12) == FAIL
)
2100 inst
.error
= BAD_ARGS
;
2104 if (skip_past_comma (&str
) == FAIL
)
2106 inst
.error
= _("comma expected after register name");
2110 skip_whitespace (str
);
2112 if ( strcmp (str
, "CPSR") == 0
2113 || strcmp (str
, "SPSR") == 0
2114 /* Lower case versions for backwards compatability. */
2115 || strcmp (str
, "cpsr") == 0
2116 || strcmp (str
, "spsr") == 0)
2119 /* This is for backwards compatability with older toolchains. */
2120 else if ( strcmp (str
, "cpsr_all") == 0
2121 || strcmp (str
, "spsr_all") == 0)
2125 inst
.error
= _("{C|S}PSR expected");
2129 if (* str
== 's' || * str
== 'S')
2130 inst
.instruction
|= SPSR_BIT
;
2133 inst
.instruction
|= flags
;
2137 /* Two possible forms:
2138 "{C|S}PSR_<field>, Rm",
2139 "{C|S}PSR_f, #expression". */
2144 unsigned long flags
;
2146 skip_whitespace (str
);
2148 if (psr_required_here (& str
) == FAIL
)
2151 if (skip_past_comma (& str
) == FAIL
)
2153 inst
.error
= _("comma missing after psr flags");
2157 skip_whitespace (str
);
2159 if (reg_required_here (& str
, 0) != FAIL
)
2162 inst
.instruction
|= flags
;
2167 if (! is_immediate_prefix (* str
))
2170 _("only a register or immediate value can follow a psr flag");
2177 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2180 _("only a register or immediate value can follow a psr flag");
2184 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2186 inst
.error
= _("only flag field of psr can be set with immediate value");
2190 flags
|= INST_IMMEDIATE
;
2192 if (inst
.reloc
.exp
.X_add_symbol
)
2194 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2195 inst
.reloc
.pc_rel
= 0;
2199 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2201 if (value
== (unsigned) FAIL
)
2203 inst
.error
= _("Invalid constant");
2207 inst
.instruction
|= value
;
2211 inst
.instruction
|= flags
;
2215 /* Long Multiply Parser
2216 UMULL RdLo, RdHi, Rm, Rs
2217 SMULL RdLo, RdHi, Rm, Rs
2218 UMLAL RdLo, RdHi, Rm, Rs
2219 SMLAL RdLo, RdHi, Rm, Rs. */
2222 do_mull (str
, flags
)
2224 unsigned long flags
;
2226 int rdlo
, rdhi
, rm
, rs
;
2228 /* Only one format "rdlo, rdhi, rm, rs". */
2229 skip_whitespace (str
);
2231 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2233 inst
.error
= BAD_ARGS
;
2237 if (skip_past_comma (&str
) == FAIL
2238 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2240 inst
.error
= BAD_ARGS
;
2244 if (skip_past_comma (&str
) == FAIL
2245 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2247 inst
.error
= BAD_ARGS
;
2251 /* rdhi, rdlo and rm must all be different. */
2252 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2253 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2255 if (skip_past_comma (&str
) == FAIL
2256 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2258 inst
.error
= BAD_ARGS
;
2262 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2264 inst
.error
= BAD_PC
;
2268 inst
.instruction
|= flags
;
2276 unsigned long flags
;
2280 /* Only one format "rd, rm, rs". */
2281 skip_whitespace (str
);
2283 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2285 inst
.error
= BAD_ARGS
;
2291 inst
.error
= BAD_PC
;
2295 if (skip_past_comma (&str
) == FAIL
2296 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2298 inst
.error
= BAD_ARGS
;
2304 inst
.error
= BAD_PC
;
2309 as_tsktsk (_("rd and rm should be different in mul"));
2311 if (skip_past_comma (&str
) == FAIL
2312 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2314 inst
.error
= BAD_ARGS
;
2320 inst
.error
= BAD_PC
;
2324 inst
.instruction
|= flags
;
2332 unsigned long flags
;
2336 /* Only one format "rd, rm, rs, rn". */
2337 skip_whitespace (str
);
2339 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2341 inst
.error
= BAD_ARGS
;
2347 inst
.error
= BAD_PC
;
2351 if (skip_past_comma (&str
) == FAIL
2352 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2354 inst
.error
= BAD_ARGS
;
2360 inst
.error
= BAD_PC
;
2365 as_tsktsk (_("rd and rm should be different in mla"));
2367 if (skip_past_comma (&str
) == FAIL
2368 || (rd
= reg_required_here (&str
, 8)) == FAIL
2369 || skip_past_comma (&str
) == FAIL
2370 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2372 inst
.error
= BAD_ARGS
;
2376 if (rd
== REG_PC
|| rm
== REG_PC
)
2378 inst
.error
= BAD_PC
;
2382 inst
.instruction
|= flags
;
2387 /* Returns the index into fp_values of a floating point number,
2388 or -1 if not in the table. */
2391 my_get_float_expression (str
)
2394 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2400 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2402 /* Look for a raw floating point number. */
2403 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2404 && is_end_of_line
[(unsigned char) *save_in
])
2406 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2408 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2410 if (words
[j
] != fp_values
[i
][j
])
2414 if (j
== MAX_LITTLENUMS
)
2422 /* Try and parse a more complex expression, this will probably fail
2423 unless the code uses a floating point prefix (eg "0f"). */
2424 save_in
= input_line_pointer
;
2425 input_line_pointer
= *str
;
2426 if (expression (&exp
) == absolute_section
2427 && exp
.X_op
== O_big
2428 && exp
.X_add_number
< 0)
2430 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2432 if (gen_to_words (words
, 5, (long) 15) == 0)
2434 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2436 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2438 if (words
[j
] != fp_values
[i
][j
])
2442 if (j
== MAX_LITTLENUMS
)
2444 *str
= input_line_pointer
;
2445 input_line_pointer
= save_in
;
2452 *str
= input_line_pointer
;
2453 input_line_pointer
= save_in
;
2457 /* Return true if anything in the expression is a bignum. */
2460 walk_no_bignums (sp
)
2463 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2466 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2468 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2469 || (symbol_get_value_expression (sp
)->X_op_symbol
2470 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2477 my_get_expression (ep
, str
)
2484 save_in
= input_line_pointer
;
2485 input_line_pointer
= *str
;
2486 seg
= expression (ep
);
2489 if (seg
!= absolute_section
2490 && seg
!= text_section
2491 && seg
!= data_section
2492 && seg
!= bss_section
2493 && seg
!= undefined_section
)
2495 inst
.error
= _("bad_segment");
2496 *str
= input_line_pointer
;
2497 input_line_pointer
= save_in
;
2502 /* Get rid of any bignums now, so that we don't generate an error for which
2503 we can't establish a line number later on. Big numbers are never valid
2504 in instructions, which is where this routine is always called. */
2505 if (ep
->X_op
== O_big
2506 || (ep
->X_add_symbol
2507 && (walk_no_bignums (ep
->X_add_symbol
)
2509 && walk_no_bignums (ep
->X_op_symbol
)))))
2511 inst
.error
= _("Invalid constant");
2512 *str
= input_line_pointer
;
2513 input_line_pointer
= save_in
;
2517 *str
= input_line_pointer
;
2518 input_line_pointer
= save_in
;
2522 /* UNRESTRICT should be one if <shift> <register> is permitted for this
2526 decode_shift (str
, unrestrict
)
2530 const struct asm_shift_name
* shift
;
2534 skip_whitespace (* str
);
2536 for (p
= * str
; isalpha (* p
); p
++)
2541 inst
.error
= _("Shift expression expected");
2547 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
2552 inst
.error
= _("Shift expression expected");
2556 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
2558 if (shift
->properties
->index
== SHIFT_RRX
)
2561 inst
.instruction
|= shift
->properties
->bit_field
;
2565 skip_whitespace (p
);
2567 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
2569 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
2573 else if (! is_immediate_prefix (* p
))
2575 inst
.error
= (unrestrict
2576 ? _("shift requires register or #expression")
2577 : _("shift requires #expression"));
2585 if (my_get_expression (& inst
.reloc
.exp
, & p
))
2588 /* Validate some simple #expressions. */
2589 if (inst
.reloc
.exp
.X_op
== O_constant
)
2591 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2593 /* Reject operations greater than 32. */
2595 /* Reject a shift of 0 unless the mode allows it. */
2596 || (num
== 0 && shift
->properties
->allows_0
== 0)
2597 /* Reject a shift of 32 unless the mode allows it. */
2598 || (num
== 32 && shift
->properties
->allows_32
== 0)
2601 /* As a special case we allow a shift of zero for
2602 modes that do not support it to be recoded as an
2603 logical shift left of zero (ie nothing). We warn
2604 about this though. */
2607 as_warn (_("Shift of 0 ignored."));
2608 shift
= & shift_names
[0];
2609 assert (shift
->properties
->index
== SHIFT_LSL
);
2613 inst
.error
= _("Invalid immediate shift");
2618 /* Shifts of 32 are encoded as 0, for those shifts that
2623 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
2627 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2628 inst
.reloc
.pc_rel
= 0;
2629 inst
.instruction
|= shift
->properties
->bit_field
;
2636 /* Do those data_ops which can take a negative immediate constant
2637 by altering the instuction. A bit of a hack really.
2641 by inverting the second operand, and
2644 by negating the second operand. */
2647 negate_data_op (instruction
, value
)
2648 unsigned long * instruction
;
2649 unsigned long value
;
2652 unsigned long negated
, inverted
;
2654 negated
= validate_immediate (-value
);
2655 inverted
= validate_immediate (~value
);
2657 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2660 /* First negates. */
2661 case OPCODE_SUB
: /* ADD <-> SUB */
2662 new_inst
= OPCODE_ADD
;
2667 new_inst
= OPCODE_SUB
;
2671 case OPCODE_CMP
: /* CMP <-> CMN */
2672 new_inst
= OPCODE_CMN
;
2677 new_inst
= OPCODE_CMP
;
2681 /* Now Inverted ops. */
2682 case OPCODE_MOV
: /* MOV <-> MVN */
2683 new_inst
= OPCODE_MVN
;
2688 new_inst
= OPCODE_MOV
;
2692 case OPCODE_AND
: /* AND <-> BIC */
2693 new_inst
= OPCODE_BIC
;
2698 new_inst
= OPCODE_AND
;
2702 case OPCODE_ADC
: /* ADC <-> SBC */
2703 new_inst
= OPCODE_SBC
;
2708 new_inst
= OPCODE_ADC
;
2712 /* We cannot do anything. */
2717 if (value
== (unsigned) FAIL
)
2720 *instruction
&= OPCODE_MASK
;
2721 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2732 skip_whitespace (* str
);
2734 if (reg_required_here (str
, 0) != FAIL
)
2736 if (skip_past_comma (str
) == SUCCESS
)
2737 /* Shift operation on register. */
2738 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2744 /* Immediate expression. */
2745 if (is_immediate_prefix (**str
))
2750 if (my_get_expression (&inst
.reloc
.exp
, str
))
2753 if (inst
.reloc
.exp
.X_add_symbol
)
2755 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2756 inst
.reloc
.pc_rel
= 0;
2760 if (skip_past_comma (str
) == SUCCESS
)
2762 /* #x, y -- ie explicit rotation by Y. */
2763 if (my_get_expression (&expr
, str
))
2766 if (expr
.X_op
!= O_constant
)
2768 inst
.error
= _("Constant expression expected");
2772 /* Rotate must be a multiple of 2. */
2773 if (((unsigned) expr
.X_add_number
) > 30
2774 || (expr
.X_add_number
& 1) != 0
2775 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2777 inst
.error
= _("Invalid constant");
2780 inst
.instruction
|= INST_IMMEDIATE
;
2781 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2782 inst
.instruction
|= expr
.X_add_number
<< 7;
2786 /* Implicit rotation, select a suitable one. */
2787 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2791 /* Can't be done. Perhaps the code reads something like
2792 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
2793 if ((value
= negate_data_op (&inst
.instruction
,
2794 inst
.reloc
.exp
.X_add_number
))
2797 inst
.error
= _("Invalid constant");
2802 inst
.instruction
|= value
;
2805 inst
.instruction
|= INST_IMMEDIATE
;
2810 inst
.error
= _("Register or shift expression expected");
2819 skip_whitespace (* str
);
2821 if (fp_reg_required_here (str
, 0) != FAIL
)
2825 /* Immediate expression. */
2826 if (*((*str
)++) == '#')
2832 skip_whitespace (* str
);
2834 /* First try and match exact strings, this is to guarantee
2835 that some formats will work even for cross assembly. */
2837 for (i
= 0; fp_const
[i
]; i
++)
2839 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2843 *str
+= strlen (fp_const
[i
]);
2844 if (is_end_of_line
[(unsigned char) **str
])
2846 inst
.instruction
|= i
+ 8;
2853 /* Just because we didn't get a match doesn't mean that the
2854 constant isn't valid, just that it is in a format that we
2855 don't automatically recognize. Try parsing it with
2856 the standard expression routines. */
2857 if ((i
= my_get_float_expression (str
)) >= 0)
2859 inst
.instruction
|= i
+ 8;
2863 inst
.error
= _("Invalid floating point immediate expression");
2867 _("Floating point register or immediate expression expected");
2873 do_arit (str
, flags
)
2875 unsigned long flags
;
2877 skip_whitespace (str
);
2879 if (reg_required_here (&str
, 12) == FAIL
2880 || skip_past_comma (&str
) == FAIL
2881 || reg_required_here (&str
, 16) == FAIL
2882 || skip_past_comma (&str
) == FAIL
2883 || data_op2 (&str
) == FAIL
)
2886 inst
.error
= BAD_ARGS
;
2890 inst
.instruction
|= flags
;
2898 unsigned long flags
;
2900 /* This is a pseudo-op of the form "adr rd, label" to be converted
2901 into a relative address of the form "add rd, pc, #label-.-8". */
2902 skip_whitespace (str
);
2904 if (reg_required_here (&str
, 12) == FAIL
2905 || skip_past_comma (&str
) == FAIL
2906 || my_get_expression (&inst
.reloc
.exp
, &str
))
2909 inst
.error
= BAD_ARGS
;
2913 /* Frag hacking will turn this into a sub instruction if the offset turns
2914 out to be negative. */
2915 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2916 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2917 inst
.reloc
.pc_rel
= 1;
2918 inst
.instruction
|= flags
;
2924 do_adrl (str
, flags
)
2926 unsigned long flags
;
2928 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2929 into a relative address of the form:
2930 add rd, pc, #low(label-.-8)"
2931 add rd, rd, #high(label-.-8)" */
2933 skip_whitespace (str
);
2935 if (reg_required_here (& str
, 12) == FAIL
2936 || skip_past_comma (& str
) == FAIL
2937 || my_get_expression (& inst
.reloc
.exp
, & str
))
2940 inst
.error
= BAD_ARGS
;
2946 /* Frag hacking will turn this into a sub instruction if the offset turns
2947 out to be negative. */
2948 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2949 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2950 inst
.reloc
.pc_rel
= 1;
2951 inst
.instruction
|= flags
;
2952 inst
.size
= INSN_SIZE
* 2;
2960 unsigned long flags
;
2962 skip_whitespace (str
);
2964 if (reg_required_here (&str
, 16) == FAIL
)
2967 inst
.error
= BAD_ARGS
;
2971 if (skip_past_comma (&str
) == FAIL
2972 || data_op2 (&str
) == FAIL
)
2975 inst
.error
= BAD_ARGS
;
2979 inst
.instruction
|= flags
;
2980 if ((flags
& 0x0000f000) == 0)
2981 inst
.instruction
|= CONDS_BIT
;
2990 unsigned long flags
;
2992 skip_whitespace (str
);
2994 if (reg_required_here (&str
, 12) == FAIL
)
2997 inst
.error
= BAD_ARGS
;
3001 if (skip_past_comma (&str
) == FAIL
3002 || data_op2 (&str
) == FAIL
)
3005 inst
.error
= BAD_ARGS
;
3009 inst
.instruction
|= flags
;
3015 ldst_extend (str
, hwse
)
3026 if (my_get_expression (& inst
.reloc
.exp
, str
))
3029 if (inst
.reloc
.exp
.X_op
== O_constant
)
3031 int value
= inst
.reloc
.exp
.X_add_number
;
3033 if ((hwse
&& (value
< -255 || value
> 255))
3034 || (value
< -4095 || value
> 4095))
3036 inst
.error
= _("address offset too large");
3046 /* Halfword and signextension instructions have the
3047 immediate value split across bits 11..8 and bits 3..0. */
3049 inst
.instruction
|= (add
| HWOFFSET_IMM
3050 | ((value
>> 4) << 8) | (value
& 0xF));
3052 inst
.instruction
|= add
| value
;
3058 inst
.instruction
|= HWOFFSET_IMM
;
3059 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3062 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3063 inst
.reloc
.pc_rel
= 0;
3076 if (reg_required_here (str
, 0) == FAIL
)
3080 inst
.instruction
|= add
;
3083 inst
.instruction
|= add
| OFFSET_REG
;
3084 if (skip_past_comma (str
) == SUCCESS
)
3085 return decode_shift (str
, SHIFT_RESTRICT
);
3093 do_ldst (str
, flags
)
3095 unsigned long flags
;
3102 /* This is not ideal, but it is the simplest way of dealing with the
3103 ARM7T halfword instructions (since they use a different
3104 encoding, but the same mnemonic): */
3105 halfword
= (flags
& 0x80000000) != 0;
3108 /* This is actually a load/store of a halfword, or a
3109 signed-extension load. */
3110 if ((cpu_variant
& ARM_HALFWORD
) == 0)
3113 = _("Processor does not support halfwords or signed bytes");
3117 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
3118 | (flags
& ~COND_MASK
));
3123 skip_whitespace (str
);
3125 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
3128 inst
.error
= BAD_ARGS
;
3132 if (skip_past_comma (& str
) == FAIL
)
3134 inst
.error
= _("Address expected");
3144 skip_whitespace (str
);
3146 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3149 /* Conflicts can occur on stores as well as loads. */
3150 conflict_reg
= (conflict_reg
== reg
);
3152 skip_whitespace (str
);
3158 if (skip_past_comma (&str
) == SUCCESS
)
3160 /* [Rn],... (post inc) */
3161 if (ldst_extend (&str
, halfword
) == FAIL
)
3164 as_warn (_("%s register same as write-back base"),
3165 ((inst
.instruction
& LOAD_BIT
)
3166 ? _("destination") : _("source")));
3172 inst
.instruction
|= HWOFFSET_IMM
;
3174 skip_whitespace (str
);
3179 as_warn (_("%s register same as write-back base"),
3180 ((inst
.instruction
& LOAD_BIT
)
3181 ? _("destination") : _("source")));
3183 inst
.instruction
|= WRITE_BACK
;
3187 if (! (flags
& TRANS_BIT
))
3194 if (skip_past_comma (&str
) == FAIL
)
3196 inst
.error
= _("pre-indexed expression expected");
3201 if (ldst_extend (&str
, halfword
) == FAIL
)
3204 skip_whitespace (str
);
3208 inst
.error
= _("missing ]");
3212 skip_whitespace (str
);
3217 as_warn (_("%s register same as write-back base"),
3218 ((inst
.instruction
& LOAD_BIT
)
3219 ? _("destination") : _("source")));
3221 inst
.instruction
|= WRITE_BACK
;
3225 else if (*str
== '=')
3227 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
3230 skip_whitespace (str
);
3232 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3235 if (inst
.reloc
.exp
.X_op
!= O_constant
3236 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3238 inst
.error
= _("Constant expression expected");
3242 if (inst
.reloc
.exp
.X_op
== O_constant
3243 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3245 /* This can be done with a mov instruction. */
3246 inst
.instruction
&= LITERAL_MASK
;
3247 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3248 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3254 /* Insert into literal pool. */
3255 if (add_to_lit_pool () == FAIL
)
3258 inst
.error
= _("literal pool insertion failed");
3262 /* Change the instruction exp to point to the pool. */
3265 inst
.instruction
|= HWOFFSET_IMM
;
3266 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3269 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3270 inst
.reloc
.pc_rel
= 1;
3271 inst
.instruction
|= (REG_PC
<< 16);
3277 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3282 inst
.instruction
|= HWOFFSET_IMM
;
3283 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3286 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3288 /* PC rel adjust. */
3289 inst
.reloc
.exp
.X_add_number
-= 8;
3291 inst
.reloc
.pc_rel
= 1;
3292 inst
.instruction
|= (REG_PC
<< 16);
3296 if (pre_inc
&& (flags
& TRANS_BIT
))
3297 inst
.error
= _("Pre-increment instruction with translate");
3299 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3308 char * str
= * strp
;
3312 /* We come back here if we get ranges concatenated by '+' or '|'. */
3327 skip_whitespace (str
);
3329 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3338 inst
.error
= _("Bad range in register list");
3342 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3344 if (range
& (1 << i
))
3346 (_("Warning: Duplicated register (r%d) in register list"),
3354 if (range
& (1 << reg
))
3355 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3357 else if (reg
<= cur_reg
)
3358 as_tsktsk (_("Warning: Register range not in ascending order"));
3363 while (skip_past_comma (&str
) != FAIL
3364 || (in_range
= 1, *str
++ == '-'));
3366 skip_whitespace (str
);
3370 inst
.error
= _("Missing `}'");
3378 if (my_get_expression (&expr
, &str
))
3381 if (expr
.X_op
== O_constant
)
3383 if (expr
.X_add_number
3384 != (expr
.X_add_number
& 0x0000ffff))
3386 inst
.error
= _("invalid register mask");
3390 if ((range
& expr
.X_add_number
) != 0)
3392 int regno
= range
& expr
.X_add_number
;
3395 regno
= (1 << regno
) - 1;
3397 (_("Warning: Duplicated register (r%d) in register list"),
3401 range
|= expr
.X_add_number
;
3405 if (inst
.reloc
.type
!= 0)
3407 inst
.error
= _("expression too complex");
3411 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3412 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3413 inst
.reloc
.pc_rel
= 0;
3417 skip_whitespace (str
);
3419 if (*str
== '|' || *str
== '+')
3425 while (another_range
);
3432 do_ldmstm (str
, flags
)
3434 unsigned long flags
;
3439 skip_whitespace (str
);
3441 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3444 if (base_reg
== REG_PC
)
3446 inst
.error
= _("r15 not allowed as base register");
3450 skip_whitespace (str
);
3454 flags
|= WRITE_BACK
;
3458 if (skip_past_comma (&str
) == FAIL
3459 || (range
= reg_list (&str
)) == FAIL
)
3462 inst
.error
= BAD_ARGS
;
3469 flags
|= LDM_TYPE_2_OR_3
;
3472 inst
.instruction
|= flags
| range
;
3480 unsigned long flags
;
3482 skip_whitespace (str
);
3484 /* Allow optional leading '#'. */
3485 if (is_immediate_prefix (*str
))
3488 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3491 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3492 inst
.reloc
.pc_rel
= 0;
3493 inst
.instruction
|= flags
;
3501 do_swap (str
, flags
)
3503 unsigned long flags
;
3507 skip_whitespace (str
);
3509 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3514 inst
.error
= _("r15 not allowed in swap");
3518 if (skip_past_comma (&str
) == FAIL
3519 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3522 inst
.error
= BAD_ARGS
;
3528 inst
.error
= _("r15 not allowed in swap");
3532 if (skip_past_comma (&str
) == FAIL
3535 inst
.error
= BAD_ARGS
;
3539 skip_whitespace (str
);
3541 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3546 inst
.error
= BAD_PC
;
3550 skip_whitespace (str
);
3554 inst
.error
= _("missing ]");
3558 inst
.instruction
|= flags
;
3564 do_branch (str
, flags
)
3566 unsigned long flags ATTRIBUTE_UNUSED
;
3568 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3575 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
3576 required for the instruction. */
3578 /* arm_parse_reloc () works on input_line_pointer.
3579 We actually want to parse the operands to the branch instruction
3580 passed in 'str'. Save the input pointer and restore it later. */
3581 save_in
= input_line_pointer
;
3582 input_line_pointer
= str
;
3583 if (inst
.reloc
.exp
.X_op
== O_symbol
3585 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3587 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3588 inst
.reloc
.pc_rel
= 0;
3589 /* Modify str to point to after parsed operands, otherwise
3590 end_of_line() will complain about the (PLT) left in str. */
3591 str
= input_line_pointer
;
3595 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3596 inst
.reloc
.pc_rel
= 1;
3598 input_line_pointer
= save_in
;
3601 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3602 inst
.reloc
.pc_rel
= 1;
3603 #endif /* OBJ_ELF */
3612 unsigned long flags ATTRIBUTE_UNUSED
;
3616 skip_whitespace (str
);
3618 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3620 inst
.error
= BAD_ARGS
;
3624 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
3626 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
3634 unsigned long flags ATTRIBUTE_UNUSED
;
3636 /* Co-processor data operation.
3637 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3638 skip_whitespace (str
);
3640 if (co_proc_number (&str
) == FAIL
)
3643 inst
.error
= BAD_ARGS
;
3647 if (skip_past_comma (&str
) == FAIL
3648 || cp_opc_expr (&str
, 20,4) == FAIL
)
3651 inst
.error
= BAD_ARGS
;
3655 if (skip_past_comma (&str
) == FAIL
3656 || cp_reg_required_here (&str
, 12) == FAIL
)
3659 inst
.error
= BAD_ARGS
;
3663 if (skip_past_comma (&str
) == FAIL
3664 || cp_reg_required_here (&str
, 16) == FAIL
)
3667 inst
.error
= BAD_ARGS
;
3671 if (skip_past_comma (&str
) == FAIL
3672 || cp_reg_required_here (&str
, 0) == FAIL
)
3675 inst
.error
= BAD_ARGS
;
3679 if (skip_past_comma (&str
) == SUCCESS
)
3681 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3684 inst
.error
= BAD_ARGS
;
3694 do_lstc (str
, flags
)
3696 unsigned long flags
;
3698 /* Co-processor register load/store.
3699 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3701 skip_whitespace (str
);
3703 if (co_proc_number (&str
) == FAIL
)
3706 inst
.error
= BAD_ARGS
;
3710 if (skip_past_comma (&str
) == FAIL
3711 || cp_reg_required_here (&str
, 12) == FAIL
)
3714 inst
.error
= BAD_ARGS
;
3718 if (skip_past_comma (&str
) == FAIL
3719 || cp_address_required_here (&str
) == FAIL
)
3722 inst
.error
= BAD_ARGS
;
3726 inst
.instruction
|= flags
;
3732 do_co_reg (str
, flags
)
3734 unsigned long flags
;
3736 /* Co-processor register transfer.
3737 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3739 skip_whitespace (str
);
3741 if (co_proc_number (&str
) == FAIL
)
3744 inst
.error
= BAD_ARGS
;
3748 if (skip_past_comma (&str
) == FAIL
3749 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3752 inst
.error
= BAD_ARGS
;
3756 if (skip_past_comma (&str
) == FAIL
3757 || reg_required_here (&str
, 12) == FAIL
)
3760 inst
.error
= BAD_ARGS
;
3764 if (skip_past_comma (&str
) == FAIL
3765 || cp_reg_required_here (&str
, 16) == FAIL
)
3768 inst
.error
= BAD_ARGS
;
3772 if (skip_past_comma (&str
) == FAIL
3773 || cp_reg_required_here (&str
, 0) == FAIL
)
3776 inst
.error
= BAD_ARGS
;
3780 if (skip_past_comma (&str
) == SUCCESS
)
3782 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3785 inst
.error
= BAD_ARGS
;
3791 inst
.error
= BAD_COND
;
3799 do_fp_ctrl (str
, flags
)
3801 unsigned long flags ATTRIBUTE_UNUSED
;
3803 /* FP control registers.
3804 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3806 skip_whitespace (str
);
3808 if (reg_required_here (&str
, 12) == FAIL
)
3811 inst
.error
= BAD_ARGS
;
3820 do_fp_ldst (str
, flags
)
3822 unsigned long flags ATTRIBUTE_UNUSED
;
3824 skip_whitespace (str
);
3826 switch (inst
.suffix
)
3831 inst
.instruction
|= CP_T_X
;
3834 inst
.instruction
|= CP_T_Y
;
3837 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3843 if (fp_reg_required_here (&str
, 12) == FAIL
)
3846 inst
.error
= BAD_ARGS
;
3850 if (skip_past_comma (&str
) == FAIL
3851 || cp_address_required_here (&str
) == FAIL
)
3854 inst
.error
= BAD_ARGS
;
3862 do_fp_ldmstm (str
, flags
)
3864 unsigned long flags
;
3868 skip_whitespace (str
);
3870 if (fp_reg_required_here (&str
, 12) == FAIL
)
3873 inst
.error
= BAD_ARGS
;
3877 /* Get Number of registers to transfer. */
3878 if (skip_past_comma (&str
) == FAIL
3879 || my_get_expression (&inst
.reloc
.exp
, &str
))
3882 inst
.error
= _("constant expression expected");
3886 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3888 inst
.error
= _("Constant value required for number of registers");
3892 num_regs
= inst
.reloc
.exp
.X_add_number
;
3894 if (num_regs
< 1 || num_regs
> 4)
3896 inst
.error
= _("number of registers must be in the range [1:4]");
3903 inst
.instruction
|= CP_T_X
;
3906 inst
.instruction
|= CP_T_Y
;
3909 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3923 /* The instruction specified "ea" or "fd", so we can only accept
3924 [Rn]{!}. The instruction does not really support stacking or
3925 unstacking, so we have to emulate these by setting appropriate
3926 bits and offsets. */
3927 if (skip_past_comma (&str
) == FAIL
3931 inst
.error
= BAD_ARGS
;
3936 skip_whitespace (str
);
3938 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3941 skip_whitespace (str
);
3945 inst
.error
= BAD_ARGS
;
3957 _("R15 not allowed as base register with write-back");
3964 if (flags
& CP_T_Pre
)
3966 /* Pre-decrement. */
3967 offset
= 3 * num_regs
;
3973 /* Post-increment. */
3977 offset
= 3 * num_regs
;
3981 /* No write-back, so convert this into a standard pre-increment
3982 instruction -- aesthetically more pleasing. */
3983 flags
= CP_T_Pre
| CP_T_UD
;
3988 inst
.instruction
|= flags
| offset
;
3990 else if (skip_past_comma (&str
) == FAIL
3991 || cp_address_required_here (&str
) == FAIL
)
3994 inst
.error
= BAD_ARGS
;
4002 do_fp_dyadic (str
, flags
)
4004 unsigned long flags
;
4006 skip_whitespace (str
);
4008 switch (inst
.suffix
)
4013 inst
.instruction
|= 0x00000080;
4016 inst
.instruction
|= 0x00080000;
4022 if (fp_reg_required_here (&str
, 12) == FAIL
)
4025 inst
.error
= BAD_ARGS
;
4029 if (skip_past_comma (&str
) == FAIL
4030 || fp_reg_required_here (&str
, 16) == FAIL
)
4033 inst
.error
= BAD_ARGS
;
4037 if (skip_past_comma (&str
) == FAIL
4038 || fp_op2 (&str
) == FAIL
)
4041 inst
.error
= BAD_ARGS
;
4045 inst
.instruction
|= flags
;
4051 do_fp_monadic (str
, flags
)
4053 unsigned long flags
;
4055 skip_whitespace (str
);
4057 switch (inst
.suffix
)
4062 inst
.instruction
|= 0x00000080;
4065 inst
.instruction
|= 0x00080000;
4071 if (fp_reg_required_here (&str
, 12) == FAIL
)
4074 inst
.error
= BAD_ARGS
;
4078 if (skip_past_comma (&str
) == FAIL
4079 || fp_op2 (&str
) == FAIL
)
4082 inst
.error
= BAD_ARGS
;
4086 inst
.instruction
|= flags
;
4092 do_fp_cmp (str
, flags
)
4094 unsigned long flags
;
4096 skip_whitespace (str
);
4098 if (fp_reg_required_here (&str
, 16) == FAIL
)
4101 inst
.error
= BAD_ARGS
;
4105 if (skip_past_comma (&str
) == FAIL
4106 || fp_op2 (&str
) == FAIL
)
4109 inst
.error
= BAD_ARGS
;
4113 inst
.instruction
|= flags
;
4119 do_fp_from_reg (str
, flags
)
4121 unsigned long flags
;
4123 skip_whitespace (str
);
4125 switch (inst
.suffix
)
4130 inst
.instruction
|= 0x00000080;
4133 inst
.instruction
|= 0x00080000;
4139 if (fp_reg_required_here (&str
, 16) == FAIL
)
4142 inst
.error
= BAD_ARGS
;
4146 if (skip_past_comma (&str
) == FAIL
4147 || reg_required_here (&str
, 12) == FAIL
)
4150 inst
.error
= BAD_ARGS
;
4154 inst
.instruction
|= flags
;
4160 do_fp_to_reg (str
, flags
)
4162 unsigned long flags
;
4164 skip_whitespace (str
);
4166 if (reg_required_here (&str
, 12) == FAIL
)
4169 if (skip_past_comma (&str
) == FAIL
4170 || fp_reg_required_here (&str
, 0) == FAIL
)
4173 inst
.error
= BAD_ARGS
;
4177 inst
.instruction
|= flags
;
4182 /* Thumb specific routines. */
4184 /* Parse and validate that a register is of the right form, this saves
4185 repeated checking of this information in many similar cases.
4186 Unlike the 32-bit case we do not insert the register into the opcode
4187 here, since the position is often unknown until the full instruction
4191 thumb_reg (strp
, hi_lo
)
4197 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
4205 inst
.error
= _("lo register required");
4213 inst
.error
= _("hi register required");
4225 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4229 thumb_add_sub (str
, subtract
)
4233 int Rd
, Rs
, Rn
= FAIL
;
4235 skip_whitespace (str
);
4237 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4238 || skip_past_comma (&str
) == FAIL
)
4241 inst
.error
= BAD_ARGS
;
4245 if (is_immediate_prefix (*str
))
4249 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4254 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4257 if (skip_past_comma (&str
) == FAIL
)
4259 /* Two operand format, shuffle the registers
4260 and pretend there are 3. */
4264 else if (is_immediate_prefix (*str
))
4267 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4270 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4274 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4275 for the latter case, EXPR contains the immediate that was found. */
4278 /* All register format. */
4279 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4283 inst
.error
= _("dest and source1 must be the same register");
4287 /* Can't do this for SUB. */
4290 inst
.error
= _("subtract valid only on lo regs");
4294 inst
.instruction
= (T_OPCODE_ADD_HI
4295 | (Rd
> 7 ? THUMB_H1
: 0)
4296 | (Rn
> 7 ? THUMB_H2
: 0));
4297 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4301 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4302 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4307 /* Immediate expression, now things start to get nasty. */
4309 /* First deal with HI regs, only very restricted cases allowed:
4310 Adjusting SP, and using PC or SP to get an address. */
4311 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4312 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4314 inst
.error
= _("invalid Hi register with immediate");
4318 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4320 /* Value isn't known yet, all we can do is store all the fragments
4321 we know about in the instruction and let the reloc hacking
4323 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4324 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4328 int offset
= inst
.reloc
.exp
.X_add_number
;
4338 /* Quick check, in case offset is MIN_INT. */
4341 inst
.error
= _("immediate value out of range");
4350 if (offset
& ~0x1fc)
4352 inst
.error
= _("invalid immediate value for stack adjust");
4355 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4356 inst
.instruction
|= offset
>> 2;
4358 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4361 || (offset
& ~0x3fc))
4363 inst
.error
= _("invalid immediate for address calculation");
4366 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4368 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4374 inst
.error
= _("immediate value out of range");
4377 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4378 inst
.instruction
|= (Rd
<< 8) | offset
;
4384 inst
.error
= _("immediate value out of range");
4387 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4388 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4397 thumb_shift (str
, shift
)
4401 int Rd
, Rs
, Rn
= FAIL
;
4403 skip_whitespace (str
);
4405 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4406 || skip_past_comma (&str
) == FAIL
)
4409 inst
.error
= BAD_ARGS
;
4413 if (is_immediate_prefix (*str
))
4415 /* Two operand immediate format, set Rs to Rd. */
4418 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4423 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4426 if (skip_past_comma (&str
) == FAIL
)
4428 /* Two operand format, shuffle the registers
4429 and pretend there are 3. */
4433 else if (is_immediate_prefix (*str
))
4436 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4439 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4443 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4444 for the latter case, EXPR contains the immediate that was found. */
4450 inst
.error
= _("source1 and dest must be same register");
4456 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4457 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4458 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4461 inst
.instruction
|= Rd
| (Rn
<< 3);
4467 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4468 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4469 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4472 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4474 /* Value isn't known yet, create a dummy reloc and let reloc
4475 hacking fix it up. */
4476 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4480 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4482 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4484 inst
.error
= _("Invalid immediate for shift");
4488 /* Shifts of zero are handled by converting to LSL. */
4489 if (shift_value
== 0)
4490 inst
.instruction
= T_OPCODE_LSL_I
;
4492 /* Shifts of 32 are encoded as a shift of zero. */
4493 if (shift_value
== 32)
4496 inst
.instruction
|= shift_value
<< 6;
4499 inst
.instruction
|= Rd
| (Rs
<< 3);
4506 thumb_mov_compare (str
, move
)
4512 skip_whitespace (str
);
4514 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4515 || skip_past_comma (&str
) == FAIL
)
4518 inst
.error
= BAD_ARGS
;
4522 if (is_immediate_prefix (*str
))
4525 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4528 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4533 if (Rs
< 8 && Rd
< 8)
4535 if (move
== THUMB_MOVE
)
4536 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4537 since a MOV instruction produces unpredictable results. */
4538 inst
.instruction
= T_OPCODE_ADD_I3
;
4540 inst
.instruction
= T_OPCODE_CMP_LR
;
4541 inst
.instruction
|= Rd
| (Rs
<< 3);
4545 if (move
== THUMB_MOVE
)
4546 inst
.instruction
= T_OPCODE_MOV_HR
;
4548 inst
.instruction
= T_OPCODE_CMP_HR
;
4551 inst
.instruction
|= THUMB_H1
;
4554 inst
.instruction
|= THUMB_H2
;
4556 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4563 inst
.error
= _("only lo regs allowed with immediate");
4567 if (move
== THUMB_MOVE
)
4568 inst
.instruction
= T_OPCODE_MOV_I8
;
4570 inst
.instruction
= T_OPCODE_CMP_I8
;
4572 inst
.instruction
|= Rd
<< 8;
4574 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4575 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4578 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4582 inst
.error
= _("invalid immediate");
4586 inst
.instruction
|= value
;
4594 thumb_load_store (str
, load_store
, size
)
4599 int Rd
, Rb
, Ro
= FAIL
;
4601 skip_whitespace (str
);
4603 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4604 || skip_past_comma (&str
) == FAIL
)
4607 inst
.error
= BAD_ARGS
;
4614 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4617 if (skip_past_comma (&str
) != FAIL
)
4619 if (is_immediate_prefix (*str
))
4622 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4625 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4630 inst
.reloc
.exp
.X_op
= O_constant
;
4631 inst
.reloc
.exp
.X_add_number
= 0;
4636 inst
.error
= _("expected ']'");
4641 else if (*str
== '=')
4643 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4646 skip_whitespace (str
);
4648 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4653 if ( inst
.reloc
.exp
.X_op
!= O_constant
4654 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4656 inst
.error
= "Constant expression expected";
4660 if (inst
.reloc
.exp
.X_op
== O_constant
4661 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4663 /* This can be done with a mov instruction. */
4665 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4666 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4670 /* Insert into literal pool. */
4671 if (add_to_lit_pool () == FAIL
)
4674 inst
.error
= "literal pool insertion failed";
4678 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4679 inst
.reloc
.pc_rel
= 1;
4680 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4681 /* Adjust ARM pipeline offset to Thumb. */
4682 inst
.reloc
.exp
.X_add_number
+= 4;
4688 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4691 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4692 inst
.reloc
.pc_rel
= 1;
4693 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
4694 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4699 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4701 if (size
!= THUMB_WORD
)
4703 inst
.error
= _("byte or halfword not valid for base register");
4706 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4708 inst
.error
= _("R15 based store not allowed");
4711 else if (Ro
!= FAIL
)
4713 inst
.error
= _("Invalid base register for register offset");
4718 inst
.instruction
= T_OPCODE_LDR_PC
;
4719 else if (load_store
== THUMB_LOAD
)
4720 inst
.instruction
= T_OPCODE_LDR_SP
;
4722 inst
.instruction
= T_OPCODE_STR_SP
;
4724 inst
.instruction
|= Rd
<< 8;
4725 if (inst
.reloc
.exp
.X_op
== O_constant
)
4727 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4729 if (offset
& ~0x3fc)
4731 inst
.error
= _("invalid offset");
4735 inst
.instruction
|= offset
>> 2;
4738 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4742 inst
.error
= _("invalid base register in load/store");
4745 else if (Ro
== FAIL
)
4747 /* Immediate offset. */
4748 if (size
== THUMB_WORD
)
4749 inst
.instruction
= (load_store
== THUMB_LOAD
4750 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4751 else if (size
== THUMB_HALFWORD
)
4752 inst
.instruction
= (load_store
== THUMB_LOAD
4753 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4755 inst
.instruction
= (load_store
== THUMB_LOAD
4756 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4758 inst
.instruction
|= Rd
| (Rb
<< 3);
4760 if (inst
.reloc
.exp
.X_op
== O_constant
)
4762 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4764 if (offset
& ~(0x1f << size
))
4766 inst
.error
= _("Invalid offset");
4769 inst
.instruction
|= (offset
>> size
) << 6;
4772 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4776 /* Register offset. */
4777 if (size
== THUMB_WORD
)
4778 inst
.instruction
= (load_store
== THUMB_LOAD
4779 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4780 else if (size
== THUMB_HALFWORD
)
4781 inst
.instruction
= (load_store
== THUMB_LOAD
4782 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4784 inst
.instruction
= (load_store
== THUMB_LOAD
4785 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4787 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4802 /* Handle the Format 4 instructions that do not have equivalents in other
4803 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4812 skip_whitespace (str
);
4814 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4815 || skip_past_comma (&str
) == FAIL
4816 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4818 inst
.error
= BAD_ARGS
;
4822 if (skip_past_comma (&str
) != FAIL
)
4824 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4825 (It isn't allowed for CMP either, but that isn't handled by this
4827 if (inst
.instruction
== T_OPCODE_TST
4828 || inst
.instruction
== T_OPCODE_CMN
4829 || inst
.instruction
== T_OPCODE_NEG
4830 || inst
.instruction
== T_OPCODE_MVN
)
4832 inst
.error
= BAD_ARGS
;
4836 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4841 inst
.error
= _("dest and source1 one must be the same register");
4847 if (inst
.instruction
== T_OPCODE_MUL
4849 as_tsktsk (_("Rs and Rd must be different in MUL"));
4851 inst
.instruction
|= Rd
| (Rs
<< 3);
4859 thumb_add_sub (str
, 0);
4866 thumb_shift (str
, THUMB_ASR
);
4873 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4875 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4876 inst
.reloc
.pc_rel
= 1;
4884 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4886 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4887 inst
.reloc
.pc_rel
= 1;
4891 /* Find the real, Thumb encoded start of a Thumb function. */
4894 find_real_start (symbolP
)
4898 const char * name
= S_GET_NAME (symbolP
);
4899 symbolS
* new_target
;
4901 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
4902 #define STUB_NAME ".real_start_of"
4907 /* Names that start with '.' are local labels, not function entry points.
4908 The compiler may generate BL instructions to these labels because it
4909 needs to perform a branch to a far away location. */
4913 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4914 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4916 new_target
= symbol_find (real_start
);
4918 if (new_target
== NULL
)
4920 as_warn ("Failed to find real start of function: %s\n", name
);
4921 new_target
= symbolP
;
4933 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4936 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4937 inst
.reloc
.pc_rel
= 1;
4940 /* If the destination of the branch is a defined symbol which does not have
4941 the THUMB_FUNC attribute, then we must be calling a function which has
4942 the (interfacearm) attribute. We look for the Thumb entry point to that
4943 function and change the branch to refer to that function instead. */
4944 if ( inst
.reloc
.exp
.X_op
== O_symbol
4945 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4946 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4947 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4948 inst
.reloc
.exp
.X_add_symbol
=
4949 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4958 skip_whitespace (str
);
4960 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4963 /* This sets THUMB_H2 from the top bit of reg. */
4964 inst
.instruction
|= reg
<< 3;
4966 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4967 should cause the alignment to be checked once it is known. This is
4968 because BX PC only works if the instruction is word aligned. */
4977 thumb_mov_compare (str
, THUMB_COMPARE
);
4987 skip_whitespace (str
);
4989 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4993 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4997 if (skip_past_comma (&str
) == FAIL
4998 || (range
= reg_list (&str
)) == FAIL
)
5001 inst
.error
= BAD_ARGS
;
5005 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5007 /* This really doesn't seem worth it. */
5008 inst
.reloc
.type
= BFD_RELOC_NONE
;
5009 inst
.error
= _("Expression too complex");
5015 inst
.error
= _("only lo-regs valid in load/store multiple");
5019 inst
.instruction
|= (Rb
<< 8) | range
;
5027 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
5034 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
5041 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
5050 skip_whitespace (str
);
5052 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5053 || skip_past_comma (&str
) == FAIL
5055 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5056 || skip_past_comma (&str
) == FAIL
5057 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5061 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
5065 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5073 thumb_shift (str
, THUMB_LSL
);
5080 thumb_shift (str
, THUMB_LSR
);
5087 thumb_mov_compare (str
, THUMB_MOVE
);
5096 skip_whitespace (str
);
5098 if ((range
= reg_list (&str
)) == FAIL
)
5101 inst
.error
= BAD_ARGS
;
5105 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5107 /* This really doesn't seem worth it. */
5108 inst
.reloc
.type
= BFD_RELOC_NONE
;
5109 inst
.error
= _("Expression too complex");
5115 if ((inst
.instruction
== T_OPCODE_PUSH
5116 && (range
& ~0xff) == 1 << REG_LR
)
5117 || (inst
.instruction
== T_OPCODE_POP
5118 && (range
& ~0xff) == 1 << REG_PC
))
5120 inst
.instruction
|= THUMB_PP_PC_LR
;
5125 inst
.error
= _("invalid register list to push/pop instruction");
5130 inst
.instruction
|= range
;
5138 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
5145 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
5152 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
5159 thumb_add_sub (str
, 1);
5166 skip_whitespace (str
);
5168 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5171 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5182 /* This is a pseudo-op of the form "adr rd, label" to be converted
5183 into a relative address of the form "add rd, pc, #label-.-4". */
5184 skip_whitespace (str
);
5186 /* Store Rd in temporary location inside instruction. */
5187 if ((reg
= reg_required_here (&str
, 4)) == FAIL
5188 || (reg
> 7) /* For Thumb reg must be r0..r7. */
5189 || skip_past_comma (&str
) == FAIL
5190 || my_get_expression (&inst
.reloc
.exp
, &str
))
5193 inst
.error
= BAD_ARGS
;
5197 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5198 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
5199 inst
.reloc
.pc_rel
= 1;
5200 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
5209 int len
= strlen (reg_table
[entry
].name
) + 2;
5210 char * buf
= (char *) xmalloc (len
);
5211 char * buf2
= (char *) xmalloc (len
);
5214 #ifdef REGISTER_PREFIX
5215 buf
[i
++] = REGISTER_PREFIX
;
5218 strcpy (buf
+ i
, reg_table
[entry
].name
);
5220 for (i
= 0; buf
[i
]; i
++)
5221 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5225 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
5226 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
5230 insert_reg_alias (str
, regnum
)
5234 struct reg_entry
*new =
5235 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
5236 char *name
= xmalloc (strlen (str
) + 1);
5240 new->number
= regnum
;
5242 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5246 set_constant_flonums ()
5250 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5251 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5261 if ( (arm_ops_hsh
= hash_new ()) == NULL
5262 || (arm_tops_hsh
= hash_new ()) == NULL
5263 || (arm_cond_hsh
= hash_new ()) == NULL
5264 || (arm_shift_hsh
= hash_new ()) == NULL
5265 || (arm_reg_hsh
= hash_new ()) == NULL
5266 || (arm_psr_hsh
= hash_new ()) == NULL
)
5267 as_fatal (_("Virtual memory exhausted"));
5269 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5270 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5271 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5272 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5273 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5274 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5275 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
5276 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
5277 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5278 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5280 for (i
= 0; reg_table
[i
].name
; i
++)
5283 set_constant_flonums ();
5285 #if defined OBJ_COFF || defined OBJ_ELF
5287 unsigned int flags
= 0;
5289 /* Set the flags in the private structure. */
5290 if (uses_apcs_26
) flags
|= F_APCS26
;
5291 if (support_interwork
) flags
|= F_INTERWORK
;
5292 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5293 if (pic_code
) flags
|= F_PIC
;
5294 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5296 bfd_set_private_flags (stdoutput
, flags
);
5300 /* Record the CPU type as well. */
5301 switch (cpu_variant
& ARM_CPU_MASK
)
5304 mach
= bfd_mach_arm_2
;
5307 case ARM_3
: /* Also ARM_250. */
5308 mach
= bfd_mach_arm_2a
;
5312 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5313 mach
= bfd_mach_arm_4
;
5316 case ARM_7
: /* Also ARM_6. */
5317 mach
= bfd_mach_arm_3
;
5321 /* Catch special cases. */
5322 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5324 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5325 mach
= bfd_mach_arm_5T
;
5326 else if (cpu_variant
& ARM_EXT_V5
)
5327 mach
= bfd_mach_arm_5
;
5328 else if (cpu_variant
& ARM_THUMB
)
5329 mach
= bfd_mach_arm_4T
;
5330 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5331 mach
= bfd_mach_arm_4
;
5332 else if (cpu_variant
& ARM_LONGMUL
)
5333 mach
= bfd_mach_arm_3M
;
5336 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5339 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5340 for use in the a.out file, and stores them in the array pointed to by buf.
5341 This knows about the endian-ness of the target machine and does
5342 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5343 2 (short) and 4 (long) Floating numbers are put out as a series of
5344 LITTLENUMS (shorts, here at least). */
5347 md_number_to_chars (buf
, val
, n
)
5352 if (target_big_endian
)
5353 number_to_chars_bigendian (buf
, val
, n
);
5355 number_to_chars_littleendian (buf
, val
, n
);
5359 md_chars_to_number (buf
, n
)
5364 unsigned char * where
= (unsigned char *) buf
;
5366 if (target_big_endian
)
5371 result
|= (*where
++ & 255);
5379 result
|= (where
[n
] & 255);
5386 /* Turn a string in input_line_pointer into a floating point constant
5387 of type TYPE, and store the appropriate bytes in *LITP. The number
5388 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5389 returned, or NULL on OK.
5391 Note that fp constants aren't represent in the normal way on the ARM.
5392 In big endian mode, things are as expected. However, in little endian
5393 mode fp constants are big-endian word-wise, and little-endian byte-wise
5394 within the words. For example, (double) 1.1 in big endian mode is
5395 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5396 the byte sequence 99 99 f1 3f 9a 99 99 99.
5398 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5401 md_atof (type
, litP
, sizeP
)
5407 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5439 return _("Bad call to MD_ATOF()");
5442 t
= atof_ieee (input_line_pointer
, type
, words
);
5444 input_line_pointer
= t
;
5447 if (target_big_endian
)
5449 for (i
= 0; i
< prec
; i
++)
5451 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5457 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5458 8 byte float the order is 1 0 3 2. */
5459 for (i
= 0; i
< prec
; i
+= 2)
5461 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5462 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5470 /* The knowledge of the PC's pipeline offset is built into the insns
5474 md_pcrel_from (fixP
)
5478 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5479 && fixP
->fx_subsy
== NULL
)
5482 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5484 /* PC relative addressing on the Thumb is slightly odd
5485 as the bottom two bits of the PC are forced to zero
5486 for the calculation. */
5487 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5491 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5492 so we un-adjust here to compensate for the accomodation. */
5493 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5495 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5499 /* Round up a section size to the appropriate boundary. */
5502 md_section_align (segment
, size
)
5503 segT segment ATTRIBUTE_UNUSED
;
5509 /* Round all sects to multiple of 4. */
5510 return (size
+ 3) & ~3;
5514 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
5515 Otherwise we have no need to default values of symbols. */
5518 md_undefined_symbol (name
)
5519 char * name ATTRIBUTE_UNUSED
;
5522 if (name
[0] == '_' && name
[1] == 'G'
5523 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5527 if (symbol_find (name
))
5528 as_bad ("GOT already in the symbol table");
5530 GOT_symbol
= symbol_new (name
, undefined_section
,
5531 (valueT
) 0, & zero_address_frag
);
5541 /* arm_reg_parse () := if it looks like a register, return its token and
5542 advance the pointer. */
5546 register char ** ccp
;
5548 char * start
= * ccp
;
5551 struct reg_entry
* reg
;
5553 #ifdef REGISTER_PREFIX
5554 if (*start
!= REGISTER_PREFIX
)
5559 #ifdef OPTIONAL_REGISTER_PREFIX
5560 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5564 if (!isalpha (*p
) || !is_name_beginner (*p
))
5568 while (isalpha (c
) || isdigit (c
) || c
== '_')
5572 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5585 md_apply_fix3 (fixP
, val
, seg
)
5590 offsetT value
= * val
;
5592 unsigned int newimm
;
5595 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5596 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5598 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5600 /* Note whether this will delete the relocation. */
5602 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
5603 doesn't work fully.) */
5604 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5607 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5611 /* If this symbol is in a different section then we need to leave it for
5612 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5613 so we have to undo it's effects here. */
5616 if (fixP
->fx_addsy
!= NULL
5617 && S_IS_DEFINED (fixP
->fx_addsy
)
5618 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5621 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5622 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5626 value
+= md_pcrel_from (fixP
);
5630 /* Remember value for emit_reloc. */
5631 fixP
->fx_addnumber
= value
;
5633 switch (fixP
->fx_r_type
)
5635 case BFD_RELOC_ARM_IMMEDIATE
:
5636 newimm
= validate_immediate (value
);
5637 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5639 /* If the instruction will fail, see if we can fix things up by
5640 changing the opcode. */
5641 if (newimm
== (unsigned int) FAIL
5642 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5644 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5645 _("invalid constant (%lx) after fixup"),
5646 (unsigned long) value
);
5650 newimm
|= (temp
& 0xfffff000);
5651 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5654 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5656 unsigned int highpart
= 0;
5657 unsigned int newinsn
= 0xe1a00000; /* nop. */
5658 newimm
= validate_immediate (value
);
5659 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5661 /* If the instruction will fail, see if we can fix things up by
5662 changing the opcode. */
5663 if (newimm
== (unsigned int) FAIL
5664 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5666 /* No ? OK - try using two ADD instructions to generate
5668 newimm
= validate_immediate_twopart (value
, & highpart
);
5670 /* Yes - then make sure that the second instruction is
5672 if (newimm
!= (unsigned int) FAIL
)
5674 /* Still No ? Try using a negated value. */
5675 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
5676 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5677 /* Otherwise - give up. */
5680 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5681 _("Unable to compute ADRL instructions for PC offset of 0x%x"),
5686 /* Replace the first operand in the 2nd instruction (which
5687 is the PC) with the destination register. We have
5688 already added in the PC in the first instruction and we
5689 do not want to do it again. */
5690 newinsn
&= ~ 0xf0000;
5691 newinsn
|= ((newinsn
& 0x0f000) << 4);
5694 newimm
|= (temp
& 0xfffff000);
5695 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5697 highpart
|= (newinsn
& 0xfffff000);
5698 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5702 case BFD_RELOC_ARM_OFFSET_IMM
:
5708 if (validate_offset_imm (value
, 0) == FAIL
)
5710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5711 _("bad immediate value for offset (%ld)"),
5716 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5717 newval
&= 0xff7ff000;
5718 newval
|= value
| (sign
? INDEX_UP
: 0);
5719 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5722 case BFD_RELOC_ARM_OFFSET_IMM8
:
5723 case BFD_RELOC_ARM_HWLITERAL
:
5729 if (validate_offset_imm (value
, 1) == FAIL
)
5731 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5733 _("invalid literal constant: pool needs to be closer"));
5735 as_bad (_("bad immediate value for half-word offset (%ld)"),
5740 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5741 newval
&= 0xff7ff0f0;
5742 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5743 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5746 case BFD_RELOC_ARM_LITERAL
:
5752 if (validate_offset_imm (value
, 0) == FAIL
)
5754 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5755 _("invalid literal constant: pool needs to be closer"));
5759 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5760 newval
&= 0xff7ff000;
5761 newval
|= value
| (sign
? INDEX_UP
: 0);
5762 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5765 case BFD_RELOC_ARM_SHIFT_IMM
:
5766 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5767 if (((unsigned long) value
) > 32
5769 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5771 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5772 _("shift expression is too large"));
5777 /* Shifts of zero must be done as lsl. */
5779 else if (value
== 32)
5781 newval
&= 0xfffff07f;
5782 newval
|= (value
& 0x1f) << 7;
5783 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5786 case BFD_RELOC_ARM_SWI
:
5787 if (arm_data
->thumb_mode
)
5789 if (((unsigned long) value
) > 0xff)
5790 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5791 _("Invalid swi expression"));
5792 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5794 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5798 if (((unsigned long) value
) > 0x00ffffff)
5799 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5800 _("Invalid swi expression"));
5801 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5803 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5807 case BFD_RELOC_ARM_MULTI
:
5808 if (((unsigned long) value
) > 0xffff)
5809 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5810 _("Invalid expression in load/store multiple"));
5811 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5812 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5815 case BFD_RELOC_ARM_PCREL_BRANCH
:
5816 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5818 /* Sign-extend a 24-bit number. */
5819 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5823 value
= fixP
->fx_offset
;
5826 /* We are going to store value (shifted right by two) in the
5827 instruction, in a 24 bit, signed field. Thus we need to check
5828 that none of the top 8 bits of the shifted value (top 7 bits of
5829 the unshifted, unsigned value) are set, or that they are all set. */
5830 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5831 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5834 /* Normally we would be stuck at this point, since we cannot store
5835 the absolute address that is the destination of the branch in the
5836 24 bits of the branch instruction. If however, we happen to know
5837 that the destination of the branch is in the same section as the
5838 branch instruciton itself, then we can compute the relocation for
5839 ourselves and not have to bother the linker with it.
5841 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5842 because I have not worked out how to do this for OBJ_COFF or
5845 && fixP
->fx_addsy
!= NULL
5846 && S_IS_DEFINED (fixP
->fx_addsy
)
5847 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5849 /* Get pc relative value to go into the branch. */
5852 /* Permit a backward branch provided that enough bits
5853 are set. Allow a forwards branch, provided that
5854 enough bits are clear. */
5855 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5856 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5860 if (! fixP
->fx_done
)
5862 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5863 _("gas can't handle same-section branch dest >= 0x04000000"));
5867 value
+= SEXT24 (newval
);
5869 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
5870 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5871 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5872 _("out of range branch"));
5874 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5875 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5878 case BFD_RELOC_ARM_PCREL_BLX
:
5881 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5885 value
= fixP
->fx_offset
;
5887 hbit
= (value
>> 1) & 1;
5888 value
= (value
>> 2) & 0x00ffffff;
5889 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5890 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5891 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5895 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
5896 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5898 addressT diff
= (newval
& 0xff) << 1;
5903 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5904 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5905 _("Branch out of range"));
5906 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5908 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5911 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
5912 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5914 addressT diff
= (newval
& 0x7ff) << 1;
5919 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5920 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5921 _("Branch out of range"));
5922 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5924 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5927 case BFD_RELOC_THUMB_PCREL_BLX
:
5928 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5933 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5934 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5935 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5936 if (diff
& 0x400000)
5939 value
= fixP
->fx_offset
;
5942 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5943 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5944 _("Branch with link out of range"));
5946 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5947 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5948 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5949 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5954 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5955 md_number_to_chars (buf
, value
, 1);
5957 else if (!target_oabi
)
5959 value
= fixP
->fx_offset
;
5960 md_number_to_chars (buf
, value
, 1);
5966 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5967 md_number_to_chars (buf
, value
, 2);
5969 else if (!target_oabi
)
5971 value
= fixP
->fx_offset
;
5972 md_number_to_chars (buf
, value
, 2);
5978 case BFD_RELOC_ARM_GOT32
:
5979 case BFD_RELOC_ARM_GOTOFF
:
5980 md_number_to_chars (buf
, 0, 4);
5986 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5987 md_number_to_chars (buf
, value
, 4);
5989 else if (!target_oabi
)
5991 value
= fixP
->fx_offset
;
5992 md_number_to_chars (buf
, value
, 4);
5998 case BFD_RELOC_ARM_PLT32
:
5999 /* It appears the instruction is fully prepared at this point. */
6003 case BFD_RELOC_ARM_GOTPC
:
6004 md_number_to_chars (buf
, value
, 4);
6007 case BFD_RELOC_ARM_CP_OFF_IMM
:
6009 if (value
< -1023 || value
> 1023 || (value
& 3))
6010 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6011 _("Illegal value for co-processor offset"));
6014 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
6015 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
6016 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6019 case BFD_RELOC_ARM_THUMB_OFFSET
:
6020 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6021 /* Exactly what ranges, and where the offset is inserted depends
6022 on the type of instruction, we can establish this from the
6024 switch (newval
>> 12)
6026 case 4: /* PC load. */
6027 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
6028 forced to zero for these loads, so we will need to round
6029 up the offset if the instruction address is not word
6030 aligned (since the final address produced must be, and
6031 we can only describe word-aligned immediate offsets). */
6033 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
6034 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6035 _("Invalid offset, target not word aligned (0x%08X)"),
6036 (unsigned int) (fixP
->fx_frag
->fr_address
6037 + fixP
->fx_where
+ value
));
6039 if ((value
+ 2) & ~0x3fe)
6040 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6041 _("Invalid offset, value too big (0x%08X)"), value
);
6043 /* Round up, since pc will be rounded down. */
6044 newval
|= (value
+ 2) >> 2;
6047 case 9: /* SP load/store. */
6049 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6050 _("Invalid offset, value too big (0x%08X)"), value
);
6051 newval
|= value
>> 2;
6054 case 6: /* Word load/store. */
6056 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6057 _("Invalid offset, value too big (0x%08X)"), value
);
6058 newval
|= value
<< 4; /* 6 - 2. */
6061 case 7: /* Byte load/store. */
6063 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6064 _("Invalid offset, value too big (0x%08X)"), value
);
6065 newval
|= value
<< 6;
6068 case 8: /* Halfword load/store. */
6070 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6071 _("Invalid offset, value too big (0x%08X)"), value
);
6072 newval
|= value
<< 5; /* 6 - 1. */
6076 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6077 "Unable to process relocation for thumb opcode: %lx",
6078 (unsigned long) newval
);
6081 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6084 case BFD_RELOC_ARM_THUMB_ADD
:
6085 /* This is a complicated relocation, since we use it for all of
6086 the following immediate relocations:
6090 9bit ADD/SUB SP word-aligned
6091 10bit ADD PC/SP word-aligned
6093 The type of instruction being processed is encoded in the
6100 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6102 int rd
= (newval
>> 4) & 0xf;
6103 int rs
= newval
& 0xf;
6104 int subtract
= newval
& 0x8000;
6109 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6110 _("Invalid immediate for stack address calculation"));
6111 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6112 newval
|= value
>> 2;
6114 else if (rs
== REG_PC
|| rs
== REG_SP
)
6118 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6119 _("Invalid immediate for address calculation (value = 0x%08lX)"),
6120 (unsigned long) value
);
6121 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
6123 newval
|= value
>> 2;
6128 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6129 _("Invalid 8bit immediate"));
6130 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6131 newval
|= (rd
<< 8) | value
;
6136 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6137 _("Invalid 3bit immediate"));
6138 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6139 newval
|= rd
| (rs
<< 3) | (value
<< 6);
6142 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6145 case BFD_RELOC_ARM_THUMB_IMM
:
6146 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
6147 switch (newval
>> 11)
6149 case 0x04: /* 8bit immediate MOV. */
6150 case 0x05: /* 8bit immediate CMP. */
6151 if (value
< 0 || value
> 255)
6152 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6153 _("Invalid immediate: %ld is too large"),
6161 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6164 case BFD_RELOC_ARM_THUMB_SHIFT
:
6165 /* 5bit shift value (0..31). */
6166 if (value
< 0 || value
> 31)
6167 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6168 _("Illegal Thumb shift value: %ld"), (long) value
);
6169 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
6170 newval
|= value
<< 6;
6171 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6174 case BFD_RELOC_VTABLE_INHERIT
:
6175 case BFD_RELOC_VTABLE_ENTRY
:
6179 case BFD_RELOC_NONE
:
6181 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6182 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6188 /* Translate internal representation of relocation info to BFD target
6192 tc_gen_reloc (section
, fixp
)
6193 asection
* section ATTRIBUTE_UNUSED
;
6197 bfd_reloc_code_real_type code
;
6199 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
6201 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6202 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6203 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6205 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
6207 if (fixp
->fx_pcrel
== 0)
6208 reloc
->addend
= fixp
->fx_offset
;
6210 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6212 reloc
->addend
= fixp
->fx_offset
;
6215 switch (fixp
->fx_r_type
)
6220 code
= BFD_RELOC_8_PCREL
;
6227 code
= BFD_RELOC_16_PCREL
;
6234 code
= BFD_RELOC_32_PCREL
;
6238 case BFD_RELOC_ARM_PCREL_BRANCH
:
6239 case BFD_RELOC_ARM_PCREL_BLX
:
6241 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6242 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6243 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6244 case BFD_RELOC_THUMB_PCREL_BLX
:
6245 case BFD_RELOC_VTABLE_ENTRY
:
6246 case BFD_RELOC_VTABLE_INHERIT
:
6247 code
= fixp
->fx_r_type
;
6250 case BFD_RELOC_ARM_LITERAL
:
6251 case BFD_RELOC_ARM_HWLITERAL
:
6252 /* If this is called then the a literal has been referenced across
6253 a section boundary - possibly due to an implicit dump. */
6254 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6255 _("Literal referenced across section boundary (Implicit dump?)"));
6259 case BFD_RELOC_ARM_GOT32
:
6260 case BFD_RELOC_ARM_GOTOFF
:
6261 case BFD_RELOC_ARM_PLT32
:
6262 code
= fixp
->fx_r_type
;
6266 case BFD_RELOC_ARM_IMMEDIATE
:
6267 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6268 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6272 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6273 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6274 _("ADRL used for a symbol not defined in the same file"),
6278 case BFD_RELOC_ARM_OFFSET_IMM
:
6279 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6280 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6288 switch (fixp
->fx_r_type
)
6290 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6291 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6292 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6293 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6294 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6295 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6296 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6297 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6298 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6299 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6300 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6301 default: type
= _("<unknown>"); break;
6303 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6304 _("Cannot represent %s relocation in this object file format"),
6311 if (code
== BFD_RELOC_32_PCREL
6313 && fixp
->fx_addsy
== GOT_symbol
)
6315 code
= BFD_RELOC_ARM_GOTPC
;
6316 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6320 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6322 if (reloc
->howto
== NULL
)
6324 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6325 _("Can not represent %s relocation in this object file format"),
6326 bfd_get_reloc_code_name (code
));
6330 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6331 vtable entry to be used in the relocation's section offset. */
6332 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6333 reloc
->address
= fixp
->fx_offset
;
6339 md_estimate_size_before_relax (fragP
, segtype
)
6340 fragS
* fragP ATTRIBUTE_UNUSED
;
6341 segT segtype ATTRIBUTE_UNUSED
;
6343 as_fatal (_("md_estimate_size_before_relax\n"));
6348 output_inst
PARAMS ((void))
6354 as_bad (inst
.error
);
6358 to
= frag_more (inst
.size
);
6360 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6362 assert (inst
.size
== (2 * THUMB_SIZE
));
6363 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6364 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6366 else if (inst
.size
> INSN_SIZE
)
6368 assert (inst
.size
== (2 * INSN_SIZE
));
6369 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6370 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6373 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6375 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6376 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6377 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6381 dwarf2_emit_insn (inst
.size
);
6394 /* Align the instruction.
6395 This may not be the right thing to do but ... */
6399 listing_prev_line (); /* Defined in listing.h. */
6401 /* Align the previous label if needed. */
6402 if (last_label_seen
!= NULL
)
6404 symbol_set_frag (last_label_seen
, frag_now
);
6405 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6406 S_SET_SEGMENT (last_label_seen
, now_seg
);
6409 memset (&inst
, '\0', sizeof (inst
));
6410 inst
.reloc
.type
= BFD_RELOC_NONE
;
6412 skip_whitespace (str
);
6414 /* Scan up to the end of the op-code, which must end in white space or
6416 for (start
= p
= str
; *p
!= '\0'; p
++)
6422 as_bad (_("No operator -- statement `%s'\n"), str
);
6428 CONST
struct thumb_opcode
* opcode
;
6432 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6437 /* Check that this instruction is supported for this CPU. */
6438 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6440 as_bad (_("selected processor does not support this opcode"));
6444 inst
.instruction
= opcode
->value
;
6445 inst
.size
= opcode
->size
;
6446 (*opcode
->parms
) (p
);
6453 CONST
struct asm_opcode
* opcode
;
6454 unsigned long cond_code
;
6456 inst
.size
= INSN_SIZE
;
6457 /* P now points to the end of the opcode, probably white space, but we
6458 have to break the opcode up in case it contains condionals and flags;
6459 keep trying with progressively smaller basic instructions until one
6460 matches, or we run out of opcode. */
6461 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6463 for (; q
!= str
; q
--)
6468 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6471 if (opcode
&& opcode
->template)
6473 unsigned long flag_bits
= 0;
6476 /* Check that this instruction is supported for this CPU. */
6477 if ((opcode
->variants
& cpu_variant
) == 0)
6480 inst
.instruction
= opcode
->value
;
6481 if (q
== p
) /* Just a simple opcode. */
6483 if (opcode
->comp_suffix
)
6485 if (*opcode
->comp_suffix
!= '\0')
6486 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6487 str
, opcode
->comp_suffix
);
6489 /* Not a conditional instruction. */
6490 (*opcode
->parms
) (q
, 0);
6494 /* A conditional instruction with default condition. */
6495 inst
.instruction
|= COND_ALWAYS
;
6496 (*opcode
->parms
) (q
, 0);
6502 /* Not just a simple opcode. Check if extra is a
6507 CONST
struct asm_cond
*cond
;
6511 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6515 if (cond
->value
== 0xf0000000)
6517 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6519 cond_code
= cond
->value
;
6523 cond_code
= COND_ALWAYS
;
6526 cond_code
= COND_ALWAYS
;
6528 /* Apply the conditional, or complain it's not allowed. */
6529 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6531 /* Instruction isn't conditional. */
6532 if (cond_code
!= COND_ALWAYS
)
6534 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6539 /* Instruction is conditional: set the condition into it. */
6540 inst
.instruction
|= cond_code
;
6542 /* If there is a compulsory suffix, it should come here
6543 before any optional flags. */
6544 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6546 CONST
char *s
= opcode
->comp_suffix
;
6558 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
6559 str
, opcode
->comp_suffix
);
6566 /* The remainder, if any should now be flags for the instruction;
6567 Scan these checking each one found with the opcode. */
6571 CONST
struct asm_flg
*flag
= opcode
->flags
;
6580 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6582 if (streq (r
, flag
[flagno
].template))
6584 flag_bits
|= flag
[flagno
].set_bits
;
6590 if (! flag
[flagno
].template)
6597 (*opcode
->parms
) (p
, flag_bits
);
6607 /* It wasn't an instruction, but it might be a register alias of the form
6610 skip_whitespace (q
);
6615 if (*q
&& !strncmp (q
, ".req ", 4))
6621 #ifdef IGNORE_OPCODE_CASE
6622 str
= original_case_string
;
6627 skip_whitespace (q
);
6629 for (r
= q
; *r
!= '\0'; r
++)
6639 regnum
= arm_reg_parse (& q
);
6642 reg
= arm_reg_parse (& str
);
6647 insert_reg_alias (str
, regnum
);
6649 as_warn (_("register '%s' does not exist\n"), q
);
6651 else if (regnum
!= FAIL
)
6654 as_warn (_("ignoring redefinition of register alias '%s'"),
6657 /* Do not warn about redefinitions to the same alias. */
6660 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6664 as_warn (_("ignoring incomplete .req pseuso op"));
6671 as_bad (_("bad instruction `%s'"), start
);
6675 Invocation line includes a switch not recognized by the base assembler.
6676 See if it's a processor-specific option. These are:
6677 Cpu variants, the arm part is optional:
6678 -m[arm]1 Currently not supported.
6679 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6680 -m[arm]3 Arm 3 processor
6681 -m[arm]6[xx], Arm 6 processors
6682 -m[arm]7[xx][t][[d]m] Arm 7 processors
6683 -m[arm]8[10] Arm 8 processors
6684 -m[arm]9[20][tdmi] Arm 9 processors
6685 -mstrongarm[110[0]] StrongARM processors
6686 -m[arm]v[2345[t]] Arm architectures
6687 -mall All (except the ARM1)
6689 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6690 -mfpe-old (No float load/store multiples)
6691 -mno-fpu Disable all floating point instructions
6692 Run-time endian selection:
6694 -EL little endian cpu
6695 ARM Procedure Calling Standard:
6696 -mapcs-32 32 bit APCS
6697 -mapcs-26 26 bit APCS
6698 -mapcs-float Pass floats in float regs
6699 -mapcs-reentrant Position independent code
6700 -mthumb-interwork Code supports Arm/Thumb interworking
6701 -moabi Old ELF ABI */
6703 CONST
char * md_shortopts
= "m:k";
6705 struct option md_longopts
[] =
6707 #ifdef ARM_BI_ENDIAN
6708 #define OPTION_EB (OPTION_MD_BASE + 0)
6709 {"EB", no_argument
, NULL
, OPTION_EB
},
6710 #define OPTION_EL (OPTION_MD_BASE + 1)
6711 {"EL", no_argument
, NULL
, OPTION_EL
},
6713 #define OPTION_OABI (OPTION_MD_BASE +2)
6714 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6717 {NULL
, no_argument
, NULL
, 0}
6720 size_t md_longopts_size
= sizeof (md_longopts
);
6723 md_parse_option (c
, arg
)
6731 #ifdef ARM_BI_ENDIAN
6733 target_big_endian
= 1;
6736 target_big_endian
= 0;
6744 if (streq (str
, "fpa10"))
6745 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6746 else if (streq (str
, "fpa11"))
6747 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6748 else if (streq (str
, "fpe-old"))
6749 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6755 if (streq (str
, "no-fpu"))
6756 cpu_variant
&= ~FPU_ALL
;
6761 if (streq (str
, "oabi"))
6767 /* Limit assembler to generating only Thumb instructions: */
6768 if (streq (str
, "thumb"))
6770 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6771 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6774 else if (streq (str
, "thumb-interwork"))
6776 if ((cpu_variant
& ARM_THUMB
) == 0)
6777 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6778 #if defined OBJ_COFF || defined OBJ_ELF
6779 support_interwork
= true;
6787 if (streq (str
, "all"))
6789 cpu_variant
= ARM_ALL
| FPU_ALL
;
6792 #if defined OBJ_COFF || defined OBJ_ELF
6793 if (! strncmp (str
, "apcs-", 5))
6795 /* GCC passes on all command line options starting "-mapcs-..."
6796 to us, so we must parse them here. */
6800 if (streq (str
, "32"))
6802 uses_apcs_26
= false;
6805 else if (streq (str
, "26"))
6807 uses_apcs_26
= true;
6810 else if (streq (str
, "frame"))
6812 /* Stack frames are being generated - does not affect
6816 else if (streq (str
, "stack-check"))
6818 /* Stack checking is being performed - does not affect
6819 linkage, but does require that the functions
6820 __rt_stkovf_split_small and __rt_stkovf_split_big be
6821 present in the final link. */
6825 else if (streq (str
, "float"))
6827 /* Floating point arguments are being passed in the floating
6828 point registers. This does affect linking, since this
6829 version of the APCS is incompatible with the version that
6830 passes floating points in the integer registers. */
6832 uses_apcs_float
= true;
6835 else if (streq (str
, "reentrant"))
6837 /* Reentrant code has been generated. This does affect
6838 linking, since there is no point in linking reentrant/
6839 position independent code with absolute position code. */
6844 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6848 /* Strip off optional "arm". */
6849 if (! strncmp (str
, "arm", 3))
6855 if (streq (str
, "1"))
6856 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6862 if (streq (str
, "2"))
6863 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6864 else if (streq (str
, "250"))
6865 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6871 if (streq (str
, "3"))
6872 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6878 switch (strtol (str
, NULL
, 10))
6885 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6893 /* Eat the processor name. */
6894 switch (strtol (str
, & str
, 10))
6907 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6913 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6917 cpu_variant
|= ARM_LONGMUL
;
6920 case 'f': /* fe => fp enabled cpu. */
6926 case 'c': /* Left over from 710c processor name. */
6927 case 'd': /* Debug. */
6928 case 'i': /* Embedded ICE. */
6929 /* Included for completeness in ARM processor naming. */
6939 if (streq (str
, "8") || streq (str
, "810"))
6940 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6941 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6947 if (streq (str
, "9"))
6948 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6949 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6950 else if (streq (str
, "920"))
6951 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6952 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6953 else if (streq (str
, "920t"))
6954 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6955 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6956 else if (streq (str
, "9tdmi"))
6957 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6958 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6964 if (streq (str
, "strongarm")
6965 || streq (str
, "strongarm110")
6966 || streq (str
, "strongarm1100"))
6967 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6968 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6974 /* Select variant based on architecture rather than
6982 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6985 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6988 as_bad (_("Invalid architecture variant -m%s"), arg
);
6994 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6998 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
7001 as_bad (_("Invalid architecture variant -m%s"), arg
);
7007 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
7011 case 't': cpu_variant
|= ARM_THUMB
; break;
7014 as_bad (_("Invalid architecture variant -m%s"), arg
);
7020 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
7023 case 't': cpu_variant
|= ARM_THUMB
; break;
7026 as_bad (_("Invalid architecture variant -m%s"), arg
);
7032 as_bad (_("Invalid architecture variant -m%s"), arg
);
7039 as_bad (_("Invalid processor variant -m%s"), arg
);
7045 #if defined OBJ_ELF || defined OBJ_COFF
7063 ARM Specific Assembler Options:\n\
7064 -m[arm][<processor name>] select processor variant\n\
7065 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
7066 -mthumb only allow Thumb instructions\n\
7067 -mthumb-interwork mark the assembled code as supporting interworking\n\
7068 -mall allow any instruction\n\
7069 -mfpa10, -mfpa11 select floating point architecture\n\
7070 -mfpe-old don't allow floating-point multiple instructions\n\
7071 -mno-fpu don't allow any floating-point instructions.\n\
7072 -k generate PIC code.\n"));
7073 #if defined OBJ_COFF || defined OBJ_ELF
7075 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
7076 -mapcs-float floating point args are passed in FP regs\n\
7077 -mapcs-reentrant the code is position independent/reentrant\n"));
7081 -moabi support the old ELF ABI\n"));
7083 #ifdef ARM_BI_ENDIAN
7085 -EB assemble code for a big endian cpu\n\
7086 -EL assemble code for a little endian cpu\n"));
7090 /* We need to be able to fix up arbitrary expressions in some statements.
7091 This is so that we can handle symbols that are an arbitrary distance from
7092 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
7093 which returns part of an address in a form which will be valid for
7094 a data instruction. We do this by pushing the expression into a symbol
7095 in the expr_section, and creating a fix for that. */
7098 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
7107 arm_fix_data
* arm_data
;
7115 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
7119 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
7124 /* Mark whether the fix is to a THUMB instruction, or an ARM
7126 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
7127 new_fix
->tc_fix_data
= (PTR
) arm_data
;
7128 arm_data
->thumb_mode
= thumb_mode
;
7133 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
7136 cons_fix_new_arm (frag
, where
, size
, exp
)
7142 bfd_reloc_code_real_type type
;
7146 FIXME: @@ Should look at CPU word size. */
7153 type
= BFD_RELOC_16
;
7157 type
= BFD_RELOC_32
;
7160 type
= BFD_RELOC_64
;
7164 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
7167 /* A good place to do this, although this was probably not intended
7168 for this kind of use. We need to dump the literal pool before
7169 references are made to a null symbol pointer. */
7174 if (current_poolP
== NULL
)
7177 /* Put it at the end of text section. */
7178 subseg_set (text_section
, 0);
7180 listing_prev_line ();
7184 arm_start_line_hook ()
7186 last_label_seen
= NULL
;
7190 arm_frob_label (sym
)
7193 last_label_seen
= sym
;
7195 ARM_SET_THUMB (sym
, thumb_mode
);
7197 #if defined OBJ_COFF || defined OBJ_ELF
7198 ARM_SET_INTERWORK (sym
, support_interwork
);
7201 if (label_is_thumb_function_name
)
7203 /* When the address of a Thumb function is taken the bottom
7204 bit of that address should be set. This will allow
7205 interworking between Arm and Thumb functions to work
7208 THUMB_SET_FUNC (sym
, 1);
7210 label_is_thumb_function_name
= false;
7214 /* Adjust the symbol table. This marks Thumb symbols as distinct from
7218 arm_adjust_symtab ()
7223 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7225 if (ARM_IS_THUMB (sym
))
7227 if (THUMB_IS_FUNC (sym
))
7229 /* Mark the symbol as a Thumb function. */
7230 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
7231 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
7232 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
7234 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
7235 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
7237 as_bad (_("%s: unexpected function type: %d"),
7238 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
7240 else switch (S_GET_STORAGE_CLASS (sym
))
7243 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
7246 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7249 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7257 if (ARM_IS_INTERWORK (sym
))
7258 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7265 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7267 if (ARM_IS_THUMB (sym
))
7269 elf_symbol_type
* elf_sym
;
7271 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7272 bind
= ELF_ST_BIND (elf_sym
);
7274 /* If it's a .thumb_func, declare it as so,
7275 otherwise tag label as .code 16. */
7276 if (THUMB_IS_FUNC (sym
))
7277 elf_sym
->internal_elf_sym
.st_info
=
7278 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7280 elf_sym
->internal_elf_sym
.st_info
=
7281 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7290 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7292 *input_line_pointer
= '/';
7293 input_line_pointer
+= 5;
7294 *input_line_pointer
= 0;
7302 arm_canonicalize_symbol_name (name
)
7307 if (thumb_mode
&& (len
= strlen (name
)) > 5
7308 && streq (name
+ len
- 5, "/data"))
7309 *(name
+ len
- 5) = 0;
7315 arm_validate_fix (fixP
)
7318 /* If the destination of the branch is a defined symbol which does not have
7319 the THUMB_FUNC attribute, then we must be calling a function which has
7320 the (interfacearm) attribute. We look for the Thumb entry point to that
7321 function and change the branch to refer to that function instead. */
7322 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7323 && fixP
->fx_addsy
!= NULL
7324 && S_IS_DEFINED (fixP
->fx_addsy
)
7325 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7327 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7335 /* Relocations against Thumb function names must be left unadjusted,
7336 so that the linker can use this information to correctly set the
7337 bottom bit of their addresses. The MIPS version of this function
7338 also prevents relocations that are mips-16 specific, but I do not
7339 know why it does this.
7342 There is one other problem that ought to be addressed here, but
7343 which currently is not: Taking the address of a label (rather
7344 than a function) and then later jumping to that address. Such
7345 addresses also ought to have their bottom bit set (assuming that
7346 they reside in Thumb code), but at the moment they will not. */
7349 arm_fix_adjustable (fixP
)
7352 if (fixP
->fx_addsy
== NULL
)
7355 /* Prevent all adjustments to global symbols. */
7356 if (S_IS_EXTERN (fixP
->fx_addsy
))
7359 if (S_IS_WEAK (fixP
->fx_addsy
))
7362 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7363 && fixP
->fx_subsy
== NULL
)
7366 /* We need the symbol name for the VTABLE entries. */
7367 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7368 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7375 elf32_arm_target_format ()
7377 if (target_big_endian
)
7380 return "elf32-bigarm-oabi";
7382 return "elf32-bigarm";
7387 return "elf32-littlearm-oabi";
7389 return "elf32-littlearm";
7394 armelf_frob_symbol (symp
, puntp
)
7398 elf_frob_symbol (symp
, puntp
);
7402 arm_force_relocation (fixp
)
7405 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7406 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7407 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7408 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7409 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7410 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7416 static bfd_reloc_code_real_type
7426 bfd_reloc_code_real_type reloc
;
7430 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
7431 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7432 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7433 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
7434 branch instructions generated by GCC for PLT relocs. */
7435 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7436 { NULL
, 0, BFD_RELOC_UNUSED
}
7440 for (i
= 0, ip
= input_line_pointer
;
7441 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7443 id
[i
] = tolower (*ip
);
7445 for (i
= 0; reloc_map
[i
].str
; i
++)
7446 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7449 input_line_pointer
+= reloc_map
[i
].len
;
7451 return reloc_map
[i
].reloc
;
7455 s_arm_elf_cons (nbytes
)
7460 #ifdef md_flush_pending_output
7461 md_flush_pending_output ();
7464 if (is_it_end_of_statement ())
7466 demand_empty_rest_of_line ();
7470 #ifdef md_cons_align
7471 md_cons_align (nbytes
);
7476 bfd_reloc_code_real_type reloc
;
7480 if (exp
.X_op
== O_symbol
7481 && * input_line_pointer
== '('
7482 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
7484 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7485 int size
= bfd_get_reloc_size (howto
);
7488 as_bad ("%s relocations do not fit in %d bytes",
7489 howto
->name
, nbytes
);
7492 register char *p
= frag_more ((int) nbytes
);
7493 int offset
= nbytes
- size
;
7495 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7500 emit_expr (&exp
, (unsigned int) nbytes
);
7502 while (*input_line_pointer
++ == ',');
7504 /* Put terminator back into stream. */
7505 input_line_pointer
--;
7506 demand_empty_rest_of_line ();
7509 #endif /* OBJ_ELF */