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
},
873 /* ATPCS additions to APCS conventions. */
874 {"wr", 7}, {"v8", 11},
876 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
877 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
878 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
879 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
880 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
881 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
882 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
883 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
884 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
885 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
886 /* ATPCS additions to float register names. */
887 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
888 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
889 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
890 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
891 /* FIXME: At some point we need to add VFP register names. */
892 /* Array terminator. */
896 #define BAD_ARGS _("Bad arguments to instruction")
897 #define BAD_PC _("r15 not allowed here")
898 #define BAD_FLAGS _("Instruction should not have flags")
899 #define BAD_COND _("Instruction is not conditional")
901 static struct hash_control
* arm_ops_hsh
= NULL
;
902 static struct hash_control
* arm_tops_hsh
= NULL
;
903 static struct hash_control
* arm_cond_hsh
= NULL
;
904 static struct hash_control
* arm_shift_hsh
= NULL
;
905 static struct hash_control
* arm_reg_hsh
= NULL
;
906 static struct hash_control
* arm_psr_hsh
= NULL
;
908 /* This table describes all the machine specific pseudo-ops the assembler
909 has to support. The fields are:
910 pseudo-op name without dot
911 function to call to execute this pseudo-op
912 Integer arg to pass to the function
915 static void s_req
PARAMS ((int));
916 static void s_align
PARAMS ((int));
917 static void s_bss
PARAMS ((int));
918 static void s_even
PARAMS ((int));
919 static void s_ltorg
PARAMS ((int));
920 static void s_arm
PARAMS ((int));
921 static void s_thumb
PARAMS ((int));
922 static void s_code
PARAMS ((int));
923 static void s_force_thumb
PARAMS ((int));
924 static void s_thumb_func
PARAMS ((int));
925 static void s_thumb_set
PARAMS ((int));
926 static void arm_s_text
PARAMS ((int));
927 static void arm_s_data
PARAMS ((int));
929 static void arm_s_section
PARAMS ((int));
930 static void s_arm_elf_cons
PARAMS ((int));
933 static int my_get_expression
PARAMS ((expressionS
*, char **));
935 CONST pseudo_typeS md_pseudo_table
[] =
937 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
939 { "align", s_align
, 0 },
941 { "thumb", s_thumb
, 0 },
942 { "code", s_code
, 0 },
943 { "force_thumb", s_force_thumb
, 0 },
944 { "thumb_func", s_thumb_func
, 0 },
945 { "thumb_set", s_thumb_set
, 0 },
946 { "even", s_even
, 0 },
947 { "ltorg", s_ltorg
, 0 },
948 { "pool", s_ltorg
, 0 },
949 /* Allow for the effect of section changes. */
950 { "text", arm_s_text
, 0 },
951 { "data", arm_s_data
, 0 },
953 { "section", arm_s_section
, 0 },
954 { "section.s", arm_s_section
, 0 },
955 { "sect", arm_s_section
, 0 },
956 { "sect.s", arm_s_section
, 0 },
957 { "word", s_arm_elf_cons
, 4 },
958 { "long", s_arm_elf_cons
, 4 },
962 { "extend", float_cons
, 'x' },
963 { "ldouble", float_cons
, 'x' },
964 { "packed", float_cons
, 'p' },
968 /* Stuff needed to resolve the label ambiguity
978 symbolS
* last_label_seen
;
979 static int label_is_thumb_function_name
= false;
983 #define MAX_LITERAL_POOL_SIZE 1024
985 typedef struct literalS
987 struct expressionS exp
;
988 struct arm_it
* inst
;
991 literalT literals
[MAX_LITERAL_POOL_SIZE
];
992 int next_literal_pool_place
= 0; /* Next free entry in the pool */
993 int lit_pool_num
= 1; /* Next literal pool number */
994 symbolS
* current_poolP
= NULL
;
1001 if (current_poolP
== NULL
)
1002 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1003 (valueT
) 0, &zero_address_frag
);
1005 /* Check if this literal value is already in the pool: */
1006 while (lit_count
< next_literal_pool_place
)
1008 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1009 && inst
.reloc
.exp
.X_op
== O_constant
1010 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
1011 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1016 if (lit_count
== next_literal_pool_place
) /* new entry */
1018 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1020 inst
.error
= _("Literal Pool Overflow");
1024 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1025 lit_count
= next_literal_pool_place
++;
1028 inst
.reloc
.exp
.X_op
= O_symbol
;
1029 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1030 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1035 /* Can't use symbol_new here, so have to create a symbol and then at
1036 a later date assign it a value. Thats what these functions do. */
1038 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1040 CONST
char * name
; /* It is copied, the caller can modify */
1041 segT segment
; /* Segment identifier (SEG_<something>) */
1042 valueT valu
; /* Symbol value */
1043 fragS
* frag
; /* Associated fragment */
1045 unsigned int name_length
;
1046 char * preserved_copy_of_name
;
1048 name_length
= strlen (name
) + 1; /* +1 for \0 */
1049 obstack_grow (¬es
, name
, name_length
);
1050 preserved_copy_of_name
= obstack_finish (¬es
);
1051 #ifdef STRIP_UNDERSCORE
1052 if (preserved_copy_of_name
[0] == '_')
1053 preserved_copy_of_name
++;
1056 #ifdef tc_canonicalize_symbol_name
1057 preserved_copy_of_name
=
1058 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1061 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1063 S_SET_SEGMENT (symbolP
, segment
);
1064 S_SET_VALUE (symbolP
, valu
);
1065 symbol_clear_list_pointers(symbolP
);
1067 symbol_set_frag (symbolP
, frag
);
1069 /* Link to end of symbol chain. */
1071 extern int symbol_table_frozen
;
1072 if (symbol_table_frozen
)
1076 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1078 obj_symbol_new_hook (symbolP
);
1080 #ifdef tc_symbol_new_hook
1081 tc_symbol_new_hook (symbolP
);
1085 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1086 #endif /* DEBUG_SYMS */
1089 /* Check that an immediate is valid, and if so, convert it to the right format. */
1092 validate_immediate (val
)
1098 #define rotate_left(v, n) (v << n | v >> (32 - n))
1100 for (i
= 0; i
< 32; i
+= 2)
1101 if ((a
= rotate_left (val
, i
)) <= 0xff)
1102 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1107 /* Check to see if an immediate can be computed as two seperate immediate
1108 values, added together. We already know that this value cannot be
1109 computed by just one ARM instruction. */
1112 validate_immediate_twopart (val
, highpart
)
1114 unsigned int * highpart
;
1119 for (i
= 0; i
< 32; i
+= 2)
1120 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1126 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1128 else if (a
& 0xff0000)
1133 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1137 assert (a
& 0xff000000);
1139 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1142 return (a
& 0xff) | (i
<< 7);
1149 validate_offset_imm (val
, hwse
)
1153 if ((hwse
&& val
> 255) || val
> 4095)
1163 as_bad (_("Invalid syntax for .req directive."));
1170 /* We don't support putting frags in the BSS segment, we fake it by
1171 marking in_bss, then looking at s_skip for clues?.. */
1172 subseg_set (bss_section
, 0);
1173 demand_empty_rest_of_line ();
1180 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1181 frag_align (1, 0, 0);
1183 record_alignment (now_seg
, 1);
1185 demand_empty_rest_of_line ();
1195 if (current_poolP
== NULL
)
1198 /* Align pool as you have word accesses */
1199 /* Only make a frag if we have to ... */
1201 frag_align (2, 0, 0);
1203 record_alignment (now_seg
, 2);
1205 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1207 symbol_locate (current_poolP
, sym_name
, now_seg
,
1208 (valueT
) frag_now_fix (), frag_now
);
1209 symbol_table_insert (current_poolP
);
1211 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1213 #if defined OBJ_COFF || defined OBJ_ELF
1214 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1217 while (lit_count
< next_literal_pool_place
)
1218 /* First output the expression in the instruction to the pool */
1219 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1221 next_literal_pool_place
= 0;
1222 current_poolP
= NULL
;
1226 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1230 register long temp_fill
;
1231 long max_alignment
= 15;
1233 temp
= get_absolute_expression ();
1234 if (temp
> max_alignment
)
1235 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1238 as_bad (_("Alignment negative. 0 assumed."));
1242 if (*input_line_pointer
== ',')
1244 input_line_pointer
++;
1245 temp_fill
= get_absolute_expression ();
1253 /* Only make a frag if we HAVE to. . . */
1254 if (temp
&& !need_pass_2
)
1255 frag_align (temp
, (int) temp_fill
, 0);
1256 demand_empty_rest_of_line ();
1258 record_alignment (now_seg
, temp
);
1262 s_force_thumb (ignore
)
1265 /* If we are not already in thumb mode go into it, EVEN if
1266 the target processor does not support thumb instructions.
1267 This is used by gcc/config/arm/lib1funcs.asm for example
1268 to compile interworking support functions even if the
1269 target processor should not support interworking. */
1275 record_alignment (now_seg
, 1);
1278 demand_empty_rest_of_line ();
1282 s_thumb_func (ignore
)
1285 /* The following label is the name/address of the start of a Thumb function.
1286 We need to know this for the interworking support. */
1288 label_is_thumb_function_name
= true;
1290 demand_empty_rest_of_line ();
1293 /* Perform a .set directive, but also mark the alias as
1294 being a thumb function. */
1300 /* XXX the following is a duplicate of the code for s_set() in read.c
1301 We cannot just call that code as we need to get at the symbol that
1303 register char * name
;
1304 register char delim
;
1305 register char * end_name
;
1306 register symbolS
* symbolP
;
1309 * Especial apologies for the random logic:
1310 * this just grew, and could be parsed much more simply!
1313 name
= input_line_pointer
;
1314 delim
= get_symbol_end ();
1315 end_name
= input_line_pointer
;
1320 if (*input_line_pointer
!= ',')
1323 as_bad (_("Expected comma after name \"%s\""), name
);
1325 ignore_rest_of_line ();
1329 input_line_pointer
++;
1332 if (name
[0] == '.' && name
[1] == '\0')
1334 /* XXX - this should not happen to .thumb_set */
1338 if ((symbolP
= symbol_find (name
)) == NULL
1339 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1342 /* When doing symbol listings, play games with dummy fragments living
1343 outside the normal fragment chain to record the file and line info
1345 if (listing
& LISTING_SYMBOLS
)
1347 extern struct list_info_struct
* listing_tail
;
1348 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1349 memset (dummy_frag
, 0, sizeof(fragS
));
1350 dummy_frag
->fr_type
= rs_fill
;
1351 dummy_frag
->line
= listing_tail
;
1352 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1353 dummy_frag
->fr_symbol
= symbolP
;
1357 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1360 /* "set" symbols are local unless otherwise specified. */
1361 SF_SET_LOCAL (symbolP
);
1362 #endif /* OBJ_COFF */
1363 } /* make a new symbol */
1365 symbol_table_insert (symbolP
);
1370 && S_IS_DEFINED (symbolP
)
1371 && S_GET_SEGMENT (symbolP
) != reg_section
)
1372 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1374 pseudo_set (symbolP
);
1376 demand_empty_rest_of_line ();
1378 /* XXX Now we come to the Thumb specific bit of code. */
1380 THUMB_SET_FUNC (symbolP
, 1);
1381 ARM_SET_THUMB (symbolP
, 1);
1382 #if defined OBJ_ELF || defined OBJ_COFF
1383 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1387 /* If we change section we must dump the literal pool first. */
1392 if (now_seg
!= text_section
)
1396 obj_elf_text (ignore
);
1406 if (flag_readonly_data_in_text
)
1408 if (now_seg
!= text_section
)
1411 else if (now_seg
!= data_section
)
1415 obj_elf_data (ignore
);
1423 arm_s_section (ignore
)
1428 obj_elf_section (ignore
);
1433 opcode_select (width
)
1441 if (! (cpu_variant
& ARM_THUMB
))
1442 as_bad (_("selected processor does not support THUMB opcodes"));
1444 /* No need to force the alignment, since we will have been
1445 coming from ARM mode, which is word-aligned. */
1446 record_alignment (now_seg
, 1);
1453 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1454 as_bad (_("selected processor does not support ARM opcodes"));
1457 frag_align (2, 0, 0);
1458 record_alignment (now_seg
, 1);
1463 as_bad (_("invalid instruction size selected (%d)"), width
);
1472 demand_empty_rest_of_line ();
1480 demand_empty_rest_of_line ();
1489 temp
= get_absolute_expression ();
1494 opcode_select (temp
);
1498 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1506 skip_whitespace (str
);
1509 inst
.error
= _("Garbage following instruction");
1513 skip_past_comma (str
)
1519 while ((c
= *p
) == ' ' || c
== ',')
1522 if (c
== ',' && comma
++)
1530 return comma
? SUCCESS
: FAIL
;
1533 /* A standard register must be given at this point.
1534 Shift is the place to put it in inst.instruction.
1535 Restores input start point on err.
1536 Returns the reg#, or FAIL. */
1539 reg_required_here (str
, shift
)
1543 static char buff
[128]; /* XXX */
1545 char * start
= *str
;
1547 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1550 inst
.instruction
|= reg
<< shift
;
1554 /* Restore the start point, we may have got a reg of the wrong class. */
1557 /* In the few cases where we might be able to accept something else
1558 this error can be overridden. */
1559 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1566 psr_required_here (str
, cpsr
, spsr
)
1572 char * start
= *str
;
1573 psr
= arm_psr_parse (str
);
1575 if (psr
== cpsr
|| psr
== spsr
)
1578 inst
.instruction
|= 1 << 22;
1583 /* In the few cases where we might be able to accept something else
1584 this error can be overridden. */
1585 inst
.error
= _("<psr(f)> expected");
1587 /* Restore the start point. */
1593 co_proc_number (str
)
1596 int processor
, pchar
;
1598 skip_whitespace (* str
);
1600 /* The data sheet seems to imply that just a number on its own is valid
1601 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1603 if (**str
== 'p' || **str
== 'P')
1607 if (pchar
>= '0' && pchar
<= '9')
1609 processor
= pchar
- '0';
1610 if (**str
>= '0' && **str
<= '9')
1612 processor
= processor
* 10 + *(*str
)++ - '0';
1615 inst
.error
= _("Illegal co-processor number");
1622 inst
.error
= _("Bad or missing co-processor number");
1626 inst
.instruction
|= processor
<< 8;
1631 cp_opc_expr (str
, where
, length
)
1638 skip_whitespace (* str
);
1640 memset (&expr
, '\0', sizeof (expr
));
1642 if (my_get_expression (&expr
, str
))
1644 if (expr
.X_op
!= O_constant
)
1646 inst
.error
= _("bad or missing expression");
1650 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1652 inst
.error
= _("immediate co-processor expression too large");
1656 inst
.instruction
|= expr
.X_add_number
<< where
;
1661 cp_reg_required_here (str
, where
)
1666 char * start
= *str
;
1668 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1671 inst
.instruction
|= reg
<< where
;
1675 /* In the few cases where we might be able to accept something else
1676 this error can be overridden. */
1677 inst
.error
= _("Co-processor register expected");
1679 /* Restore the start point. */
1685 fp_reg_required_here (str
, where
)
1690 char * start
= *str
;
1692 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1695 inst
.instruction
|= reg
<< where
;
1699 /* In the few cases where we might be able to accept something else
1700 this error can be overridden. */
1701 inst
.error
= _("Floating point register expected");
1703 /* Restore the start point. */
1709 cp_address_offset (str
)
1714 skip_whitespace (* str
);
1716 if (! is_immediate_prefix (**str
))
1718 inst
.error
= _("immediate expression expected");
1724 if (my_get_expression (& inst
.reloc
.exp
, str
))
1727 if (inst
.reloc
.exp
.X_op
== O_constant
)
1729 offset
= inst
.reloc
.exp
.X_add_number
;
1733 inst
.error
= _("co-processor address must be word aligned");
1737 if (offset
> 1023 || offset
< -1023)
1739 inst
.error
= _("offset too large");
1744 inst
.instruction
|= INDEX_UP
;
1748 inst
.instruction
|= offset
>> 2;
1751 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1757 cp_address_required_here (str
)
1769 skip_whitespace (p
);
1771 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1774 skip_whitespace (p
);
1780 if (skip_past_comma (& p
) == SUCCESS
)
1783 write_back
= WRITE_BACK
;
1787 inst
.error
= _("pc may not be used in post-increment");
1791 if (cp_address_offset (& p
) == FAIL
)
1795 pre_inc
= PRE_INDEX
| INDEX_UP
;
1799 /* '['Rn, #expr']'[!] */
1801 if (skip_past_comma (& p
) == FAIL
)
1803 inst
.error
= _("pre-indexed expression expected");
1807 pre_inc
= PRE_INDEX
;
1809 if (cp_address_offset (& p
) == FAIL
)
1812 skip_whitespace (p
);
1816 inst
.error
= _("missing ]");
1820 skip_whitespace (p
);
1826 inst
.error
= _("pc may not be used with write-back");
1831 write_back
= WRITE_BACK
;
1837 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1840 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1841 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1842 inst
.reloc
.pc_rel
= 1;
1843 inst
.instruction
|= (REG_PC
<< 16);
1844 pre_inc
= PRE_INDEX
;
1847 inst
.instruction
|= write_back
| pre_inc
;
1855 unsigned long flags
;
1857 /* Do nothing really. */
1858 inst
.instruction
|= flags
; /* This is pointless. */
1866 unsigned long flags
;
1868 /* Only one syntax. */
1869 skip_whitespace (str
);
1871 if (reg_required_here (&str
, 12) == FAIL
)
1873 inst
.error
= BAD_ARGS
;
1877 if (skip_past_comma (&str
) == FAIL
1878 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1880 inst
.error
= _("<psr> expected");
1884 inst
.instruction
|= flags
;
1889 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1893 unsigned long flags
;
1897 skip_whitespace (str
);
1899 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1901 inst
.instruction
|= PSR_ALL
;
1903 /* Sytax should be "<psr>, Rm" */
1904 if (skip_past_comma (&str
) == FAIL
1905 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1907 inst
.error
= BAD_ARGS
;
1913 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1914 inst
.instruction
|= PSR_FLAGS
;
1915 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1916 inst
.instruction
|= PSR_CONTROL
;
1919 inst
.error
= BAD_ARGS
;
1923 if (skip_past_comma (&str
) == FAIL
)
1925 inst
.error
= BAD_ARGS
;
1929 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1931 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1933 /* Immediate expression. */
1934 else if (is_immediate_prefix (* str
))
1939 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1941 inst
.error
= _("Register or shift expression expected");
1945 if (inst
.reloc
.exp
.X_add_symbol
)
1947 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1948 inst
.reloc
.pc_rel
= 0;
1952 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1955 inst
.error
= _("Invalid constant");
1959 inst
.instruction
|= value
;
1962 flags
|= INST_IMMEDIATE
;
1966 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1972 inst
.instruction
|= flags
;
1977 /* Long Multiply Parser
1978 UMULL RdLo, RdHi, Rm, Rs
1979 SMULL RdLo, RdHi, Rm, Rs
1980 UMLAL RdLo, RdHi, Rm, Rs
1981 SMLAL RdLo, RdHi, Rm, Rs
1984 do_mull (str
, flags
)
1986 unsigned long flags
;
1988 int rdlo
, rdhi
, rm
, rs
;
1990 /* Only one format "rdlo, rdhi, rm, rs" */
1991 skip_whitespace (str
);
1993 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1995 inst
.error
= BAD_ARGS
;
1999 if (skip_past_comma (&str
) == FAIL
2000 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2002 inst
.error
= BAD_ARGS
;
2006 if (skip_past_comma (&str
) == FAIL
2007 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2009 inst
.error
= BAD_ARGS
;
2013 /* rdhi, rdlo and rm must all be different */
2014 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2015 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2017 if (skip_past_comma (&str
) == FAIL
2018 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2020 inst
.error
= BAD_ARGS
;
2024 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2026 inst
.error
= BAD_PC
;
2030 inst
.instruction
|= flags
;
2038 unsigned long flags
;
2042 /* Only one format "rd, rm, rs" */
2043 skip_whitespace (str
);
2045 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2047 inst
.error
= BAD_ARGS
;
2053 inst
.error
= BAD_PC
;
2057 if (skip_past_comma (&str
) == FAIL
2058 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2060 inst
.error
= BAD_ARGS
;
2066 inst
.error
= BAD_PC
;
2071 as_tsktsk (_("rd and rm should be different in mul"));
2073 if (skip_past_comma (&str
) == FAIL
2074 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2076 inst
.error
= BAD_ARGS
;
2082 inst
.error
= BAD_PC
;
2086 inst
.instruction
|= flags
;
2094 unsigned long flags
;
2098 /* Only one format "rd, rm, rs, rn" */
2099 skip_whitespace (str
);
2101 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2103 inst
.error
= BAD_ARGS
;
2109 inst
.error
= BAD_PC
;
2113 if (skip_past_comma (&str
) == FAIL
2114 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2116 inst
.error
= BAD_ARGS
;
2122 inst
.error
= BAD_PC
;
2127 as_tsktsk (_("rd and rm should be different in mla"));
2129 if (skip_past_comma (&str
) == FAIL
2130 || (rd
= reg_required_here (&str
, 8)) == FAIL
2131 || skip_past_comma (&str
) == FAIL
2132 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2134 inst
.error
= BAD_ARGS
;
2138 if (rd
== REG_PC
|| rm
== REG_PC
)
2140 inst
.error
= BAD_PC
;
2144 inst
.instruction
|= flags
;
2149 /* Returns the index into fp_values of a floating point number, or -1 if
2150 not in the table. */
2152 my_get_float_expression (str
)
2155 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2161 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2162 /* Look for a raw floating point number */
2163 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2164 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2166 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2168 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2170 if (words
[j
] != fp_values
[i
][j
])
2174 if (j
== MAX_LITTLENUMS
)
2182 /* Try and parse a more complex expression, this will probably fail
2183 unless the code uses a floating point prefix (eg "0f") */
2184 save_in
= input_line_pointer
;
2185 input_line_pointer
= *str
;
2186 if (expression (&exp
) == absolute_section
2187 && exp
.X_op
== O_big
2188 && exp
.X_add_number
< 0)
2190 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2192 if (gen_to_words (words
, 5, (long)15) == 0)
2194 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2196 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2198 if (words
[j
] != fp_values
[i
][j
])
2202 if (j
== MAX_LITTLENUMS
)
2204 *str
= input_line_pointer
;
2205 input_line_pointer
= save_in
;
2212 *str
= input_line_pointer
;
2213 input_line_pointer
= save_in
;
2217 /* Return true if anything in the expression is a bignum */
2219 walk_no_bignums (sp
)
2222 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2225 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2227 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2228 || (symbol_get_value_expression (sp
)->X_op_symbol
2229 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2236 my_get_expression (ep
, str
)
2243 save_in
= input_line_pointer
;
2244 input_line_pointer
= *str
;
2245 seg
= expression (ep
);
2248 if (seg
!= absolute_section
2249 && seg
!= text_section
2250 && seg
!= data_section
2251 && seg
!= bss_section
2252 && seg
!= undefined_section
)
2254 inst
.error
= _("bad_segment");
2255 *str
= input_line_pointer
;
2256 input_line_pointer
= save_in
;
2261 /* Get rid of any bignums now, so that we don't generate an error for which
2262 we can't establish a line number later on. Big numbers are never valid
2263 in instructions, which is where this routine is always called. */
2264 if (ep
->X_op
== O_big
2265 || (ep
->X_add_symbol
2266 && (walk_no_bignums (ep
->X_add_symbol
)
2268 && walk_no_bignums (ep
->X_op_symbol
)))))
2270 inst
.error
= _("Invalid constant");
2271 *str
= input_line_pointer
;
2272 input_line_pointer
= save_in
;
2276 *str
= input_line_pointer
;
2277 input_line_pointer
= save_in
;
2281 /* unrestrict should be one if <shift> <register> is permitted for this
2285 decode_shift (str
, unrestrict
)
2289 struct asm_shift
* shft
;
2293 skip_whitespace (* str
);
2295 for (p
= *str
; isalpha (*p
); p
++)
2300 inst
.error
= _("Shift expression expected");
2306 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2310 if (!strncmp (*str
, "rrx", 3)
2311 || !strncmp (*str
, "RRX", 3))
2314 inst
.instruction
|= shft
->value
;
2318 skip_whitespace (p
);
2320 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2322 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2326 else if (is_immediate_prefix (* p
))
2330 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2333 /* Validate some simple #expressions */
2334 if (inst
.reloc
.exp
.X_op
== O_constant
)
2336 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2338 /* Reject operations greater than 32, or lsl #32 */
2339 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2341 inst
.error
= _("Invalid immediate shift");
2345 /* Shifts of zero should be converted to lsl (which is zero)*/
2352 /* Shifts of 32 are encoded as 0, for those shifts that
2357 inst
.instruction
|= (num
<< 7) | shft
->value
;
2362 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2363 inst
.reloc
.pc_rel
= 0;
2364 inst
.instruction
|= shft
->value
;
2370 inst
.error
= unrestrict
? _("shift requires register or #expression")
2371 : _("shift requires #expression");
2377 inst
.error
= _("Shift expression expected");
2381 /* Do those data_ops which can take a negative immediate constant */
2382 /* by altering the instuction. A bit of a hack really */
2386 by inverting the second operand, and
2389 by negating the second operand.
2392 negate_data_op (instruction
, value
)
2393 unsigned long * instruction
;
2394 unsigned long value
;
2397 unsigned long negated
, inverted
;
2399 negated
= validate_immediate (-value
);
2400 inverted
= validate_immediate (~value
);
2402 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2406 case OPCODE_SUB
: /* ADD <-> SUB */
2407 new_inst
= OPCODE_ADD
;
2412 new_inst
= OPCODE_SUB
;
2416 case OPCODE_CMP
: /* CMP <-> CMN */
2417 new_inst
= OPCODE_CMN
;
2422 new_inst
= OPCODE_CMP
;
2426 /* Now Inverted ops */
2427 case OPCODE_MOV
: /* MOV <-> MVN */
2428 new_inst
= OPCODE_MVN
;
2433 new_inst
= OPCODE_MOV
;
2437 case OPCODE_AND
: /* AND <-> BIC */
2438 new_inst
= OPCODE_BIC
;
2443 new_inst
= OPCODE_AND
;
2447 case OPCODE_ADC
: /* ADC <-> SBC */
2448 new_inst
= OPCODE_SBC
;
2453 new_inst
= OPCODE_ADC
;
2457 /* We cannot do anything */
2465 *instruction
&= OPCODE_MASK
;
2466 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2477 skip_whitespace (* str
);
2479 if (reg_required_here (str
, 0) != FAIL
)
2481 if (skip_past_comma (str
) == SUCCESS
)
2482 /* Shift operation on register. */
2483 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2489 /* Immediate expression */
2490 if (is_immediate_prefix (**str
))
2495 if (my_get_expression (&inst
.reloc
.exp
, str
))
2498 if (inst
.reloc
.exp
.X_add_symbol
)
2500 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2501 inst
.reloc
.pc_rel
= 0;
2505 if (skip_past_comma (str
) == SUCCESS
)
2507 /* #x, y -- ie explicit rotation by Y */
2508 if (my_get_expression (&expr
, str
))
2511 if (expr
.X_op
!= O_constant
)
2513 inst
.error
= _("Constant expression expected");
2517 /* Rotate must be a multiple of 2 */
2518 if (((unsigned) expr
.X_add_number
) > 30
2519 || (expr
.X_add_number
& 1) != 0
2520 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2522 inst
.error
= _("Invalid constant");
2525 inst
.instruction
|= INST_IMMEDIATE
;
2526 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2527 inst
.instruction
|= expr
.X_add_number
<< 7;
2531 /* Implicit rotation, select a suitable one */
2532 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2536 /* Can't be done, perhaps the code reads something like
2537 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2538 if ((value
= negate_data_op (&inst
.instruction
,
2539 inst
.reloc
.exp
.X_add_number
))
2542 inst
.error
= _("Invalid constant");
2547 inst
.instruction
|= value
;
2550 inst
.instruction
|= INST_IMMEDIATE
;
2555 inst
.error
= _("Register or shift expression expected");
2564 skip_whitespace (* str
);
2566 if (fp_reg_required_here (str
, 0) != FAIL
)
2570 /* Immediate expression */
2571 if (*((*str
)++) == '#')
2577 skip_whitespace (* str
);
2579 /* First try and match exact strings, this is to guarantee that
2580 some formats will work even for cross assembly */
2582 for (i
= 0; fp_const
[i
]; i
++)
2584 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2588 *str
+= strlen (fp_const
[i
]);
2589 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2591 inst
.instruction
|= i
+ 8;
2598 /* Just because we didn't get a match doesn't mean that the
2599 constant isn't valid, just that it is in a format that we
2600 don't automatically recognize. Try parsing it with
2601 the standard expression routines. */
2602 if ((i
= my_get_float_expression (str
)) >= 0)
2604 inst
.instruction
|= i
+ 8;
2608 inst
.error
= _("Invalid floating point immediate expression");
2611 inst
.error
= _("Floating point register or immediate expression expected");
2617 do_arit (str
, flags
)
2619 unsigned long flags
;
2621 skip_whitespace (str
);
2623 if (reg_required_here (&str
, 12) == FAIL
2624 || skip_past_comma (&str
) == FAIL
2625 || reg_required_here (&str
, 16) == FAIL
2626 || skip_past_comma (&str
) == FAIL
2627 || data_op2 (&str
) == FAIL
)
2630 inst
.error
= BAD_ARGS
;
2634 inst
.instruction
|= flags
;
2642 unsigned long flags
;
2644 /* This is a pseudo-op of the form "adr rd, label" to be converted
2645 into a relative address of the form "add rd, pc, #label-.-8" */
2647 skip_whitespace (str
);
2649 if (reg_required_here (&str
, 12) == FAIL
2650 || skip_past_comma (&str
) == FAIL
2651 || my_get_expression (&inst
.reloc
.exp
, &str
))
2654 inst
.error
= BAD_ARGS
;
2657 /* Frag hacking will turn this into a sub instruction if the offset turns
2658 out to be negative. */
2659 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2660 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2661 inst
.reloc
.pc_rel
= 1;
2662 inst
.instruction
|= flags
;
2668 do_adrl (str
, flags
)
2670 unsigned long flags
;
2672 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2673 into a relative address of the form:
2674 add rd, pc, #low(label-.-8)"
2675 add rd, rd, #high(label-.-8)" */
2677 skip_whitespace (str
);
2679 if (reg_required_here (& str
, 12) == FAIL
2680 || skip_past_comma (& str
) == FAIL
2681 || my_get_expression (& inst
.reloc
.exp
, & str
))
2684 inst
.error
= BAD_ARGS
;
2690 /* Frag hacking will turn this into a sub instruction if the offset turns
2691 out to be negative. */
2692 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2693 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2694 inst
.reloc
.pc_rel
= 1;
2695 inst
.instruction
|= flags
;
2696 inst
.size
= INSN_SIZE
* 2;
2704 unsigned long flags
;
2706 skip_whitespace (str
);
2708 if (reg_required_here (&str
, 16) == FAIL
)
2711 inst
.error
= BAD_ARGS
;
2715 if (skip_past_comma (&str
) == FAIL
2716 || data_op2 (&str
) == FAIL
)
2719 inst
.error
= BAD_ARGS
;
2723 inst
.instruction
|= flags
;
2724 if ((flags
& 0x0000f000) == 0)
2725 inst
.instruction
|= CONDS_BIT
;
2734 unsigned long flags
;
2736 skip_whitespace (str
);
2738 if (reg_required_here (&str
, 12) == FAIL
)
2741 inst
.error
= BAD_ARGS
;
2745 if (skip_past_comma (&str
) == FAIL
2746 || data_op2 (&str
) == FAIL
)
2749 inst
.error
= BAD_ARGS
;
2753 inst
.instruction
|= flags
;
2759 ldst_extend (str
, hwse
)
2770 if (my_get_expression (& inst
.reloc
.exp
, str
))
2773 if (inst
.reloc
.exp
.X_op
== O_constant
)
2775 int value
= inst
.reloc
.exp
.X_add_number
;
2777 if ((hwse
&& (value
< -255 || value
> 255))
2778 || (value
< -4095 || value
> 4095))
2780 inst
.error
= _("address offset too large");
2790 /* Halfword and signextension instructions have the
2791 immediate value split across bits 11..8 and bits 3..0 */
2793 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2795 inst
.instruction
|= add
| value
;
2801 inst
.instruction
|= HWOFFSET_IMM
;
2802 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2805 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2806 inst
.reloc
.pc_rel
= 0;
2811 add
= 0; /* and fall through */
2813 (*str
)++; /* and fall through */
2815 if (reg_required_here (str
, 0) == FAIL
)
2819 inst
.instruction
|= add
;
2822 inst
.instruction
|= add
| OFFSET_REG
;
2823 if (skip_past_comma (str
) == SUCCESS
)
2824 return decode_shift (str
, SHIFT_RESTRICT
);
2832 do_ldst (str
, flags
)
2834 unsigned long flags
;
2841 /* This is not ideal, but it is the simplest way of dealing with the
2842 ARM7T halfword instructions (since they use a different
2843 encoding, but the same mnemonic): */
2844 halfword
= (flags
& 0x80000000) != 0;
2847 /* This is actually a load/store of a halfword, or a
2848 signed-extension load */
2849 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2852 = _("Processor does not support halfwords or signed bytes");
2856 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2857 | (flags
& ~COND_MASK
);
2862 skip_whitespace (str
);
2864 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2867 inst
.error
= BAD_ARGS
;
2871 if (skip_past_comma (& str
) == FAIL
)
2873 inst
.error
= _("Address expected");
2883 skip_whitespace (str
);
2885 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2888 /* Conflicts can occur on stores as well as loads. */
2889 conflict_reg
= (conflict_reg
== reg
);
2891 skip_whitespace (str
);
2897 if (skip_past_comma (&str
) == SUCCESS
)
2899 /* [Rn],... (post inc) */
2900 if (ldst_extend (&str
, halfword
) == FAIL
)
2903 as_warn (_("%s register same as write-back base"),
2904 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2910 inst
.instruction
|= HWOFFSET_IMM
;
2912 skip_whitespace (str
);
2917 as_warn (_("%s register same as write-back base"),
2918 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2920 inst
.instruction
|= WRITE_BACK
;
2924 if (! (flags
& TRANS_BIT
))
2931 if (skip_past_comma (&str
) == FAIL
)
2933 inst
.error
= _("pre-indexed expression expected");
2938 if (ldst_extend (&str
, halfword
) == FAIL
)
2941 skip_whitespace (str
);
2945 inst
.error
= _("missing ]");
2949 skip_whitespace (str
);
2954 as_warn (_("%s register same as write-back base"),
2955 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2957 inst
.instruction
|= WRITE_BACK
;
2961 else if (*str
== '=')
2963 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2966 skip_whitespace (str
);
2968 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2971 if (inst
.reloc
.exp
.X_op
!= O_constant
2972 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2974 inst
.error
= _("Constant expression expected");
2978 if (inst
.reloc
.exp
.X_op
== O_constant
2979 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2981 /* This can be done with a mov instruction */
2982 inst
.instruction
&= LITERAL_MASK
;
2983 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2984 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2990 /* Insert into literal pool */
2991 if (add_to_lit_pool () == FAIL
)
2994 inst
.error
= _("literal pool insertion failed");
2998 /* Change the instruction exp to point to the pool */
3001 inst
.instruction
|= HWOFFSET_IMM
;
3002 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3005 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3006 inst
.reloc
.pc_rel
= 1;
3007 inst
.instruction
|= (REG_PC
<< 16);
3013 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3018 inst
.instruction
|= HWOFFSET_IMM
;
3019 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3022 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3023 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3024 inst
.reloc
.pc_rel
= 1;
3025 inst
.instruction
|= (REG_PC
<< 16);
3029 if (pre_inc
&& (flags
& TRANS_BIT
))
3030 inst
.error
= _("Pre-increment instruction with translate");
3032 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3045 /* We come back here if we get ranges concatenated by '+' or '|' */
3060 skip_whitespace (str
);
3062 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3071 inst
.error
= _("Bad range in register list");
3075 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3077 if (range
& (1 << i
))
3079 (_("Warning: Duplicated register (r%d) in register list"),
3087 if (range
& (1 << reg
))
3088 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3090 else if (reg
<= cur_reg
)
3091 as_tsktsk (_("Warning: Register range not in ascending order"));
3095 } while (skip_past_comma (&str
) != FAIL
3096 || (in_range
= 1, *str
++ == '-'));
3098 skip_whitespace (str
);
3102 inst
.error
= _("Missing `}'");
3110 if (my_get_expression (&expr
, &str
))
3113 if (expr
.X_op
== O_constant
)
3115 if (expr
.X_add_number
3116 != (expr
.X_add_number
& 0x0000ffff))
3118 inst
.error
= _("invalid register mask");
3122 if ((range
& expr
.X_add_number
) != 0)
3124 int regno
= range
& expr
.X_add_number
;
3127 regno
= (1 << regno
) - 1;
3129 (_("Warning: Duplicated register (r%d) in register list"),
3133 range
|= expr
.X_add_number
;
3137 if (inst
.reloc
.type
!= 0)
3139 inst
.error
= _("expression too complex");
3143 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3144 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3145 inst
.reloc
.pc_rel
= 0;
3149 skip_whitespace (str
);
3151 if (*str
== '|' || *str
== '+')
3156 } while (another_range
);
3163 do_ldmstm (str
, flags
)
3165 unsigned long flags
;
3170 skip_whitespace (str
);
3172 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3175 if (base_reg
== REG_PC
)
3177 inst
.error
= _("r15 not allowed as base register");
3181 skip_whitespace (str
);
3185 flags
|= WRITE_BACK
;
3189 if (skip_past_comma (&str
) == FAIL
3190 || (range
= reg_list (&str
)) == FAIL
)
3193 inst
.error
= BAD_ARGS
;
3200 flags
|= LDM_TYPE_2_OR_3
;
3203 inst
.instruction
|= flags
| range
;
3211 unsigned long flags
;
3213 skip_whitespace (str
);
3215 /* Allow optional leading '#'. */
3216 if (is_immediate_prefix (*str
))
3219 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3222 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3223 inst
.reloc
.pc_rel
= 0;
3224 inst
.instruction
|= flags
;
3232 do_swap (str
, flags
)
3234 unsigned long flags
;
3238 skip_whitespace (str
);
3240 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3245 inst
.error
= _("r15 not allowed in swap");
3249 if (skip_past_comma (&str
) == FAIL
3250 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3253 inst
.error
= BAD_ARGS
;
3259 inst
.error
= _("r15 not allowed in swap");
3263 if (skip_past_comma (&str
) == FAIL
3266 inst
.error
= BAD_ARGS
;
3270 skip_whitespace (str
);
3272 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3277 inst
.error
= BAD_PC
;
3281 skip_whitespace (str
);
3285 inst
.error
= _("missing ]");
3289 inst
.instruction
|= flags
;
3295 do_branch (str
, flags
)
3297 unsigned long flags
;
3299 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3306 /* ScottB: February 5, 1998 */
3307 /* Check to see of PLT32 reloc required for the instruction. */
3309 /* arm_parse_reloc() works on input_line_pointer.
3310 We actually want to parse the operands to the branch instruction
3311 passed in 'str'. Save the input pointer and restore it later. */
3312 save_in
= input_line_pointer
;
3313 input_line_pointer
= str
;
3314 if (inst
.reloc
.exp
.X_op
== O_symbol
3316 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3318 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3319 inst
.reloc
.pc_rel
= 0;
3320 /* Modify str to point to after parsed operands, otherwise
3321 end_of_line() will complain about the (PLT) left in str. */
3322 str
= input_line_pointer
;
3326 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3327 inst
.reloc
.pc_rel
= 1;
3329 input_line_pointer
= save_in
;
3332 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3333 inst
.reloc
.pc_rel
= 1;
3334 #endif /* OBJ_ELF */
3343 unsigned long flags
;
3347 skip_whitespace (str
);
3349 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3351 inst
.error
= BAD_ARGS
;
3356 inst
.error
= BAD_PC
;
3364 unsigned long flags
;
3366 /* Co-processor data operation.
3367 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3368 skip_whitespace (str
);
3370 if (co_proc_number (&str
) == FAIL
)
3373 inst
.error
= BAD_ARGS
;
3377 if (skip_past_comma (&str
) == FAIL
3378 || cp_opc_expr (&str
, 20,4) == FAIL
)
3381 inst
.error
= BAD_ARGS
;
3385 if (skip_past_comma (&str
) == FAIL
3386 || cp_reg_required_here (&str
, 12) == FAIL
)
3389 inst
.error
= BAD_ARGS
;
3393 if (skip_past_comma (&str
) == FAIL
3394 || cp_reg_required_here (&str
, 16) == FAIL
)
3397 inst
.error
= BAD_ARGS
;
3401 if (skip_past_comma (&str
) == FAIL
3402 || cp_reg_required_here (&str
, 0) == FAIL
)
3405 inst
.error
= BAD_ARGS
;
3409 if (skip_past_comma (&str
) == SUCCESS
)
3411 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3414 inst
.error
= BAD_ARGS
;
3424 do_lstc (str
, flags
)
3426 unsigned long flags
;
3428 /* Co-processor register load/store.
3429 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3431 skip_whitespace (str
);
3433 if (co_proc_number (&str
) == FAIL
)
3436 inst
.error
= BAD_ARGS
;
3440 if (skip_past_comma (&str
) == FAIL
3441 || cp_reg_required_here (&str
, 12) == FAIL
)
3444 inst
.error
= BAD_ARGS
;
3448 if (skip_past_comma (&str
) == FAIL
3449 || cp_address_required_here (&str
) == FAIL
)
3452 inst
.error
= BAD_ARGS
;
3456 inst
.instruction
|= flags
;
3462 do_co_reg (str
, flags
)
3464 unsigned long flags
;
3466 /* Co-processor register transfer.
3467 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3469 skip_whitespace (str
);
3471 if (co_proc_number (&str
) == FAIL
)
3474 inst
.error
= BAD_ARGS
;
3478 if (skip_past_comma (&str
) == FAIL
3479 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3482 inst
.error
= BAD_ARGS
;
3486 if (skip_past_comma (&str
) == FAIL
3487 || reg_required_here (&str
, 12) == FAIL
)
3490 inst
.error
= BAD_ARGS
;
3494 if (skip_past_comma (&str
) == FAIL
3495 || cp_reg_required_here (&str
, 16) == FAIL
)
3498 inst
.error
= BAD_ARGS
;
3502 if (skip_past_comma (&str
) == FAIL
3503 || cp_reg_required_here (&str
, 0) == FAIL
)
3506 inst
.error
= BAD_ARGS
;
3510 if (skip_past_comma (&str
) == SUCCESS
)
3512 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3515 inst
.error
= BAD_ARGS
;
3521 inst
.error
= BAD_COND
;
3529 do_fp_ctrl (str
, flags
)
3531 unsigned long flags
;
3533 /* FP control registers.
3534 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3536 skip_whitespace (str
);
3538 if (reg_required_here (&str
, 12) == FAIL
)
3541 inst
.error
= BAD_ARGS
;
3550 do_fp_ldst (str
, flags
)
3552 unsigned long flags
;
3554 skip_whitespace (str
);
3556 switch (inst
.suffix
)
3561 inst
.instruction
|= CP_T_X
;
3564 inst
.instruction
|= CP_T_Y
;
3567 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3573 if (fp_reg_required_here (&str
, 12) == FAIL
)
3576 inst
.error
= BAD_ARGS
;
3580 if (skip_past_comma (&str
) == FAIL
3581 || cp_address_required_here (&str
) == FAIL
)
3584 inst
.error
= BAD_ARGS
;
3592 do_fp_ldmstm (str
, flags
)
3594 unsigned long flags
;
3598 skip_whitespace (str
);
3600 if (fp_reg_required_here (&str
, 12) == FAIL
)
3603 inst
.error
= BAD_ARGS
;
3607 /* Get Number of registers to transfer */
3608 if (skip_past_comma (&str
) == FAIL
3609 || my_get_expression (&inst
.reloc
.exp
, &str
))
3612 inst
.error
= _("constant expression expected");
3616 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3618 inst
.error
= _("Constant value required for number of registers");
3622 num_regs
= inst
.reloc
.exp
.X_add_number
;
3624 if (num_regs
< 1 || num_regs
> 4)
3626 inst
.error
= _("number of registers must be in the range [1:4]");
3633 inst
.instruction
|= CP_T_X
;
3636 inst
.instruction
|= CP_T_Y
;
3639 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3653 /* The instruction specified "ea" or "fd", so we can only accept
3654 [Rn]{!}. The instruction does not really support stacking or
3655 unstacking, so we have to emulate these by setting appropriate
3656 bits and offsets. */
3657 if (skip_past_comma (&str
) == FAIL
3661 inst
.error
= BAD_ARGS
;
3666 skip_whitespace (str
);
3668 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3671 skip_whitespace (str
);
3675 inst
.error
= BAD_ARGS
;
3686 inst
.error
= _("R15 not allowed as base register with write-back");
3693 if (flags
& CP_T_Pre
)
3696 offset
= 3 * num_regs
;
3702 /* Post-increment */
3706 offset
= 3 * num_regs
;
3710 /* No write-back, so convert this into a standard pre-increment
3711 instruction -- aesthetically more pleasing. */
3712 flags
= CP_T_Pre
| CP_T_UD
;
3717 inst
.instruction
|= flags
| offset
;
3719 else if (skip_past_comma (&str
) == FAIL
3720 || cp_address_required_here (&str
) == FAIL
)
3723 inst
.error
= BAD_ARGS
;
3731 do_fp_dyadic (str
, flags
)
3733 unsigned long flags
;
3735 skip_whitespace (str
);
3737 switch (inst
.suffix
)
3742 inst
.instruction
|= 0x00000080;
3745 inst
.instruction
|= 0x00080000;
3751 if (fp_reg_required_here (&str
, 12) == FAIL
)
3754 inst
.error
= BAD_ARGS
;
3758 if (skip_past_comma (&str
) == FAIL
3759 || fp_reg_required_here (&str
, 16) == FAIL
)
3762 inst
.error
= BAD_ARGS
;
3766 if (skip_past_comma (&str
) == FAIL
3767 || fp_op2 (&str
) == FAIL
)
3770 inst
.error
= BAD_ARGS
;
3774 inst
.instruction
|= flags
;
3780 do_fp_monadic (str
, flags
)
3782 unsigned long flags
;
3784 skip_whitespace (str
);
3786 switch (inst
.suffix
)
3791 inst
.instruction
|= 0x00000080;
3794 inst
.instruction
|= 0x00080000;
3800 if (fp_reg_required_here (&str
, 12) == FAIL
)
3803 inst
.error
= BAD_ARGS
;
3807 if (skip_past_comma (&str
) == FAIL
3808 || fp_op2 (&str
) == FAIL
)
3811 inst
.error
= BAD_ARGS
;
3815 inst
.instruction
|= flags
;
3821 do_fp_cmp (str
, flags
)
3823 unsigned long flags
;
3825 skip_whitespace (str
);
3827 if (fp_reg_required_here (&str
, 16) == FAIL
)
3830 inst
.error
= BAD_ARGS
;
3834 if (skip_past_comma (&str
) == FAIL
3835 || fp_op2 (&str
) == FAIL
)
3838 inst
.error
= BAD_ARGS
;
3842 inst
.instruction
|= flags
;
3848 do_fp_from_reg (str
, flags
)
3850 unsigned long flags
;
3852 skip_whitespace (str
);
3854 switch (inst
.suffix
)
3859 inst
.instruction
|= 0x00000080;
3862 inst
.instruction
|= 0x00080000;
3868 if (fp_reg_required_here (&str
, 16) == FAIL
)
3871 inst
.error
= BAD_ARGS
;
3875 if (skip_past_comma (&str
) == FAIL
3876 || reg_required_here (&str
, 12) == FAIL
)
3879 inst
.error
= BAD_ARGS
;
3883 inst
.instruction
|= flags
;
3889 do_fp_to_reg (str
, flags
)
3891 unsigned long flags
;
3893 skip_whitespace (str
);
3895 if (reg_required_here (&str
, 12) == FAIL
)
3898 if (skip_past_comma (&str
) == FAIL
3899 || fp_reg_required_here (&str
, 0) == FAIL
)
3902 inst
.error
= BAD_ARGS
;
3906 inst
.instruction
|= flags
;
3911 /* Thumb specific routines */
3913 /* Parse and validate that a register is of the right form, this saves
3914 repeated checking of this information in many similar cases.
3915 Unlike the 32-bit case we do not insert the register into the opcode
3916 here, since the position is often unknown until the full instruction
3919 thumb_reg (strp
, hi_lo
)
3925 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3933 inst
.error
= _("lo register required");
3941 inst
.error
= _("hi register required");
3953 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3956 thumb_add_sub (str
, subtract
)
3960 int Rd
, Rs
, Rn
= FAIL
;
3962 skip_whitespace (str
);
3964 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3965 || skip_past_comma (&str
) == FAIL
)
3968 inst
.error
= BAD_ARGS
;
3972 if (is_immediate_prefix (*str
))
3976 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3981 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3984 if (skip_past_comma (&str
) == FAIL
)
3986 /* Two operand format, shuffle the registers and pretend there
3991 else if (is_immediate_prefix (*str
))
3994 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3997 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4001 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4002 for the latter case, EXPR contains the immediate that was found. */
4005 /* All register format. */
4006 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4010 inst
.error
= _("dest and source1 must be the same register");
4014 /* Can't do this for SUB */
4017 inst
.error
= _("subtract valid only on lo regs");
4021 inst
.instruction
= (T_OPCODE_ADD_HI
4022 | (Rd
> 7 ? THUMB_H1
: 0)
4023 | (Rn
> 7 ? THUMB_H2
: 0));
4024 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4028 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4029 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4034 /* Immediate expression, now things start to get nasty. */
4036 /* First deal with HI regs, only very restricted cases allowed:
4037 Adjusting SP, and using PC or SP to get an address. */
4038 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4039 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4041 inst
.error
= _("invalid Hi register with immediate");
4045 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4047 /* Value isn't known yet, all we can do is store all the fragments
4048 we know about in the instruction and let the reloc hacking
4050 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4051 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4055 int offset
= inst
.reloc
.exp
.X_add_number
;
4065 /* Quick check, in case offset is MIN_INT */
4068 inst
.error
= _("immediate value out of range");
4077 if (offset
& ~0x1fc)
4079 inst
.error
= _("invalid immediate value for stack adjust");
4082 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4083 inst
.instruction
|= offset
>> 2;
4085 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4088 || (offset
& ~0x3fc))
4090 inst
.error
= _("invalid immediate for address calculation");
4093 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4095 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4101 inst
.error
= _("immediate value out of range");
4104 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4105 inst
.instruction
|= (Rd
<< 8) | offset
;
4111 inst
.error
= _("immediate value out of range");
4114 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4115 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4123 thumb_shift (str
, shift
)
4127 int Rd
, Rs
, Rn
= FAIL
;
4129 skip_whitespace (str
);
4131 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4132 || skip_past_comma (&str
) == FAIL
)
4135 inst
.error
= BAD_ARGS
;
4139 if (is_immediate_prefix (*str
))
4141 /* Two operand immediate format, set Rs to Rd. */
4144 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4149 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4152 if (skip_past_comma (&str
) == FAIL
)
4154 /* Two operand format, shuffle the registers and pretend there
4159 else if (is_immediate_prefix (*str
))
4162 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4165 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4169 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4170 for the latter case, EXPR contains the immediate that was found. */
4176 inst
.error
= _("source1 and dest must be same register");
4182 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4183 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4184 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4187 inst
.instruction
|= Rd
| (Rn
<< 3);
4193 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4194 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4195 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4198 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4200 /* Value isn't known yet, create a dummy reloc and let reloc
4201 hacking fix it up */
4203 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4207 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4209 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4211 inst
.error
= _("Invalid immediate for shift");
4215 /* Shifts of zero are handled by converting to LSL */
4216 if (shift_value
== 0)
4217 inst
.instruction
= T_OPCODE_LSL_I
;
4219 /* Shifts of 32 are encoded as a shift of zero */
4220 if (shift_value
== 32)
4223 inst
.instruction
|= shift_value
<< 6;
4226 inst
.instruction
|= Rd
| (Rs
<< 3);
4232 thumb_mov_compare (str
, move
)
4238 skip_whitespace (str
);
4240 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4241 || skip_past_comma (&str
) == FAIL
)
4244 inst
.error
= BAD_ARGS
;
4248 if (is_immediate_prefix (*str
))
4251 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4254 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4259 if (Rs
< 8 && Rd
< 8)
4261 if (move
== THUMB_MOVE
)
4262 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4263 since a MOV instruction produces unpredictable results */
4264 inst
.instruction
= T_OPCODE_ADD_I3
;
4266 inst
.instruction
= T_OPCODE_CMP_LR
;
4267 inst
.instruction
|= Rd
| (Rs
<< 3);
4271 if (move
== THUMB_MOVE
)
4272 inst
.instruction
= T_OPCODE_MOV_HR
;
4274 inst
.instruction
= T_OPCODE_CMP_HR
;
4277 inst
.instruction
|= THUMB_H1
;
4280 inst
.instruction
|= THUMB_H2
;
4282 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4289 inst
.error
= _("only lo regs allowed with immediate");
4293 if (move
== THUMB_MOVE
)
4294 inst
.instruction
= T_OPCODE_MOV_I8
;
4296 inst
.instruction
= T_OPCODE_CMP_I8
;
4298 inst
.instruction
|= Rd
<< 8;
4300 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4301 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4304 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4308 inst
.error
= _("invalid immediate");
4312 inst
.instruction
|= value
;
4320 thumb_load_store (str
, load_store
, size
)
4325 int Rd
, Rb
, Ro
= FAIL
;
4327 skip_whitespace (str
);
4329 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4330 || skip_past_comma (&str
) == FAIL
)
4333 inst
.error
= BAD_ARGS
;
4340 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4343 if (skip_past_comma (&str
) != FAIL
)
4345 if (is_immediate_prefix (*str
))
4348 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4351 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4356 inst
.reloc
.exp
.X_op
= O_constant
;
4357 inst
.reloc
.exp
.X_add_number
= 0;
4362 inst
.error
= _("expected ']'");
4367 else if (*str
== '=')
4369 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4372 skip_whitespace (str
);
4374 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4379 if ( inst
.reloc
.exp
.X_op
!= O_constant
4380 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4382 inst
.error
= "Constant expression expected";
4386 if (inst
.reloc
.exp
.X_op
== O_constant
4387 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4389 /* This can be done with a mov instruction */
4391 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4392 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4396 /* Insert into literal pool */
4397 if (add_to_lit_pool () == FAIL
)
4400 inst
.error
= "literal pool insertion failed";
4404 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4405 inst
.reloc
.pc_rel
= 1;
4406 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4407 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4413 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4416 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4417 inst
.reloc
.pc_rel
= 1;
4418 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4419 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4424 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4426 if (size
!= THUMB_WORD
)
4428 inst
.error
= _("byte or halfword not valid for base register");
4431 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4433 inst
.error
= _("R15 based store not allowed");
4436 else if (Ro
!= FAIL
)
4438 inst
.error
= _("Invalid base register for register offset");
4443 inst
.instruction
= T_OPCODE_LDR_PC
;
4444 else if (load_store
== THUMB_LOAD
)
4445 inst
.instruction
= T_OPCODE_LDR_SP
;
4447 inst
.instruction
= T_OPCODE_STR_SP
;
4449 inst
.instruction
|= Rd
<< 8;
4450 if (inst
.reloc
.exp
.X_op
== O_constant
)
4452 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4454 if (offset
& ~0x3fc)
4456 inst
.error
= _("invalid offset");
4460 inst
.instruction
|= offset
>> 2;
4463 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4467 inst
.error
= _("invalid base register in load/store");
4470 else if (Ro
== FAIL
)
4472 /* Immediate offset */
4473 if (size
== THUMB_WORD
)
4474 inst
.instruction
= (load_store
== THUMB_LOAD
4475 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4476 else if (size
== THUMB_HALFWORD
)
4477 inst
.instruction
= (load_store
== THUMB_LOAD
4478 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4480 inst
.instruction
= (load_store
== THUMB_LOAD
4481 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4483 inst
.instruction
|= Rd
| (Rb
<< 3);
4485 if (inst
.reloc
.exp
.X_op
== O_constant
)
4487 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4489 if (offset
& ~(0x1f << size
))
4491 inst
.error
= _("Invalid offset");
4494 inst
.instruction
|= (offset
>> size
) << 6;
4497 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4501 /* Register offset */
4502 if (size
== THUMB_WORD
)
4503 inst
.instruction
= (load_store
== THUMB_LOAD
4504 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4505 else if (size
== THUMB_HALFWORD
)
4506 inst
.instruction
= (load_store
== THUMB_LOAD
4507 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4509 inst
.instruction
= (load_store
== THUMB_LOAD
4510 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4512 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4527 /* Handle the Format 4 instructions that do not have equivalents in other
4528 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4536 skip_whitespace (str
);
4538 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4539 || skip_past_comma (&str
) == FAIL
4540 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4542 inst
.error
= BAD_ARGS
;
4546 if (skip_past_comma (&str
) != FAIL
)
4548 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4549 (It isn't allowed for CMP either, but that isn't handled by this
4551 if (inst
.instruction
== T_OPCODE_TST
4552 || inst
.instruction
== T_OPCODE_CMN
4553 || inst
.instruction
== T_OPCODE_NEG
4554 || inst
.instruction
== T_OPCODE_MVN
)
4556 inst
.error
= BAD_ARGS
;
4560 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4565 inst
.error
= _("dest and source1 one must be the same register");
4571 if (inst
.instruction
== T_OPCODE_MUL
4573 as_tsktsk (_("Rs and Rd must be different in MUL"));
4575 inst
.instruction
|= Rd
| (Rs
<< 3);
4583 thumb_add_sub (str
, 0);
4590 thumb_shift (str
, THUMB_ASR
);
4597 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4599 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4600 inst
.reloc
.pc_rel
= 1;
4608 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4610 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4611 inst
.reloc
.pc_rel
= 1;
4615 /* Find the real, Thumb encoded start of a Thumb function. */
4618 find_real_start (symbolP
)
4622 const char * name
= S_GET_NAME (symbolP
);
4623 symbolS
* new_target
;
4625 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4626 #define STUB_NAME ".real_start_of"
4631 /* Names that start with '.' are local labels, not function entry points.
4632 The compiler may generate BL instructions to these labels because it
4633 needs to perform a branch to a far away location. */
4637 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4638 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4640 new_target
= symbol_find (real_start
);
4642 if (new_target
== NULL
)
4644 as_warn ("Failed to find real start of function: %s\n", name
);
4645 new_target
= symbolP
;
4658 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4661 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4662 inst
.reloc
.pc_rel
= 1;
4665 /* If the destination of the branch is a defined symbol which does not have
4666 the THUMB_FUNC attribute, then we must be calling a function which has
4667 the (interfacearm) attribute. We look for the Thumb entry point to that
4668 function and change the branch to refer to that function instead. */
4669 if ( inst
.reloc
.exp
.X_op
== O_symbol
4670 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4671 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4672 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4673 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4682 skip_whitespace (str
);
4684 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4687 /* This sets THUMB_H2 from the top bit of reg. */
4688 inst
.instruction
|= reg
<< 3;
4690 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4691 should cause the alignment to be checked once it is known. This is
4692 because BX PC only works if the instruction is word aligned. */
4701 thumb_mov_compare (str
, THUMB_COMPARE
);
4711 skip_whitespace (str
);
4713 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4717 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4721 if (skip_past_comma (&str
) == FAIL
4722 || (range
= reg_list (&str
)) == FAIL
)
4725 inst
.error
= BAD_ARGS
;
4729 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4731 /* This really doesn't seem worth it. */
4732 inst
.reloc
.type
= BFD_RELOC_NONE
;
4733 inst
.error
= _("Expression too complex");
4739 inst
.error
= _("only lo-regs valid in load/store multiple");
4743 inst
.instruction
|= (Rb
<< 8) | range
;
4751 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4758 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4765 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4774 skip_whitespace (str
);
4776 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4777 || skip_past_comma (&str
) == FAIL
4779 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4780 || skip_past_comma (&str
) == FAIL
4781 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4785 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4789 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4797 thumb_shift (str
, THUMB_LSL
);
4804 thumb_shift (str
, THUMB_LSR
);
4811 thumb_mov_compare (str
, THUMB_MOVE
);
4820 skip_whitespace (str
);
4822 if ((range
= reg_list (&str
)) == FAIL
)
4825 inst
.error
= BAD_ARGS
;
4829 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4831 /* This really doesn't seem worth it. */
4832 inst
.reloc
.type
= BFD_RELOC_NONE
;
4833 inst
.error
= _("Expression too complex");
4839 if ((inst
.instruction
== T_OPCODE_PUSH
4840 && (range
& ~0xff) == 1 << REG_LR
)
4841 || (inst
.instruction
== T_OPCODE_POP
4842 && (range
& ~0xff) == 1 << REG_PC
))
4844 inst
.instruction
|= THUMB_PP_PC_LR
;
4849 inst
.error
= _("invalid register list to push/pop instruction");
4854 inst
.instruction
|= range
;
4862 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4869 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4876 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4883 thumb_add_sub (str
, 1);
4890 skip_whitespace (str
);
4892 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4895 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4904 /* This is a pseudo-op of the form "adr rd, label" to be converted
4905 into a relative address of the form "add rd, pc, #label-.-4" */
4906 skip_whitespace (str
);
4908 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4909 || skip_past_comma (&str
) == FAIL
4910 || my_get_expression (&inst
.reloc
.exp
, &str
))
4913 inst
.error
= BAD_ARGS
;
4917 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4918 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4919 inst
.reloc
.pc_rel
= 1;
4920 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4928 int len
= strlen (reg_table
[entry
].name
) + 2;
4929 char * buf
= (char *) xmalloc (len
);
4930 char * buf2
= (char *) xmalloc (len
);
4933 #ifdef REGISTER_PREFIX
4934 buf
[i
++] = REGISTER_PREFIX
;
4937 strcpy (buf
+ i
, reg_table
[entry
].name
);
4939 for (i
= 0; buf
[i
]; i
++)
4940 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4944 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4945 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4949 insert_reg_alias (str
, regnum
)
4953 struct reg_entry
*new =
4954 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4955 char *name
= xmalloc (strlen (str
) + 1);
4959 new->number
= regnum
;
4961 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4965 set_constant_flonums ()
4969 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4970 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4979 if ( (arm_ops_hsh
= hash_new ()) == NULL
4980 || (arm_tops_hsh
= hash_new ()) == NULL
4981 || (arm_cond_hsh
= hash_new ()) == NULL
4982 || (arm_shift_hsh
= hash_new ()) == NULL
4983 || (arm_reg_hsh
= hash_new ()) == NULL
4984 || (arm_psr_hsh
= hash_new ()) == NULL
)
4985 as_fatal (_("Virtual memory exhausted"));
4987 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4988 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4989 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4990 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4991 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4992 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4993 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4994 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4995 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4996 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4998 for (i
= 0; reg_table
[i
].name
; i
++)
5001 set_constant_flonums ();
5003 #if defined OBJ_COFF || defined OBJ_ELF
5005 unsigned int flags
= 0;
5007 /* Set the flags in the private structure */
5008 if (uses_apcs_26
) flags
|= F_APCS26
;
5009 if (support_interwork
) flags
|= F_INTERWORK
;
5010 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5011 if (pic_code
) flags
|= F_PIC
;
5012 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5014 bfd_set_private_flags (stdoutput
, flags
);
5021 /* Record the CPU type as well */
5022 switch (cpu_variant
& ARM_CPU_MASK
)
5025 mach
= bfd_mach_arm_2
;
5028 case ARM_3
: /* also ARM_250 */
5029 mach
= bfd_mach_arm_2a
;
5033 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
5034 mach
= bfd_mach_arm_4
;
5037 case ARM_7
: /* also ARM_6 */
5038 mach
= bfd_mach_arm_3
;
5042 /* Catch special cases. */
5043 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5045 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5046 mach
= bfd_mach_arm_5T
;
5047 else if (cpu_variant
& ARM_EXT_V5
)
5048 mach
= bfd_mach_arm_5
;
5049 else if (cpu_variant
& ARM_THUMB
)
5050 mach
= bfd_mach_arm_4T
;
5051 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5052 mach
= bfd_mach_arm_4
;
5053 else if (cpu_variant
& ARM_LONGMUL
)
5054 mach
= bfd_mach_arm_3M
;
5057 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5061 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5062 for use in the a.out file, and stores them in the array pointed to by buf.
5063 This knows about the endian-ness of the target machine and does
5064 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5065 2 (short) and 4 (long) Floating numbers are put out as a series of
5066 LITTLENUMS (shorts, here at least). */
5068 md_number_to_chars (buf
, val
, n
)
5073 if (target_big_endian
)
5074 number_to_chars_bigendian (buf
, val
, n
);
5076 number_to_chars_littleendian (buf
, val
, n
);
5080 md_chars_to_number (buf
, n
)
5085 unsigned char * where
= (unsigned char *) buf
;
5087 if (target_big_endian
)
5092 result
|= (*where
++ & 255);
5100 result
|= (where
[n
] & 255);
5107 /* Turn a string in input_line_pointer into a floating point constant
5108 of type TYPE, and store the appropriate bytes in *litP. The number
5109 of LITTLENUMS emitted is stored in *sizeP . An error message is
5110 returned, or NULL on OK.
5112 Note that fp constants aren't represent in the normal way on the ARM.
5113 In big endian mode, things are as expected. However, in little endian
5114 mode fp constants are big-endian word-wise, and little-endian byte-wise
5115 within the words. For example, (double) 1.1 in big endian mode is
5116 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5117 the byte sequence 99 99 f1 3f 9a 99 99 99.
5119 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5122 md_atof (type
, litP
, sizeP
)
5128 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5160 return _("Bad call to MD_ATOF()");
5163 t
= atof_ieee (input_line_pointer
, type
, words
);
5165 input_line_pointer
= t
;
5168 if (target_big_endian
)
5170 for (i
= 0; i
< prec
; i
++)
5172 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5178 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5179 8 byte float the order is 1 0 3 2. */
5180 for (i
= 0; i
< prec
; i
+= 2)
5182 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5183 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5191 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5193 md_pcrel_from (fixP
)
5197 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5198 && fixP
->fx_subsy
== NULL
)
5201 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5203 /* PC relative addressing on the Thumb is slightly odd
5204 as the bottom two bits of the PC are forced to zero
5205 for the calculation. */
5206 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5209 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5212 /* Round up a section size to the appropriate boundary. */
5214 md_section_align (segment
, size
)
5221 /* Round all sects to multiple of 4 */
5222 return (size
+ 3) & ~3;
5226 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5227 we have no need to default values of symbols. */
5231 md_undefined_symbol (name
)
5235 if (name
[0] == '_' && name
[1] == 'G'
5236 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5240 if (symbol_find (name
))
5241 as_bad ("GOT already in the symbol table");
5243 GOT_symbol
= symbol_new (name
, undefined_section
,
5244 (valueT
)0, & zero_address_frag
);
5254 /* arm_reg_parse () := if it looks like a register, return its token and
5255 advance the pointer. */
5259 register char ** ccp
;
5261 char * start
= * ccp
;
5264 struct reg_entry
* reg
;
5266 #ifdef REGISTER_PREFIX
5267 if (*start
!= REGISTER_PREFIX
)
5272 #ifdef OPTIONAL_REGISTER_PREFIX
5273 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5277 if (!isalpha (*p
) || !is_name_beginner (*p
))
5281 while (isalpha (c
) || isdigit (c
) || c
== '_')
5285 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5299 register char ** ccp
;
5301 char * start
= * ccp
;
5304 CONST
struct asm_psr
* psr
;
5308 while (isalpha (c
) || c
== '_')
5312 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5325 md_apply_fix3 (fixP
, val
, seg
)
5330 offsetT value
= * val
;
5332 unsigned int newimm
;
5335 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5336 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5338 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5340 /* Note whether this will delete the relocation. */
5341 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5342 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5345 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5349 /* If this symbol is in a different section then we need to leave it for
5350 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5351 so we have to undo it's effects here. */
5354 if (fixP
->fx_addsy
!= NULL
5355 && S_IS_DEFINED (fixP
->fx_addsy
)
5356 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5359 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5363 value
+= md_pcrel_from (fixP
);
5367 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5369 switch (fixP
->fx_r_type
)
5371 case BFD_RELOC_ARM_IMMEDIATE
:
5372 newimm
= validate_immediate (value
);
5373 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5375 /* If the instruction will fail, see if we can fix things up by
5376 changing the opcode. */
5377 if (newimm
== (unsigned int) FAIL
5378 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5380 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5381 _("invalid constant (%lx) after fixup"),
5382 (unsigned long) value
);
5386 newimm
|= (temp
& 0xfffff000);
5387 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5390 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5392 unsigned int highpart
= 0;
5393 unsigned int newinsn
= 0xe1a00000; /* nop */
5394 newimm
= validate_immediate (value
);
5395 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5397 /* If the instruction will fail, see if we can fix things up by
5398 changing the opcode. */
5399 if (newimm
== (unsigned int) FAIL
5400 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5402 /* No ? OK - try using two ADD instructions to generate the value. */
5403 newimm
= validate_immediate_twopart (value
, & highpart
);
5405 /* Yes - then make sure that the second instruction is also an add. */
5406 if (newimm
!= (unsigned int) FAIL
)
5408 /* Still No ? Try using a negated value. */
5409 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5410 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5411 /* Otherwise - give up. */
5414 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5415 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5419 /* Replace the first operand in the 2nd instruction (which is the PC)
5420 with the destination register. We have already added in the PC in the
5421 first instruction and we do not want to do it again. */
5422 newinsn
&= ~ 0xf0000;
5423 newinsn
|= ((newinsn
& 0x0f000) << 4);
5426 newimm
|= (temp
& 0xfffff000);
5427 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5429 highpart
|= (newinsn
& 0xfffff000);
5430 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5434 case BFD_RELOC_ARM_OFFSET_IMM
:
5440 if (validate_offset_imm (value
, 0) == FAIL
)
5442 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5443 _("bad immediate value for offset (%ld)"), (long) value
);
5447 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5448 newval
&= 0xff7ff000;
5449 newval
|= value
| (sign
? INDEX_UP
: 0);
5450 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5453 case BFD_RELOC_ARM_OFFSET_IMM8
:
5454 case BFD_RELOC_ARM_HWLITERAL
:
5460 if (validate_offset_imm (value
, 1) == FAIL
)
5462 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5463 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5464 _("invalid literal constant: pool needs to be closer"));
5466 as_bad (_("bad immediate value for half-word offset (%ld)"),
5471 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5472 newval
&= 0xff7ff0f0;
5473 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5474 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5477 case BFD_RELOC_ARM_LITERAL
:
5483 if (validate_offset_imm (value
, 0) == FAIL
)
5485 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5486 _("invalid literal constant: pool needs to be closer"));
5490 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5491 newval
&= 0xff7ff000;
5492 newval
|= value
| (sign
? INDEX_UP
: 0);
5493 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5496 case BFD_RELOC_ARM_SHIFT_IMM
:
5497 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5498 if (((unsigned long) value
) > 32
5500 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5502 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5503 _("shift expression is too large"));
5508 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5509 else if (value
== 32)
5511 newval
&= 0xfffff07f;
5512 newval
|= (value
& 0x1f) << 7;
5513 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5516 case BFD_RELOC_ARM_SWI
:
5517 if (arm_data
->thumb_mode
)
5519 if (((unsigned long) value
) > 0xff)
5520 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5521 _("Invalid swi expression"));
5522 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5524 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5528 if (((unsigned long) value
) > 0x00ffffff)
5529 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5530 _("Invalid swi expression"));
5531 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5533 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5537 case BFD_RELOC_ARM_MULTI
:
5538 if (((unsigned long) value
) > 0xffff)
5539 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5540 _("Invalid expression in load/store multiple"));
5541 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5542 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5545 case BFD_RELOC_ARM_PCREL_BRANCH
:
5546 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5550 value
= fixP
->fx_offset
;
5552 value
= (value
>> 2) & 0x00ffffff;
5553 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5554 newval
= value
| (newval
& 0xff000000);
5555 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5559 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5560 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5562 addressT diff
= (newval
& 0xff) << 1;
5567 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5568 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5569 _("Branch out of range"));
5570 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5572 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5575 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5576 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5578 addressT diff
= (newval
& 0x7ff) << 1;
5583 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5584 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5585 _("Branch out of range"));
5586 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5588 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5591 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5596 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5597 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5598 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5599 if (diff
& 0x400000)
5602 value
= fixP
->fx_offset
;
5605 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5606 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5607 _("Branch with link out of range"));
5609 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5610 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5611 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5612 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5617 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5618 md_number_to_chars (buf
, value
, 1);
5620 else if (!target_oabi
)
5622 value
= fixP
->fx_offset
;
5623 md_number_to_chars (buf
, value
, 1);
5629 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5630 md_number_to_chars (buf
, value
, 2);
5632 else if (!target_oabi
)
5634 value
= fixP
->fx_offset
;
5635 md_number_to_chars (buf
, value
, 2);
5641 case BFD_RELOC_ARM_GOT32
:
5642 case BFD_RELOC_ARM_GOTOFF
:
5643 md_number_to_chars (buf
, 0, 4);
5649 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5650 md_number_to_chars (buf
, value
, 4);
5652 else if (!target_oabi
)
5654 value
= fixP
->fx_offset
;
5655 md_number_to_chars (buf
, value
, 4);
5661 case BFD_RELOC_ARM_PLT32
:
5662 /* It appears the instruction is fully prepared at this point. */
5666 case BFD_RELOC_ARM_GOTPC
:
5667 md_number_to_chars (buf
, value
, 4);
5670 case BFD_RELOC_ARM_CP_OFF_IMM
:
5672 if (value
< -1023 || value
> 1023 || (value
& 3))
5673 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5674 _("Illegal value for co-processor offset"));
5677 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5678 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5679 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5682 case BFD_RELOC_ARM_THUMB_OFFSET
:
5683 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5684 /* Exactly what ranges, and where the offset is inserted depends on
5685 the type of instruction, we can establish this from the top 4 bits */
5686 switch (newval
>> 12)
5688 case 4: /* PC load */
5689 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5690 forced to zero for these loads, so we will need to round
5691 up the offset if the instruction address is not word
5692 aligned (since the final address produced must be, and
5693 we can only describe word-aligned immediate offsets). */
5695 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5697 _("Invalid offset, target not word aligned (0x%08X)"),
5698 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5700 if ((value
+ 2) & ~0x3fe)
5701 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5702 _("Invalid offset, value too big (0x%08X)"), value
);
5704 /* Round up, since pc will be rounded down. */
5705 newval
|= (value
+ 2) >> 2;
5708 case 9: /* SP load/store */
5710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5711 _("Invalid offset, value too big (0x%08X)"), value
);
5712 newval
|= value
>> 2;
5715 case 6: /* Word load/store */
5717 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5718 _("Invalid offset, value too big (0x%08X)"), value
);
5719 newval
|= value
<< 4; /* 6 - 2 */
5722 case 7: /* Byte load/store */
5724 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5725 _("Invalid offset, value too big (0x%08X)"), value
);
5726 newval
|= value
<< 6;
5729 case 8: /* Halfword load/store */
5731 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5732 _("Invalid offset, value too big (0x%08X)"), value
);
5733 newval
|= value
<< 5; /* 6 - 1 */
5737 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5738 "Unable to process relocation for thumb opcode: %lx",
5739 (unsigned long) newval
);
5742 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5745 case BFD_RELOC_ARM_THUMB_ADD
:
5746 /* This is a complicated relocation, since we use it for all of
5747 the following immediate relocations:
5750 9bit ADD/SUB SP word-aligned
5751 10bit ADD PC/SP word-aligned
5753 The type of instruction being processed is encoded in the
5759 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5761 int rd
= (newval
>> 4) & 0xf;
5762 int rs
= newval
& 0xf;
5763 int subtract
= newval
& 0x8000;
5768 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5769 _("Invalid immediate for stack address calculation"));
5770 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5771 newval
|= value
>> 2;
5773 else if (rs
== REG_PC
|| rs
== REG_SP
)
5777 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5778 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5779 (unsigned long) value
);
5780 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5782 newval
|= value
>> 2;
5787 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5788 _("Invalid 8bit immediate"));
5789 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5790 newval
|= (rd
<< 8) | value
;
5795 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5796 _("Invalid 3bit immediate"));
5797 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5798 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5801 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5804 case BFD_RELOC_ARM_THUMB_IMM
:
5805 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5806 switch (newval
>> 11)
5808 case 0x04: /* 8bit immediate MOV */
5809 case 0x05: /* 8bit immediate CMP */
5810 if (value
< 0 || value
> 255)
5811 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5812 _("Invalid immediate: %ld is too large"),
5820 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5823 case BFD_RELOC_ARM_THUMB_SHIFT
:
5824 /* 5bit shift value (0..31) */
5825 if (value
< 0 || value
> 31)
5826 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5827 _("Illegal Thumb shift value: %ld"), (long) value
);
5828 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5829 newval
|= value
<< 6;
5830 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5833 case BFD_RELOC_VTABLE_INHERIT
:
5834 case BFD_RELOC_VTABLE_ENTRY
:
5838 case BFD_RELOC_NONE
:
5840 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5841 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5847 /* Translate internal representation of relocation info to BFD target
5850 tc_gen_reloc (section
, fixp
)
5855 bfd_reloc_code_real_type code
;
5857 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5859 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5860 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5861 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5863 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5865 if (fixp
->fx_pcrel
== 0)
5866 reloc
->addend
= fixp
->fx_offset
;
5868 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5870 reloc
->addend
= fixp
->fx_offset
;
5873 switch (fixp
->fx_r_type
)
5878 code
= BFD_RELOC_8_PCREL
;
5885 code
= BFD_RELOC_16_PCREL
;
5892 code
= BFD_RELOC_32_PCREL
;
5896 case BFD_RELOC_ARM_PCREL_BRANCH
:
5898 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5899 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5900 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5901 case BFD_RELOC_VTABLE_ENTRY
:
5902 case BFD_RELOC_VTABLE_INHERIT
:
5903 code
= fixp
->fx_r_type
;
5906 case BFD_RELOC_ARM_LITERAL
:
5907 case BFD_RELOC_ARM_HWLITERAL
:
5908 /* If this is called then the a literal has been referenced across
5909 a section boundary - possibly due to an implicit dump */
5910 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5911 _("Literal referenced across section boundary (Implicit dump?)"));
5915 case BFD_RELOC_ARM_GOT32
:
5916 case BFD_RELOC_ARM_GOTOFF
:
5917 case BFD_RELOC_ARM_PLT32
:
5918 code
= fixp
->fx_r_type
;
5922 case BFD_RELOC_ARM_IMMEDIATE
:
5923 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5924 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5928 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5929 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5930 _("ADRL used for a symbol not defined in the same file"),
5934 case BFD_RELOC_ARM_OFFSET_IMM
:
5935 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5936 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5943 switch (fixp
->fx_r_type
)
5945 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5946 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5947 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5948 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5949 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5950 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5951 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5952 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5953 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5954 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5955 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5956 default: type
= _("<unknown>"); break;
5958 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5959 _("Can not represent %s relocation in this object file format (%d)"),
5960 type
, fixp
->fx_pcrel
);
5966 if (code
== BFD_RELOC_32_PCREL
5968 && fixp
->fx_addsy
== GOT_symbol
)
5970 code
= BFD_RELOC_ARM_GOTPC
;
5971 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5975 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5977 if (reloc
->howto
== NULL
)
5979 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5980 _("Can not represent %s relocation in this object file format"),
5981 bfd_get_reloc_code_name (code
));
5985 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5986 vtable entry to be used in the relocation's section offset. */
5987 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5988 reloc
->address
= fixp
->fx_offset
;
5994 md_estimate_size_before_relax (fragP
, segtype
)
5998 as_fatal (_("md_estimate_size_before_relax\n"));
6003 output_inst
PARAMS ((void))
6009 as_bad (inst
.error
);
6013 to
= frag_more (inst
.size
);
6015 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6017 assert (inst
.size
== (2 * THUMB_SIZE
));
6018 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6019 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6021 else if (inst
.size
> INSN_SIZE
)
6023 assert (inst
.size
== (2 * INSN_SIZE
));
6024 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6025 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6028 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6030 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6031 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6032 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6047 /* Align the instruction.
6048 This may not be the right thing to do but ... */
6049 /* arm_align (2, 0); */
6050 listing_prev_line (); /* Defined in listing.h */
6052 /* Align the previous label if needed. */
6053 if (last_label_seen
!= NULL
)
6055 symbol_set_frag (last_label_seen
, frag_now
);
6056 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6057 S_SET_SEGMENT (last_label_seen
, now_seg
);
6060 memset (&inst
, '\0', sizeof (inst
));
6061 inst
.reloc
.type
= BFD_RELOC_NONE
;
6063 skip_whitespace (str
);
6065 /* Scan up to the end of the op-code, which must end in white space or
6067 for (start
= p
= str
; *p
!= '\0'; p
++)
6073 as_bad (_("No operator -- statement `%s'\n"), str
);
6079 CONST
struct thumb_opcode
* opcode
;
6083 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6088 /* Check that this instruction is supported for this CPU. */
6089 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6091 as_bad (_("selected processor does not support this opcode"));
6095 inst
.instruction
= opcode
->value
;
6096 inst
.size
= opcode
->size
;
6097 (*opcode
->parms
)(p
);
6104 CONST
struct asm_opcode
* opcode
;
6105 unsigned long cond_code
;
6107 inst
.size
= INSN_SIZE
;
6108 /* p now points to the end of the opcode, probably white space, but we
6109 have to break the opcode up in case it contains condionals and flags;
6110 keep trying with progressively smaller basic instructions until one
6111 matches, or we run out of opcode. */
6112 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6113 for (; q
!= str
; q
--)
6117 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6120 if (opcode
&& opcode
->template)
6122 unsigned long flag_bits
= 0;
6125 /* Check that this instruction is supported for this CPU. */
6126 if ((opcode
->variants
& cpu_variant
) == 0)
6129 inst
.instruction
= opcode
->value
;
6130 if (q
== p
) /* Just a simple opcode. */
6132 if (opcode
->comp_suffix
)
6134 if (*opcode
->comp_suffix
!= '\0')
6135 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6136 str
, opcode
->comp_suffix
);
6138 /* Not a conditional instruction. */
6139 (*opcode
->parms
)(q
, 0);
6143 /* A conditional instruction with default condition. */
6144 inst
.instruction
|= COND_ALWAYS
;
6145 (*opcode
->parms
)(q
, 0);
6151 /* Not just a simple opcode. Check if extra is a conditional. */
6155 CONST
struct asm_cond
*cond
;
6159 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6163 if (cond
->value
== 0xf0000000)
6165 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6167 cond_code
= cond
->value
;
6171 cond_code
= COND_ALWAYS
;
6174 cond_code
= COND_ALWAYS
;
6176 /* Apply the conditional, or complain it's not allowed. */
6177 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6179 /* Instruction isn't conditional */
6180 if (cond_code
!= COND_ALWAYS
)
6182 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6187 /* Instruction is conditional: set the condition into it. */
6188 inst
.instruction
|= cond_code
;
6191 /* If there is a compulsory suffix, it should come here, before
6192 any optional flags. */
6193 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6195 CONST
char *s
= opcode
->comp_suffix
;
6207 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6208 opcode
->comp_suffix
);
6215 /* The remainder, if any should now be flags for the instruction;
6216 Scan these checking each one found with the opcode. */
6220 CONST
struct asm_flg
*flag
= opcode
->flags
;
6229 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6231 if (streq (r
, flag
[flagno
].template))
6233 flag_bits
|= flag
[flagno
].set_bits
;
6239 if (! flag
[flagno
].template)
6246 (*opcode
->parms
) (p
, flag_bits
);
6256 /* It wasn't an instruction, but it might be a register alias of the form
6259 skip_whitespace (q
);
6264 if (*q
&& !strncmp (q
, ".req ", 4))
6267 char * copy_of_str
= str
;
6271 skip_whitespace (q
);
6273 for (r
= q
; *r
!= '\0'; r
++)
6283 regnum
= arm_reg_parse (& q
);
6286 reg
= arm_reg_parse (& str
);
6291 insert_reg_alias (str
, regnum
);
6293 as_warn (_("register '%s' does not exist\n"), q
);
6295 else if (regnum
!= FAIL
)
6298 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6300 /* Do not warn about redefinitions to the same alias. */
6303 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6307 as_warn (_("ignoring incomplete .req pseuso op"));
6314 as_bad (_("bad instruction `%s'"), start
);
6319 * Invocation line includes a switch not recognized by the base assembler.
6320 * See if it's a processor-specific option. These are:
6321 * Cpu variants, the arm part is optional:
6322 * -m[arm]1 Currently not supported.
6323 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6324 * -m[arm]3 Arm 3 processor
6325 * -m[arm]6[xx], Arm 6 processors
6326 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6327 * -m[arm]8[10] Arm 8 processors
6328 * -m[arm]9[20][tdmi] Arm 9 processors
6329 * -mstrongarm[110[0]] StrongARM processors
6330 * -m[arm]v[2345] Arm architectures
6331 * -mall All (except the ARM1)
6333 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6334 * -mfpe-old (No float load/store multiples)
6335 * -mno-fpu Disable all floating point instructions
6336 * Run-time endian selection:
6337 * -EB big endian cpu
6338 * -EL little endian cpu
6339 * ARM Procedure Calling Standard:
6340 * -mapcs-32 32 bit APCS
6341 * -mapcs-26 26 bit APCS
6342 * -mapcs-float Pass floats in float regs
6343 * -mapcs-reentrant Position independent code
6344 * -mthumb-interwork Code supports Arm/Thumb interworking
6345 * -moabi Old ELF ABI
6348 CONST
char * md_shortopts
= "m:k";
6349 struct option md_longopts
[] =
6351 #ifdef ARM_BI_ENDIAN
6352 #define OPTION_EB (OPTION_MD_BASE + 0)
6353 {"EB", no_argument
, NULL
, OPTION_EB
},
6354 #define OPTION_EL (OPTION_MD_BASE + 1)
6355 {"EL", no_argument
, NULL
, OPTION_EL
},
6357 #define OPTION_OABI (OPTION_MD_BASE +2)
6358 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6361 {NULL
, no_argument
, NULL
, 0}
6363 size_t md_longopts_size
= sizeof (md_longopts
);
6366 md_parse_option (c
, arg
)
6374 #ifdef ARM_BI_ENDIAN
6376 target_big_endian
= 1;
6379 target_big_endian
= 0;
6387 if (streq (str
, "fpa10"))
6388 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6389 else if (streq (str
, "fpa11"))
6390 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6391 else if (streq (str
, "fpe-old"))
6392 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6398 if (streq (str
, "no-fpu"))
6399 cpu_variant
&= ~FPU_ALL
;
6404 if (streq (str
, "oabi"))
6410 /* Limit assembler to generating only Thumb instructions: */
6411 if (streq (str
, "thumb"))
6413 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6414 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6417 else if (streq (str
, "thumb-interwork"))
6419 if ((cpu_variant
& ARM_THUMB
) == 0)
6420 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6421 #if defined OBJ_COFF || defined OBJ_ELF
6422 support_interwork
= true;
6430 if (streq (str
, "all"))
6432 cpu_variant
= ARM_ALL
| FPU_ALL
;
6435 #if defined OBJ_COFF || defined OBJ_ELF
6436 if (! strncmp (str
, "apcs-", 5))
6438 /* GCC passes on all command line options starting "-mapcs-..."
6439 to us, so we must parse them here. */
6443 if (streq (str
, "32"))
6445 uses_apcs_26
= false;
6448 else if (streq (str
, "26"))
6450 uses_apcs_26
= true;
6453 else if (streq (str
, "frame"))
6455 /* Stack frames are being generated - does not affect
6459 else if (streq (str
, "stack-check"))
6461 /* Stack checking is being performed - does not affect
6462 linkage, but does require that the functions
6463 __rt_stkovf_split_small and __rt_stkovf_split_big be
6464 present in the final link. */
6468 else if (streq (str
, "float"))
6470 /* Floating point arguments are being passed in the floating
6471 point registers. This does affect linking, since this
6472 version of the APCS is incompatible with the version that
6473 passes floating points in the integer registers. */
6475 uses_apcs_float
= true;
6478 else if (streq (str
, "reentrant"))
6480 /* Reentrant code has been generated. This does affect
6481 linking, since there is no point in linking reentrant/
6482 position independent code with absolute position code. */
6487 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6491 /* Strip off optional "arm" */
6492 if (! strncmp (str
, "arm", 3))
6498 if (streq (str
, "1"))
6499 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6505 if (streq (str
, "2"))
6506 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6507 else if (streq (str
, "250"))
6508 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6514 if (streq (str
, "3"))
6515 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6521 switch (strtol (str
, NULL
, 10))
6528 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6536 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6549 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6555 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6559 cpu_variant
|= ARM_LONGMUL
;
6562 case 'f': /* fe => fp enabled cpu. */
6568 case 'c': /* Left over from 710c processor name. */
6569 case 'd': /* Debug */
6570 case 'i': /* Embedded ICE */
6571 /* Included for completeness in ARM processor naming. */
6581 if (streq (str
, "8") || streq (str
, "810"))
6582 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6588 if (streq (str
, "9"))
6589 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6590 else if (streq (str
, "920"))
6591 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6592 else if (streq (str
, "920t"))
6593 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6594 else if (streq (str
, "9tdmi"))
6595 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6602 if (streq (str
, "strongarm")
6603 || streq (str
, "strongarm110")
6604 || streq (str
, "strongarm1100"))
6605 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6611 /* Select variant based on architecture rather than processor */
6617 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6618 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6619 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6624 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6628 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6630 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6635 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6639 case 't': cpu_variant
|= ARM_THUMB
; break;
6641 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6646 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6649 case 't': cpu_variant
|= ARM_THUMB
; break;
6650 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
6652 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6657 as_bad (_("Invalid architecture variant -m%s"), arg
);
6664 as_bad (_("Invalid processor variant -m%s"), arg
);
6670 #if defined OBJ_ELF || defined OBJ_COFF
6689 ARM Specific Assembler Options:\n\
6690 -m[arm][<processor name>] select processor variant\n\
6691 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6692 -mthumb only allow Thumb instructions\n\
6693 -mthumb-interwork mark the assembled code as supporting interworking\n\
6694 -mall allow any instruction\n\
6695 -mfpa10, -mfpa11 select floating point architecture\n\
6696 -mfpe-old don't allow floating-point multiple instructions\n\
6697 -mno-fpu don't allow any floating-point instructions.\n"));
6700 -k generate PIC code.\n"));
6701 #if defined OBJ_COFF || defined OBJ_ELF
6704 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6707 -mapcs-float floating point args are passed in FP regs\n"));
6710 -mapcs-reentrant the code is position independent/reentrant\n"));
6715 -moabi support the old ELF ABI\n"));
6717 #ifdef ARM_BI_ENDIAN
6720 -EB assemble code for a big endian cpu\n\
6721 -EL assemble code for a little endian cpu\n"));
6725 /* We need to be able to fix up arbitrary expressions in some statements.
6726 This is so that we can handle symbols that are an arbitrary distance from
6727 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6728 which returns part of an address in a form which will be valid for
6729 a data instruction. We do this by pushing the expression into a symbol
6730 in the expr_section, and creating a fix for that. */
6733 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6742 arm_fix_data
* arm_data
;
6750 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6754 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6759 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6760 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6761 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6762 arm_data
->thumb_mode
= thumb_mode
;
6768 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6770 cons_fix_new_arm (frag
, where
, size
, exp
)
6776 bfd_reloc_code_real_type type
;
6781 * @@ Should look at CPU word size.
6786 type
= BFD_RELOC_16
;
6790 type
= BFD_RELOC_32
;
6793 type
= BFD_RELOC_64
;
6797 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6800 /* A good place to do this, although this was probably not intended
6801 for this kind of use. We need to dump the literal pool before
6802 references are made to a null symbol pointer. */
6806 if (current_poolP
== NULL
)
6809 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6811 listing_prev_line ();
6815 arm_start_line_hook ()
6817 last_label_seen
= NULL
;
6821 arm_frob_label (sym
)
6824 last_label_seen
= sym
;
6826 ARM_SET_THUMB (sym
, thumb_mode
);
6828 #if defined OBJ_COFF || defined OBJ_ELF
6829 ARM_SET_INTERWORK (sym
, support_interwork
);
6832 if (label_is_thumb_function_name
)
6834 /* When the address of a Thumb function is taken the bottom
6835 bit of that address should be set. This will allow
6836 interworking between Arm and Thumb functions to work
6839 THUMB_SET_FUNC (sym
, 1);
6841 label_is_thumb_function_name
= false;
6845 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6849 arm_adjust_symtab ()
6854 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6856 if (ARM_IS_THUMB (sym
))
6858 if (THUMB_IS_FUNC (sym
))
6860 /* Mark the symbol as a Thumb function. */
6861 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6862 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6863 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6865 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6866 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6868 as_bad (_("%s: unexpected function type: %d"),
6869 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6871 else switch (S_GET_STORAGE_CLASS (sym
))
6874 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6877 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6880 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6882 default: /* do nothing */
6887 if (ARM_IS_INTERWORK (sym
))
6888 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6893 elf_symbol_type
* elf_sym
;
6896 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6898 if (ARM_IS_THUMB (sym
))
6900 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6901 bind
= ELF_ST_BIND (elf_sym
);
6903 /* If it's a .thumb_func, declare it as so, else tag label as .code 16. */
6904 if (THUMB_IS_FUNC (sym
))
6905 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6907 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_16BIT
);
6916 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6918 *input_line_pointer
= '/';
6919 input_line_pointer
+= 5;
6920 *input_line_pointer
= 0;
6928 arm_canonicalize_symbol_name (name
)
6933 if (thumb_mode
&& (len
= strlen (name
)) > 5
6934 && streq (name
+ len
- 5, "/data"))
6935 *(name
+ len
- 5) = 0;
6941 arm_validate_fix (fixP
)
6944 /* If the destination of the branch is a defined symbol which does not have
6945 the THUMB_FUNC attribute, then we must be calling a function which has
6946 the (interfacearm) attribute. We look for the Thumb entry point to that
6947 function and change the branch to refer to that function instead. */
6948 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6949 && fixP
->fx_addsy
!= NULL
6950 && S_IS_DEFINED (fixP
->fx_addsy
)
6951 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6953 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6961 /* Relocations against Thumb function names must be left unadjusted,
6962 so that the linker can use this information to correctly set the
6963 bottom bit of their addresses. The MIPS version of this function
6964 also prevents relocations that are mips-16 specific, but I do not
6965 know why it does this.
6968 There is one other problem that ought to be addressed here, but
6969 which currently is not: Taking the address of a label (rather
6970 than a function) and then later jumping to that address. Such
6971 addresses also ought to have their bottom bit set (assuming that
6972 they reside in Thumb code), but at the moment they will not. */
6975 arm_fix_adjustable (fixP
)
6978 if (fixP
->fx_addsy
== NULL
)
6981 /* Prevent all adjustments to global symbols. */
6982 if (S_IS_EXTERN (fixP
->fx_addsy
))
6985 if (S_IS_WEAK (fixP
->fx_addsy
))
6988 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6989 && fixP
->fx_subsy
== NULL
)
6992 /* We need the symbol name for the VTABLE entries */
6993 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6994 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7001 elf32_arm_target_format ()
7003 if (target_big_endian
)
7005 return "elf32-bigarm-oabi";
7007 return "elf32-bigarm";
7010 return "elf32-littlearm-oabi";
7012 return "elf32-littlearm";
7016 armelf_frob_symbol (symp
, puntp
)
7020 elf_frob_symbol (symp
, puntp
);
7024 arm_force_relocation (fixp
)
7027 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7028 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7029 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7030 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7036 static bfd_reloc_code_real_type
7046 bfd_reloc_code_real_type reloc
;
7050 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7051 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7052 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7053 /* ScottB: Jan 30, 1998 */
7054 /* Added support for parsing "var(PLT)" branch instructions */
7055 /* generated by GCC for PLT relocs */
7056 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7057 { NULL
, 0, BFD_RELOC_UNUSED
}
7061 for (i
= 0, ip
= input_line_pointer
;
7062 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7064 id
[i
] = tolower (*ip
);
7066 for (i
= 0; reloc_map
[i
].str
; i
++)
7067 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7070 input_line_pointer
+= reloc_map
[i
].len
;
7072 return reloc_map
[i
].reloc
;
7076 s_arm_elf_cons (nbytes
)
7081 #ifdef md_flush_pending_output
7082 md_flush_pending_output ();
7085 if (is_it_end_of_statement ())
7087 demand_empty_rest_of_line ();
7091 #ifdef md_cons_align
7092 md_cons_align (nbytes
);
7097 bfd_reloc_code_real_type reloc
;
7101 if (exp
.X_op
== O_symbol
7102 && * input_line_pointer
== '('
7103 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7105 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7106 int size
= bfd_get_reloc_size (howto
);
7109 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7112 register char * p
= frag_more ((int) nbytes
);
7113 int offset
= nbytes
- size
;
7115 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7120 emit_expr (& exp
, (unsigned int) nbytes
);
7122 while (*input_line_pointer
++ == ',');
7124 input_line_pointer
--; /* Put terminator back into stream. */
7125 demand_empty_rest_of_line ();
7128 #endif /* OBJ_ELF */