1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
55 #define ARM_EXT_V5E 0x00000200 /* "El Segundo" */
57 /* Architectures are the sum of the base and extensions */
58 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
60 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5 )
61 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP (ARM_ANY - ARM_1)
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #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
[] = "#";
120 CONST
char line_separator_chars
[] = ";";
122 CONST
char line_separator_chars
[] = "";
125 /* Chars that can be used to separate mant from exp in floating point nums */
126 CONST
char EXP_CHARS
[] = "eE";
128 /* Chars that mean this number is a floating point constant */
132 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
134 /* Prefix characters that indicate the start of an immediate
136 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
139 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
142 CONST
int md_reloc_size
= 8; /* Size of relocation record */
144 static int thumb_mode
= 0; /* 0: assemble for ARM, 1: assemble for Thumb,
145 2: assemble for Thumb even though target cpu
146 does not support thumb instructions */
147 typedef struct arm_fix
155 unsigned long instruction
;
160 bfd_reloc_code_real_type type
;
170 CONST
char * template;
174 static CONST
struct asm_shift shift
[] =
190 #define NO_SHIFT_RESTRICT 1
191 #define SHIFT_RESTRICT 0
193 #define NUM_FLOAT_VALS 8
195 CONST
char * fp_const
[] =
197 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
200 /* Number of littlenums required to hold an extended precision number */
201 #define MAX_LITTLENUMS 6
203 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
213 #define CP_T_X 0x00008000
214 #define CP_T_Y 0x00400000
215 #define CP_T_Pre 0x01000000
216 #define CP_T_UD 0x00800000
217 #define CP_T_WB 0x00200000
219 #define CONDS_BIT (0x00100000)
220 #define LOAD_BIT (0x00100000)
221 #define TRANS_BIT (0x00200000)
225 CONST
char * template;
229 /* This is to save a hash look-up in the common case */
230 #define COND_ALWAYS 0xe0000000
232 static CONST
struct asm_cond conds
[] =
236 {"cs", 0x20000000}, {"hs", 0x20000000},
237 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
252 /* Warning: If the top bit of the set_bits is set, then the standard
253 instruction bitmask is ignored, and the new bitmask is taken from
257 CONST
char * template; /* Basic flag string */
258 unsigned long set_bits
; /* Bits to set */
261 static CONST
struct asm_flg s_flag
[] =
267 static CONST
struct asm_flg ldr_flags
[] =
271 {"bt", 0x00400000 | TRANS_BIT
},
278 static CONST
struct asm_flg str_flags
[] =
282 {"bt", 0x00400000 | TRANS_BIT
},
287 static CONST
struct asm_flg byte_flag
[] =
293 static CONST
struct asm_flg cmp_flags
[] =
300 static CONST
struct asm_flg ldm_flags
[] =
313 static CONST
struct asm_flg stm_flags
[] =
326 static CONST
struct asm_flg lfm_flags
[] =
333 static CONST
struct asm_flg sfm_flags
[] =
340 static CONST
struct asm_flg round_flags
[] =
348 /* The implementation of the FIX instruction is broken on some assemblers,
349 in that it accepts a precision specifier as well as a rounding specifier,
350 despite the fact that this is meaningless. To be more compatible, we
351 accept it as well, though of course it does not set any bits. */
352 static CONST
struct asm_flg fix_flags
[] =
369 static CONST
struct asm_flg except_flag
[] =
375 static CONST
struct asm_flg cplong_flag
[] =
383 CONST
char * template;
384 unsigned long number
;
387 #define PSR_FIELD_MASK 0x000f0000
389 #define PSR_FLAGS 0x00080000
390 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
391 #define PSR_ALL 0x00090000
400 static CONST
struct asm_psr psrs
[] =
404 {"cpsr_all", CPSR_ALL
},
406 {"spsr_all", SPSR_ALL
},
409 {"cpsr_flg", CPSR_FLG
},
410 {"spsr_flg", SPSR_FLG
},
413 {"cpsr_c", CPSR_CTL
},
414 {"cpsr_ctl", CPSR_CTL
},
415 {"spsr_c", SPSR_CTL
},
416 {"spsr_ctl", SPSR_CTL
}
419 /* Functions called by parser */
420 /* ARM instructions */
421 static void do_arit
PARAMS ((char *, unsigned long));
422 static void do_cmp
PARAMS ((char *, unsigned long));
423 static void do_mov
PARAMS ((char *, unsigned long));
424 static void do_ldst
PARAMS ((char *, unsigned long));
425 static void do_ldmstm
PARAMS ((char *, unsigned long));
426 static void do_branch
PARAMS ((char *, unsigned long));
427 static void do_swi
PARAMS ((char *, unsigned long));
428 /* Pseudo Op codes */
429 static void do_adr
PARAMS ((char *, unsigned long));
430 static void do_adrl
PARAMS ((char *, unsigned long));
431 static void do_nop
PARAMS ((char *, unsigned long));
433 static void do_mul
PARAMS ((char *, unsigned long));
434 static void do_mla
PARAMS ((char *, unsigned long));
436 static void do_swap
PARAMS ((char *, unsigned long));
438 static void do_msr
PARAMS ((char *, unsigned long));
439 static void do_mrs
PARAMS ((char *, unsigned long));
441 static void do_mull
PARAMS ((char *, unsigned long));
443 static void do_bx
PARAMS ((char *, unsigned long));
446 /* Coprocessor Instructions */
447 static void do_cdp
PARAMS ((char *, unsigned long));
448 static void do_lstc
PARAMS ((char *, unsigned long));
449 static void do_co_reg
PARAMS ((char *, unsigned long));
450 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
451 static void do_fp_ldst
PARAMS ((char *, unsigned long));
452 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
453 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
454 static void do_fp_monadic
PARAMS ((char *, unsigned long));
455 static void do_fp_cmp
PARAMS ((char *, unsigned long));
456 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
457 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
459 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
460 static int arm_reg_parse
PARAMS ((char **));
461 static int arm_psr_parse
PARAMS ((char **));
462 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
463 static int add_to_lit_pool
PARAMS ((void));
464 static unsigned validate_immediate
PARAMS ((unsigned));
465 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
466 static int validate_offset_imm
PARAMS ((unsigned int, int));
467 static void opcode_select
PARAMS ((int));
468 static void end_of_line
PARAMS ((char *));
469 static int reg_required_here
PARAMS ((char **, int));
470 static int psr_required_here
PARAMS ((char **, int, int));
471 static int co_proc_number
PARAMS ((char **));
472 static int cp_opc_expr
PARAMS ((char **, int, int));
473 static int cp_reg_required_here
PARAMS ((char **, int));
474 static int fp_reg_required_here
PARAMS ((char **, int));
475 static int cp_address_offset
PARAMS ((char **));
476 static int cp_address_required_here
PARAMS ((char **));
477 static int my_get_float_expression
PARAMS ((char **));
478 static int skip_past_comma
PARAMS ((char **));
479 static int walk_no_bignums
PARAMS ((symbolS
*));
480 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
481 static int data_op2
PARAMS ((char **));
482 static int fp_op2
PARAMS ((char **));
483 static long reg_list
PARAMS ((char **));
484 static void thumb_load_store
PARAMS ((char *, int, int));
485 static int decode_shift
PARAMS ((char **, int));
486 static int ldst_extend
PARAMS ((char **, int));
487 static void thumb_add_sub
PARAMS ((char *, int));
488 static void insert_reg
PARAMS ((int));
489 static void thumb_shift
PARAMS ((char *, int));
490 static void thumb_mov_compare
PARAMS ((char *, int));
491 static void set_constant_flonums
PARAMS ((void));
492 static valueT md_chars_to_number
PARAMS ((char *, int));
493 static void insert_reg_alias
PARAMS ((char *, int));
494 static void output_inst
PARAMS ((void));
496 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
499 /* ARM instructions take 4bytes in the object file, Thumb instructions
503 /* LONGEST_INST is the longest basic instruction name without conditions or
505 * ARM7M has 4 of length 5
508 #define LONGEST_INST 5
513 CONST
char * template; /* Basic string to match */
514 unsigned long value
; /* Basic instruction code */
516 /* Compulsory suffix that must follow conds. If "", then the
517 instruction is not conditional and must have no suffix. */
518 CONST
char * comp_suffix
;
520 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
521 unsigned long variants
; /* Which CPU variants this exists for */
522 /* Function to call to parse args */
523 void (* parms
) PARAMS ((char *, unsigned long));
526 static CONST
struct asm_opcode insns
[] =
528 /* ARM Instructions */
529 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
530 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
531 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
532 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
533 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
534 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
535 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
536 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
537 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
538 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
539 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
540 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
541 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
542 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
543 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
544 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
545 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
546 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
547 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
548 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
549 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
550 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
551 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
554 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
555 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
556 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
558 /* ARM 2 multiplies */
559 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
560 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
562 /* ARM 3 - swp instructions */
563 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
565 /* ARM 6 Coprocessor instructions */
566 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
567 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
568 /* ScottB: our code uses 0x0128f000 for msr.
569 NickC: but this is wrong because the bits 16 and 19 are handled
570 by the PSR_xxx defines above. */
572 /* ARM 7M long multiplies - need signed/unsigned flags! */
573 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
574 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
575 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
576 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
578 /* ARM THUMB interworking */
579 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
581 /* Floating point instructions */
582 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
583 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
584 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
585 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
586 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
587 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
588 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
589 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
590 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
595 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
596 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
597 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
598 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
599 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
600 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
601 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
602 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
603 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
604 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
605 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
607 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
608 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
609 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
610 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
611 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
612 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
613 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
614 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
615 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
616 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
617 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
618 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
619 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
620 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
621 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
622 be an optional suffix, but part of the instruction. To be compatible,
624 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
625 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
626 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
627 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
629 /* Generic copressor instructions */
630 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
631 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
632 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
633 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
634 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
637 /* defines for various bits that we will want to toggle */
639 #define INST_IMMEDIATE 0x02000000
640 #define OFFSET_REG 0x02000000
641 #define HWOFFSET_IMM 0x00400000
642 #define SHIFT_BY_REG 0x00000010
643 #define PRE_INDEX 0x01000000
644 #define INDEX_UP 0x00800000
645 #define WRITE_BACK 0x00200000
646 #define LDM_TYPE_2_OR_3 0x00400000
648 #define LITERAL_MASK 0xf000f000
649 #define COND_MASK 0xf0000000
650 #define OPCODE_MASK 0xfe1fffff
651 #define DATA_OP_SHIFT 21
653 /* Codes to distinguish the arithmetic instructions */
665 #define OPCODE_CMP 10
666 #define OPCODE_CMN 11
667 #define OPCODE_ORR 12
668 #define OPCODE_MOV 13
669 #define OPCODE_BIC 14
670 #define OPCODE_MVN 15
672 static void do_t_nop
PARAMS ((char *));
673 static void do_t_arit
PARAMS ((char *));
674 static void do_t_add
PARAMS ((char *));
675 static void do_t_asr
PARAMS ((char *));
676 static void do_t_branch9
PARAMS ((char *));
677 static void do_t_branch12
PARAMS ((char *));
678 static void do_t_branch23
PARAMS ((char *));
679 static void do_t_bx
PARAMS ((char *));
680 static void do_t_compare
PARAMS ((char *));
681 static void do_t_ldmstm
PARAMS ((char *));
682 static void do_t_ldr
PARAMS ((char *));
683 static void do_t_ldrb
PARAMS ((char *));
684 static void do_t_ldrh
PARAMS ((char *));
685 static void do_t_lds
PARAMS ((char *));
686 static void do_t_lsl
PARAMS ((char *));
687 static void do_t_lsr
PARAMS ((char *));
688 static void do_t_mov
PARAMS ((char *));
689 static void do_t_push_pop
PARAMS ((char *));
690 static void do_t_str
PARAMS ((char *));
691 static void do_t_strb
PARAMS ((char *));
692 static void do_t_strh
PARAMS ((char *));
693 static void do_t_sub
PARAMS ((char *));
694 static void do_t_swi
PARAMS ((char *));
695 static void do_t_adr
PARAMS ((char *));
697 #define T_OPCODE_MUL 0x4340
698 #define T_OPCODE_TST 0x4200
699 #define T_OPCODE_CMN 0x42c0
700 #define T_OPCODE_NEG 0x4240
701 #define T_OPCODE_MVN 0x43c0
703 #define T_OPCODE_ADD_R3 0x1800
704 #define T_OPCODE_SUB_R3 0x1a00
705 #define T_OPCODE_ADD_HI 0x4400
706 #define T_OPCODE_ADD_ST 0xb000
707 #define T_OPCODE_SUB_ST 0xb080
708 #define T_OPCODE_ADD_SP 0xa800
709 #define T_OPCODE_ADD_PC 0xa000
710 #define T_OPCODE_ADD_I8 0x3000
711 #define T_OPCODE_SUB_I8 0x3800
712 #define T_OPCODE_ADD_I3 0x1c00
713 #define T_OPCODE_SUB_I3 0x1e00
715 #define T_OPCODE_ASR_R 0x4100
716 #define T_OPCODE_LSL_R 0x4080
717 #define T_OPCODE_LSR_R 0x40c0
718 #define T_OPCODE_ASR_I 0x1000
719 #define T_OPCODE_LSL_I 0x0000
720 #define T_OPCODE_LSR_I 0x0800
722 #define T_OPCODE_MOV_I8 0x2000
723 #define T_OPCODE_CMP_I8 0x2800
724 #define T_OPCODE_CMP_LR 0x4280
725 #define T_OPCODE_MOV_HR 0x4600
726 #define T_OPCODE_CMP_HR 0x4500
728 #define T_OPCODE_LDR_PC 0x4800
729 #define T_OPCODE_LDR_SP 0x9800
730 #define T_OPCODE_STR_SP 0x9000
731 #define T_OPCODE_LDR_IW 0x6800
732 #define T_OPCODE_STR_IW 0x6000
733 #define T_OPCODE_LDR_IH 0x8800
734 #define T_OPCODE_STR_IH 0x8000
735 #define T_OPCODE_LDR_IB 0x7800
736 #define T_OPCODE_STR_IB 0x7000
737 #define T_OPCODE_LDR_RW 0x5800
738 #define T_OPCODE_STR_RW 0x5000
739 #define T_OPCODE_LDR_RH 0x5a00
740 #define T_OPCODE_STR_RH 0x5200
741 #define T_OPCODE_LDR_RB 0x5c00
742 #define T_OPCODE_STR_RB 0x5400
744 #define T_OPCODE_PUSH 0xb400
745 #define T_OPCODE_POP 0xbc00
747 #define T_OPCODE_BRANCH 0xe7fe
749 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
751 #define THUMB_SIZE 2 /* Size of thumb instruction */
752 #define THUMB_REG_LO 0x1
753 #define THUMB_REG_HI 0x2
754 #define THUMB_REG_ANY 0x3
756 #define THUMB_H1 0x0080
757 #define THUMB_H2 0x0040
764 #define THUMB_COMPARE 1
767 #define THUMB_STORE 1
769 #define THUMB_PP_PC_LR 0x0100
771 /* These three are used for immediate shifts, do not alter */
773 #define THUMB_HALFWORD 1
778 CONST
char * template; /* Basic string to match */
779 unsigned long value
; /* Basic instruction code */
781 unsigned long variants
; /* Which CPU variants this exists for */
782 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
785 static CONST
struct thumb_opcode tinsns
[] =
787 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
788 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
789 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
790 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
791 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
792 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
793 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
794 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
795 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
796 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
797 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
798 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
799 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
800 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
801 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
802 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
803 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
804 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
805 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
806 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
807 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
808 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
809 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
810 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
811 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
812 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
813 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
814 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
815 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
816 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
817 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
818 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
819 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
820 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
821 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
822 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
823 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
824 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
825 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
826 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
827 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
828 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
829 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
830 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
831 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
832 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
833 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
834 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
835 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
836 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
837 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
838 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
839 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
840 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
842 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
843 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
852 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
853 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
854 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
860 /* These are the standard names; Users can add aliases with .req */
861 static CONST
struct reg_entry reg_table
[] =
863 /* Processor Register Numbers */
864 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
865 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
866 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
867 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
868 /* APCS conventions */
869 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
870 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
871 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
872 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
874 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
875 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
876 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
877 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
878 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
879 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
880 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
881 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
882 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
883 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
887 #define BAD_ARGS _("Bad arguments to instruction")
888 #define BAD_PC _("r15 not allowed here")
889 #define BAD_FLAGS _("Instruction should not have flags")
890 #define BAD_COND _("Instruction is not conditional")
892 static struct hash_control
* arm_ops_hsh
= NULL
;
893 static struct hash_control
* arm_tops_hsh
= NULL
;
894 static struct hash_control
* arm_cond_hsh
= NULL
;
895 static struct hash_control
* arm_shift_hsh
= NULL
;
896 static struct hash_control
* arm_reg_hsh
= NULL
;
897 static struct hash_control
* arm_psr_hsh
= NULL
;
899 /* This table describes all the machine specific pseudo-ops the assembler
900 has to support. The fields are:
901 pseudo-op name without dot
902 function to call to execute this pseudo-op
903 Integer arg to pass to the function
906 static void s_req
PARAMS ((int));
907 static void s_align
PARAMS ((int));
908 static void s_bss
PARAMS ((int));
909 static void s_even
PARAMS ((int));
910 static void s_ltorg
PARAMS ((int));
911 static void s_arm
PARAMS ((int));
912 static void s_thumb
PARAMS ((int));
913 static void s_code
PARAMS ((int));
914 static void s_force_thumb
PARAMS ((int));
915 static void s_thumb_func
PARAMS ((int));
916 static void s_thumb_set
PARAMS ((int));
917 static void arm_s_text
PARAMS ((int));
918 static void arm_s_data
PARAMS ((int));
920 static void arm_s_section
PARAMS ((int));
921 static void s_arm_elf_cons
PARAMS ((int));
924 static int my_get_expression
PARAMS ((expressionS
*, char **));
926 CONST pseudo_typeS md_pseudo_table
[] =
928 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
930 { "align", s_align
, 0 },
932 { "thumb", s_thumb
, 0 },
933 { "code", s_code
, 0 },
934 { "force_thumb", s_force_thumb
, 0 },
935 { "thumb_func", s_thumb_func
, 0 },
936 { "thumb_set", s_thumb_set
, 0 },
937 { "even", s_even
, 0 },
938 { "ltorg", s_ltorg
, 0 },
939 { "pool", s_ltorg
, 0 },
940 /* Allow for the effect of section changes. */
941 { "text", arm_s_text
, 0 },
942 { "data", arm_s_data
, 0 },
944 { "section", arm_s_section
, 0 },
945 { "section.s", arm_s_section
, 0 },
946 { "sect", arm_s_section
, 0 },
947 { "sect.s", arm_s_section
, 0 },
948 { "word", s_arm_elf_cons
, 4 },
949 { "long", s_arm_elf_cons
, 4 },
953 { "extend", float_cons
, 'x' },
954 { "ldouble", float_cons
, 'x' },
955 { "packed", float_cons
, 'p' },
959 /* Stuff needed to resolve the label ambiguity
969 symbolS
* last_label_seen
;
970 static int label_is_thumb_function_name
= false;
974 #define MAX_LITERAL_POOL_SIZE 1024
976 typedef struct literalS
978 struct expressionS exp
;
979 struct arm_it
* inst
;
982 literalT literals
[MAX_LITERAL_POOL_SIZE
];
983 int next_literal_pool_place
= 0; /* Next free entry in the pool */
984 int lit_pool_num
= 1; /* Next literal pool number */
985 symbolS
* current_poolP
= NULL
;
992 if (current_poolP
== NULL
)
993 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
994 (valueT
) 0, &zero_address_frag
);
996 /* Check if this literal value is already in the pool: */
997 while (lit_count
< next_literal_pool_place
)
999 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1000 && inst
.reloc
.exp
.X_op
== O_constant
1001 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
1002 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1007 if (lit_count
== next_literal_pool_place
) /* new entry */
1009 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1011 inst
.error
= _("Literal Pool Overflow");
1015 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1016 lit_count
= next_literal_pool_place
++;
1019 inst
.reloc
.exp
.X_op
= O_symbol
;
1020 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1021 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1026 /* Can't use symbol_new here, so have to create a symbol and then at
1027 a later date assign it a value. Thats what these functions do. */
1029 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1031 CONST
char * name
; /* It is copied, the caller can modify */
1032 segT segment
; /* Segment identifier (SEG_<something>) */
1033 valueT valu
; /* Symbol value */
1034 fragS
* frag
; /* Associated fragment */
1036 unsigned int name_length
;
1037 char * preserved_copy_of_name
;
1039 name_length
= strlen (name
) + 1; /* +1 for \0 */
1040 obstack_grow (¬es
, name
, name_length
);
1041 preserved_copy_of_name
= obstack_finish (¬es
);
1042 #ifdef STRIP_UNDERSCORE
1043 if (preserved_copy_of_name
[0] == '_')
1044 preserved_copy_of_name
++;
1047 #ifdef tc_canonicalize_symbol_name
1048 preserved_copy_of_name
=
1049 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1052 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1054 S_SET_SEGMENT (symbolP
, segment
);
1055 S_SET_VALUE (symbolP
, valu
);
1056 symbol_clear_list_pointers(symbolP
);
1058 symbol_set_frag (symbolP
, frag
);
1060 /* Link to end of symbol chain. */
1062 extern int symbol_table_frozen
;
1063 if (symbol_table_frozen
)
1067 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1069 obj_symbol_new_hook (symbolP
);
1071 #ifdef tc_symbol_new_hook
1072 tc_symbol_new_hook (symbolP
);
1076 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1077 #endif /* DEBUG_SYMS */
1080 /* Check that an immediate is valid, and if so, convert it to the right format. */
1083 validate_immediate (val
)
1089 #define rotate_left(v, n) (v << n | v >> (32 - n))
1091 for (i
= 0; i
< 32; i
+= 2)
1092 if ((a
= rotate_left (val
, i
)) <= 0xff)
1093 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1098 /* Check to see if an immediate can be computed as two seperate immediate
1099 values, added together. We already know that this value cannot be
1100 computed by just one ARM instruction. */
1103 validate_immediate_twopart (val
, highpart
)
1105 unsigned int * highpart
;
1110 for (i
= 0; i
< 32; i
+= 2)
1111 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1117 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1119 else if (a
& 0xff0000)
1124 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1128 assert (a
& 0xff000000);
1130 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1133 return (a
& 0xff) | (i
<< 7);
1140 validate_offset_imm (val
, hwse
)
1144 if ((hwse
&& val
> 255) || val
> 4095)
1154 as_bad (_("Invalid syntax for .req directive."));
1161 /* We don't support putting frags in the BSS segment, we fake it by
1162 marking in_bss, then looking at s_skip for clues?.. */
1163 subseg_set (bss_section
, 0);
1164 demand_empty_rest_of_line ();
1171 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1172 frag_align (1, 0, 0);
1174 record_alignment (now_seg
, 1);
1176 demand_empty_rest_of_line ();
1186 if (current_poolP
== NULL
)
1189 /* Align pool as you have word accesses */
1190 /* Only make a frag if we have to ... */
1192 frag_align (2, 0, 0);
1194 record_alignment (now_seg
, 2);
1196 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1198 symbol_locate (current_poolP
, sym_name
, now_seg
,
1199 (valueT
) frag_now_fix (), frag_now
);
1200 symbol_table_insert (current_poolP
);
1202 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1204 #if defined OBJ_COFF || defined OBJ_ELF
1205 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1208 while (lit_count
< next_literal_pool_place
)
1209 /* First output the expression in the instruction to the pool */
1210 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1212 next_literal_pool_place
= 0;
1213 current_poolP
= NULL
;
1217 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1221 register long temp_fill
;
1222 long max_alignment
= 15;
1224 temp
= get_absolute_expression ();
1225 if (temp
> max_alignment
)
1226 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1229 as_bad (_("Alignment negative. 0 assumed."));
1233 if (*input_line_pointer
== ',')
1235 input_line_pointer
++;
1236 temp_fill
= get_absolute_expression ();
1244 /* Only make a frag if we HAVE to. . . */
1245 if (temp
&& !need_pass_2
)
1246 frag_align (temp
, (int) temp_fill
, 0);
1247 demand_empty_rest_of_line ();
1249 record_alignment (now_seg
, temp
);
1253 s_force_thumb (ignore
)
1256 /* If we are not already in thumb mode go into it, EVEN if
1257 the target processor does not support thumb instructions.
1258 This is used by gcc/config/arm/lib1funcs.asm for example
1259 to compile interworking support functions even if the
1260 target processor should not support interworking. */
1266 record_alignment (now_seg
, 1);
1269 demand_empty_rest_of_line ();
1273 s_thumb_func (ignore
)
1276 /* The following label is the name/address of the start of a Thumb function.
1277 We need to know this for the interworking support. */
1279 label_is_thumb_function_name
= true;
1281 demand_empty_rest_of_line ();
1284 /* Perform a .set directive, but also mark the alias as
1285 being a thumb function. */
1291 /* XXX the following is a duplicate of the code for s_set() in read.c
1292 We cannot just call that code as we need to get at the symbol that
1294 register char * name
;
1295 register char delim
;
1296 register char * end_name
;
1297 register symbolS
* symbolP
;
1300 * Especial apologies for the random logic:
1301 * this just grew, and could be parsed much more simply!
1304 name
= input_line_pointer
;
1305 delim
= get_symbol_end ();
1306 end_name
= input_line_pointer
;
1311 if (*input_line_pointer
!= ',')
1314 as_bad (_("Expected comma after name \"%s\""), name
);
1316 ignore_rest_of_line ();
1320 input_line_pointer
++;
1323 if (name
[0] == '.' && name
[1] == '\0')
1325 /* XXX - this should not happen to .thumb_set */
1329 if ((symbolP
= symbol_find (name
)) == NULL
1330 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1333 /* When doing symbol listings, play games with dummy fragments living
1334 outside the normal fragment chain to record the file and line info
1336 if (listing
& LISTING_SYMBOLS
)
1338 extern struct list_info_struct
* listing_tail
;
1339 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1340 memset (dummy_frag
, 0, sizeof(fragS
));
1341 dummy_frag
->fr_type
= rs_fill
;
1342 dummy_frag
->line
= listing_tail
;
1343 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1344 dummy_frag
->fr_symbol
= symbolP
;
1348 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1351 /* "set" symbols are local unless otherwise specified. */
1352 SF_SET_LOCAL (symbolP
);
1353 #endif /* OBJ_COFF */
1354 } /* make a new symbol */
1356 symbol_table_insert (symbolP
);
1361 && S_IS_DEFINED (symbolP
)
1362 && S_GET_SEGMENT (symbolP
) != reg_section
)
1363 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1365 pseudo_set (symbolP
);
1367 demand_empty_rest_of_line ();
1369 /* XXX Now we come to the Thumb specific bit of code. */
1371 THUMB_SET_FUNC (symbolP
, 1);
1372 ARM_SET_THUMB (symbolP
, 1);
1373 #if defined OBJ_ELF || defined OBJ_COFF
1374 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1378 /* If we change section we must dump the literal pool first. */
1383 if (now_seg
!= text_section
)
1393 if (flag_readonly_data_in_text
)
1395 if (now_seg
!= text_section
)
1398 else if (now_seg
!= data_section
)
1406 arm_s_section (ignore
)
1411 obj_elf_section (ignore
);
1416 opcode_select (width
)
1424 if (! (cpu_variant
& ARM_THUMB
))
1425 as_bad (_("selected processor does not support THUMB opcodes"));
1427 /* No need to force the alignment, since we will have been
1428 coming from ARM mode, which is word-aligned. */
1429 record_alignment (now_seg
, 1);
1436 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1437 as_bad (_("selected processor does not support ARM opcodes"));
1440 frag_align (2, 0, 0);
1441 record_alignment (now_seg
, 1);
1446 as_bad (_("invalid instruction size selected (%d)"), width
);
1455 demand_empty_rest_of_line ();
1463 demand_empty_rest_of_line ();
1472 temp
= get_absolute_expression ();
1477 opcode_select (temp
);
1481 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1489 skip_whitespace (str
);
1492 inst
.error
= _("Garbage following instruction");
1496 skip_past_comma (str
)
1502 while ((c
= *p
) == ' ' || c
== ',')
1505 if (c
== ',' && comma
++)
1513 return comma
? SUCCESS
: FAIL
;
1516 /* A standard register must be given at this point.
1517 Shift is the place to put it in inst.instruction.
1518 Restores input start point on err.
1519 Returns the reg#, or FAIL. */
1522 reg_required_here (str
, shift
)
1526 static char buff
[128]; /* XXX */
1528 char * start
= *str
;
1530 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1533 inst
.instruction
|= reg
<< shift
;
1537 /* Restore the start point, we may have got a reg of the wrong class. */
1540 /* In the few cases where we might be able to accept something else
1541 this error can be overridden. */
1542 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1549 psr_required_here (str
, cpsr
, spsr
)
1555 char * start
= *str
;
1556 psr
= arm_psr_parse (str
);
1558 if (psr
== cpsr
|| psr
== spsr
)
1561 inst
.instruction
|= 1 << 22;
1566 /* In the few cases where we might be able to accept something else
1567 this error can be overridden. */
1568 inst
.error
= _("<psr(f)> expected");
1570 /* Restore the start point. */
1576 co_proc_number (str
)
1579 int processor
, pchar
;
1581 skip_whitespace (* str
);
1583 /* The data sheet seems to imply that just a number on its own is valid
1584 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1586 if (**str
== 'p' || **str
== 'P')
1590 if (pchar
>= '0' && pchar
<= '9')
1592 processor
= pchar
- '0';
1593 if (**str
>= '0' && **str
<= '9')
1595 processor
= processor
* 10 + *(*str
)++ - '0';
1598 inst
.error
= _("Illegal co-processor number");
1605 inst
.error
= _("Bad or missing co-processor number");
1609 inst
.instruction
|= processor
<< 8;
1614 cp_opc_expr (str
, where
, length
)
1621 skip_whitespace (* str
);
1623 memset (&expr
, '\0', sizeof (expr
));
1625 if (my_get_expression (&expr
, str
))
1627 if (expr
.X_op
!= O_constant
)
1629 inst
.error
= _("bad or missing expression");
1633 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1635 inst
.error
= _("immediate co-processor expression too large");
1639 inst
.instruction
|= expr
.X_add_number
<< where
;
1644 cp_reg_required_here (str
, where
)
1649 char * start
= *str
;
1651 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1654 inst
.instruction
|= reg
<< where
;
1658 /* In the few cases where we might be able to accept something else
1659 this error can be overridden. */
1660 inst
.error
= _("Co-processor register expected");
1662 /* Restore the start point. */
1668 fp_reg_required_here (str
, where
)
1673 char * start
= *str
;
1675 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1678 inst
.instruction
|= reg
<< where
;
1682 /* In the few cases where we might be able to accept something else
1683 this error can be overridden. */
1684 inst
.error
= _("Floating point register expected");
1686 /* Restore the start point. */
1692 cp_address_offset (str
)
1697 skip_whitespace (* str
);
1699 if (! is_immediate_prefix (**str
))
1701 inst
.error
= _("immediate expression expected");
1707 if (my_get_expression (& inst
.reloc
.exp
, str
))
1710 if (inst
.reloc
.exp
.X_op
== O_constant
)
1712 offset
= inst
.reloc
.exp
.X_add_number
;
1716 inst
.error
= _("co-processor address must be word aligned");
1720 if (offset
> 1023 || offset
< -1023)
1722 inst
.error
= _("offset too large");
1727 inst
.instruction
|= INDEX_UP
;
1731 inst
.instruction
|= offset
>> 2;
1734 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1740 cp_address_required_here (str
)
1752 skip_whitespace (p
);
1754 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1757 skip_whitespace (p
);
1763 if (skip_past_comma (& p
) == SUCCESS
)
1766 write_back
= WRITE_BACK
;
1770 inst
.error
= _("pc may not be used in post-increment");
1774 if (cp_address_offset (& p
) == FAIL
)
1778 pre_inc
= PRE_INDEX
| INDEX_UP
;
1782 /* '['Rn, #expr']'[!] */
1784 if (skip_past_comma (& p
) == FAIL
)
1786 inst
.error
= _("pre-indexed expression expected");
1790 pre_inc
= PRE_INDEX
;
1792 if (cp_address_offset (& p
) == FAIL
)
1795 skip_whitespace (p
);
1799 inst
.error
= _("missing ]");
1803 skip_whitespace (p
);
1809 inst
.error
= _("pc may not be used with write-back");
1814 write_back
= WRITE_BACK
;
1820 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1823 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1824 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1825 inst
.reloc
.pc_rel
= 1;
1826 inst
.instruction
|= (REG_PC
<< 16);
1827 pre_inc
= PRE_INDEX
;
1830 inst
.instruction
|= write_back
| pre_inc
;
1838 unsigned long flags
;
1840 /* Do nothing really. */
1841 inst
.instruction
|= flags
; /* This is pointless. */
1849 unsigned long flags
;
1851 /* Only one syntax. */
1852 skip_whitespace (str
);
1854 if (reg_required_here (&str
, 12) == FAIL
)
1856 inst
.error
= BAD_ARGS
;
1860 if (skip_past_comma (&str
) == FAIL
1861 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1863 inst
.error
= _("<psr> expected");
1867 inst
.instruction
|= flags
;
1872 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1876 unsigned long flags
;
1880 skip_whitespace (str
);
1882 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1884 inst
.instruction
|= PSR_ALL
;
1886 /* Sytax should be "<psr>, Rm" */
1887 if (skip_past_comma (&str
) == FAIL
1888 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1890 inst
.error
= BAD_ARGS
;
1896 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1897 inst
.instruction
|= PSR_FLAGS
;
1898 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1899 inst
.instruction
|= PSR_CONTROL
;
1902 inst
.error
= BAD_ARGS
;
1906 if (skip_past_comma (&str
) == FAIL
)
1908 inst
.error
= BAD_ARGS
;
1912 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1914 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1916 /* Immediate expression. */
1917 else if (is_immediate_prefix (* str
))
1922 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1924 inst
.error
= _("Register or shift expression expected");
1928 if (inst
.reloc
.exp
.X_add_symbol
)
1930 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1931 inst
.reloc
.pc_rel
= 0;
1935 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1938 inst
.error
= _("Invalid constant");
1942 inst
.instruction
|= value
;
1945 flags
|= INST_IMMEDIATE
;
1949 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1955 inst
.instruction
|= flags
;
1960 /* Long Multiply Parser
1961 UMULL RdLo, RdHi, Rm, Rs
1962 SMULL RdLo, RdHi, Rm, Rs
1963 UMLAL RdLo, RdHi, Rm, Rs
1964 SMLAL RdLo, RdHi, Rm, Rs
1967 do_mull (str
, flags
)
1969 unsigned long flags
;
1971 int rdlo
, rdhi
, rm
, rs
;
1973 /* Only one format "rdlo, rdhi, rm, rs" */
1974 skip_whitespace (str
);
1976 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1978 inst
.error
= BAD_ARGS
;
1982 if (skip_past_comma (&str
) == FAIL
1983 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1985 inst
.error
= BAD_ARGS
;
1989 if (skip_past_comma (&str
) == FAIL
1990 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1992 inst
.error
= BAD_ARGS
;
1996 /* rdhi, rdlo and rm must all be different */
1997 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1998 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2000 if (skip_past_comma (&str
) == FAIL
2001 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2003 inst
.error
= BAD_ARGS
;
2007 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2009 inst
.error
= BAD_PC
;
2013 inst
.instruction
|= flags
;
2021 unsigned long flags
;
2025 /* Only one format "rd, rm, rs" */
2026 skip_whitespace (str
);
2028 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2030 inst
.error
= BAD_ARGS
;
2036 inst
.error
= BAD_PC
;
2040 if (skip_past_comma (&str
) == FAIL
2041 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2043 inst
.error
= BAD_ARGS
;
2049 inst
.error
= BAD_PC
;
2054 as_tsktsk (_("rd and rm should be different in mul"));
2056 if (skip_past_comma (&str
) == FAIL
2057 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2059 inst
.error
= BAD_ARGS
;
2065 inst
.error
= BAD_PC
;
2069 inst
.instruction
|= flags
;
2077 unsigned long flags
;
2081 /* Only one format "rd, rm, rs, rn" */
2082 skip_whitespace (str
);
2084 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2086 inst
.error
= BAD_ARGS
;
2092 inst
.error
= BAD_PC
;
2096 if (skip_past_comma (&str
) == FAIL
2097 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2099 inst
.error
= BAD_ARGS
;
2105 inst
.error
= BAD_PC
;
2110 as_tsktsk (_("rd and rm should be different in mla"));
2112 if (skip_past_comma (&str
) == FAIL
2113 || (rd
= reg_required_here (&str
, 8)) == FAIL
2114 || skip_past_comma (&str
) == FAIL
2115 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2117 inst
.error
= BAD_ARGS
;
2121 if (rd
== REG_PC
|| rm
== REG_PC
)
2123 inst
.error
= BAD_PC
;
2127 inst
.instruction
|= flags
;
2132 /* Returns the index into fp_values of a floating point number, or -1 if
2133 not in the table. */
2135 my_get_float_expression (str
)
2138 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2144 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2145 /* Look for a raw floating point number */
2146 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2147 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2149 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2151 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2153 if (words
[j
] != fp_values
[i
][j
])
2157 if (j
== MAX_LITTLENUMS
)
2165 /* Try and parse a more complex expression, this will probably fail
2166 unless the code uses a floating point prefix (eg "0f") */
2167 save_in
= input_line_pointer
;
2168 input_line_pointer
= *str
;
2169 if (expression (&exp
) == absolute_section
2170 && exp
.X_op
== O_big
2171 && exp
.X_add_number
< 0)
2173 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2175 if (gen_to_words (words
, 5, (long)15) == 0)
2177 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2179 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2181 if (words
[j
] != fp_values
[i
][j
])
2185 if (j
== MAX_LITTLENUMS
)
2187 *str
= input_line_pointer
;
2188 input_line_pointer
= save_in
;
2195 *str
= input_line_pointer
;
2196 input_line_pointer
= save_in
;
2200 /* Return true if anything in the expression is a bignum */
2202 walk_no_bignums (sp
)
2205 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2208 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2210 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2211 || (symbol_get_value_expression (sp
)->X_op_symbol
2212 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2219 my_get_expression (ep
, str
)
2226 save_in
= input_line_pointer
;
2227 input_line_pointer
= *str
;
2228 seg
= expression (ep
);
2231 if (seg
!= absolute_section
2232 && seg
!= text_section
2233 && seg
!= data_section
2234 && seg
!= bss_section
2235 && seg
!= undefined_section
)
2237 inst
.error
= _("bad_segment");
2238 *str
= input_line_pointer
;
2239 input_line_pointer
= save_in
;
2244 /* Get rid of any bignums now, so that we don't generate an error for which
2245 we can't establish a line number later on. Big numbers are never valid
2246 in instructions, which is where this routine is always called. */
2247 if (ep
->X_op
== O_big
2248 || (ep
->X_add_symbol
2249 && (walk_no_bignums (ep
->X_add_symbol
)
2251 && walk_no_bignums (ep
->X_op_symbol
)))))
2253 inst
.error
= _("Invalid constant");
2254 *str
= input_line_pointer
;
2255 input_line_pointer
= save_in
;
2259 *str
= input_line_pointer
;
2260 input_line_pointer
= save_in
;
2264 /* unrestrict should be one if <shift> <register> is permitted for this
2268 decode_shift (str
, unrestrict
)
2272 struct asm_shift
* shft
;
2276 skip_whitespace (* str
);
2278 for (p
= *str
; isalpha (*p
); p
++)
2283 inst
.error
= _("Shift expression expected");
2289 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2293 if (!strncmp (*str
, "rrx", 3)
2294 || !strncmp (*str
, "RRX", 3))
2297 inst
.instruction
|= shft
->value
;
2301 skip_whitespace (p
);
2303 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2305 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2309 else if (is_immediate_prefix (* p
))
2313 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2316 /* Validate some simple #expressions */
2317 if (inst
.reloc
.exp
.X_op
== O_constant
)
2319 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2321 /* Reject operations greater than 32, or lsl #32 */
2322 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2324 inst
.error
= _("Invalid immediate shift");
2328 /* Shifts of zero should be converted to lsl (which is zero)*/
2335 /* Shifts of 32 are encoded as 0, for those shifts that
2340 inst
.instruction
|= (num
<< 7) | shft
->value
;
2345 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2346 inst
.reloc
.pc_rel
= 0;
2347 inst
.instruction
|= shft
->value
;
2353 inst
.error
= unrestrict
? _("shift requires register or #expression")
2354 : _("shift requires #expression");
2360 inst
.error
= _("Shift expression expected");
2364 /* Do those data_ops which can take a negative immediate constant */
2365 /* by altering the instuction. A bit of a hack really */
2369 by inverting the second operand, and
2372 by negating the second operand.
2375 negate_data_op (instruction
, value
)
2376 unsigned long * instruction
;
2377 unsigned long value
;
2380 unsigned long negated
, inverted
;
2382 negated
= validate_immediate (-value
);
2383 inverted
= validate_immediate (~value
);
2385 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2389 case OPCODE_SUB
: /* ADD <-> SUB */
2390 new_inst
= OPCODE_ADD
;
2395 new_inst
= OPCODE_SUB
;
2399 case OPCODE_CMP
: /* CMP <-> CMN */
2400 new_inst
= OPCODE_CMN
;
2405 new_inst
= OPCODE_CMP
;
2409 /* Now Inverted ops */
2410 case OPCODE_MOV
: /* MOV <-> MVN */
2411 new_inst
= OPCODE_MVN
;
2416 new_inst
= OPCODE_MOV
;
2420 case OPCODE_AND
: /* AND <-> BIC */
2421 new_inst
= OPCODE_BIC
;
2426 new_inst
= OPCODE_AND
;
2430 case OPCODE_ADC
: /* ADC <-> SBC */
2431 new_inst
= OPCODE_SBC
;
2436 new_inst
= OPCODE_ADC
;
2440 /* We cannot do anything */
2448 *instruction
&= OPCODE_MASK
;
2449 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2460 skip_whitespace (* str
);
2462 if (reg_required_here (str
, 0) != FAIL
)
2464 if (skip_past_comma (str
) == SUCCESS
)
2465 /* Shift operation on register. */
2466 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2472 /* Immediate expression */
2473 if (is_immediate_prefix (**str
))
2478 if (my_get_expression (&inst
.reloc
.exp
, str
))
2481 if (inst
.reloc
.exp
.X_add_symbol
)
2483 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2484 inst
.reloc
.pc_rel
= 0;
2488 if (skip_past_comma (str
) == SUCCESS
)
2490 /* #x, y -- ie explicit rotation by Y */
2491 if (my_get_expression (&expr
, str
))
2494 if (expr
.X_op
!= O_constant
)
2496 inst
.error
= _("Constant expression expected");
2500 /* Rotate must be a multiple of 2 */
2501 if (((unsigned) expr
.X_add_number
) > 30
2502 || (expr
.X_add_number
& 1) != 0
2503 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2505 inst
.error
= _("Invalid constant");
2508 inst
.instruction
|= INST_IMMEDIATE
;
2509 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2510 inst
.instruction
|= expr
.X_add_number
<< 7;
2514 /* Implicit rotation, select a suitable one */
2515 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2519 /* Can't be done, perhaps the code reads something like
2520 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2521 if ((value
= negate_data_op (&inst
.instruction
,
2522 inst
.reloc
.exp
.X_add_number
))
2525 inst
.error
= _("Invalid constant");
2530 inst
.instruction
|= value
;
2533 inst
.instruction
|= INST_IMMEDIATE
;
2538 inst
.error
= _("Register or shift expression expected");
2547 skip_whitespace (* str
);
2549 if (fp_reg_required_here (str
, 0) != FAIL
)
2553 /* Immediate expression */
2554 if (*((*str
)++) == '#')
2560 skip_whitespace (* str
);
2562 /* First try and match exact strings, this is to guarantee that
2563 some formats will work even for cross assembly */
2565 for (i
= 0; fp_const
[i
]; i
++)
2567 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2571 *str
+= strlen (fp_const
[i
]);
2572 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2574 inst
.instruction
|= i
+ 8;
2581 /* Just because we didn't get a match doesn't mean that the
2582 constant isn't valid, just that it is in a format that we
2583 don't automatically recognize. Try parsing it with
2584 the standard expression routines. */
2585 if ((i
= my_get_float_expression (str
)) >= 0)
2587 inst
.instruction
|= i
+ 8;
2591 inst
.error
= _("Invalid floating point immediate expression");
2594 inst
.error
= _("Floating point register or immediate expression expected");
2600 do_arit (str
, flags
)
2602 unsigned long flags
;
2604 skip_whitespace (str
);
2606 if (reg_required_here (&str
, 12) == FAIL
2607 || skip_past_comma (&str
) == FAIL
2608 || reg_required_here (&str
, 16) == FAIL
2609 || skip_past_comma (&str
) == FAIL
2610 || data_op2 (&str
) == FAIL
)
2613 inst
.error
= BAD_ARGS
;
2617 inst
.instruction
|= flags
;
2625 unsigned long flags
;
2627 /* This is a pseudo-op of the form "adr rd, label" to be converted
2628 into a relative address of the form "add rd, pc, #label-.-8" */
2630 skip_whitespace (str
);
2632 if (reg_required_here (&str
, 12) == FAIL
2633 || skip_past_comma (&str
) == FAIL
2634 || my_get_expression (&inst
.reloc
.exp
, &str
))
2637 inst
.error
= BAD_ARGS
;
2640 /* Frag hacking will turn this into a sub instruction if the offset turns
2641 out to be negative. */
2642 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2643 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2644 inst
.reloc
.pc_rel
= 1;
2645 inst
.instruction
|= flags
;
2651 do_adrl (str
, flags
)
2653 unsigned long flags
;
2655 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2656 into a relative address of the form:
2657 add rd, pc, #low(label-.-8)"
2658 add rd, rd, #high(label-.-8)" */
2660 skip_whitespace (str
);
2662 if (reg_required_here (& str
, 12) == FAIL
2663 || skip_past_comma (& str
) == FAIL
2664 || my_get_expression (& inst
.reloc
.exp
, & str
))
2667 inst
.error
= BAD_ARGS
;
2673 /* Frag hacking will turn this into a sub instruction if the offset turns
2674 out to be negative. */
2675 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2676 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2677 inst
.reloc
.pc_rel
= 1;
2678 inst
.instruction
|= flags
;
2679 inst
.size
= INSN_SIZE
* 2;
2687 unsigned long flags
;
2689 skip_whitespace (str
);
2691 if (reg_required_here (&str
, 16) == FAIL
)
2694 inst
.error
= BAD_ARGS
;
2698 if (skip_past_comma (&str
) == FAIL
2699 || data_op2 (&str
) == FAIL
)
2702 inst
.error
= BAD_ARGS
;
2706 inst
.instruction
|= flags
;
2707 if ((flags
& 0x0000f000) == 0)
2708 inst
.instruction
|= CONDS_BIT
;
2717 unsigned long flags
;
2719 skip_whitespace (str
);
2721 if (reg_required_here (&str
, 12) == FAIL
)
2724 inst
.error
= BAD_ARGS
;
2728 if (skip_past_comma (&str
) == FAIL
2729 || data_op2 (&str
) == FAIL
)
2732 inst
.error
= BAD_ARGS
;
2736 inst
.instruction
|= flags
;
2742 ldst_extend (str
, hwse
)
2753 if (my_get_expression (& inst
.reloc
.exp
, str
))
2756 if (inst
.reloc
.exp
.X_op
== O_constant
)
2758 int value
= inst
.reloc
.exp
.X_add_number
;
2760 if ((hwse
&& (value
< -255 || value
> 255))
2761 || (value
< -4095 || value
> 4095))
2763 inst
.error
= _("address offset too large");
2773 /* Halfword and signextension instructions have the
2774 immediate value split across bits 11..8 and bits 3..0 */
2776 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2778 inst
.instruction
|= add
| value
;
2784 inst
.instruction
|= HWOFFSET_IMM
;
2785 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2788 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2789 inst
.reloc
.pc_rel
= 0;
2794 add
= 0; /* and fall through */
2796 (*str
)++; /* and fall through */
2798 if (reg_required_here (str
, 0) == FAIL
)
2802 inst
.instruction
|= add
;
2805 inst
.instruction
|= add
| OFFSET_REG
;
2806 if (skip_past_comma (str
) == SUCCESS
)
2807 return decode_shift (str
, SHIFT_RESTRICT
);
2815 do_ldst (str
, flags
)
2817 unsigned long flags
;
2824 /* This is not ideal, but it is the simplest way of dealing with the
2825 ARM7T halfword instructions (since they use a different
2826 encoding, but the same mnemonic): */
2827 halfword
= (flags
& 0x80000000) != 0;
2830 /* This is actually a load/store of a halfword, or a
2831 signed-extension load */
2832 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2835 = _("Processor does not support halfwords or signed bytes");
2839 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2840 | (flags
& ~COND_MASK
);
2845 skip_whitespace (str
);
2847 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2850 inst
.error
= BAD_ARGS
;
2854 if (skip_past_comma (& str
) == FAIL
)
2856 inst
.error
= _("Address expected");
2866 skip_whitespace (str
);
2868 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2871 /* Conflicts can occur on stores as well as loads. */
2872 conflict_reg
= (conflict_reg
== reg
);
2874 skip_whitespace (str
);
2880 if (skip_past_comma (&str
) == SUCCESS
)
2882 /* [Rn],... (post inc) */
2883 if (ldst_extend (&str
, halfword
) == FAIL
)
2886 as_warn (_("%s register same as write-back base"),
2887 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2893 inst
.instruction
|= HWOFFSET_IMM
;
2895 skip_whitespace (str
);
2900 as_warn (_("%s register same as write-back base"),
2901 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2903 inst
.instruction
|= WRITE_BACK
;
2907 if (! (flags
& TRANS_BIT
))
2914 if (skip_past_comma (&str
) == FAIL
)
2916 inst
.error
= _("pre-indexed expression expected");
2921 if (ldst_extend (&str
, halfword
) == FAIL
)
2924 skip_whitespace (str
);
2928 inst
.error
= _("missing ]");
2932 skip_whitespace (str
);
2937 as_warn (_("%s register same as write-back base"),
2938 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2940 inst
.instruction
|= WRITE_BACK
;
2944 else if (*str
== '=')
2946 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2949 skip_whitespace (str
);
2951 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2954 if (inst
.reloc
.exp
.X_op
!= O_constant
2955 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2957 inst
.error
= _("Constant expression expected");
2961 if (inst
.reloc
.exp
.X_op
== O_constant
2962 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2964 /* This can be done with a mov instruction */
2965 inst
.instruction
&= LITERAL_MASK
;
2966 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2967 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2973 /* Insert into literal pool */
2974 if (add_to_lit_pool () == FAIL
)
2977 inst
.error
= _("literal pool insertion failed");
2981 /* Change the instruction exp to point to the pool */
2984 inst
.instruction
|= HWOFFSET_IMM
;
2985 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2988 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2989 inst
.reloc
.pc_rel
= 1;
2990 inst
.instruction
|= (REG_PC
<< 16);
2996 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3001 inst
.instruction
|= HWOFFSET_IMM
;
3002 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3005 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3006 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3007 inst
.reloc
.pc_rel
= 1;
3008 inst
.instruction
|= (REG_PC
<< 16);
3012 if (pre_inc
&& (flags
& TRANS_BIT
))
3013 inst
.error
= _("Pre-increment instruction with translate");
3015 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3028 /* We come back here if we get ranges concatenated by '+' or '|' */
3043 skip_whitespace (str
);
3045 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3054 inst
.error
= _("Bad range in register list");
3058 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3060 if (range
& (1 << i
))
3062 (_("Warning: Duplicated register (r%d) in register list"),
3070 if (range
& (1 << reg
))
3071 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3073 else if (reg
<= cur_reg
)
3074 as_tsktsk (_("Warning: Register range not in ascending order"));
3078 } while (skip_past_comma (&str
) != FAIL
3079 || (in_range
= 1, *str
++ == '-'));
3081 skip_whitespace (str
);
3085 inst
.error
= _("Missing `}'");
3093 if (my_get_expression (&expr
, &str
))
3096 if (expr
.X_op
== O_constant
)
3098 if (expr
.X_add_number
3099 != (expr
.X_add_number
& 0x0000ffff))
3101 inst
.error
= _("invalid register mask");
3105 if ((range
& expr
.X_add_number
) != 0)
3107 int regno
= range
& expr
.X_add_number
;
3110 regno
= (1 << regno
) - 1;
3112 (_("Warning: Duplicated register (r%d) in register list"),
3116 range
|= expr
.X_add_number
;
3120 if (inst
.reloc
.type
!= 0)
3122 inst
.error
= _("expression too complex");
3126 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3127 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3128 inst
.reloc
.pc_rel
= 0;
3132 skip_whitespace (str
);
3134 if (*str
== '|' || *str
== '+')
3139 } while (another_range
);
3146 do_ldmstm (str
, flags
)
3148 unsigned long flags
;
3153 skip_whitespace (str
);
3155 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3158 if (base_reg
== REG_PC
)
3160 inst
.error
= _("r15 not allowed as base register");
3164 skip_whitespace (str
);
3168 flags
|= WRITE_BACK
;
3172 if (skip_past_comma (&str
) == FAIL
3173 || (range
= reg_list (&str
)) == FAIL
)
3176 inst
.error
= BAD_ARGS
;
3183 flags
|= LDM_TYPE_2_OR_3
;
3186 inst
.instruction
|= flags
| range
;
3194 unsigned long flags
;
3196 skip_whitespace (str
);
3198 /* Allow optional leading '#'. */
3199 if (is_immediate_prefix (*str
))
3202 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3205 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3206 inst
.reloc
.pc_rel
= 0;
3207 inst
.instruction
|= flags
;
3215 do_swap (str
, flags
)
3217 unsigned long flags
;
3221 skip_whitespace (str
);
3223 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3228 inst
.error
= _("r15 not allowed in swap");
3232 if (skip_past_comma (&str
) == FAIL
3233 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3236 inst
.error
= BAD_ARGS
;
3242 inst
.error
= _("r15 not allowed in swap");
3246 if (skip_past_comma (&str
) == FAIL
3249 inst
.error
= BAD_ARGS
;
3253 skip_whitespace (str
);
3255 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3260 inst
.error
= BAD_PC
;
3264 skip_whitespace (str
);
3268 inst
.error
= _("missing ]");
3272 inst
.instruction
|= flags
;
3278 do_branch (str
, flags
)
3280 unsigned long flags
;
3282 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3289 /* ScottB: February 5, 1998 */
3290 /* Check to see of PLT32 reloc required for the instruction. */
3292 /* arm_parse_reloc() works on input_line_pointer.
3293 We actually want to parse the operands to the branch instruction
3294 passed in 'str'. Save the input pointer and restore it later. */
3295 save_in
= input_line_pointer
;
3296 input_line_pointer
= str
;
3297 if (inst
.reloc
.exp
.X_op
== O_symbol
3299 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3301 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3302 inst
.reloc
.pc_rel
= 0;
3303 /* Modify str to point to after parsed operands, otherwise
3304 end_of_line() will complain about the (PLT) left in str. */
3305 str
= input_line_pointer
;
3309 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3310 inst
.reloc
.pc_rel
= 1;
3312 input_line_pointer
= save_in
;
3315 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3316 inst
.reloc
.pc_rel
= 1;
3317 #endif /* OBJ_ELF */
3326 unsigned long flags
;
3330 skip_whitespace (str
);
3332 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3334 inst
.error
= BAD_ARGS
;
3339 inst
.error
= BAD_PC
;
3347 unsigned long flags
;
3349 /* Co-processor data operation.
3350 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3351 skip_whitespace (str
);
3353 if (co_proc_number (&str
) == FAIL
)
3356 inst
.error
= BAD_ARGS
;
3360 if (skip_past_comma (&str
) == FAIL
3361 || cp_opc_expr (&str
, 20,4) == FAIL
)
3364 inst
.error
= BAD_ARGS
;
3368 if (skip_past_comma (&str
) == FAIL
3369 || cp_reg_required_here (&str
, 12) == FAIL
)
3372 inst
.error
= BAD_ARGS
;
3376 if (skip_past_comma (&str
) == FAIL
3377 || cp_reg_required_here (&str
, 16) == FAIL
)
3380 inst
.error
= BAD_ARGS
;
3384 if (skip_past_comma (&str
) == FAIL
3385 || cp_reg_required_here (&str
, 0) == FAIL
)
3388 inst
.error
= BAD_ARGS
;
3392 if (skip_past_comma (&str
) == SUCCESS
)
3394 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3397 inst
.error
= BAD_ARGS
;
3407 do_lstc (str
, flags
)
3409 unsigned long flags
;
3411 /* Co-processor register load/store.
3412 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3414 skip_whitespace (str
);
3416 if (co_proc_number (&str
) == FAIL
)
3419 inst
.error
= BAD_ARGS
;
3423 if (skip_past_comma (&str
) == FAIL
3424 || cp_reg_required_here (&str
, 12) == FAIL
)
3427 inst
.error
= BAD_ARGS
;
3431 if (skip_past_comma (&str
) == FAIL
3432 || cp_address_required_here (&str
) == FAIL
)
3435 inst
.error
= BAD_ARGS
;
3439 inst
.instruction
|= flags
;
3445 do_co_reg (str
, flags
)
3447 unsigned long flags
;
3449 /* Co-processor register transfer.
3450 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3452 skip_whitespace (str
);
3454 if (co_proc_number (&str
) == FAIL
)
3457 inst
.error
= BAD_ARGS
;
3461 if (skip_past_comma (&str
) == FAIL
3462 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3465 inst
.error
= BAD_ARGS
;
3469 if (skip_past_comma (&str
) == FAIL
3470 || reg_required_here (&str
, 12) == FAIL
)
3473 inst
.error
= BAD_ARGS
;
3477 if (skip_past_comma (&str
) == FAIL
3478 || cp_reg_required_here (&str
, 16) == FAIL
)
3481 inst
.error
= BAD_ARGS
;
3485 if (skip_past_comma (&str
) == FAIL
3486 || cp_reg_required_here (&str
, 0) == FAIL
)
3489 inst
.error
= BAD_ARGS
;
3493 if (skip_past_comma (&str
) == SUCCESS
)
3495 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3498 inst
.error
= BAD_ARGS
;
3504 inst
.error
= BAD_COND
;
3512 do_fp_ctrl (str
, flags
)
3514 unsigned long flags
;
3516 /* FP control registers.
3517 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3519 skip_whitespace (str
);
3521 if (reg_required_here (&str
, 12) == FAIL
)
3524 inst
.error
= BAD_ARGS
;
3533 do_fp_ldst (str
, flags
)
3535 unsigned long flags
;
3537 skip_whitespace (str
);
3539 switch (inst
.suffix
)
3544 inst
.instruction
|= CP_T_X
;
3547 inst
.instruction
|= CP_T_Y
;
3550 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3556 if (fp_reg_required_here (&str
, 12) == FAIL
)
3559 inst
.error
= BAD_ARGS
;
3563 if (skip_past_comma (&str
) == FAIL
3564 || cp_address_required_here (&str
) == FAIL
)
3567 inst
.error
= BAD_ARGS
;
3575 do_fp_ldmstm (str
, flags
)
3577 unsigned long flags
;
3581 skip_whitespace (str
);
3583 if (fp_reg_required_here (&str
, 12) == FAIL
)
3586 inst
.error
= BAD_ARGS
;
3590 /* Get Number of registers to transfer */
3591 if (skip_past_comma (&str
) == FAIL
3592 || my_get_expression (&inst
.reloc
.exp
, &str
))
3595 inst
.error
= _("constant expression expected");
3599 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3601 inst
.error
= _("Constant value required for number of registers");
3605 num_regs
= inst
.reloc
.exp
.X_add_number
;
3607 if (num_regs
< 1 || num_regs
> 4)
3609 inst
.error
= _("number of registers must be in the range [1:4]");
3616 inst
.instruction
|= CP_T_X
;
3619 inst
.instruction
|= CP_T_Y
;
3622 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3636 /* The instruction specified "ea" or "fd", so we can only accept
3637 [Rn]{!}. The instruction does not really support stacking or
3638 unstacking, so we have to emulate these by setting appropriate
3639 bits and offsets. */
3640 if (skip_past_comma (&str
) == FAIL
3644 inst
.error
= BAD_ARGS
;
3649 skip_whitespace (str
);
3651 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3654 skip_whitespace (str
);
3658 inst
.error
= BAD_ARGS
;
3669 inst
.error
= _("R15 not allowed as base register with write-back");
3676 if (flags
& CP_T_Pre
)
3679 offset
= 3 * num_regs
;
3685 /* Post-increment */
3689 offset
= 3 * num_regs
;
3693 /* No write-back, so convert this into a standard pre-increment
3694 instruction -- aesthetically more pleasing. */
3695 flags
= CP_T_Pre
| CP_T_UD
;
3700 inst
.instruction
|= flags
| offset
;
3702 else if (skip_past_comma (&str
) == FAIL
3703 || cp_address_required_here (&str
) == FAIL
)
3706 inst
.error
= BAD_ARGS
;
3714 do_fp_dyadic (str
, flags
)
3716 unsigned long flags
;
3718 skip_whitespace (str
);
3720 switch (inst
.suffix
)
3725 inst
.instruction
|= 0x00000080;
3728 inst
.instruction
|= 0x00080000;
3734 if (fp_reg_required_here (&str
, 12) == FAIL
)
3737 inst
.error
= BAD_ARGS
;
3741 if (skip_past_comma (&str
) == FAIL
3742 || fp_reg_required_here (&str
, 16) == FAIL
)
3745 inst
.error
= BAD_ARGS
;
3749 if (skip_past_comma (&str
) == FAIL
3750 || fp_op2 (&str
) == FAIL
)
3753 inst
.error
= BAD_ARGS
;
3757 inst
.instruction
|= flags
;
3763 do_fp_monadic (str
, flags
)
3765 unsigned long flags
;
3767 skip_whitespace (str
);
3769 switch (inst
.suffix
)
3774 inst
.instruction
|= 0x00000080;
3777 inst
.instruction
|= 0x00080000;
3783 if (fp_reg_required_here (&str
, 12) == FAIL
)
3786 inst
.error
= BAD_ARGS
;
3790 if (skip_past_comma (&str
) == FAIL
3791 || fp_op2 (&str
) == FAIL
)
3794 inst
.error
= BAD_ARGS
;
3798 inst
.instruction
|= flags
;
3804 do_fp_cmp (str
, flags
)
3806 unsigned long flags
;
3808 skip_whitespace (str
);
3810 if (fp_reg_required_here (&str
, 16) == FAIL
)
3813 inst
.error
= BAD_ARGS
;
3817 if (skip_past_comma (&str
) == FAIL
3818 || fp_op2 (&str
) == FAIL
)
3821 inst
.error
= BAD_ARGS
;
3825 inst
.instruction
|= flags
;
3831 do_fp_from_reg (str
, flags
)
3833 unsigned long flags
;
3835 skip_whitespace (str
);
3837 switch (inst
.suffix
)
3842 inst
.instruction
|= 0x00000080;
3845 inst
.instruction
|= 0x00080000;
3851 if (fp_reg_required_here (&str
, 16) == FAIL
)
3854 inst
.error
= BAD_ARGS
;
3858 if (skip_past_comma (&str
) == FAIL
3859 || reg_required_here (&str
, 12) == FAIL
)
3862 inst
.error
= BAD_ARGS
;
3866 inst
.instruction
|= flags
;
3872 do_fp_to_reg (str
, flags
)
3874 unsigned long flags
;
3876 skip_whitespace (str
);
3878 if (reg_required_here (&str
, 12) == FAIL
)
3881 if (skip_past_comma (&str
) == FAIL
3882 || fp_reg_required_here (&str
, 0) == FAIL
)
3885 inst
.error
= BAD_ARGS
;
3889 inst
.instruction
|= flags
;
3894 /* Thumb specific routines */
3896 /* Parse and validate that a register is of the right form, this saves
3897 repeated checking of this information in many similar cases.
3898 Unlike the 32-bit case we do not insert the register into the opcode
3899 here, since the position is often unknown until the full instruction
3902 thumb_reg (strp
, hi_lo
)
3908 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3916 inst
.error
= _("lo register required");
3924 inst
.error
= _("hi register required");
3936 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3939 thumb_add_sub (str
, subtract
)
3943 int Rd
, Rs
, Rn
= FAIL
;
3945 skip_whitespace (str
);
3947 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3948 || skip_past_comma (&str
) == FAIL
)
3951 inst
.error
= BAD_ARGS
;
3955 if (is_immediate_prefix (*str
))
3959 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3964 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3967 if (skip_past_comma (&str
) == FAIL
)
3969 /* Two operand format, shuffle the registers and pretend there
3974 else if (is_immediate_prefix (*str
))
3977 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3980 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3984 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3985 for the latter case, EXPR contains the immediate that was found. */
3988 /* All register format. */
3989 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3993 inst
.error
= _("dest and source1 must be the same register");
3997 /* Can't do this for SUB */
4000 inst
.error
= _("subtract valid only on lo regs");
4004 inst
.instruction
= (T_OPCODE_ADD_HI
4005 | (Rd
> 7 ? THUMB_H1
: 0)
4006 | (Rn
> 7 ? THUMB_H2
: 0));
4007 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4011 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4012 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4017 /* Immediate expression, now things start to get nasty. */
4019 /* First deal with HI regs, only very restricted cases allowed:
4020 Adjusting SP, and using PC or SP to get an address. */
4021 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4022 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4024 inst
.error
= _("invalid Hi register with immediate");
4028 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4030 /* Value isn't known yet, all we can do is store all the fragments
4031 we know about in the instruction and let the reloc hacking
4033 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4034 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4038 int offset
= inst
.reloc
.exp
.X_add_number
;
4048 /* Quick check, in case offset is MIN_INT */
4051 inst
.error
= _("immediate value out of range");
4060 if (offset
& ~0x1fc)
4062 inst
.error
= _("invalid immediate value for stack adjust");
4065 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4066 inst
.instruction
|= offset
>> 2;
4068 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4071 || (offset
& ~0x3fc))
4073 inst
.error
= _("invalid immediate for address calculation");
4076 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4078 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4084 inst
.error
= _("immediate value out of range");
4087 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4088 inst
.instruction
|= (Rd
<< 8) | offset
;
4094 inst
.error
= _("immediate value out of range");
4097 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4098 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4106 thumb_shift (str
, shift
)
4110 int Rd
, Rs
, Rn
= FAIL
;
4112 skip_whitespace (str
);
4114 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4115 || skip_past_comma (&str
) == FAIL
)
4118 inst
.error
= BAD_ARGS
;
4122 if (is_immediate_prefix (*str
))
4124 /* Two operand immediate format, set Rs to Rd. */
4127 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4132 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4135 if (skip_past_comma (&str
) == FAIL
)
4137 /* Two operand format, shuffle the registers and pretend there
4142 else if (is_immediate_prefix (*str
))
4145 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4148 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4152 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4153 for the latter case, EXPR contains the immediate that was found. */
4159 inst
.error
= _("source1 and dest must be same register");
4165 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4166 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4167 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4170 inst
.instruction
|= Rd
| (Rn
<< 3);
4176 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4177 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4178 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4181 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4183 /* Value isn't known yet, create a dummy reloc and let reloc
4184 hacking fix it up */
4186 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4190 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4192 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4194 inst
.error
= _("Invalid immediate for shift");
4198 /* Shifts of zero are handled by converting to LSL */
4199 if (shift_value
== 0)
4200 inst
.instruction
= T_OPCODE_LSL_I
;
4202 /* Shifts of 32 are encoded as a shift of zero */
4203 if (shift_value
== 32)
4206 inst
.instruction
|= shift_value
<< 6;
4209 inst
.instruction
|= Rd
| (Rs
<< 3);
4215 thumb_mov_compare (str
, move
)
4221 skip_whitespace (str
);
4223 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4224 || skip_past_comma (&str
) == FAIL
)
4227 inst
.error
= BAD_ARGS
;
4231 if (is_immediate_prefix (*str
))
4234 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4237 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4242 if (Rs
< 8 && Rd
< 8)
4244 if (move
== THUMB_MOVE
)
4245 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4246 since a MOV instruction produces unpredictable results */
4247 inst
.instruction
= T_OPCODE_ADD_I3
;
4249 inst
.instruction
= T_OPCODE_CMP_LR
;
4250 inst
.instruction
|= Rd
| (Rs
<< 3);
4254 if (move
== THUMB_MOVE
)
4255 inst
.instruction
= T_OPCODE_MOV_HR
;
4257 inst
.instruction
= T_OPCODE_CMP_HR
;
4260 inst
.instruction
|= THUMB_H1
;
4263 inst
.instruction
|= THUMB_H2
;
4265 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4272 inst
.error
= _("only lo regs allowed with immediate");
4276 if (move
== THUMB_MOVE
)
4277 inst
.instruction
= T_OPCODE_MOV_I8
;
4279 inst
.instruction
= T_OPCODE_CMP_I8
;
4281 inst
.instruction
|= Rd
<< 8;
4283 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4284 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4287 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4291 inst
.error
= _("invalid immediate");
4295 inst
.instruction
|= value
;
4303 thumb_load_store (str
, load_store
, size
)
4308 int Rd
, Rb
, Ro
= FAIL
;
4310 skip_whitespace (str
);
4312 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4313 || skip_past_comma (&str
) == FAIL
)
4316 inst
.error
= BAD_ARGS
;
4323 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4326 if (skip_past_comma (&str
) != FAIL
)
4328 if (is_immediate_prefix (*str
))
4331 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4334 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4339 inst
.reloc
.exp
.X_op
= O_constant
;
4340 inst
.reloc
.exp
.X_add_number
= 0;
4345 inst
.error
= _("expected ']'");
4350 else if (*str
== '=')
4352 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4355 skip_whitespace (str
);
4357 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4362 if ( inst
.reloc
.exp
.X_op
!= O_constant
4363 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4365 inst
.error
= "Constant expression expected";
4369 if (inst
.reloc
.exp
.X_op
== O_constant
4370 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4372 /* This can be done with a mov instruction */
4374 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4375 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4379 /* Insert into literal pool */
4380 if (add_to_lit_pool () == FAIL
)
4383 inst
.error
= "literal pool insertion failed";
4387 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4388 inst
.reloc
.pc_rel
= 1;
4389 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4390 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4396 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4399 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4400 inst
.reloc
.pc_rel
= 1;
4401 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4402 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4407 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4409 if (size
!= THUMB_WORD
)
4411 inst
.error
= _("byte or halfword not valid for base register");
4414 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4416 inst
.error
= _("R15 based store not allowed");
4419 else if (Ro
!= FAIL
)
4421 inst
.error
= _("Invalid base register for register offset");
4426 inst
.instruction
= T_OPCODE_LDR_PC
;
4427 else if (load_store
== THUMB_LOAD
)
4428 inst
.instruction
= T_OPCODE_LDR_SP
;
4430 inst
.instruction
= T_OPCODE_STR_SP
;
4432 inst
.instruction
|= Rd
<< 8;
4433 if (inst
.reloc
.exp
.X_op
== O_constant
)
4435 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4437 if (offset
& ~0x3fc)
4439 inst
.error
= _("invalid offset");
4443 inst
.instruction
|= offset
>> 2;
4446 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4450 inst
.error
= _("invalid base register in load/store");
4453 else if (Ro
== FAIL
)
4455 /* Immediate offset */
4456 if (size
== THUMB_WORD
)
4457 inst
.instruction
= (load_store
== THUMB_LOAD
4458 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4459 else if (size
== THUMB_HALFWORD
)
4460 inst
.instruction
= (load_store
== THUMB_LOAD
4461 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4463 inst
.instruction
= (load_store
== THUMB_LOAD
4464 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4466 inst
.instruction
|= Rd
| (Rb
<< 3);
4468 if (inst
.reloc
.exp
.X_op
== O_constant
)
4470 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4472 if (offset
& ~(0x1f << size
))
4474 inst
.error
= _("Invalid offset");
4477 inst
.instruction
|= (offset
>> size
) << 6;
4480 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4484 /* Register offset */
4485 if (size
== THUMB_WORD
)
4486 inst
.instruction
= (load_store
== THUMB_LOAD
4487 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4488 else if (size
== THUMB_HALFWORD
)
4489 inst
.instruction
= (load_store
== THUMB_LOAD
4490 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4492 inst
.instruction
= (load_store
== THUMB_LOAD
4493 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4495 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4510 /* Handle the Format 4 instructions that do not have equivalents in other
4511 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4519 skip_whitespace (str
);
4521 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4522 || skip_past_comma (&str
) == FAIL
4523 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4525 inst
.error
= BAD_ARGS
;
4529 if (skip_past_comma (&str
) != FAIL
)
4531 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4532 (It isn't allowed for CMP either, but that isn't handled by this
4534 if (inst
.instruction
== T_OPCODE_TST
4535 || inst
.instruction
== T_OPCODE_CMN
4536 || inst
.instruction
== T_OPCODE_NEG
4537 || inst
.instruction
== T_OPCODE_MVN
)
4539 inst
.error
= BAD_ARGS
;
4543 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4548 inst
.error
= _("dest and source1 one must be the same register");
4554 if (inst
.instruction
== T_OPCODE_MUL
4556 as_tsktsk (_("Rs and Rd must be different in MUL"));
4558 inst
.instruction
|= Rd
| (Rs
<< 3);
4566 thumb_add_sub (str
, 0);
4573 thumb_shift (str
, THUMB_ASR
);
4580 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4582 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4583 inst
.reloc
.pc_rel
= 1;
4591 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4593 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4594 inst
.reloc
.pc_rel
= 1;
4598 /* Find the real, Thumb encoded start of a Thumb function. */
4601 find_real_start (symbolP
)
4605 const char * name
= S_GET_NAME (symbolP
);
4606 symbolS
* new_target
;
4608 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4609 #define STUB_NAME ".real_start_of"
4614 /* Names that start with '.' are local labels, not function entry points.
4615 The compiler may generate BL instructions to these labels because it
4616 needs to perform a branch to a far away location. */
4620 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4621 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4623 new_target
= symbol_find (real_start
);
4625 if (new_target
== NULL
)
4627 as_warn ("Failed to find real start of function: %s\n", name
);
4628 new_target
= symbolP
;
4641 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4644 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4645 inst
.reloc
.pc_rel
= 1;
4648 /* If the destination of the branch is a defined symbol which does not have
4649 the THUMB_FUNC attribute, then we must be calling a function which has
4650 the (interfacearm) attribute. We look for the Thumb entry point to that
4651 function and change the branch to refer to that function instead. */
4652 if ( inst
.reloc
.exp
.X_op
== O_symbol
4653 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4654 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4655 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4656 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4665 skip_whitespace (str
);
4667 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4670 /* This sets THUMB_H2 from the top bit of reg. */
4671 inst
.instruction
|= reg
<< 3;
4673 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4674 should cause the alignment to be checked once it is known. This is
4675 because BX PC only works if the instruction is word aligned. */
4684 thumb_mov_compare (str
, THUMB_COMPARE
);
4694 skip_whitespace (str
);
4696 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4700 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4704 if (skip_past_comma (&str
) == FAIL
4705 || (range
= reg_list (&str
)) == FAIL
)
4708 inst
.error
= BAD_ARGS
;
4712 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4714 /* This really doesn't seem worth it. */
4715 inst
.reloc
.type
= BFD_RELOC_NONE
;
4716 inst
.error
= _("Expression too complex");
4722 inst
.error
= _("only lo-regs valid in load/store multiple");
4726 inst
.instruction
|= (Rb
<< 8) | range
;
4734 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4741 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4748 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4757 skip_whitespace (str
);
4759 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4760 || skip_past_comma (&str
) == FAIL
4762 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4763 || skip_past_comma (&str
) == FAIL
4764 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4768 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4772 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4780 thumb_shift (str
, THUMB_LSL
);
4787 thumb_shift (str
, THUMB_LSR
);
4794 thumb_mov_compare (str
, THUMB_MOVE
);
4803 skip_whitespace (str
);
4805 if ((range
= reg_list (&str
)) == FAIL
)
4808 inst
.error
= BAD_ARGS
;
4812 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4814 /* This really doesn't seem worth it. */
4815 inst
.reloc
.type
= BFD_RELOC_NONE
;
4816 inst
.error
= _("Expression too complex");
4822 if ((inst
.instruction
== T_OPCODE_PUSH
4823 && (range
& ~0xff) == 1 << REG_LR
)
4824 || (inst
.instruction
== T_OPCODE_POP
4825 && (range
& ~0xff) == 1 << REG_PC
))
4827 inst
.instruction
|= THUMB_PP_PC_LR
;
4832 inst
.error
= _("invalid register list to push/pop instruction");
4837 inst
.instruction
|= range
;
4845 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4852 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4859 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4866 thumb_add_sub (str
, 1);
4873 skip_whitespace (str
);
4875 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4878 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4887 /* This is a pseudo-op of the form "adr rd, label" to be converted
4888 into a relative address of the form "add rd, pc, #label-.-4" */
4889 skip_whitespace (str
);
4891 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4892 || skip_past_comma (&str
) == FAIL
4893 || my_get_expression (&inst
.reloc
.exp
, &str
))
4896 inst
.error
= BAD_ARGS
;
4900 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4901 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4902 inst
.reloc
.pc_rel
= 1;
4903 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4911 int len
= strlen (reg_table
[entry
].name
) + 2;
4912 char * buf
= (char *) xmalloc (len
);
4913 char * buf2
= (char *) xmalloc (len
);
4916 #ifdef REGISTER_PREFIX
4917 buf
[i
++] = REGISTER_PREFIX
;
4920 strcpy (buf
+ i
, reg_table
[entry
].name
);
4922 for (i
= 0; buf
[i
]; i
++)
4923 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4927 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4928 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4932 insert_reg_alias (str
, regnum
)
4936 struct reg_entry
*new =
4937 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4938 char *name
= xmalloc (strlen (str
) + 1);
4942 new->number
= regnum
;
4944 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4948 set_constant_flonums ()
4952 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4953 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4962 if ( (arm_ops_hsh
= hash_new ()) == NULL
4963 || (arm_tops_hsh
= hash_new ()) == NULL
4964 || (arm_cond_hsh
= hash_new ()) == NULL
4965 || (arm_shift_hsh
= hash_new ()) == NULL
4966 || (arm_reg_hsh
= hash_new ()) == NULL
4967 || (arm_psr_hsh
= hash_new ()) == NULL
)
4968 as_fatal (_("Virtual memory exhausted"));
4970 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4971 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4972 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4973 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4974 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4975 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4976 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4977 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4978 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4979 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4981 for (i
= 0; reg_table
[i
].name
; i
++)
4984 set_constant_flonums ();
4986 #if defined OBJ_COFF || defined OBJ_ELF
4988 unsigned int flags
= 0;
4990 /* Set the flags in the private structure */
4991 if (uses_apcs_26
) flags
|= F_APCS26
;
4992 if (support_interwork
) flags
|= F_INTERWORK
;
4993 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4994 if (pic_code
) flags
|= F_PIC
;
4995 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
4997 bfd_set_private_flags (stdoutput
, flags
);
5004 /* Record the CPU type as well */
5005 switch (cpu_variant
& ARM_CPU_MASK
)
5008 mach
= bfd_mach_arm_2
;
5011 case ARM_3
: /* also ARM_250 */
5012 mach
= bfd_mach_arm_2a
;
5016 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
5017 mach
= bfd_mach_arm_4
;
5020 case ARM_7
: /* also ARM_6 */
5021 mach
= bfd_mach_arm_3
;
5025 /* Catch special cases. */
5026 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5028 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5029 mach
= bfd_mach_arm_5T
;
5030 else if (cpu_variant
& ARM_EXT_V5
)
5031 mach
= bfd_mach_arm_5
;
5032 else if (cpu_variant
& ARM_THUMB
)
5033 mach
= bfd_mach_arm_4T
;
5034 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5035 mach
= bfd_mach_arm_4
;
5036 else if (cpu_variant
& ARM_LONGMUL
)
5037 mach
= bfd_mach_arm_3M
;
5040 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5044 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5045 for use in the a.out file, and stores them in the array pointed to by buf.
5046 This knows about the endian-ness of the target machine and does
5047 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5048 2 (short) and 4 (long) Floating numbers are put out as a series of
5049 LITTLENUMS (shorts, here at least). */
5051 md_number_to_chars (buf
, val
, n
)
5056 if (target_big_endian
)
5057 number_to_chars_bigendian (buf
, val
, n
);
5059 number_to_chars_littleendian (buf
, val
, n
);
5063 md_chars_to_number (buf
, n
)
5068 unsigned char * where
= (unsigned char *) buf
;
5070 if (target_big_endian
)
5075 result
|= (*where
++ & 255);
5083 result
|= (where
[n
] & 255);
5090 /* Turn a string in input_line_pointer into a floating point constant
5091 of type TYPE, and store the appropriate bytes in *litP. The number
5092 of LITTLENUMS emitted is stored in *sizeP . An error message is
5093 returned, or NULL on OK.
5095 Note that fp constants aren't represent in the normal way on the ARM.
5096 In big endian mode, things are as expected. However, in little endian
5097 mode fp constants are big-endian word-wise, and little-endian byte-wise
5098 within the words. For example, (double) 1.1 in big endian mode is
5099 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5100 the byte sequence 99 99 f1 3f 9a 99 99 99.
5102 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5105 md_atof (type
, litP
, sizeP
)
5111 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5143 return _("Bad call to MD_ATOF()");
5146 t
= atof_ieee (input_line_pointer
, type
, words
);
5148 input_line_pointer
= t
;
5151 if (target_big_endian
)
5153 for (i
= 0; i
< prec
; i
++)
5155 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5161 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5162 8 byte float the order is 1 0 3 2. */
5163 for (i
= 0; i
< prec
; i
+= 2)
5165 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5166 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5174 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5176 md_pcrel_from (fixP
)
5180 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5181 && fixP
->fx_subsy
== NULL
)
5184 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5186 /* PC relative addressing on the Thumb is slightly odd
5187 as the bottom two bits of the PC are forced to zero
5188 for the calculation. */
5189 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5192 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5195 /* Round up a section size to the appropriate boundary. */
5197 md_section_align (segment
, size
)
5204 /* Round all sects to multiple of 4 */
5205 return (size
+ 3) & ~3;
5209 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5210 we have no need to default values of symbols. */
5214 md_undefined_symbol (name
)
5218 if (name
[0] == '_' && name
[1] == 'G'
5219 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5223 if (symbol_find (name
))
5224 as_bad ("GOT already in the symbol table");
5226 GOT_symbol
= symbol_new (name
, undefined_section
,
5227 (valueT
)0, & zero_address_frag
);
5237 /* arm_reg_parse () := if it looks like a register, return its token and
5238 advance the pointer. */
5242 register char ** ccp
;
5244 char * start
= * ccp
;
5247 struct reg_entry
* reg
;
5249 #ifdef REGISTER_PREFIX
5250 if (*start
!= REGISTER_PREFIX
)
5255 #ifdef OPTIONAL_REGISTER_PREFIX
5256 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5260 if (!isalpha (*p
) || !is_name_beginner (*p
))
5264 while (isalpha (c
) || isdigit (c
) || c
== '_')
5268 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5282 register char ** ccp
;
5284 char * start
= * ccp
;
5287 CONST
struct asm_psr
* psr
;
5291 while (isalpha (c
) || c
== '_')
5295 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5308 md_apply_fix3 (fixP
, val
, seg
)
5313 offsetT value
= * val
;
5315 unsigned int newimm
;
5318 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5319 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5321 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5323 /* Note whether this will delete the relocation. */
5324 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5325 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5328 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5332 /* If this symbol is in a different section then we need to leave it for
5333 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5334 so we have to undo it's effects here. */
5337 if (fixP
->fx_addsy
!= NULL
5338 && S_IS_DEFINED (fixP
->fx_addsy
)
5339 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5342 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5346 value
+= md_pcrel_from (fixP
);
5350 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5352 switch (fixP
->fx_r_type
)
5354 case BFD_RELOC_ARM_IMMEDIATE
:
5355 newimm
= validate_immediate (value
);
5356 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5358 /* If the instruction will fail, see if we can fix things up by
5359 changing the opcode. */
5360 if (newimm
== (unsigned int) FAIL
5361 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5363 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5364 _("invalid constant (%lx) after fixup"),
5365 (unsigned long) value
);
5369 newimm
|= (temp
& 0xfffff000);
5370 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5373 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5375 unsigned int highpart
= 0;
5376 unsigned int newinsn
= 0xe1a00000; /* nop */
5377 newimm
= validate_immediate (value
);
5378 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5380 /* If the instruction will fail, see if we can fix things up by
5381 changing the opcode. */
5382 if (newimm
== (unsigned int) FAIL
5383 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5385 /* No ? OK - try using two ADD instructions to generate the value. */
5386 newimm
= validate_immediate_twopart (value
, & highpart
);
5388 /* Yes - then make sure that the second instruction is also an add. */
5389 if (newimm
!= (unsigned int) FAIL
)
5391 /* Still No ? Try using a negated value. */
5392 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5393 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5394 /* Otherwise - give up. */
5397 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5398 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5402 /* Replace the first operand in the 2nd instruction (which is the PC)
5403 with the destination register. We have already added in the PC in the
5404 first instruction and we do not want to do it again. */
5405 newinsn
&= ~ 0xf0000;
5406 newinsn
|= ((newinsn
& 0x0f000) << 4);
5409 newimm
|= (temp
& 0xfffff000);
5410 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5412 highpart
|= (newinsn
& 0xfffff000);
5413 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5417 case BFD_RELOC_ARM_OFFSET_IMM
:
5423 if (validate_offset_imm (value
, 0) == FAIL
)
5425 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5426 _("bad immediate value for offset (%ld)"), (long) value
);
5430 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5431 newval
&= 0xff7ff000;
5432 newval
|= value
| (sign
? INDEX_UP
: 0);
5433 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5436 case BFD_RELOC_ARM_OFFSET_IMM8
:
5437 case BFD_RELOC_ARM_HWLITERAL
:
5443 if (validate_offset_imm (value
, 1) == FAIL
)
5445 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5446 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5447 _("invalid literal constant: pool needs to be closer"));
5449 as_bad (_("bad immediate value for half-word offset (%ld)"),
5454 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5455 newval
&= 0xff7ff0f0;
5456 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5457 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5460 case BFD_RELOC_ARM_LITERAL
:
5466 if (validate_offset_imm (value
, 0) == FAIL
)
5468 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5469 _("invalid literal constant: pool needs to be closer"));
5473 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5474 newval
&= 0xff7ff000;
5475 newval
|= value
| (sign
? INDEX_UP
: 0);
5476 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5479 case BFD_RELOC_ARM_SHIFT_IMM
:
5480 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5481 if (((unsigned long) value
) > 32
5483 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5485 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5486 _("shift expression is too large"));
5491 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5492 else if (value
== 32)
5494 newval
&= 0xfffff07f;
5495 newval
|= (value
& 0x1f) << 7;
5496 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5499 case BFD_RELOC_ARM_SWI
:
5500 if (arm_data
->thumb_mode
)
5502 if (((unsigned long) value
) > 0xff)
5503 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5504 _("Invalid swi expression"));
5505 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5507 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5511 if (((unsigned long) value
) > 0x00ffffff)
5512 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5513 _("Invalid swi expression"));
5514 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5516 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5520 case BFD_RELOC_ARM_MULTI
:
5521 if (((unsigned long) value
) > 0xffff)
5522 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5523 _("Invalid expression in load/store multiple"));
5524 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5525 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5528 case BFD_RELOC_ARM_PCREL_BRANCH
:
5529 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5533 value
= fixP
->fx_offset
;
5535 value
= (value
>> 2) & 0x00ffffff;
5536 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5537 newval
= value
| (newval
& 0xff000000);
5538 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5542 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5543 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5545 addressT diff
= (newval
& 0xff) << 1;
5550 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5551 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5552 _("Branch out of range"));
5553 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5555 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5558 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5559 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5561 addressT diff
= (newval
& 0x7ff) << 1;
5566 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5567 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5568 _("Branch out of range"));
5569 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5571 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5574 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5579 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5580 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5581 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5582 if (diff
& 0x400000)
5585 value
= fixP
->fx_offset
;
5588 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5589 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5590 _("Branch with link out of range"));
5592 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5593 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5594 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5595 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5600 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5601 md_number_to_chars (buf
, value
, 1);
5603 else if (!target_oabi
)
5605 value
= fixP
->fx_offset
;
5606 md_number_to_chars (buf
, value
, 1);
5612 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5613 md_number_to_chars (buf
, value
, 2);
5615 else if (!target_oabi
)
5617 value
= fixP
->fx_offset
;
5618 md_number_to_chars (buf
, value
, 2);
5624 case BFD_RELOC_ARM_GOT32
:
5625 case BFD_RELOC_ARM_GOTOFF
:
5626 md_number_to_chars (buf
, 0, 4);
5632 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5633 md_number_to_chars (buf
, value
, 4);
5635 else if (!target_oabi
)
5637 value
= fixP
->fx_offset
;
5638 md_number_to_chars (buf
, value
, 4);
5644 case BFD_RELOC_ARM_PLT32
:
5645 /* It appears the instruction is fully prepared at this point. */
5649 case BFD_RELOC_ARM_GOTPC
:
5650 md_number_to_chars (buf
, value
, 4);
5653 case BFD_RELOC_ARM_CP_OFF_IMM
:
5655 if (value
< -1023 || value
> 1023 || (value
& 3))
5656 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5657 _("Illegal value for co-processor offset"));
5660 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5661 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5662 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5665 case BFD_RELOC_ARM_THUMB_OFFSET
:
5666 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5667 /* Exactly what ranges, and where the offset is inserted depends on
5668 the type of instruction, we can establish this from the top 4 bits */
5669 switch (newval
>> 12)
5671 case 4: /* PC load */
5672 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5673 forced to zero for these loads, so we will need to round
5674 up the offset if the instruction address is not word
5675 aligned (since the final address produced must be, and
5676 we can only describe word-aligned immediate offsets). */
5678 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5679 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5680 _("Invalid offset, target not word aligned (0x%08X)"),
5681 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5683 if ((value
+ 2) & ~0x3fe)
5684 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5685 _("Invalid offset, value too big (0x%08X)"), value
);
5687 /* Round up, since pc will be rounded down. */
5688 newval
|= (value
+ 2) >> 2;
5691 case 9: /* SP load/store */
5693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5694 _("Invalid offset, value too big (0x%08X)"), value
);
5695 newval
|= value
>> 2;
5698 case 6: /* Word load/store */
5700 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5701 _("Invalid offset, value too big (0x%08X)"), value
);
5702 newval
|= value
<< 4; /* 6 - 2 */
5705 case 7: /* Byte load/store */
5707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5708 _("Invalid offset, value too big (0x%08X)"), value
);
5709 newval
|= value
<< 6;
5712 case 8: /* Halfword load/store */
5714 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5715 _("Invalid offset, value too big (0x%08X)"), value
);
5716 newval
|= value
<< 5; /* 6 - 1 */
5720 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5721 "Unable to process relocation for thumb opcode: %lx",
5722 (unsigned long) newval
);
5725 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5728 case BFD_RELOC_ARM_THUMB_ADD
:
5729 /* This is a complicated relocation, since we use it for all of
5730 the following immediate relocations:
5733 9bit ADD/SUB SP word-aligned
5734 10bit ADD PC/SP word-aligned
5736 The type of instruction being processed is encoded in the
5742 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5744 int rd
= (newval
>> 4) & 0xf;
5745 int rs
= newval
& 0xf;
5746 int subtract
= newval
& 0x8000;
5751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5752 _("Invalid immediate for stack address calculation"));
5753 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5754 newval
|= value
>> 2;
5756 else if (rs
== REG_PC
|| rs
== REG_SP
)
5760 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5761 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5762 (unsigned long) value
);
5763 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5765 newval
|= value
>> 2;
5770 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5771 _("Invalid 8bit immediate"));
5772 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5773 newval
|= (rd
<< 8) | value
;
5778 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5779 _("Invalid 3bit immediate"));
5780 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5781 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5784 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5787 case BFD_RELOC_ARM_THUMB_IMM
:
5788 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5789 switch (newval
>> 11)
5791 case 0x04: /* 8bit immediate MOV */
5792 case 0x05: /* 8bit immediate CMP */
5793 if (value
< 0 || value
> 255)
5794 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5795 _("Invalid immediate: %ld is too large"),
5803 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5806 case BFD_RELOC_ARM_THUMB_SHIFT
:
5807 /* 5bit shift value (0..31) */
5808 if (value
< 0 || value
> 31)
5809 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5810 _("Illegal Thumb shift value: %ld"), (long) value
);
5811 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5812 newval
|= value
<< 6;
5813 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5816 case BFD_RELOC_VTABLE_INHERIT
:
5817 case BFD_RELOC_VTABLE_ENTRY
:
5821 case BFD_RELOC_NONE
:
5823 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5824 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5830 /* Translate internal representation of relocation info to BFD target
5833 tc_gen_reloc (section
, fixp
)
5838 bfd_reloc_code_real_type code
;
5840 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5842 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5843 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5844 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5846 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5848 if (fixp
->fx_pcrel
== 0)
5849 reloc
->addend
= fixp
->fx_offset
;
5851 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5853 reloc
->addend
= fixp
->fx_offset
;
5856 switch (fixp
->fx_r_type
)
5861 code
= BFD_RELOC_8_PCREL
;
5868 code
= BFD_RELOC_16_PCREL
;
5875 code
= BFD_RELOC_32_PCREL
;
5879 case BFD_RELOC_ARM_PCREL_BRANCH
:
5881 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5882 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5883 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5884 case BFD_RELOC_VTABLE_ENTRY
:
5885 case BFD_RELOC_VTABLE_INHERIT
:
5886 code
= fixp
->fx_r_type
;
5889 case BFD_RELOC_ARM_LITERAL
:
5890 case BFD_RELOC_ARM_HWLITERAL
:
5891 /* If this is called then the a literal has been referenced across
5892 a section boundary - possibly due to an implicit dump */
5893 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5894 _("Literal referenced across section boundary (Implicit dump?)"));
5898 case BFD_RELOC_ARM_GOT32
:
5899 case BFD_RELOC_ARM_GOTOFF
:
5900 case BFD_RELOC_ARM_PLT32
:
5901 code
= fixp
->fx_r_type
;
5905 case BFD_RELOC_ARM_IMMEDIATE
:
5906 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5907 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5911 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5912 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5913 _("ADRL used for a symbol not defined in the same file"),
5917 case BFD_RELOC_ARM_OFFSET_IMM
:
5918 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5919 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5926 switch (fixp
->fx_r_type
)
5928 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5929 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5930 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5931 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5932 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5933 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5934 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5935 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5936 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5937 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5938 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5939 default: type
= _("<unknown>"); break;
5941 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5942 _("Can not represent %s relocation in this object file format (%d)"),
5943 type
, fixp
->fx_pcrel
);
5949 if (code
== BFD_RELOC_32_PCREL
5951 && fixp
->fx_addsy
== GOT_symbol
)
5953 code
= BFD_RELOC_ARM_GOTPC
;
5954 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5958 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5960 if (reloc
->howto
== NULL
)
5962 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5963 _("Can not represent %s relocation in this object file format"),
5964 bfd_get_reloc_code_name (code
));
5968 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5969 vtable entry to be used in the relocation's section offset. */
5970 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5971 reloc
->address
= fixp
->fx_offset
;
5977 md_estimate_size_before_relax (fragP
, segtype
)
5981 as_fatal (_("md_estimate_size_before_relax\n"));
5986 output_inst
PARAMS ((void))
5992 as_bad (inst
.error
);
5996 to
= frag_more (inst
.size
);
5998 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6000 assert (inst
.size
== (2 * THUMB_SIZE
));
6001 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6002 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6004 else if (inst
.size
> INSN_SIZE
)
6006 assert (inst
.size
== (2 * INSN_SIZE
));
6007 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6008 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6011 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6013 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6014 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6015 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6030 /* Align the instruction.
6031 This may not be the right thing to do but ... */
6032 /* arm_align (2, 0); */
6033 listing_prev_line (); /* Defined in listing.h */
6035 /* Align the previous label if needed. */
6036 if (last_label_seen
!= NULL
)
6038 symbol_set_frag (last_label_seen
, frag_now
);
6039 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6040 S_SET_SEGMENT (last_label_seen
, now_seg
);
6043 memset (&inst
, '\0', sizeof (inst
));
6044 inst
.reloc
.type
= BFD_RELOC_NONE
;
6046 skip_whitespace (str
);
6048 /* Scan up to the end of the op-code, which must end in white space or
6050 for (start
= p
= str
; *p
!= '\0'; p
++)
6056 as_bad (_("No operator -- statement `%s'\n"), str
);
6062 CONST
struct thumb_opcode
* opcode
;
6066 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6071 /* Check that this instruction is supported for this CPU. */
6072 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6074 as_bad (_("selected processor does not support this opcode"));
6078 inst
.instruction
= opcode
->value
;
6079 inst
.size
= opcode
->size
;
6080 (*opcode
->parms
)(p
);
6087 CONST
struct asm_opcode
* opcode
;
6088 unsigned long cond_code
;
6090 inst
.size
= INSN_SIZE
;
6091 /* p now points to the end of the opcode, probably white space, but we
6092 have to break the opcode up in case it contains condionals and flags;
6093 keep trying with progressively smaller basic instructions until one
6094 matches, or we run out of opcode. */
6095 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6096 for (; q
!= str
; q
--)
6100 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6103 if (opcode
&& opcode
->template)
6105 unsigned long flag_bits
= 0;
6108 /* Check that this instruction is supported for this CPU. */
6109 if ((opcode
->variants
& cpu_variant
) == 0)
6112 inst
.instruction
= opcode
->value
;
6113 if (q
== p
) /* Just a simple opcode. */
6115 if (opcode
->comp_suffix
)
6117 if (*opcode
->comp_suffix
!= '\0')
6118 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
6119 str
, opcode
->comp_suffix
);
6121 /* Not a conditional instruction. */
6122 (*opcode
->parms
)(q
, 0);
6126 /* A conditional instruction with default condition. */
6127 inst
.instruction
|= COND_ALWAYS
;
6128 (*opcode
->parms
)(q
, 0);
6134 /* Not just a simple opcode. Check if extra is a conditional. */
6138 CONST
struct asm_cond
*cond
;
6142 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6146 if (cond
->value
== 0xf0000000)
6148 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6150 cond_code
= cond
->value
;
6154 cond_code
= COND_ALWAYS
;
6157 cond_code
= COND_ALWAYS
;
6160 /* Apply the conditional, or complain it's not allowed. */
6161 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6163 /* Instruction isn't conditional */
6164 if (cond_code
!= COND_ALWAYS
)
6166 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6171 /* Instruction is conditional: set the condition into it. */
6172 inst
.instruction
|= cond_code
;
6175 /* If there is a compulsory suffix, it should come here, before
6176 any optional flags. */
6177 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6179 CONST
char *s
= opcode
->comp_suffix
;
6191 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6192 opcode
->comp_suffix
);
6199 /* The remainder, if any should now be flags for the instruction;
6200 Scan these checking each one found with the opcode. */
6204 CONST
struct asm_flg
*flag
= opcode
->flags
;
6213 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6215 if (streq (r
, flag
[flagno
].template))
6217 flag_bits
|= flag
[flagno
].set_bits
;
6223 if (! flag
[flagno
].template)
6230 (*opcode
->parms
) (p
, flag_bits
);
6240 /* It wasn't an instruction, but it might be a register alias of the form
6243 skip_whitespace (q
);
6248 if (*q
&& !strncmp (q
, ".req ", 4))
6251 char * copy_of_str
= str
;
6255 skip_whitespace (q
);
6257 for (r
= q
; *r
!= '\0'; r
++)
6267 regnum
= arm_reg_parse (& q
);
6270 reg
= arm_reg_parse (& str
);
6275 insert_reg_alias (str
, regnum
);
6277 as_warn (_("register '%s' does not exist\n"), q
);
6279 else if (regnum
!= FAIL
)
6282 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6284 /* Do not warn about redefinitions to the same alias. */
6287 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6291 as_warn (_("ignoring incomplete .req pseuso op"));
6298 as_bad (_("bad instruction `%s'"), start
);
6303 * Invocation line includes a switch not recognized by the base assembler.
6304 * See if it's a processor-specific option. These are:
6305 * Cpu variants, the arm part is optional:
6306 * -m[arm]1 Currently not supported.
6307 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6308 * -m[arm]3 Arm 3 processor
6309 * -m[arm]6[xx], Arm 6 processors
6310 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6311 * -m[arm]8[10] Arm 8 processors
6312 * -m[arm]9[20][tdmi] Arm 9 processors
6313 * -mstrongarm[110[0]] StrongARM processors
6314 * -m[arm]v[2345] Arm architectures
6315 * -mall All (except the ARM1)
6317 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6318 * -mfpe-old (No float load/store multiples)
6319 * -mno-fpu Disable all floating point instructions
6320 * Run-time endian selection:
6321 * -EB big endian cpu
6322 * -EL little endian cpu
6323 * ARM Procedure Calling Standard:
6324 * -mapcs-32 32 bit APCS
6325 * -mapcs-26 26 bit APCS
6326 * -mapcs-float Pass floats in float regs
6327 * -mapcs-reentrant Position independent code
6328 * -mthumb-interwork Code supports Arm/Thumb interworking
6329 * -moabi Old ELF ABI
6332 CONST
char * md_shortopts
= "m:k";
6333 struct option md_longopts
[] =
6335 #ifdef ARM_BI_ENDIAN
6336 #define OPTION_EB (OPTION_MD_BASE + 0)
6337 {"EB", no_argument
, NULL
, OPTION_EB
},
6338 #define OPTION_EL (OPTION_MD_BASE + 1)
6339 {"EL", no_argument
, NULL
, OPTION_EL
},
6341 #define OPTION_OABI (OPTION_MD_BASE +2)
6342 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6345 {NULL
, no_argument
, NULL
, 0}
6347 size_t md_longopts_size
= sizeof (md_longopts
);
6350 md_parse_option (c
, arg
)
6358 #ifdef ARM_BI_ENDIAN
6360 target_big_endian
= 1;
6363 target_big_endian
= 0;
6371 if (streq (str
, "fpa10"))
6372 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6373 else if (streq (str
, "fpa11"))
6374 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6375 else if (streq (str
, "fpe-old"))
6376 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6382 if (streq (str
, "no-fpu"))
6383 cpu_variant
&= ~FPU_ALL
;
6388 if (streq (str
, "oabi"))
6394 /* Limit assembler to generating only Thumb instructions: */
6395 if (streq (str
, "thumb"))
6397 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6398 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6401 else if (streq (str
, "thumb-interwork"))
6403 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCH_V4
;
6404 #if defined OBJ_COFF || defined OBJ_ELF
6405 support_interwork
= true;
6413 if (streq (str
, "all"))
6415 cpu_variant
= ARM_ALL
| FPU_ALL
;
6418 #if defined OBJ_COFF || defined OBJ_ELF
6419 if (! strncmp (str
, "apcs-", 5))
6421 /* GCC passes on all command line options starting "-mapcs-..."
6422 to us, so we must parse them here. */
6426 if (streq (str
, "32"))
6428 uses_apcs_26
= false;
6431 else if (streq (str
, "26"))
6433 uses_apcs_26
= true;
6436 else if (streq (str
, "frame"))
6438 /* Stack frames are being generated - does not affect
6442 else if (streq (str
, "stack-check"))
6444 /* Stack checking is being performed - does not affect
6445 linkage, but does require that the functions
6446 __rt_stkovf_split_small and __rt_stkovf_split_big be
6447 present in the final link. */
6451 else if (streq (str
, "float"))
6453 /* Floating point arguments are being passed in the floating
6454 point registers. This does affect linking, since this
6455 version of the APCS is incompatible with the version that
6456 passes floating points in the integer registers. */
6458 uses_apcs_float
= true;
6461 else if (streq (str
, "reentrant"))
6463 /* Reentrant code has been generated. This does affect
6464 linking, since there is no point in linking reentrant/
6465 position independent code with absolute position code. */
6470 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6474 /* Strip off optional "arm" */
6475 if (! strncmp (str
, "arm", 3))
6481 if (streq (str
, "1"))
6482 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6488 if (streq (str
, "2"))
6489 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6490 else if (streq (str
, "250"))
6491 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6497 if (streq (str
, "3"))
6498 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6504 switch (strtol (str
, NULL
, 10))
6511 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6519 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6531 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6537 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6541 cpu_variant
|= ARM_LONGMUL
;
6544 case 'f': /* fe => fp enabled cpu. */
6550 case 'c': /* Left over from 710c processor name. */
6551 case 'd': /* Debug */
6552 case 'i': /* Embedded ICE */
6553 /* Included for completeness in ARM processor naming. */
6563 if (streq (str
, "8") || streq (str
, "810"))
6564 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6570 if (streq (str
, "9"))
6571 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6572 else if (streq (str
, "920"))
6573 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6574 else if (streq (str
, "920t"))
6575 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6576 else if (streq (str
, "9tdmi"))
6577 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6584 if (streq (str
, "strongarm")
6585 || streq (str
, "strongarm110")
6586 || streq (str
, "strongarm1100"))
6587 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6593 /* Select variant based on architecture rather than processor */
6599 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6600 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6601 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6606 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6610 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6612 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6617 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6621 case 't': cpu_variant
|= ARM_THUMB
; break;
6623 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6628 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6631 case 't': cpu_variant
|= ARM_THUMB
; break;
6632 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
6634 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6640 as_bad (_("Invalid architecture variant -m%s"), arg
);
6647 as_bad (_("Invalid processor variant -m%s"), arg
);
6653 #if defined OBJ_ELF || defined OBJ_COFF
6672 ARM Specific Assembler Options:\n\
6673 -m[arm][<processor name>] select processor variant\n\
6674 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6675 -mthumb only allow Thumb instructions\n\
6676 -mthumb-interwork mark the assembled code as supporting interworking\n\
6677 -mall allow any instruction\n\
6678 -mfpa10, -mfpa11 select floating point architecture\n\
6679 -mfpe-old don't allow floating-point multiple instructions\n\
6680 -mno-fpu don't allow any floating-point instructions.\n"));
6683 -k generate PIC code.\n"));
6684 #if defined OBJ_COFF || defined OBJ_ELF
6687 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6690 -mapcs-float floating point args are passed in FP regs\n"));
6693 -mapcs-reentrant the code is position independent/reentrant\n"));
6698 -moabi support the old ELF ABI\n"));
6700 #ifdef ARM_BI_ENDIAN
6703 -EB assemble code for a big endian cpu\n\
6704 -EL assemble code for a little endian cpu\n"));
6708 /* We need to be able to fix up arbitrary expressions in some statements.
6709 This is so that we can handle symbols that are an arbitrary distance from
6710 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6711 which returns part of an address in a form which will be valid for
6712 a data instruction. We do this by pushing the expression into a symbol
6713 in the expr_section, and creating a fix for that. */
6716 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6725 arm_fix_data
* arm_data
;
6733 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6737 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6742 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6743 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6744 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6745 arm_data
->thumb_mode
= thumb_mode
;
6751 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6753 cons_fix_new_arm (frag
, where
, size
, exp
)
6759 bfd_reloc_code_real_type type
;
6764 * @@ Should look at CPU word size.
6769 type
= BFD_RELOC_16
;
6773 type
= BFD_RELOC_32
;
6776 type
= BFD_RELOC_64
;
6780 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6783 /* A good place to do this, although this was probably not intended
6784 for this kind of use. We need to dump the literal pool before
6785 references are made to a null symbol pointer. */
6789 if (current_poolP
== NULL
)
6792 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6794 listing_prev_line ();
6798 arm_start_line_hook ()
6800 last_label_seen
= NULL
;
6804 arm_frob_label (sym
)
6807 last_label_seen
= sym
;
6809 ARM_SET_THUMB (sym
, thumb_mode
);
6811 #if defined OBJ_COFF || defined OBJ_ELF
6812 ARM_SET_INTERWORK (sym
, support_interwork
);
6815 if (label_is_thumb_function_name
)
6817 /* When the address of a Thumb function is taken the bottom
6818 bit of that address should be set. This will allow
6819 interworking between Arm and Thumb functions to work
6822 THUMB_SET_FUNC (sym
, 1);
6824 label_is_thumb_function_name
= false;
6828 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6832 arm_adjust_symtab ()
6837 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6839 if (ARM_IS_THUMB (sym
))
6841 if (THUMB_IS_FUNC (sym
))
6843 /* Mark the symbol as a Thumb function. */
6844 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6845 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6846 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6848 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6849 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6851 as_bad (_("%s: unexpected function type: %d"),
6852 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6854 else switch (S_GET_STORAGE_CLASS (sym
))
6857 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6860 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6863 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6865 default: /* do nothing */
6870 if (ARM_IS_INTERWORK (sym
))
6871 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6876 elf_symbol_type
* elf_sym
;
6879 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6881 if (ARM_IS_THUMB (sym
))
6883 if (THUMB_IS_FUNC (sym
))
6885 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6886 bind
= ELF_ST_BIND (elf_sym
);
6887 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6897 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6899 *input_line_pointer
= '/';
6900 input_line_pointer
+= 5;
6901 *input_line_pointer
= 0;
6909 arm_canonicalize_symbol_name (name
)
6914 if (thumb_mode
&& (len
= strlen (name
)) > 5
6915 && streq (name
+ len
- 5, "/data"))
6916 *(name
+ len
- 5) = 0;
6922 arm_validate_fix (fixP
)
6925 /* If the destination of the branch is a defined symbol which does not have
6926 the THUMB_FUNC attribute, then we must be calling a function which has
6927 the (interfacearm) attribute. We look for the Thumb entry point to that
6928 function and change the branch to refer to that function instead. */
6929 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6930 && fixP
->fx_addsy
!= NULL
6931 && S_IS_DEFINED (fixP
->fx_addsy
)
6932 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6934 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6942 /* Relocations against Thumb function names must be left unadjusted,
6943 so that the linker can use this information to correctly set the
6944 bottom bit of their addresses. The MIPS version of this function
6945 also prevents relocations that are mips-16 specific, but I do not
6946 know why it does this.
6949 There is one other problem that ought to be addressed here, but
6950 which currently is not: Taking the address of a label (rather
6951 than a function) and then later jumping to that address. Such
6952 addresses also ought to have their bottom bit set (assuming that
6953 they reside in Thumb code), but at the moment they will not. */
6956 arm_fix_adjustable (fixP
)
6959 if (fixP
->fx_addsy
== NULL
)
6962 /* Prevent all adjustments to global symbols. */
6963 if (S_IS_EXTERN (fixP
->fx_addsy
))
6966 if (S_IS_WEAK (fixP
->fx_addsy
))
6969 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6970 && fixP
->fx_subsy
== NULL
)
6973 /* We need the symbol name for the VTABLE entries */
6974 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6975 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6982 elf32_arm_target_format ()
6984 if (target_big_endian
)
6986 return "elf32-bigarm-oabi";
6988 return "elf32-bigarm";
6991 return "elf32-littlearm-oabi";
6993 return "elf32-littlearm";
6997 armelf_frob_symbol (symp
, puntp
)
7001 elf_frob_symbol (symp
, puntp
);
7005 arm_force_relocation (fixp
)
7008 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7009 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7010 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7011 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7017 static bfd_reloc_code_real_type
7027 bfd_reloc_code_real_type reloc
;
7031 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7032 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7033 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7034 /* ScottB: Jan 30, 1998 */
7035 /* Added support for parsing "var(PLT)" branch instructions */
7036 /* generated by GCC for PLT relocs */
7037 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7038 { NULL
, 0, BFD_RELOC_UNUSED
}
7042 for (i
= 0, ip
= input_line_pointer
;
7043 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7045 id
[i
] = tolower (*ip
);
7047 for (i
= 0; reloc_map
[i
].str
; i
++)
7048 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7051 input_line_pointer
+= reloc_map
[i
].len
;
7053 return reloc_map
[i
].reloc
;
7057 s_arm_elf_cons (nbytes
)
7062 #ifdef md_flush_pending_output
7063 md_flush_pending_output ();
7066 if (is_it_end_of_statement ())
7068 demand_empty_rest_of_line ();
7072 #ifdef md_cons_align
7073 md_cons_align (nbytes
);
7078 bfd_reloc_code_real_type reloc
;
7082 if (exp
.X_op
== O_symbol
7083 && * input_line_pointer
== '('
7084 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7086 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7087 int size
= bfd_get_reloc_size (howto
);
7090 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7093 register char * p
= frag_more ((int) nbytes
);
7094 int offset
= nbytes
- size
;
7096 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7101 emit_expr (& exp
, (unsigned int) nbytes
);
7103 while (*input_line_pointer
++ == ',');
7105 input_line_pointer
--; /* Put terminator back into stream. */
7106 demand_empty_rest_of_line ();
7109 #endif /* OBJ_ELF */