1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
55 #define ARM_EXT_V5E 0x00000200 /* "El Segundo" */
57 /* Architectures are the sum of the base and extensions */
58 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
60 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
61 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP (ARM_ANY - ARM_1)
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
82 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
84 #define CPU_DEFAULT ARM_ALL
89 #define FPU_DEFAULT FPU_ALL
92 #define streq(a, b) (strcmp (a, b) == 0)
93 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
95 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
96 static int target_oabi
= 0;
98 #if defined OBJ_COFF || defined OBJ_ELF
99 /* Flags stored in private area of BFD structure */
100 static boolean uses_apcs_26
= false;
101 static boolean support_interwork
= false;
102 static boolean uses_apcs_float
= false;
103 static boolean pic_code
= false;
106 /* This array holds the chars that always start a comment. If the
107 pre-processor is disabled, these aren't very useful */
108 CONST
char comment_chars
[] = "@";
110 /* This array holds the chars that only start a comment at the beginning of
111 a line. If the line seems to have the form '# 123 filename'
112 .line and .file directives will appear in the pre-processed output */
113 /* Note that input_file.c hand checks for '#' at the beginning of the
114 first line of the input file. This is because the compiler outputs
115 #NO_APP at the beginning of its output. */
116 /* Also note that comments like this one will always work. */
117 CONST
char line_comment_chars
[] = "#";
120 CONST
char line_separator_chars
[] = ";";
122 CONST
char line_separator_chars
[] = "";
125 /* Chars that can be used to separate mant from exp in floating point nums */
126 CONST
char EXP_CHARS
[] = "eE";
128 /* Chars that mean this number is a floating point constant */
132 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
134 /* Prefix characters that indicate the start of an immediate
136 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
139 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
142 CONST
int md_reloc_size
= 8; /* Size of relocation record */
144 static int thumb_mode
= 0; /* 0: assemble for ARM, 1: assemble for Thumb,
145 2: assemble for Thumb even though target cpu
146 does not support thumb instructions */
147 typedef struct arm_fix
155 unsigned long instruction
;
160 bfd_reloc_code_real_type type
;
170 CONST
char * template;
174 static CONST
struct asm_shift shift
[] =
190 #define NO_SHIFT_RESTRICT 1
191 #define SHIFT_RESTRICT 0
193 #define NUM_FLOAT_VALS 8
195 CONST
char * fp_const
[] =
197 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
200 /* Number of littlenums required to hold an extended precision number */
201 #define MAX_LITTLENUMS 6
203 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
213 #define CP_T_X 0x00008000
214 #define CP_T_Y 0x00400000
215 #define CP_T_Pre 0x01000000
216 #define CP_T_UD 0x00800000
217 #define CP_T_WB 0x00200000
219 #define CONDS_BIT (0x00100000)
220 #define LOAD_BIT (0x00100000)
221 #define TRANS_BIT (0x00200000)
225 CONST
char * template;
229 /* This is to save a hash look-up in the common case */
230 #define COND_ALWAYS 0xe0000000
232 static CONST
struct asm_cond conds
[] =
236 {"cs", 0x20000000}, {"hs", 0x20000000},
237 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
252 /* Warning: If the top bit of the set_bits is set, then the standard
253 instruction bitmask is ignored, and the new bitmask is taken from
257 CONST
char * template; /* Basic flag string */
258 unsigned long set_bits
; /* Bits to set */
261 static CONST
struct asm_flg s_flag
[] =
267 static CONST
struct asm_flg ldr_flags
[] =
271 {"bt", 0x00400000 | TRANS_BIT
},
278 static CONST
struct asm_flg str_flags
[] =
282 {"bt", 0x00400000 | TRANS_BIT
},
287 static CONST
struct asm_flg byte_flag
[] =
293 static CONST
struct asm_flg cmp_flags
[] =
300 static CONST
struct asm_flg ldm_flags
[] =
313 static CONST
struct asm_flg stm_flags
[] =
326 static CONST
struct asm_flg lfm_flags
[] =
333 static CONST
struct asm_flg sfm_flags
[] =
340 static CONST
struct asm_flg round_flags
[] =
348 /* The implementation of the FIX instruction is broken on some assemblers,
349 in that it accepts a precision specifier as well as a rounding specifier,
350 despite the fact that this is meaningless. To be more compatible, we
351 accept it as well, though of course it does not set any bits. */
352 static CONST
struct asm_flg fix_flags
[] =
369 static CONST
struct asm_flg except_flag
[] =
375 static CONST
struct asm_flg cplong_flag
[] =
383 CONST
char * template;
384 unsigned long number
;
387 #define PSR_FIELD_MASK 0x000f0000
389 #define PSR_FLAGS 0x00080000
390 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
391 #define PSR_ALL 0x00090000
400 static CONST
struct asm_psr psrs
[] =
404 {"cpsr_all", CPSR_ALL
},
406 {"spsr_all", SPSR_ALL
},
409 {"cpsr_flg", CPSR_FLG
},
410 {"spsr_flg", SPSR_FLG
},
413 {"cpsr_c", CPSR_CTL
},
414 {"cpsr_ctl", CPSR_CTL
},
415 {"spsr_c", SPSR_CTL
},
416 {"spsr_ctl", SPSR_CTL
}
419 /* Functions called by parser */
420 /* ARM instructions */
421 static void do_arit
PARAMS ((char *, unsigned long));
422 static void do_cmp
PARAMS ((char *, unsigned long));
423 static void do_mov
PARAMS ((char *, unsigned long));
424 static void do_ldst
PARAMS ((char *, unsigned long));
425 static void do_ldmstm
PARAMS ((char *, unsigned long));
426 static void do_branch
PARAMS ((char *, unsigned long));
427 static void do_swi
PARAMS ((char *, unsigned long));
428 /* Pseudo Op codes */
429 static void do_adr
PARAMS ((char *, unsigned long));
430 static void do_adrl
PARAMS ((char *, unsigned long));
431 static void do_nop
PARAMS ((char *, unsigned long));
433 static void do_mul
PARAMS ((char *, unsigned long));
434 static void do_mla
PARAMS ((char *, unsigned long));
436 static void do_swap
PARAMS ((char *, unsigned long));
438 static void do_msr
PARAMS ((char *, unsigned long));
439 static void do_mrs
PARAMS ((char *, unsigned long));
441 static void do_mull
PARAMS ((char *, unsigned long));
443 static void do_bx
PARAMS ((char *, unsigned long));
446 /* Coprocessor Instructions */
447 static void do_cdp
PARAMS ((char *, unsigned long));
448 static void do_lstc
PARAMS ((char *, unsigned long));
449 static void do_co_reg
PARAMS ((char *, unsigned long));
450 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
451 static void do_fp_ldst
PARAMS ((char *, unsigned long));
452 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
453 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
454 static void do_fp_monadic
PARAMS ((char *, unsigned long));
455 static void do_fp_cmp
PARAMS ((char *, unsigned long));
456 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
457 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
459 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
460 static int arm_reg_parse
PARAMS ((char **));
461 static int arm_psr_parse
PARAMS ((char **));
462 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
463 static int add_to_lit_pool
PARAMS ((void));
464 static unsigned validate_immediate
PARAMS ((unsigned));
465 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
466 static int validate_offset_imm
PARAMS ((unsigned int, int));
467 static void opcode_select
PARAMS ((int));
468 static void end_of_line
PARAMS ((char *));
469 static int reg_required_here
PARAMS ((char **, int));
470 static int psr_required_here
PARAMS ((char **, int, int));
471 static int co_proc_number
PARAMS ((char **));
472 static int cp_opc_expr
PARAMS ((char **, int, int));
473 static int cp_reg_required_here
PARAMS ((char **, int));
474 static int fp_reg_required_here
PARAMS ((char **, int));
475 static int cp_address_offset
PARAMS ((char **));
476 static int cp_address_required_here
PARAMS ((char **));
477 static int my_get_float_expression
PARAMS ((char **));
478 static int skip_past_comma
PARAMS ((char **));
479 static int walk_no_bignums
PARAMS ((symbolS
*));
480 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
481 static int data_op2
PARAMS ((char **));
482 static int fp_op2
PARAMS ((char **));
483 static long reg_list
PARAMS ((char **));
484 static void thumb_load_store
PARAMS ((char *, int, int));
485 static int decode_shift
PARAMS ((char **, int));
486 static int ldst_extend
PARAMS ((char **, int));
487 static void thumb_add_sub
PARAMS ((char *, int));
488 static void insert_reg
PARAMS ((int));
489 static void thumb_shift
PARAMS ((char *, int));
490 static void thumb_mov_compare
PARAMS ((char *, int));
491 static void set_constant_flonums
PARAMS ((void));
492 static valueT md_chars_to_number
PARAMS ((char *, int));
493 static void insert_reg_alias
PARAMS ((char *, int));
494 static void output_inst
PARAMS ((void));
496 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
499 /* ARM instructions take 4bytes in the object file, Thumb instructions
503 /* LONGEST_INST is the longest basic instruction name without conditions or
505 * ARM7M has 4 of length 5
508 #define LONGEST_INST 5
513 CONST
char * template; /* Basic string to match */
514 unsigned long value
; /* Basic instruction code */
516 /* Compulsory suffix that must follow conds. If "", then the
517 instruction is not conditional and must have no suffix. */
518 CONST
char * comp_suffix
;
520 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
521 unsigned long variants
; /* Which CPU variants this exists for */
522 /* Function to call to parse args */
523 void (* parms
) PARAMS ((char *, unsigned long));
526 static CONST
struct asm_opcode insns
[] =
528 /* ARM Instructions */
529 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
530 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
531 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
532 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
533 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
534 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
535 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
536 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
537 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
538 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
539 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
540 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
541 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
542 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
543 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
544 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
545 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
546 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
547 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
548 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
549 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
550 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
551 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
554 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
555 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
556 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
558 /* ARM 2 multiplies */
559 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
560 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
562 /* ARM 3 - swp instructions */
563 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
565 /* ARM 6 Coprocessor instructions */
566 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
567 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
568 /* ScottB: our code uses 0x0128f000 for msr.
569 NickC: but this is wrong because the bits 16 and 19 are handled
570 by the PSR_xxx defines above. */
572 /* ARM 7M long multiplies - need signed/unsigned flags! */
573 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
574 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
575 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
576 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
578 /* ARM THUMB interworking */
579 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
581 /* Floating point instructions */
582 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
583 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
584 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
585 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
586 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
587 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
588 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
589 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
590 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
595 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
596 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
597 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
598 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
599 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
600 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
601 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
602 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
603 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
604 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
605 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
607 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
608 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
609 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
610 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
611 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
612 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
613 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
614 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
615 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
616 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
617 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
618 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
619 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
620 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
621 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
622 be an optional suffix, but part of the instruction. To be compatible,
624 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
625 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
626 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
627 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
629 /* Generic copressor instructions */
630 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
631 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
632 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
633 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
634 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
637 /* defines for various bits that we will want to toggle */
639 #define INST_IMMEDIATE 0x02000000
640 #define OFFSET_REG 0x02000000
641 #define HWOFFSET_IMM 0x00400000
642 #define SHIFT_BY_REG 0x00000010
643 #define PRE_INDEX 0x01000000
644 #define INDEX_UP 0x00800000
645 #define WRITE_BACK 0x00200000
646 #define LDM_TYPE_2_OR_3 0x00400000
648 #define LITERAL_MASK 0xf000f000
649 #define COND_MASK 0xf0000000
650 #define OPCODE_MASK 0xfe1fffff
651 #define DATA_OP_SHIFT 21
653 /* Codes to distinguish the arithmetic instructions */
665 #define OPCODE_CMP 10
666 #define OPCODE_CMN 11
667 #define OPCODE_ORR 12
668 #define OPCODE_MOV 13
669 #define OPCODE_BIC 14
670 #define OPCODE_MVN 15
672 static void do_t_nop
PARAMS ((char *));
673 static void do_t_arit
PARAMS ((char *));
674 static void do_t_add
PARAMS ((char *));
675 static void do_t_asr
PARAMS ((char *));
676 static void do_t_branch9
PARAMS ((char *));
677 static void do_t_branch12
PARAMS ((char *));
678 static void do_t_branch23
PARAMS ((char *));
679 static void do_t_bx
PARAMS ((char *));
680 static void do_t_compare
PARAMS ((char *));
681 static void do_t_ldmstm
PARAMS ((char *));
682 static void do_t_ldr
PARAMS ((char *));
683 static void do_t_ldrb
PARAMS ((char *));
684 static void do_t_ldrh
PARAMS ((char *));
685 static void do_t_lds
PARAMS ((char *));
686 static void do_t_lsl
PARAMS ((char *));
687 static void do_t_lsr
PARAMS ((char *));
688 static void do_t_mov
PARAMS ((char *));
689 static void do_t_push_pop
PARAMS ((char *));
690 static void do_t_str
PARAMS ((char *));
691 static void do_t_strb
PARAMS ((char *));
692 static void do_t_strh
PARAMS ((char *));
693 static void do_t_sub
PARAMS ((char *));
694 static void do_t_swi
PARAMS ((char *));
695 static void do_t_adr
PARAMS ((char *));
697 #define T_OPCODE_MUL 0x4340
698 #define T_OPCODE_TST 0x4200
699 #define T_OPCODE_CMN 0x42c0
700 #define T_OPCODE_NEG 0x4240
701 #define T_OPCODE_MVN 0x43c0
703 #define T_OPCODE_ADD_R3 0x1800
704 #define T_OPCODE_SUB_R3 0x1a00
705 #define T_OPCODE_ADD_HI 0x4400
706 #define T_OPCODE_ADD_ST 0xb000
707 #define T_OPCODE_SUB_ST 0xb080
708 #define T_OPCODE_ADD_SP 0xa800
709 #define T_OPCODE_ADD_PC 0xa000
710 #define T_OPCODE_ADD_I8 0x3000
711 #define T_OPCODE_SUB_I8 0x3800
712 #define T_OPCODE_ADD_I3 0x1c00
713 #define T_OPCODE_SUB_I3 0x1e00
715 #define T_OPCODE_ASR_R 0x4100
716 #define T_OPCODE_LSL_R 0x4080
717 #define T_OPCODE_LSR_R 0x40c0
718 #define T_OPCODE_ASR_I 0x1000
719 #define T_OPCODE_LSL_I 0x0000
720 #define T_OPCODE_LSR_I 0x0800
722 #define T_OPCODE_MOV_I8 0x2000
723 #define T_OPCODE_CMP_I8 0x2800
724 #define T_OPCODE_CMP_LR 0x4280
725 #define T_OPCODE_MOV_HR 0x4600
726 #define T_OPCODE_CMP_HR 0x4500
728 #define T_OPCODE_LDR_PC 0x4800
729 #define T_OPCODE_LDR_SP 0x9800
730 #define T_OPCODE_STR_SP 0x9000
731 #define T_OPCODE_LDR_IW 0x6800
732 #define T_OPCODE_STR_IW 0x6000
733 #define T_OPCODE_LDR_IH 0x8800
734 #define T_OPCODE_STR_IH 0x8000
735 #define T_OPCODE_LDR_IB 0x7800
736 #define T_OPCODE_STR_IB 0x7000
737 #define T_OPCODE_LDR_RW 0x5800
738 #define T_OPCODE_STR_RW 0x5000
739 #define T_OPCODE_LDR_RH 0x5a00
740 #define T_OPCODE_STR_RH 0x5200
741 #define T_OPCODE_LDR_RB 0x5c00
742 #define T_OPCODE_STR_RB 0x5400
744 #define T_OPCODE_PUSH 0xb400
745 #define T_OPCODE_POP 0xbc00
747 #define T_OPCODE_BRANCH 0xe7fe
749 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
751 #define THUMB_SIZE 2 /* Size of thumb instruction */
752 #define THUMB_REG_LO 0x1
753 #define THUMB_REG_HI 0x2
754 #define THUMB_REG_ANY 0x3
756 #define THUMB_H1 0x0080
757 #define THUMB_H2 0x0040
764 #define THUMB_COMPARE 1
767 #define THUMB_STORE 1
769 #define THUMB_PP_PC_LR 0x0100
771 /* These three are used for immediate shifts, do not alter */
773 #define THUMB_HALFWORD 1
778 CONST
char * template; /* Basic string to match */
779 unsigned long value
; /* Basic instruction code */
781 unsigned long variants
; /* Which CPU variants this exists for */
782 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
785 static CONST
struct thumb_opcode tinsns
[] =
787 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
788 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
789 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
790 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
791 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
792 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
793 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
794 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
795 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
796 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
797 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
798 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
799 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
800 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
801 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
802 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
803 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
804 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
805 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
806 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
807 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
808 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
809 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
810 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
811 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
812 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
813 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
814 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
815 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
816 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
817 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
818 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
819 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
820 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
821 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
822 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
823 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
824 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
825 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
826 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
827 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
828 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
829 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
830 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
831 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
832 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
833 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
834 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
835 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
836 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
837 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
838 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
839 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
840 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
842 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
843 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
852 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
853 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
854 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
860 /* These are the standard names; Users can add aliases with .req */
861 static CONST
struct reg_entry reg_table
[] =
863 /* Processor Register Numbers */
864 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
865 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
866 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
867 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
868 /* APCS conventions */
869 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
870 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
871 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
872 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
874 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
875 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
876 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
877 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
878 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
879 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
880 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
881 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
882 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
883 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
887 #define BAD_ARGS _("Bad arguments to instruction")
888 #define BAD_PC _("r15 not allowed here")
889 #define BAD_FLAGS _("Instruction should not have flags")
890 #define BAD_COND _("Instruction is not conditional")
892 static struct hash_control
* arm_ops_hsh
= NULL
;
893 static struct hash_control
* arm_tops_hsh
= NULL
;
894 static struct hash_control
* arm_cond_hsh
= NULL
;
895 static struct hash_control
* arm_shift_hsh
= NULL
;
896 static struct hash_control
* arm_reg_hsh
= NULL
;
897 static struct hash_control
* arm_psr_hsh
= NULL
;
899 /* This table describes all the machine specific pseudo-ops the assembler
900 has to support. The fields are:
901 pseudo-op name without dot
902 function to call to execute this pseudo-op
903 Integer arg to pass to the function
906 static void s_req
PARAMS ((int));
907 static void s_align
PARAMS ((int));
908 static void s_bss
PARAMS ((int));
909 static void s_even
PARAMS ((int));
910 static void s_ltorg
PARAMS ((int));
911 static void s_arm
PARAMS ((int));
912 static void s_thumb
PARAMS ((int));
913 static void s_code
PARAMS ((int));
914 static void s_force_thumb
PARAMS ((int));
915 static void s_thumb_func
PARAMS ((int));
916 static void s_thumb_set
PARAMS ((int));
917 static void arm_s_text
PARAMS ((int));
918 static void arm_s_data
PARAMS ((int));
920 static void arm_s_section
PARAMS ((int));
921 static void s_arm_elf_cons
PARAMS ((int));
924 static int my_get_expression
PARAMS ((expressionS
*, char **));
926 CONST pseudo_typeS md_pseudo_table
[] =
928 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
930 { "align", s_align
, 0 },
932 { "thumb", s_thumb
, 0 },
933 { "code", s_code
, 0 },
934 { "force_thumb", s_force_thumb
, 0 },
935 { "thumb_func", s_thumb_func
, 0 },
936 { "thumb_set", s_thumb_set
, 0 },
937 { "even", s_even
, 0 },
938 { "ltorg", s_ltorg
, 0 },
939 { "pool", s_ltorg
, 0 },
940 /* Allow for the effect of section changes. */
941 { "text", arm_s_text
, 0 },
942 { "data", arm_s_data
, 0 },
944 { "section", arm_s_section
, 0 },
945 { "section.s", arm_s_section
, 0 },
946 { "sect", arm_s_section
, 0 },
947 { "sect.s", arm_s_section
, 0 },
948 { "word", s_arm_elf_cons
, 4 },
949 { "long", s_arm_elf_cons
, 4 },
953 { "extend", float_cons
, 'x' },
954 { "ldouble", float_cons
, 'x' },
955 { "packed", float_cons
, 'p' },
959 /* Stuff needed to resolve the label ambiguity
969 symbolS
* last_label_seen
;
970 static int label_is_thumb_function_name
= false;
974 #define MAX_LITERAL_POOL_SIZE 1024
976 typedef struct literalS
978 struct expressionS exp
;
979 struct arm_it
* inst
;
982 literalT literals
[MAX_LITERAL_POOL_SIZE
];
983 int next_literal_pool_place
= 0; /* Next free entry in the pool */
984 int lit_pool_num
= 1; /* Next literal pool number */
985 symbolS
* current_poolP
= NULL
;
992 if (current_poolP
== NULL
)
993 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
994 (valueT
) 0, &zero_address_frag
);
996 /* Check if this literal value is already in the pool: */
997 while (lit_count
< next_literal_pool_place
)
999 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1000 && inst
.reloc
.exp
.X_op
== O_constant
1001 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
1002 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1007 if (lit_count
== next_literal_pool_place
) /* new entry */
1009 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1011 inst
.error
= _("Literal Pool Overflow");
1015 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1016 lit_count
= next_literal_pool_place
++;
1019 inst
.reloc
.exp
.X_op
= O_symbol
;
1020 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1021 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1026 /* Can't use symbol_new here, so have to create a symbol and then at
1027 a later date assign it a value. Thats what these functions do. */
1029 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1031 CONST
char * name
; /* It is copied, the caller can modify */
1032 segT segment
; /* Segment identifier (SEG_<something>) */
1033 valueT valu
; /* Symbol value */
1034 fragS
* frag
; /* Associated fragment */
1036 unsigned int name_length
;
1037 char * preserved_copy_of_name
;
1039 name_length
= strlen (name
) + 1; /* +1 for \0 */
1040 obstack_grow (¬es
, name
, name_length
);
1041 preserved_copy_of_name
= obstack_finish (¬es
);
1042 #ifdef STRIP_UNDERSCORE
1043 if (preserved_copy_of_name
[0] == '_')
1044 preserved_copy_of_name
++;
1047 #ifdef tc_canonicalize_symbol_name
1048 preserved_copy_of_name
=
1049 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1052 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1054 S_SET_SEGMENT (symbolP
, segment
);
1055 S_SET_VALUE (symbolP
, valu
);
1056 symbol_clear_list_pointers(symbolP
);
1058 symbol_set_frag (symbolP
, frag
);
1060 /* Link to end of symbol chain. */
1062 extern int symbol_table_frozen
;
1063 if (symbol_table_frozen
)
1067 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1069 obj_symbol_new_hook (symbolP
);
1071 #ifdef tc_symbol_new_hook
1072 tc_symbol_new_hook (symbolP
);
1076 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1077 #endif /* DEBUG_SYMS */
1080 /* Check that an immediate is valid, and if so, convert it to the right format. */
1083 validate_immediate (val
)
1089 #define rotate_left(v, n) (v << n | v >> (32 - n))
1091 for (i
= 0; i
< 32; i
+= 2)
1092 if ((a
= rotate_left (val
, i
)) <= 0xff)
1093 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1098 /* Check to see if an immediate can be computed as two seperate immediate
1099 values, added together. We already know that this value cannot be
1100 computed by just one ARM instruction. */
1103 validate_immediate_twopart (val
, highpart
)
1105 unsigned int * highpart
;
1110 for (i
= 0; i
< 32; i
+= 2)
1111 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1117 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1119 else if (a
& 0xff0000)
1124 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1128 assert (a
& 0xff000000);
1130 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1133 return (a
& 0xff) | (i
<< 7);
1140 validate_offset_imm (val
, hwse
)
1144 if ((hwse
&& val
> 255) || val
> 4095)
1154 as_bad (_("Invalid syntax for .req directive."));
1161 /* We don't support putting frags in the BSS segment, we fake it by
1162 marking in_bss, then looking at s_skip for clues?.. */
1163 subseg_set (bss_section
, 0);
1164 demand_empty_rest_of_line ();
1171 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1172 frag_align (1, 0, 0);
1174 record_alignment (now_seg
, 1);
1176 demand_empty_rest_of_line ();
1186 if (current_poolP
== NULL
)
1189 /* Align pool as you have word accesses */
1190 /* Only make a frag if we have to ... */
1192 frag_align (2, 0, 0);
1194 record_alignment (now_seg
, 2);
1196 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1198 symbol_locate (current_poolP
, sym_name
, now_seg
,
1199 (valueT
) frag_now_fix (), frag_now
);
1200 symbol_table_insert (current_poolP
);
1202 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1204 #if defined OBJ_COFF || defined OBJ_ELF
1205 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1208 while (lit_count
< next_literal_pool_place
)
1209 /* First output the expression in the instruction to the pool */
1210 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1212 next_literal_pool_place
= 0;
1213 current_poolP
= NULL
;
1217 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1221 register long temp_fill
;
1222 long max_alignment
= 15;
1224 temp
= get_absolute_expression ();
1225 if (temp
> max_alignment
)
1226 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1229 as_bad (_("Alignment negative. 0 assumed."));
1233 if (*input_line_pointer
== ',')
1235 input_line_pointer
++;
1236 temp_fill
= get_absolute_expression ();
1244 /* Only make a frag if we HAVE to. . . */
1245 if (temp
&& !need_pass_2
)
1246 frag_align (temp
, (int) temp_fill
, 0);
1247 demand_empty_rest_of_line ();
1249 record_alignment (now_seg
, temp
);
1253 s_force_thumb (ignore
)
1256 /* If we are not already in thumb mode go into it, EVEN if
1257 the target processor does not support thumb instructions.
1258 This is used by gcc/config/arm/lib1funcs.asm for example
1259 to compile interworking support functions even if the
1260 target processor should not support interworking. */
1266 record_alignment (now_seg
, 1);
1269 demand_empty_rest_of_line ();
1273 s_thumb_func (ignore
)
1276 /* The following label is the name/address of the start of a Thumb function.
1277 We need to know this for the interworking support. */
1279 label_is_thumb_function_name
= true;
1281 demand_empty_rest_of_line ();
1284 /* Perform a .set directive, but also mark the alias as
1285 being a thumb function. */
1291 /* XXX the following is a duplicate of the code for s_set() in read.c
1292 We cannot just call that code as we need to get at the symbol that
1294 register char * name
;
1295 register char delim
;
1296 register char * end_name
;
1297 register symbolS
* symbolP
;
1300 * Especial apologies for the random logic:
1301 * this just grew, and could be parsed much more simply!
1304 name
= input_line_pointer
;
1305 delim
= get_symbol_end ();
1306 end_name
= input_line_pointer
;
1311 if (*input_line_pointer
!= ',')
1314 as_bad (_("Expected comma after name \"%s\""), name
);
1316 ignore_rest_of_line ();
1320 input_line_pointer
++;
1323 if (name
[0] == '.' && name
[1] == '\0')
1325 /* XXX - this should not happen to .thumb_set */
1329 if ((symbolP
= symbol_find (name
)) == NULL
1330 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1333 /* When doing symbol listings, play games with dummy fragments living
1334 outside the normal fragment chain to record the file and line info
1336 if (listing
& LISTING_SYMBOLS
)
1338 extern struct list_info_struct
* listing_tail
;
1339 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1340 memset (dummy_frag
, 0, sizeof(fragS
));
1341 dummy_frag
->fr_type
= rs_fill
;
1342 dummy_frag
->line
= listing_tail
;
1343 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1344 dummy_frag
->fr_symbol
= symbolP
;
1348 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1351 /* "set" symbols are local unless otherwise specified. */
1352 SF_SET_LOCAL (symbolP
);
1353 #endif /* OBJ_COFF */
1354 } /* make a new symbol */
1356 symbol_table_insert (symbolP
);
1361 && S_IS_DEFINED (symbolP
)
1362 && S_GET_SEGMENT (symbolP
) != reg_section
)
1363 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1365 pseudo_set (symbolP
);
1367 demand_empty_rest_of_line ();
1369 /* XXX Now we come to the Thumb specific bit of code. */
1371 THUMB_SET_FUNC (symbolP
, 1);
1372 ARM_SET_THUMB (symbolP
, 1);
1373 #if defined OBJ_ELF || defined OBJ_COFF
1374 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1378 /* If we change section we must dump the literal pool first. */
1383 if (now_seg
!= text_section
)
1387 obj_elf_text (ignore
);
1397 if (flag_readonly_data_in_text
)
1399 if (now_seg
!= text_section
)
1402 else if (now_seg
!= data_section
)
1406 obj_elf_data (ignore
);
1414 arm_s_section (ignore
)
1419 obj_elf_section (ignore
);
1424 opcode_select (width
)
1432 if (! (cpu_variant
& ARM_THUMB
))
1433 as_bad (_("selected processor does not support THUMB opcodes"));
1435 /* No need to force the alignment, since we will have been
1436 coming from ARM mode, which is word-aligned. */
1437 record_alignment (now_seg
, 1);
1444 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1445 as_bad (_("selected processor does not support ARM opcodes"));
1448 frag_align (2, 0, 0);
1449 record_alignment (now_seg
, 1);
1454 as_bad (_("invalid instruction size selected (%d)"), width
);
1463 demand_empty_rest_of_line ();
1471 demand_empty_rest_of_line ();
1480 temp
= get_absolute_expression ();
1485 opcode_select (temp
);
1489 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1497 skip_whitespace (str
);
1500 inst
.error
= _("Garbage following instruction");
1504 skip_past_comma (str
)
1510 while ((c
= *p
) == ' ' || c
== ',')
1513 if (c
== ',' && comma
++)
1521 return comma
? SUCCESS
: FAIL
;
1524 /* A standard register must be given at this point.
1525 Shift is the place to put it in inst.instruction.
1526 Restores input start point on err.
1527 Returns the reg#, or FAIL. */
1530 reg_required_here (str
, shift
)
1534 static char buff
[128]; /* XXX */
1536 char * start
= *str
;
1538 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1541 inst
.instruction
|= reg
<< shift
;
1545 /* Restore the start point, we may have got a reg of the wrong class. */
1548 /* In the few cases where we might be able to accept something else
1549 this error can be overridden. */
1550 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1557 psr_required_here (str
, cpsr
, spsr
)
1563 char * start
= *str
;
1564 psr
= arm_psr_parse (str
);
1566 if (psr
== cpsr
|| psr
== spsr
)
1569 inst
.instruction
|= 1 << 22;
1574 /* In the few cases where we might be able to accept something else
1575 this error can be overridden. */
1576 inst
.error
= _("<psr(f)> expected");
1578 /* Restore the start point. */
1584 co_proc_number (str
)
1587 int processor
, pchar
;
1589 skip_whitespace (* str
);
1591 /* The data sheet seems to imply that just a number on its own is valid
1592 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1594 if (**str
== 'p' || **str
== 'P')
1598 if (pchar
>= '0' && pchar
<= '9')
1600 processor
= pchar
- '0';
1601 if (**str
>= '0' && **str
<= '9')
1603 processor
= processor
* 10 + *(*str
)++ - '0';
1606 inst
.error
= _("Illegal co-processor number");
1613 inst
.error
= _("Bad or missing co-processor number");
1617 inst
.instruction
|= processor
<< 8;
1622 cp_opc_expr (str
, where
, length
)
1629 skip_whitespace (* str
);
1631 memset (&expr
, '\0', sizeof (expr
));
1633 if (my_get_expression (&expr
, str
))
1635 if (expr
.X_op
!= O_constant
)
1637 inst
.error
= _("bad or missing expression");
1641 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1643 inst
.error
= _("immediate co-processor expression too large");
1647 inst
.instruction
|= expr
.X_add_number
<< where
;
1652 cp_reg_required_here (str
, where
)
1657 char * start
= *str
;
1659 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1662 inst
.instruction
|= reg
<< where
;
1666 /* In the few cases where we might be able to accept something else
1667 this error can be overridden. */
1668 inst
.error
= _("Co-processor register expected");
1670 /* Restore the start point. */
1676 fp_reg_required_here (str
, where
)
1681 char * start
= *str
;
1683 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1686 inst
.instruction
|= reg
<< where
;
1690 /* In the few cases where we might be able to accept something else
1691 this error can be overridden. */
1692 inst
.error
= _("Floating point register expected");
1694 /* Restore the start point. */
1700 cp_address_offset (str
)
1705 skip_whitespace (* str
);
1707 if (! is_immediate_prefix (**str
))
1709 inst
.error
= _("immediate expression expected");
1715 if (my_get_expression (& inst
.reloc
.exp
, str
))
1718 if (inst
.reloc
.exp
.X_op
== O_constant
)
1720 offset
= inst
.reloc
.exp
.X_add_number
;
1724 inst
.error
= _("co-processor address must be word aligned");
1728 if (offset
> 1023 || offset
< -1023)
1730 inst
.error
= _("offset too large");
1735 inst
.instruction
|= INDEX_UP
;
1739 inst
.instruction
|= offset
>> 2;
1742 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1748 cp_address_required_here (str
)
1760 skip_whitespace (p
);
1762 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1765 skip_whitespace (p
);
1771 if (skip_past_comma (& p
) == SUCCESS
)
1774 write_back
= WRITE_BACK
;
1778 inst
.error
= _("pc may not be used in post-increment");
1782 if (cp_address_offset (& p
) == FAIL
)
1786 pre_inc
= PRE_INDEX
| INDEX_UP
;
1790 /* '['Rn, #expr']'[!] */
1792 if (skip_past_comma (& p
) == FAIL
)
1794 inst
.error
= _("pre-indexed expression expected");
1798 pre_inc
= PRE_INDEX
;
1800 if (cp_address_offset (& p
) == FAIL
)
1803 skip_whitespace (p
);
1807 inst
.error
= _("missing ]");
1811 skip_whitespace (p
);
1817 inst
.error
= _("pc may not be used with write-back");
1822 write_back
= WRITE_BACK
;
1828 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1831 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1832 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1833 inst
.reloc
.pc_rel
= 1;
1834 inst
.instruction
|= (REG_PC
<< 16);
1835 pre_inc
= PRE_INDEX
;
1838 inst
.instruction
|= write_back
| pre_inc
;
1846 unsigned long flags
;
1848 /* Do nothing really. */
1849 inst
.instruction
|= flags
; /* This is pointless. */
1857 unsigned long flags
;
1859 /* Only one syntax. */
1860 skip_whitespace (str
);
1862 if (reg_required_here (&str
, 12) == FAIL
)
1864 inst
.error
= BAD_ARGS
;
1868 if (skip_past_comma (&str
) == FAIL
1869 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1871 inst
.error
= _("<psr> expected");
1875 inst
.instruction
|= flags
;
1880 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1884 unsigned long flags
;
1888 skip_whitespace (str
);
1890 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1892 inst
.instruction
|= PSR_ALL
;
1894 /* Sytax should be "<psr>, Rm" */
1895 if (skip_past_comma (&str
) == FAIL
1896 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1898 inst
.error
= BAD_ARGS
;
1904 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1905 inst
.instruction
|= PSR_FLAGS
;
1906 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1907 inst
.instruction
|= PSR_CONTROL
;
1910 inst
.error
= BAD_ARGS
;
1914 if (skip_past_comma (&str
) == FAIL
)
1916 inst
.error
= BAD_ARGS
;
1920 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1922 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1924 /* Immediate expression. */
1925 else if (is_immediate_prefix (* str
))
1930 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1932 inst
.error
= _("Register or shift expression expected");
1936 if (inst
.reloc
.exp
.X_add_symbol
)
1938 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1939 inst
.reloc
.pc_rel
= 0;
1943 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1946 inst
.error
= _("Invalid constant");
1950 inst
.instruction
|= value
;
1953 flags
|= INST_IMMEDIATE
;
1957 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1963 inst
.instruction
|= flags
;
1968 /* Long Multiply Parser
1969 UMULL RdLo, RdHi, Rm, Rs
1970 SMULL RdLo, RdHi, Rm, Rs
1971 UMLAL RdLo, RdHi, Rm, Rs
1972 SMLAL RdLo, RdHi, Rm, Rs
1975 do_mull (str
, flags
)
1977 unsigned long flags
;
1979 int rdlo
, rdhi
, rm
, rs
;
1981 /* Only one format "rdlo, rdhi, rm, rs" */
1982 skip_whitespace (str
);
1984 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1986 inst
.error
= BAD_ARGS
;
1990 if (skip_past_comma (&str
) == FAIL
1991 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1993 inst
.error
= BAD_ARGS
;
1997 if (skip_past_comma (&str
) == FAIL
1998 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2000 inst
.error
= BAD_ARGS
;
2004 /* rdhi, rdlo and rm must all be different */
2005 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2006 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2008 if (skip_past_comma (&str
) == FAIL
2009 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2011 inst
.error
= BAD_ARGS
;
2015 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2017 inst
.error
= BAD_PC
;
2021 inst
.instruction
|= flags
;
2029 unsigned long flags
;
2033 /* Only one format "rd, rm, rs" */
2034 skip_whitespace (str
);
2036 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2038 inst
.error
= BAD_ARGS
;
2044 inst
.error
= BAD_PC
;
2048 if (skip_past_comma (&str
) == FAIL
2049 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2051 inst
.error
= BAD_ARGS
;
2057 inst
.error
= BAD_PC
;
2062 as_tsktsk (_("rd and rm should be different in mul"));
2064 if (skip_past_comma (&str
) == FAIL
2065 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2067 inst
.error
= BAD_ARGS
;
2073 inst
.error
= BAD_PC
;
2077 inst
.instruction
|= flags
;
2085 unsigned long flags
;
2089 /* Only one format "rd, rm, rs, rn" */
2090 skip_whitespace (str
);
2092 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2094 inst
.error
= BAD_ARGS
;
2100 inst
.error
= BAD_PC
;
2104 if (skip_past_comma (&str
) == FAIL
2105 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2107 inst
.error
= BAD_ARGS
;
2113 inst
.error
= BAD_PC
;
2118 as_tsktsk (_("rd and rm should be different in mla"));
2120 if (skip_past_comma (&str
) == FAIL
2121 || (rd
= reg_required_here (&str
, 8)) == FAIL
2122 || skip_past_comma (&str
) == FAIL
2123 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2125 inst
.error
= BAD_ARGS
;
2129 if (rd
== REG_PC
|| rm
== REG_PC
)
2131 inst
.error
= BAD_PC
;
2135 inst
.instruction
|= flags
;
2140 /* Returns the index into fp_values of a floating point number, or -1 if
2141 not in the table. */
2143 my_get_float_expression (str
)
2146 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2152 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2153 /* Look for a raw floating point number */
2154 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2155 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2157 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2159 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2161 if (words
[j
] != fp_values
[i
][j
])
2165 if (j
== MAX_LITTLENUMS
)
2173 /* Try and parse a more complex expression, this will probably fail
2174 unless the code uses a floating point prefix (eg "0f") */
2175 save_in
= input_line_pointer
;
2176 input_line_pointer
= *str
;
2177 if (expression (&exp
) == absolute_section
2178 && exp
.X_op
== O_big
2179 && exp
.X_add_number
< 0)
2181 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2183 if (gen_to_words (words
, 5, (long)15) == 0)
2185 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2187 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2189 if (words
[j
] != fp_values
[i
][j
])
2193 if (j
== MAX_LITTLENUMS
)
2195 *str
= input_line_pointer
;
2196 input_line_pointer
= save_in
;
2203 *str
= input_line_pointer
;
2204 input_line_pointer
= save_in
;
2208 /* Return true if anything in the expression is a bignum */
2210 walk_no_bignums (sp
)
2213 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2216 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2218 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2219 || (symbol_get_value_expression (sp
)->X_op_symbol
2220 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2227 my_get_expression (ep
, str
)
2234 save_in
= input_line_pointer
;
2235 input_line_pointer
= *str
;
2236 seg
= expression (ep
);
2239 if (seg
!= absolute_section
2240 && seg
!= text_section
2241 && seg
!= data_section
2242 && seg
!= bss_section
2243 && seg
!= undefined_section
)
2245 inst
.error
= _("bad_segment");
2246 *str
= input_line_pointer
;
2247 input_line_pointer
= save_in
;
2252 /* Get rid of any bignums now, so that we don't generate an error for which
2253 we can't establish a line number later on. Big numbers are never valid
2254 in instructions, which is where this routine is always called. */
2255 if (ep
->X_op
== O_big
2256 || (ep
->X_add_symbol
2257 && (walk_no_bignums (ep
->X_add_symbol
)
2259 && walk_no_bignums (ep
->X_op_symbol
)))))
2261 inst
.error
= _("Invalid constant");
2262 *str
= input_line_pointer
;
2263 input_line_pointer
= save_in
;
2267 *str
= input_line_pointer
;
2268 input_line_pointer
= save_in
;
2272 /* unrestrict should be one if <shift> <register> is permitted for this
2276 decode_shift (str
, unrestrict
)
2280 struct asm_shift
* shft
;
2284 skip_whitespace (* str
);
2286 for (p
= *str
; isalpha (*p
); p
++)
2291 inst
.error
= _("Shift expression expected");
2297 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2301 if (!strncmp (*str
, "rrx", 3)
2302 || !strncmp (*str
, "RRX", 3))
2305 inst
.instruction
|= shft
->value
;
2309 skip_whitespace (p
);
2311 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2313 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2317 else if (is_immediate_prefix (* p
))
2321 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2324 /* Validate some simple #expressions */
2325 if (inst
.reloc
.exp
.X_op
== O_constant
)
2327 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2329 /* Reject operations greater than 32, or lsl #32 */
2330 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2332 inst
.error
= _("Invalid immediate shift");
2336 /* Shifts of zero should be converted to lsl (which is zero)*/
2343 /* Shifts of 32 are encoded as 0, for those shifts that
2348 inst
.instruction
|= (num
<< 7) | shft
->value
;
2353 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2354 inst
.reloc
.pc_rel
= 0;
2355 inst
.instruction
|= shft
->value
;
2361 inst
.error
= unrestrict
? _("shift requires register or #expression")
2362 : _("shift requires #expression");
2368 inst
.error
= _("Shift expression expected");
2372 /* Do those data_ops which can take a negative immediate constant */
2373 /* by altering the instuction. A bit of a hack really */
2377 by inverting the second operand, and
2380 by negating the second operand.
2383 negate_data_op (instruction
, value
)
2384 unsigned long * instruction
;
2385 unsigned long value
;
2388 unsigned long negated
, inverted
;
2390 negated
= validate_immediate (-value
);
2391 inverted
= validate_immediate (~value
);
2393 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2397 case OPCODE_SUB
: /* ADD <-> SUB */
2398 new_inst
= OPCODE_ADD
;
2403 new_inst
= OPCODE_SUB
;
2407 case OPCODE_CMP
: /* CMP <-> CMN */
2408 new_inst
= OPCODE_CMN
;
2413 new_inst
= OPCODE_CMP
;
2417 /* Now Inverted ops */
2418 case OPCODE_MOV
: /* MOV <-> MVN */
2419 new_inst
= OPCODE_MVN
;
2424 new_inst
= OPCODE_MOV
;
2428 case OPCODE_AND
: /* AND <-> BIC */
2429 new_inst
= OPCODE_BIC
;
2434 new_inst
= OPCODE_AND
;
2438 case OPCODE_ADC
: /* ADC <-> SBC */
2439 new_inst
= OPCODE_SBC
;
2444 new_inst
= OPCODE_ADC
;
2448 /* We cannot do anything */
2456 *instruction
&= OPCODE_MASK
;
2457 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2468 skip_whitespace (* str
);
2470 if (reg_required_here (str
, 0) != FAIL
)
2472 if (skip_past_comma (str
) == SUCCESS
)
2473 /* Shift operation on register. */
2474 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2480 /* Immediate expression */
2481 if (is_immediate_prefix (**str
))
2486 if (my_get_expression (&inst
.reloc
.exp
, str
))
2489 if (inst
.reloc
.exp
.X_add_symbol
)
2491 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2492 inst
.reloc
.pc_rel
= 0;
2496 if (skip_past_comma (str
) == SUCCESS
)
2498 /* #x, y -- ie explicit rotation by Y */
2499 if (my_get_expression (&expr
, str
))
2502 if (expr
.X_op
!= O_constant
)
2504 inst
.error
= _("Constant expression expected");
2508 /* Rotate must be a multiple of 2 */
2509 if (((unsigned) expr
.X_add_number
) > 30
2510 || (expr
.X_add_number
& 1) != 0
2511 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2513 inst
.error
= _("Invalid constant");
2516 inst
.instruction
|= INST_IMMEDIATE
;
2517 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2518 inst
.instruction
|= expr
.X_add_number
<< 7;
2522 /* Implicit rotation, select a suitable one */
2523 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2527 /* Can't be done, perhaps the code reads something like
2528 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2529 if ((value
= negate_data_op (&inst
.instruction
,
2530 inst
.reloc
.exp
.X_add_number
))
2533 inst
.error
= _("Invalid constant");
2538 inst
.instruction
|= value
;
2541 inst
.instruction
|= INST_IMMEDIATE
;
2546 inst
.error
= _("Register or shift expression expected");
2555 skip_whitespace (* str
);
2557 if (fp_reg_required_here (str
, 0) != FAIL
)
2561 /* Immediate expression */
2562 if (*((*str
)++) == '#')
2568 skip_whitespace (* str
);
2570 /* First try and match exact strings, this is to guarantee that
2571 some formats will work even for cross assembly */
2573 for (i
= 0; fp_const
[i
]; i
++)
2575 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2579 *str
+= strlen (fp_const
[i
]);
2580 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2582 inst
.instruction
|= i
+ 8;
2589 /* Just because we didn't get a match doesn't mean that the
2590 constant isn't valid, just that it is in a format that we
2591 don't automatically recognize. Try parsing it with
2592 the standard expression routines. */
2593 if ((i
= my_get_float_expression (str
)) >= 0)
2595 inst
.instruction
|= i
+ 8;
2599 inst
.error
= _("Invalid floating point immediate expression");
2602 inst
.error
= _("Floating point register or immediate expression expected");
2608 do_arit (str
, flags
)
2610 unsigned long flags
;
2612 skip_whitespace (str
);
2614 if (reg_required_here (&str
, 12) == FAIL
2615 || skip_past_comma (&str
) == FAIL
2616 || reg_required_here (&str
, 16) == FAIL
2617 || skip_past_comma (&str
) == FAIL
2618 || data_op2 (&str
) == FAIL
)
2621 inst
.error
= BAD_ARGS
;
2625 inst
.instruction
|= flags
;
2633 unsigned long flags
;
2635 /* This is a pseudo-op of the form "adr rd, label" to be converted
2636 into a relative address of the form "add rd, pc, #label-.-8" */
2638 skip_whitespace (str
);
2640 if (reg_required_here (&str
, 12) == FAIL
2641 || skip_past_comma (&str
) == FAIL
2642 || my_get_expression (&inst
.reloc
.exp
, &str
))
2645 inst
.error
= BAD_ARGS
;
2648 /* Frag hacking will turn this into a sub instruction if the offset turns
2649 out to be negative. */
2650 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2651 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2652 inst
.reloc
.pc_rel
= 1;
2653 inst
.instruction
|= flags
;
2659 do_adrl (str
, flags
)
2661 unsigned long flags
;
2663 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2664 into a relative address of the form:
2665 add rd, pc, #low(label-.-8)"
2666 add rd, rd, #high(label-.-8)" */
2668 skip_whitespace (str
);
2670 if (reg_required_here (& str
, 12) == FAIL
2671 || skip_past_comma (& str
) == FAIL
2672 || my_get_expression (& inst
.reloc
.exp
, & str
))
2675 inst
.error
= BAD_ARGS
;
2681 /* Frag hacking will turn this into a sub instruction if the offset turns
2682 out to be negative. */
2683 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2684 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2685 inst
.reloc
.pc_rel
= 1;
2686 inst
.instruction
|= flags
;
2687 inst
.size
= INSN_SIZE
* 2;
2695 unsigned long flags
;
2697 skip_whitespace (str
);
2699 if (reg_required_here (&str
, 16) == FAIL
)
2702 inst
.error
= BAD_ARGS
;
2706 if (skip_past_comma (&str
) == FAIL
2707 || data_op2 (&str
) == FAIL
)
2710 inst
.error
= BAD_ARGS
;
2714 inst
.instruction
|= flags
;
2715 if ((flags
& 0x0000f000) == 0)
2716 inst
.instruction
|= CONDS_BIT
;
2725 unsigned long flags
;
2727 skip_whitespace (str
);
2729 if (reg_required_here (&str
, 12) == FAIL
)
2732 inst
.error
= BAD_ARGS
;
2736 if (skip_past_comma (&str
) == FAIL
2737 || data_op2 (&str
) == FAIL
)
2740 inst
.error
= BAD_ARGS
;
2744 inst
.instruction
|= flags
;
2750 ldst_extend (str
, hwse
)
2761 if (my_get_expression (& inst
.reloc
.exp
, str
))
2764 if (inst
.reloc
.exp
.X_op
== O_constant
)
2766 int value
= inst
.reloc
.exp
.X_add_number
;
2768 if ((hwse
&& (value
< -255 || value
> 255))
2769 || (value
< -4095 || value
> 4095))
2771 inst
.error
= _("address offset too large");
2781 /* Halfword and signextension instructions have the
2782 immediate value split across bits 11..8 and bits 3..0 */
2784 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2786 inst
.instruction
|= add
| value
;
2792 inst
.instruction
|= HWOFFSET_IMM
;
2793 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2796 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2797 inst
.reloc
.pc_rel
= 0;
2802 add
= 0; /* and fall through */
2804 (*str
)++; /* and fall through */
2806 if (reg_required_here (str
, 0) == FAIL
)
2810 inst
.instruction
|= add
;
2813 inst
.instruction
|= add
| OFFSET_REG
;
2814 if (skip_past_comma (str
) == SUCCESS
)
2815 return decode_shift (str
, SHIFT_RESTRICT
);
2823 do_ldst (str
, flags
)
2825 unsigned long flags
;
2832 /* This is not ideal, but it is the simplest way of dealing with the
2833 ARM7T halfword instructions (since they use a different
2834 encoding, but the same mnemonic): */
2835 halfword
= (flags
& 0x80000000) != 0;
2838 /* This is actually a load/store of a halfword, or a
2839 signed-extension load */
2840 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2843 = _("Processor does not support halfwords or signed bytes");
2847 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2848 | (flags
& ~COND_MASK
);
2853 skip_whitespace (str
);
2855 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2858 inst
.error
= BAD_ARGS
;
2862 if (skip_past_comma (& str
) == FAIL
)
2864 inst
.error
= _("Address expected");
2874 skip_whitespace (str
);
2876 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2879 /* Conflicts can occur on stores as well as loads. */
2880 conflict_reg
= (conflict_reg
== reg
);
2882 skip_whitespace (str
);
2888 if (skip_past_comma (&str
) == SUCCESS
)
2890 /* [Rn],... (post inc) */
2891 if (ldst_extend (&str
, halfword
) == FAIL
)
2894 as_warn (_("%s register same as write-back base"),
2895 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2901 inst
.instruction
|= HWOFFSET_IMM
;
2903 skip_whitespace (str
);
2908 as_warn (_("%s register same as write-back base"),
2909 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2911 inst
.instruction
|= WRITE_BACK
;
2915 if (! (flags
& TRANS_BIT
))
2922 if (skip_past_comma (&str
) == FAIL
)
2924 inst
.error
= _("pre-indexed expression expected");
2929 if (ldst_extend (&str
, halfword
) == FAIL
)
2932 skip_whitespace (str
);
2936 inst
.error
= _("missing ]");
2940 skip_whitespace (str
);
2945 as_warn (_("%s register same as write-back base"),
2946 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2948 inst
.instruction
|= WRITE_BACK
;
2952 else if (*str
== '=')
2954 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2957 skip_whitespace (str
);
2959 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2962 if (inst
.reloc
.exp
.X_op
!= O_constant
2963 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2965 inst
.error
= _("Constant expression expected");
2969 if (inst
.reloc
.exp
.X_op
== O_constant
2970 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2972 /* This can be done with a mov instruction */
2973 inst
.instruction
&= LITERAL_MASK
;
2974 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2975 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2981 /* Insert into literal pool */
2982 if (add_to_lit_pool () == FAIL
)
2985 inst
.error
= _("literal pool insertion failed");
2989 /* Change the instruction exp to point to the pool */
2992 inst
.instruction
|= HWOFFSET_IMM
;
2993 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2996 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2997 inst
.reloc
.pc_rel
= 1;
2998 inst
.instruction
|= (REG_PC
<< 16);
3004 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3009 inst
.instruction
|= HWOFFSET_IMM
;
3010 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3013 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3014 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3015 inst
.reloc
.pc_rel
= 1;
3016 inst
.instruction
|= (REG_PC
<< 16);
3020 if (pre_inc
&& (flags
& TRANS_BIT
))
3021 inst
.error
= _("Pre-increment instruction with translate");
3023 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3036 /* We come back here if we get ranges concatenated by '+' or '|' */
3051 skip_whitespace (str
);
3053 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3062 inst
.error
= _("Bad range in register list");
3066 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3068 if (range
& (1 << i
))
3070 (_("Warning: Duplicated register (r%d) in register list"),
3078 if (range
& (1 << reg
))
3079 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3081 else if (reg
<= cur_reg
)
3082 as_tsktsk (_("Warning: Register range not in ascending order"));
3086 } while (skip_past_comma (&str
) != FAIL
3087 || (in_range
= 1, *str
++ == '-'));
3089 skip_whitespace (str
);
3093 inst
.error
= _("Missing `}'");
3101 if (my_get_expression (&expr
, &str
))
3104 if (expr
.X_op
== O_constant
)
3106 if (expr
.X_add_number
3107 != (expr
.X_add_number
& 0x0000ffff))
3109 inst
.error
= _("invalid register mask");
3113 if ((range
& expr
.X_add_number
) != 0)
3115 int regno
= range
& expr
.X_add_number
;
3118 regno
= (1 << regno
) - 1;
3120 (_("Warning: Duplicated register (r%d) in register list"),
3124 range
|= expr
.X_add_number
;
3128 if (inst
.reloc
.type
!= 0)
3130 inst
.error
= _("expression too complex");
3134 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3135 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3136 inst
.reloc
.pc_rel
= 0;
3140 skip_whitespace (str
);
3142 if (*str
== '|' || *str
== '+')
3147 } while (another_range
);
3154 do_ldmstm (str
, flags
)
3156 unsigned long flags
;
3161 skip_whitespace (str
);
3163 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3166 if (base_reg
== REG_PC
)
3168 inst
.error
= _("r15 not allowed as base register");
3172 skip_whitespace (str
);
3176 flags
|= WRITE_BACK
;
3180 if (skip_past_comma (&str
) == FAIL
3181 || (range
= reg_list (&str
)) == FAIL
)
3184 inst
.error
= BAD_ARGS
;
3191 flags
|= LDM_TYPE_2_OR_3
;
3194 inst
.instruction
|= flags
| range
;
3202 unsigned long flags
;
3204 skip_whitespace (str
);
3206 /* Allow optional leading '#'. */
3207 if (is_immediate_prefix (*str
))
3210 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3213 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3214 inst
.reloc
.pc_rel
= 0;
3215 inst
.instruction
|= flags
;
3223 do_swap (str
, flags
)
3225 unsigned long flags
;
3229 skip_whitespace (str
);
3231 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3236 inst
.error
= _("r15 not allowed in swap");
3240 if (skip_past_comma (&str
) == FAIL
3241 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3244 inst
.error
= BAD_ARGS
;
3250 inst
.error
= _("r15 not allowed in swap");
3254 if (skip_past_comma (&str
) == FAIL
3257 inst
.error
= BAD_ARGS
;
3261 skip_whitespace (str
);
3263 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3268 inst
.error
= BAD_PC
;
3272 skip_whitespace (str
);
3276 inst
.error
= _("missing ]");
3280 inst
.instruction
|= flags
;
3286 do_branch (str
, flags
)
3288 unsigned long flags
;
3290 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3297 /* ScottB: February 5, 1998 */
3298 /* Check to see of PLT32 reloc required for the instruction. */
3300 /* arm_parse_reloc() works on input_line_pointer.
3301 We actually want to parse the operands to the branch instruction
3302 passed in 'str'. Save the input pointer and restore it later. */
3303 save_in
= input_line_pointer
;
3304 input_line_pointer
= str
;
3305 if (inst
.reloc
.exp
.X_op
== O_symbol
3307 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3309 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3310 inst
.reloc
.pc_rel
= 0;
3311 /* Modify str to point to after parsed operands, otherwise
3312 end_of_line() will complain about the (PLT) left in str. */
3313 str
= input_line_pointer
;
3317 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3318 inst
.reloc
.pc_rel
= 1;
3320 input_line_pointer
= save_in
;
3323 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3324 inst
.reloc
.pc_rel
= 1;
3325 #endif /* OBJ_ELF */
3334 unsigned long flags
;
3338 skip_whitespace (str
);
3340 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3342 inst
.error
= BAD_ARGS
;
3347 inst
.error
= BAD_PC
;
3355 unsigned long flags
;
3357 /* Co-processor data operation.
3358 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3359 skip_whitespace (str
);
3361 if (co_proc_number (&str
) == FAIL
)
3364 inst
.error
= BAD_ARGS
;
3368 if (skip_past_comma (&str
) == FAIL
3369 || cp_opc_expr (&str
, 20,4) == FAIL
)
3372 inst
.error
= BAD_ARGS
;
3376 if (skip_past_comma (&str
) == FAIL
3377 || cp_reg_required_here (&str
, 12) == FAIL
)
3380 inst
.error
= BAD_ARGS
;
3384 if (skip_past_comma (&str
) == FAIL
3385 || cp_reg_required_here (&str
, 16) == FAIL
)
3388 inst
.error
= BAD_ARGS
;
3392 if (skip_past_comma (&str
) == FAIL
3393 || cp_reg_required_here (&str
, 0) == FAIL
)
3396 inst
.error
= BAD_ARGS
;
3400 if (skip_past_comma (&str
) == SUCCESS
)
3402 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3405 inst
.error
= BAD_ARGS
;
3415 do_lstc (str
, flags
)
3417 unsigned long flags
;
3419 /* Co-processor register load/store.
3420 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3422 skip_whitespace (str
);
3424 if (co_proc_number (&str
) == FAIL
)
3427 inst
.error
= BAD_ARGS
;
3431 if (skip_past_comma (&str
) == FAIL
3432 || cp_reg_required_here (&str
, 12) == FAIL
)
3435 inst
.error
= BAD_ARGS
;
3439 if (skip_past_comma (&str
) == FAIL
3440 || cp_address_required_here (&str
) == FAIL
)
3443 inst
.error
= BAD_ARGS
;
3447 inst
.instruction
|= flags
;
3453 do_co_reg (str
, flags
)
3455 unsigned long flags
;
3457 /* Co-processor register transfer.
3458 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3460 skip_whitespace (str
);
3462 if (co_proc_number (&str
) == FAIL
)
3465 inst
.error
= BAD_ARGS
;
3469 if (skip_past_comma (&str
) == FAIL
3470 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3473 inst
.error
= BAD_ARGS
;
3477 if (skip_past_comma (&str
) == FAIL
3478 || reg_required_here (&str
, 12) == FAIL
)
3481 inst
.error
= BAD_ARGS
;
3485 if (skip_past_comma (&str
) == FAIL
3486 || cp_reg_required_here (&str
, 16) == FAIL
)
3489 inst
.error
= BAD_ARGS
;
3493 if (skip_past_comma (&str
) == FAIL
3494 || cp_reg_required_here (&str
, 0) == FAIL
)
3497 inst
.error
= BAD_ARGS
;
3501 if (skip_past_comma (&str
) == SUCCESS
)
3503 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3506 inst
.error
= BAD_ARGS
;
3512 inst
.error
= BAD_COND
;
3520 do_fp_ctrl (str
, flags
)
3522 unsigned long flags
;
3524 /* FP control registers.
3525 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3527 skip_whitespace (str
);
3529 if (reg_required_here (&str
, 12) == FAIL
)
3532 inst
.error
= BAD_ARGS
;
3541 do_fp_ldst (str
, flags
)
3543 unsigned long flags
;
3545 skip_whitespace (str
);
3547 switch (inst
.suffix
)
3552 inst
.instruction
|= CP_T_X
;
3555 inst
.instruction
|= CP_T_Y
;
3558 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3564 if (fp_reg_required_here (&str
, 12) == FAIL
)
3567 inst
.error
= BAD_ARGS
;
3571 if (skip_past_comma (&str
) == FAIL
3572 || cp_address_required_here (&str
) == FAIL
)
3575 inst
.error
= BAD_ARGS
;
3583 do_fp_ldmstm (str
, flags
)
3585 unsigned long flags
;
3589 skip_whitespace (str
);
3591 if (fp_reg_required_here (&str
, 12) == FAIL
)
3594 inst
.error
= BAD_ARGS
;
3598 /* Get Number of registers to transfer */
3599 if (skip_past_comma (&str
) == FAIL
3600 || my_get_expression (&inst
.reloc
.exp
, &str
))
3603 inst
.error
= _("constant expression expected");
3607 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3609 inst
.error
= _("Constant value required for number of registers");
3613 num_regs
= inst
.reloc
.exp
.X_add_number
;
3615 if (num_regs
< 1 || num_regs
> 4)
3617 inst
.error
= _("number of registers must be in the range [1:4]");
3624 inst
.instruction
|= CP_T_X
;
3627 inst
.instruction
|= CP_T_Y
;
3630 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3644 /* The instruction specified "ea" or "fd", so we can only accept
3645 [Rn]{!}. The instruction does not really support stacking or
3646 unstacking, so we have to emulate these by setting appropriate
3647 bits and offsets. */
3648 if (skip_past_comma (&str
) == FAIL
3652 inst
.error
= BAD_ARGS
;
3657 skip_whitespace (str
);
3659 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3662 skip_whitespace (str
);
3666 inst
.error
= BAD_ARGS
;
3677 inst
.error
= _("R15 not allowed as base register with write-back");
3684 if (flags
& CP_T_Pre
)
3687 offset
= 3 * num_regs
;
3693 /* Post-increment */
3697 offset
= 3 * num_regs
;
3701 /* No write-back, so convert this into a standard pre-increment
3702 instruction -- aesthetically more pleasing. */
3703 flags
= CP_T_Pre
| CP_T_UD
;
3708 inst
.instruction
|= flags
| offset
;
3710 else if (skip_past_comma (&str
) == FAIL
3711 || cp_address_required_here (&str
) == FAIL
)
3714 inst
.error
= BAD_ARGS
;
3722 do_fp_dyadic (str
, flags
)
3724 unsigned long flags
;
3726 skip_whitespace (str
);
3728 switch (inst
.suffix
)
3733 inst
.instruction
|= 0x00000080;
3736 inst
.instruction
|= 0x00080000;
3742 if (fp_reg_required_here (&str
, 12) == FAIL
)
3745 inst
.error
= BAD_ARGS
;
3749 if (skip_past_comma (&str
) == FAIL
3750 || fp_reg_required_here (&str
, 16) == FAIL
)
3753 inst
.error
= BAD_ARGS
;
3757 if (skip_past_comma (&str
) == FAIL
3758 || fp_op2 (&str
) == FAIL
)
3761 inst
.error
= BAD_ARGS
;
3765 inst
.instruction
|= flags
;
3771 do_fp_monadic (str
, flags
)
3773 unsigned long flags
;
3775 skip_whitespace (str
);
3777 switch (inst
.suffix
)
3782 inst
.instruction
|= 0x00000080;
3785 inst
.instruction
|= 0x00080000;
3791 if (fp_reg_required_here (&str
, 12) == FAIL
)
3794 inst
.error
= BAD_ARGS
;
3798 if (skip_past_comma (&str
) == FAIL
3799 || fp_op2 (&str
) == FAIL
)
3802 inst
.error
= BAD_ARGS
;
3806 inst
.instruction
|= flags
;
3812 do_fp_cmp (str
, flags
)
3814 unsigned long flags
;
3816 skip_whitespace (str
);
3818 if (fp_reg_required_here (&str
, 16) == FAIL
)
3821 inst
.error
= BAD_ARGS
;
3825 if (skip_past_comma (&str
) == FAIL
3826 || fp_op2 (&str
) == FAIL
)
3829 inst
.error
= BAD_ARGS
;
3833 inst
.instruction
|= flags
;
3839 do_fp_from_reg (str
, flags
)
3841 unsigned long flags
;
3843 skip_whitespace (str
);
3845 switch (inst
.suffix
)
3850 inst
.instruction
|= 0x00000080;
3853 inst
.instruction
|= 0x00080000;
3859 if (fp_reg_required_here (&str
, 16) == FAIL
)
3862 inst
.error
= BAD_ARGS
;
3866 if (skip_past_comma (&str
) == FAIL
3867 || reg_required_here (&str
, 12) == FAIL
)
3870 inst
.error
= BAD_ARGS
;
3874 inst
.instruction
|= flags
;
3880 do_fp_to_reg (str
, flags
)
3882 unsigned long flags
;
3884 skip_whitespace (str
);
3886 if (reg_required_here (&str
, 12) == FAIL
)
3889 if (skip_past_comma (&str
) == FAIL
3890 || fp_reg_required_here (&str
, 0) == FAIL
)
3893 inst
.error
= BAD_ARGS
;
3897 inst
.instruction
|= flags
;
3902 /* Thumb specific routines */
3904 /* Parse and validate that a register is of the right form, this saves
3905 repeated checking of this information in many similar cases.
3906 Unlike the 32-bit case we do not insert the register into the opcode
3907 here, since the position is often unknown until the full instruction
3910 thumb_reg (strp
, hi_lo
)
3916 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3924 inst
.error
= _("lo register required");
3932 inst
.error
= _("hi register required");
3944 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3947 thumb_add_sub (str
, subtract
)
3951 int Rd
, Rs
, Rn
= FAIL
;
3953 skip_whitespace (str
);
3955 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3956 || skip_past_comma (&str
) == FAIL
)
3959 inst
.error
= BAD_ARGS
;
3963 if (is_immediate_prefix (*str
))
3967 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3972 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3975 if (skip_past_comma (&str
) == FAIL
)
3977 /* Two operand format, shuffle the registers and pretend there
3982 else if (is_immediate_prefix (*str
))
3985 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3988 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3992 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3993 for the latter case, EXPR contains the immediate that was found. */
3996 /* All register format. */
3997 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4001 inst
.error
= _("dest and source1 must be the same register");
4005 /* Can't do this for SUB */
4008 inst
.error
= _("subtract valid only on lo regs");
4012 inst
.instruction
= (T_OPCODE_ADD_HI
4013 | (Rd
> 7 ? THUMB_H1
: 0)
4014 | (Rn
> 7 ? THUMB_H2
: 0));
4015 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4019 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4020 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4025 /* Immediate expression, now things start to get nasty. */
4027 /* First deal with HI regs, only very restricted cases allowed:
4028 Adjusting SP, and using PC or SP to get an address. */
4029 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4030 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4032 inst
.error
= _("invalid Hi register with immediate");
4036 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4038 /* Value isn't known yet, all we can do is store all the fragments
4039 we know about in the instruction and let the reloc hacking
4041 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4042 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4046 int offset
= inst
.reloc
.exp
.X_add_number
;
4056 /* Quick check, in case offset is MIN_INT */
4059 inst
.error
= _("immediate value out of range");
4068 if (offset
& ~0x1fc)
4070 inst
.error
= _("invalid immediate value for stack adjust");
4073 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4074 inst
.instruction
|= offset
>> 2;
4076 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4079 || (offset
& ~0x3fc))
4081 inst
.error
= _("invalid immediate for address calculation");
4084 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4086 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4092 inst
.error
= _("immediate value out of range");
4095 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4096 inst
.instruction
|= (Rd
<< 8) | offset
;
4102 inst
.error
= _("immediate value out of range");
4105 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4106 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4114 thumb_shift (str
, shift
)
4118 int Rd
, Rs
, Rn
= FAIL
;
4120 skip_whitespace (str
);
4122 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4123 || skip_past_comma (&str
) == FAIL
)
4126 inst
.error
= BAD_ARGS
;
4130 if (is_immediate_prefix (*str
))
4132 /* Two operand immediate format, set Rs to Rd. */
4135 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4140 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4143 if (skip_past_comma (&str
) == FAIL
)
4145 /* Two operand format, shuffle the registers and pretend there
4150 else if (is_immediate_prefix (*str
))
4153 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4156 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4160 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4161 for the latter case, EXPR contains the immediate that was found. */
4167 inst
.error
= _("source1 and dest must be same register");
4173 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4174 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4175 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4178 inst
.instruction
|= Rd
| (Rn
<< 3);
4184 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4185 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4186 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4189 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4191 /* Value isn't known yet, create a dummy reloc and let reloc
4192 hacking fix it up */
4194 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4198 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4200 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4202 inst
.error
= _("Invalid immediate for shift");
4206 /* Shifts of zero are handled by converting to LSL */
4207 if (shift_value
== 0)
4208 inst
.instruction
= T_OPCODE_LSL_I
;
4210 /* Shifts of 32 are encoded as a shift of zero */
4211 if (shift_value
== 32)
4214 inst
.instruction
|= shift_value
<< 6;
4217 inst
.instruction
|= Rd
| (Rs
<< 3);
4223 thumb_mov_compare (str
, move
)
4229 skip_whitespace (str
);
4231 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4232 || skip_past_comma (&str
) == FAIL
)
4235 inst
.error
= BAD_ARGS
;
4239 if (is_immediate_prefix (*str
))
4242 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4245 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4250 if (Rs
< 8 && Rd
< 8)
4252 if (move
== THUMB_MOVE
)
4253 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4254 since a MOV instruction produces unpredictable results */
4255 inst
.instruction
= T_OPCODE_ADD_I3
;
4257 inst
.instruction
= T_OPCODE_CMP_LR
;
4258 inst
.instruction
|= Rd
| (Rs
<< 3);
4262 if (move
== THUMB_MOVE
)
4263 inst
.instruction
= T_OPCODE_MOV_HR
;
4265 inst
.instruction
= T_OPCODE_CMP_HR
;
4268 inst
.instruction
|= THUMB_H1
;
4271 inst
.instruction
|= THUMB_H2
;
4273 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4280 inst
.error
= _("only lo regs allowed with immediate");
4284 if (move
== THUMB_MOVE
)
4285 inst
.instruction
= T_OPCODE_MOV_I8
;
4287 inst
.instruction
= T_OPCODE_CMP_I8
;
4289 inst
.instruction
|= Rd
<< 8;
4291 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4292 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4295 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4299 inst
.error
= _("invalid immediate");
4303 inst
.instruction
|= value
;
4311 thumb_load_store (str
, load_store
, size
)
4316 int Rd
, Rb
, Ro
= FAIL
;
4318 skip_whitespace (str
);
4320 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4321 || skip_past_comma (&str
) == FAIL
)
4324 inst
.error
= BAD_ARGS
;
4331 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4334 if (skip_past_comma (&str
) != FAIL
)
4336 if (is_immediate_prefix (*str
))
4339 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4342 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4347 inst
.reloc
.exp
.X_op
= O_constant
;
4348 inst
.reloc
.exp
.X_add_number
= 0;
4353 inst
.error
= _("expected ']'");
4358 else if (*str
== '=')
4360 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4363 skip_whitespace (str
);
4365 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4370 if ( inst
.reloc
.exp
.X_op
!= O_constant
4371 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4373 inst
.error
= "Constant expression expected";
4377 if (inst
.reloc
.exp
.X_op
== O_constant
4378 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4380 /* This can be done with a mov instruction */
4382 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4383 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4387 /* Insert into literal pool */
4388 if (add_to_lit_pool () == FAIL
)
4391 inst
.error
= "literal pool insertion failed";
4395 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4396 inst
.reloc
.pc_rel
= 1;
4397 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4398 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4404 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4407 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4408 inst
.reloc
.pc_rel
= 1;
4409 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4410 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4415 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4417 if (size
!= THUMB_WORD
)
4419 inst
.error
= _("byte or halfword not valid for base register");
4422 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4424 inst
.error
= _("R15 based store not allowed");
4427 else if (Ro
!= FAIL
)
4429 inst
.error
= _("Invalid base register for register offset");
4434 inst
.instruction
= T_OPCODE_LDR_PC
;
4435 else if (load_store
== THUMB_LOAD
)
4436 inst
.instruction
= T_OPCODE_LDR_SP
;
4438 inst
.instruction
= T_OPCODE_STR_SP
;
4440 inst
.instruction
|= Rd
<< 8;
4441 if (inst
.reloc
.exp
.X_op
== O_constant
)
4443 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4445 if (offset
& ~0x3fc)
4447 inst
.error
= _("invalid offset");
4451 inst
.instruction
|= offset
>> 2;
4454 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4458 inst
.error
= _("invalid base register in load/store");
4461 else if (Ro
== FAIL
)
4463 /* Immediate offset */
4464 if (size
== THUMB_WORD
)
4465 inst
.instruction
= (load_store
== THUMB_LOAD
4466 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4467 else if (size
== THUMB_HALFWORD
)
4468 inst
.instruction
= (load_store
== THUMB_LOAD
4469 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4471 inst
.instruction
= (load_store
== THUMB_LOAD
4472 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4474 inst
.instruction
|= Rd
| (Rb
<< 3);
4476 if (inst
.reloc
.exp
.X_op
== O_constant
)
4478 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4480 if (offset
& ~(0x1f << size
))
4482 inst
.error
= _("Invalid offset");
4485 inst
.instruction
|= (offset
>> size
) << 6;
4488 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4492 /* Register offset */
4493 if (size
== THUMB_WORD
)
4494 inst
.instruction
= (load_store
== THUMB_LOAD
4495 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4496 else if (size
== THUMB_HALFWORD
)
4497 inst
.instruction
= (load_store
== THUMB_LOAD
4498 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4500 inst
.instruction
= (load_store
== THUMB_LOAD
4501 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4503 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4518 /* Handle the Format 4 instructions that do not have equivalents in other
4519 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4527 skip_whitespace (str
);
4529 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4530 || skip_past_comma (&str
) == FAIL
4531 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4533 inst
.error
= BAD_ARGS
;
4537 if (skip_past_comma (&str
) != FAIL
)
4539 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4540 (It isn't allowed for CMP either, but that isn't handled by this
4542 if (inst
.instruction
== T_OPCODE_TST
4543 || inst
.instruction
== T_OPCODE_CMN
4544 || inst
.instruction
== T_OPCODE_NEG
4545 || inst
.instruction
== T_OPCODE_MVN
)
4547 inst
.error
= BAD_ARGS
;
4551 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4556 inst
.error
= _("dest and source1 one must be the same register");
4562 if (inst
.instruction
== T_OPCODE_MUL
4564 as_tsktsk (_("Rs and Rd must be different in MUL"));
4566 inst
.instruction
|= Rd
| (Rs
<< 3);
4574 thumb_add_sub (str
, 0);
4581 thumb_shift (str
, THUMB_ASR
);
4588 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4590 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4591 inst
.reloc
.pc_rel
= 1;
4599 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4601 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4602 inst
.reloc
.pc_rel
= 1;
4606 /* Find the real, Thumb encoded start of a Thumb function. */
4609 find_real_start (symbolP
)
4613 const char * name
= S_GET_NAME (symbolP
);
4614 symbolS
* new_target
;
4616 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4617 #define STUB_NAME ".real_start_of"
4622 /* Names that start with '.' are local labels, not function entry points.
4623 The compiler may generate BL instructions to these labels because it
4624 needs to perform a branch to a far away location. */
4628 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4629 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4631 new_target
= symbol_find (real_start
);
4633 if (new_target
== NULL
)
4635 as_warn ("Failed to find real start of function: %s\n", name
);
4636 new_target
= symbolP
;
4649 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4652 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4653 inst
.reloc
.pc_rel
= 1;
4656 /* If the destination of the branch is a defined symbol which does not have
4657 the THUMB_FUNC attribute, then we must be calling a function which has
4658 the (interfacearm) attribute. We look for the Thumb entry point to that
4659 function and change the branch to refer to that function instead. */
4660 if ( inst
.reloc
.exp
.X_op
== O_symbol
4661 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4662 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4663 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4664 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4673 skip_whitespace (str
);
4675 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4678 /* This sets THUMB_H2 from the top bit of reg. */
4679 inst
.instruction
|= reg
<< 3;
4681 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4682 should cause the alignment to be checked once it is known. This is
4683 because BX PC only works if the instruction is word aligned. */
4692 thumb_mov_compare (str
, THUMB_COMPARE
);
4702 skip_whitespace (str
);
4704 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4708 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4712 if (skip_past_comma (&str
) == FAIL
4713 || (range
= reg_list (&str
)) == FAIL
)
4716 inst
.error
= BAD_ARGS
;
4720 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4722 /* This really doesn't seem worth it. */
4723 inst
.reloc
.type
= BFD_RELOC_NONE
;
4724 inst
.error
= _("Expression too complex");
4730 inst
.error
= _("only lo-regs valid in load/store multiple");
4734 inst
.instruction
|= (Rb
<< 8) | range
;
4742 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4749 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4756 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4765 skip_whitespace (str
);
4767 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4768 || skip_past_comma (&str
) == FAIL
4770 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4771 || skip_past_comma (&str
) == FAIL
4772 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4776 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4780 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4788 thumb_shift (str
, THUMB_LSL
);
4795 thumb_shift (str
, THUMB_LSR
);
4802 thumb_mov_compare (str
, THUMB_MOVE
);
4811 skip_whitespace (str
);
4813 if ((range
= reg_list (&str
)) == FAIL
)
4816 inst
.error
= BAD_ARGS
;
4820 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4822 /* This really doesn't seem worth it. */
4823 inst
.reloc
.type
= BFD_RELOC_NONE
;
4824 inst
.error
= _("Expression too complex");
4830 if ((inst
.instruction
== T_OPCODE_PUSH
4831 && (range
& ~0xff) == 1 << REG_LR
)
4832 || (inst
.instruction
== T_OPCODE_POP
4833 && (range
& ~0xff) == 1 << REG_PC
))
4835 inst
.instruction
|= THUMB_PP_PC_LR
;
4840 inst
.error
= _("invalid register list to push/pop instruction");
4845 inst
.instruction
|= range
;
4853 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4860 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4867 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4874 thumb_add_sub (str
, 1);
4881 skip_whitespace (str
);
4883 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4886 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4895 /* This is a pseudo-op of the form "adr rd, label" to be converted
4896 into a relative address of the form "add rd, pc, #label-.-4" */
4897 skip_whitespace (str
);
4899 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4900 || skip_past_comma (&str
) == FAIL
4901 || my_get_expression (&inst
.reloc
.exp
, &str
))
4904 inst
.error
= BAD_ARGS
;
4908 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4909 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4910 inst
.reloc
.pc_rel
= 1;
4911 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4919 int len
= strlen (reg_table
[entry
].name
) + 2;
4920 char * buf
= (char *) xmalloc (len
);
4921 char * buf2
= (char *) xmalloc (len
);
4924 #ifdef REGISTER_PREFIX
4925 buf
[i
++] = REGISTER_PREFIX
;
4928 strcpy (buf
+ i
, reg_table
[entry
].name
);
4930 for (i
= 0; buf
[i
]; i
++)
4931 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4935 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4936 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4940 insert_reg_alias (str
, regnum
)
4944 struct reg_entry
*new =
4945 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4946 char *name
= xmalloc (strlen (str
) + 1);
4950 new->number
= regnum
;
4952 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4956 set_constant_flonums ()
4960 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4961 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4970 if ( (arm_ops_hsh
= hash_new ()) == NULL
4971 || (arm_tops_hsh
= hash_new ()) == NULL
4972 || (arm_cond_hsh
= hash_new ()) == NULL
4973 || (arm_shift_hsh
= hash_new ()) == NULL
4974 || (arm_reg_hsh
= hash_new ()) == NULL
4975 || (arm_psr_hsh
= hash_new ()) == NULL
)
4976 as_fatal (_("Virtual memory exhausted"));
4978 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4979 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4980 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4981 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4982 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4983 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4984 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4985 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4986 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4987 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4989 for (i
= 0; reg_table
[i
].name
; i
++)
4992 set_constant_flonums ();
4994 #if defined OBJ_COFF || defined OBJ_ELF
4996 unsigned int flags
= 0;
4998 /* Set the flags in the private structure */
4999 if (uses_apcs_26
) flags
|= F_APCS26
;
5000 if (support_interwork
) flags
|= F_INTERWORK
;
5001 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5002 if (pic_code
) flags
|= F_PIC
;
5003 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5005 bfd_set_private_flags (stdoutput
, flags
);
5012 /* Record the CPU type as well */
5013 switch (cpu_variant
& ARM_CPU_MASK
)
5016 mach
= bfd_mach_arm_2
;
5019 case ARM_3
: /* also ARM_250 */
5020 mach
= bfd_mach_arm_2a
;
5024 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
5025 mach
= bfd_mach_arm_4
;
5028 case ARM_7
: /* also ARM_6 */
5029 mach
= bfd_mach_arm_3
;
5033 /* Catch special cases. */
5034 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5036 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5037 mach
= bfd_mach_arm_5T
;
5038 else if (cpu_variant
& ARM_EXT_V5
)
5039 mach
= bfd_mach_arm_5
;
5040 else if (cpu_variant
& ARM_THUMB
)
5041 mach
= bfd_mach_arm_4T
;
5042 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5043 mach
= bfd_mach_arm_4
;
5044 else if (cpu_variant
& ARM_LONGMUL
)
5045 mach
= bfd_mach_arm_3M
;
5048 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5052 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5053 for use in the a.out file, and stores them in the array pointed to by buf.
5054 This knows about the endian-ness of the target machine and does
5055 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5056 2 (short) and 4 (long) Floating numbers are put out as a series of
5057 LITTLENUMS (shorts, here at least). */
5059 md_number_to_chars (buf
, val
, n
)
5064 if (target_big_endian
)
5065 number_to_chars_bigendian (buf
, val
, n
);
5067 number_to_chars_littleendian (buf
, val
, n
);
5071 md_chars_to_number (buf
, n
)
5076 unsigned char * where
= (unsigned char *) buf
;
5078 if (target_big_endian
)
5083 result
|= (*where
++ & 255);
5091 result
|= (where
[n
] & 255);
5098 /* Turn a string in input_line_pointer into a floating point constant
5099 of type TYPE, and store the appropriate bytes in *litP. The number
5100 of LITTLENUMS emitted is stored in *sizeP . An error message is
5101 returned, or NULL on OK.
5103 Note that fp constants aren't represent in the normal way on the ARM.
5104 In big endian mode, things are as expected. However, in little endian
5105 mode fp constants are big-endian word-wise, and little-endian byte-wise
5106 within the words. For example, (double) 1.1 in big endian mode is
5107 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5108 the byte sequence 99 99 f1 3f 9a 99 99 99.
5110 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5113 md_atof (type
, litP
, sizeP
)
5119 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5151 return _("Bad call to MD_ATOF()");
5154 t
= atof_ieee (input_line_pointer
, type
, words
);
5156 input_line_pointer
= t
;
5159 if (target_big_endian
)
5161 for (i
= 0; i
< prec
; i
++)
5163 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5169 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5170 8 byte float the order is 1 0 3 2. */
5171 for (i
= 0; i
< prec
; i
+= 2)
5173 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5174 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5182 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5184 md_pcrel_from (fixP
)
5188 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5189 && fixP
->fx_subsy
== NULL
)
5192 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5194 /* PC relative addressing on the Thumb is slightly odd
5195 as the bottom two bits of the PC are forced to zero
5196 for the calculation. */
5197 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5200 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5203 /* Round up a section size to the appropriate boundary. */
5205 md_section_align (segment
, size
)
5212 /* Round all sects to multiple of 4 */
5213 return (size
+ 3) & ~3;
5217 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5218 we have no need to default values of symbols. */
5222 md_undefined_symbol (name
)
5226 if (name
[0] == '_' && name
[1] == 'G'
5227 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5231 if (symbol_find (name
))
5232 as_bad ("GOT already in the symbol table");
5234 GOT_symbol
= symbol_new (name
, undefined_section
,
5235 (valueT
)0, & zero_address_frag
);
5245 /* arm_reg_parse () := if it looks like a register, return its token and
5246 advance the pointer. */
5250 register char ** ccp
;
5252 char * start
= * ccp
;
5255 struct reg_entry
* reg
;
5257 #ifdef REGISTER_PREFIX
5258 if (*start
!= REGISTER_PREFIX
)
5263 #ifdef OPTIONAL_REGISTER_PREFIX
5264 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5268 if (!isalpha (*p
) || !is_name_beginner (*p
))
5272 while (isalpha (c
) || isdigit (c
) || c
== '_')
5276 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5290 register char ** ccp
;
5292 char * start
= * ccp
;
5295 CONST
struct asm_psr
* psr
;
5299 while (isalpha (c
) || c
== '_')
5303 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5316 md_apply_fix3 (fixP
, val
, seg
)
5321 offsetT value
= * val
;
5323 unsigned int newimm
;
5326 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5327 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5329 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5331 /* Note whether this will delete the relocation. */
5332 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5333 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5336 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5340 /* If this symbol is in a different section then we need to leave it for
5341 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5342 so we have to undo it's effects here. */
5345 if (fixP
->fx_addsy
!= NULL
5346 && S_IS_DEFINED (fixP
->fx_addsy
)
5347 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5350 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5354 value
+= md_pcrel_from (fixP
);
5358 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5360 switch (fixP
->fx_r_type
)
5362 case BFD_RELOC_ARM_IMMEDIATE
:
5363 newimm
= validate_immediate (value
);
5364 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5366 /* If the instruction will fail, see if we can fix things up by
5367 changing the opcode. */
5368 if (newimm
== (unsigned int) FAIL
5369 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5371 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5372 _("invalid constant (%lx) after fixup"),
5373 (unsigned long) value
);
5377 newimm
|= (temp
& 0xfffff000);
5378 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5381 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5383 unsigned int highpart
= 0;
5384 unsigned int newinsn
= 0xe1a00000; /* nop */
5385 newimm
= validate_immediate (value
);
5386 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5388 /* If the instruction will fail, see if we can fix things up by
5389 changing the opcode. */
5390 if (newimm
== (unsigned int) FAIL
5391 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5393 /* No ? OK - try using two ADD instructions to generate the value. */
5394 newimm
= validate_immediate_twopart (value
, & highpart
);
5396 /* Yes - then make sure that the second instruction is also an add. */
5397 if (newimm
!= (unsigned int) FAIL
)
5399 /* Still No ? Try using a negated value. */
5400 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5401 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5402 /* Otherwise - give up. */
5405 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5406 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5410 /* Replace the first operand in the 2nd instruction (which is the PC)
5411 with the destination register. We have already added in the PC in the
5412 first instruction and we do not want to do it again. */
5413 newinsn
&= ~ 0xf0000;
5414 newinsn
|= ((newinsn
& 0x0f000) << 4);
5417 newimm
|= (temp
& 0xfffff000);
5418 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5420 highpart
|= (newinsn
& 0xfffff000);
5421 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5425 case BFD_RELOC_ARM_OFFSET_IMM
:
5431 if (validate_offset_imm (value
, 0) == FAIL
)
5433 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5434 _("bad immediate value for offset (%ld)"), (long) value
);
5438 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5439 newval
&= 0xff7ff000;
5440 newval
|= value
| (sign
? INDEX_UP
: 0);
5441 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5444 case BFD_RELOC_ARM_OFFSET_IMM8
:
5445 case BFD_RELOC_ARM_HWLITERAL
:
5451 if (validate_offset_imm (value
, 1) == FAIL
)
5453 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5454 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5455 _("invalid literal constant: pool needs to be closer"));
5457 as_bad (_("bad immediate value for half-word offset (%ld)"),
5462 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5463 newval
&= 0xff7ff0f0;
5464 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5465 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5468 case BFD_RELOC_ARM_LITERAL
:
5474 if (validate_offset_imm (value
, 0) == FAIL
)
5476 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5477 _("invalid literal constant: pool needs to be closer"));
5481 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5482 newval
&= 0xff7ff000;
5483 newval
|= value
| (sign
? INDEX_UP
: 0);
5484 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5487 case BFD_RELOC_ARM_SHIFT_IMM
:
5488 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5489 if (((unsigned long) value
) > 32
5491 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5493 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5494 _("shift expression is too large"));
5499 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5500 else if (value
== 32)
5502 newval
&= 0xfffff07f;
5503 newval
|= (value
& 0x1f) << 7;
5504 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5507 case BFD_RELOC_ARM_SWI
:
5508 if (arm_data
->thumb_mode
)
5510 if (((unsigned long) value
) > 0xff)
5511 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5512 _("Invalid swi expression"));
5513 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5515 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5519 if (((unsigned long) value
) > 0x00ffffff)
5520 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5521 _("Invalid swi expression"));
5522 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5524 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5528 case BFD_RELOC_ARM_MULTI
:
5529 if (((unsigned long) value
) > 0xffff)
5530 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5531 _("Invalid expression in load/store multiple"));
5532 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5533 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5536 case BFD_RELOC_ARM_PCREL_BRANCH
:
5537 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5541 value
= fixP
->fx_offset
;
5543 value
= (value
>> 2) & 0x00ffffff;
5544 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5545 newval
= value
| (newval
& 0xff000000);
5546 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5550 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5551 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5553 addressT diff
= (newval
& 0xff) << 1;
5558 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5559 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5560 _("Branch out of range"));
5561 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5563 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5566 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5567 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5569 addressT diff
= (newval
& 0x7ff) << 1;
5574 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5575 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5576 _("Branch out of range"));
5577 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5579 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5582 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5587 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5588 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5589 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5590 if (diff
& 0x400000)
5593 value
= fixP
->fx_offset
;
5596 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5597 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5598 _("Branch with link out of range"));
5600 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5601 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5602 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5603 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5608 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5609 md_number_to_chars (buf
, value
, 1);
5611 else if (!target_oabi
)
5613 value
= fixP
->fx_offset
;
5614 md_number_to_chars (buf
, value
, 1);
5620 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5621 md_number_to_chars (buf
, value
, 2);
5623 else if (!target_oabi
)
5625 value
= fixP
->fx_offset
;
5626 md_number_to_chars (buf
, value
, 2);
5632 case BFD_RELOC_ARM_GOT32
:
5633 case BFD_RELOC_ARM_GOTOFF
:
5634 md_number_to_chars (buf
, 0, 4);
5640 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5641 md_number_to_chars (buf
, value
, 4);
5643 else if (!target_oabi
)
5645 value
= fixP
->fx_offset
;
5646 md_number_to_chars (buf
, value
, 4);
5652 case BFD_RELOC_ARM_PLT32
:
5653 /* It appears the instruction is fully prepared at this point. */
5657 case BFD_RELOC_ARM_GOTPC
:
5658 md_number_to_chars (buf
, value
, 4);
5661 case BFD_RELOC_ARM_CP_OFF_IMM
:
5663 if (value
< -1023 || value
> 1023 || (value
& 3))
5664 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5665 _("Illegal value for co-processor offset"));
5668 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5669 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5670 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5673 case BFD_RELOC_ARM_THUMB_OFFSET
:
5674 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5675 /* Exactly what ranges, and where the offset is inserted depends on
5676 the type of instruction, we can establish this from the top 4 bits */
5677 switch (newval
>> 12)
5679 case 4: /* PC load */
5680 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5681 forced to zero for these loads, so we will need to round
5682 up the offset if the instruction address is not word
5683 aligned (since the final address produced must be, and
5684 we can only describe word-aligned immediate offsets). */
5686 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5687 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5688 _("Invalid offset, target not word aligned (0x%08X)"),
5689 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5691 if ((value
+ 2) & ~0x3fe)
5692 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5693 _("Invalid offset, value too big (0x%08X)"), value
);
5695 /* Round up, since pc will be rounded down. */
5696 newval
|= (value
+ 2) >> 2;
5699 case 9: /* SP load/store */
5701 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5702 _("Invalid offset, value too big (0x%08X)"), value
);
5703 newval
|= value
>> 2;
5706 case 6: /* Word load/store */
5708 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5709 _("Invalid offset, value too big (0x%08X)"), value
);
5710 newval
|= value
<< 4; /* 6 - 2 */
5713 case 7: /* Byte load/store */
5715 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5716 _("Invalid offset, value too big (0x%08X)"), value
);
5717 newval
|= value
<< 6;
5720 case 8: /* Halfword load/store */
5722 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5723 _("Invalid offset, value too big (0x%08X)"), value
);
5724 newval
|= value
<< 5; /* 6 - 1 */
5728 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5729 "Unable to process relocation for thumb opcode: %lx",
5730 (unsigned long) newval
);
5733 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5736 case BFD_RELOC_ARM_THUMB_ADD
:
5737 /* This is a complicated relocation, since we use it for all of
5738 the following immediate relocations:
5741 9bit ADD/SUB SP word-aligned
5742 10bit ADD PC/SP word-aligned
5744 The type of instruction being processed is encoded in the
5750 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5752 int rd
= (newval
>> 4) & 0xf;
5753 int rs
= newval
& 0xf;
5754 int subtract
= newval
& 0x8000;
5759 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5760 _("Invalid immediate for stack address calculation"));
5761 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5762 newval
|= value
>> 2;
5764 else if (rs
== REG_PC
|| rs
== REG_SP
)
5768 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5769 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5770 (unsigned long) value
);
5771 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5773 newval
|= value
>> 2;
5778 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5779 _("Invalid 8bit immediate"));
5780 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5781 newval
|= (rd
<< 8) | value
;
5786 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5787 _("Invalid 3bit immediate"));
5788 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5789 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5792 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5795 case BFD_RELOC_ARM_THUMB_IMM
:
5796 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5797 switch (newval
>> 11)
5799 case 0x04: /* 8bit immediate MOV */
5800 case 0x05: /* 8bit immediate CMP */
5801 if (value
< 0 || value
> 255)
5802 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5803 _("Invalid immediate: %ld is too large"),
5811 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5814 case BFD_RELOC_ARM_THUMB_SHIFT
:
5815 /* 5bit shift value (0..31) */
5816 if (value
< 0 || value
> 31)
5817 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5818 _("Illegal Thumb shift value: %ld"), (long) value
);
5819 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5820 newval
|= value
<< 6;
5821 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5824 case BFD_RELOC_VTABLE_INHERIT
:
5825 case BFD_RELOC_VTABLE_ENTRY
:
5829 case BFD_RELOC_NONE
:
5831 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5832 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5838 /* Translate internal representation of relocation info to BFD target
5841 tc_gen_reloc (section
, fixp
)
5846 bfd_reloc_code_real_type code
;
5848 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5850 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5851 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5852 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5854 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5856 if (fixp
->fx_pcrel
== 0)
5857 reloc
->addend
= fixp
->fx_offset
;
5859 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5861 reloc
->addend
= fixp
->fx_offset
;
5864 switch (fixp
->fx_r_type
)
5869 code
= BFD_RELOC_8_PCREL
;
5876 code
= BFD_RELOC_16_PCREL
;
5883 code
= BFD_RELOC_32_PCREL
;
5887 case BFD_RELOC_ARM_PCREL_BRANCH
:
5889 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5890 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5891 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5892 case BFD_RELOC_VTABLE_ENTRY
:
5893 case BFD_RELOC_VTABLE_INHERIT
:
5894 code
= fixp
->fx_r_type
;
5897 case BFD_RELOC_ARM_LITERAL
:
5898 case BFD_RELOC_ARM_HWLITERAL
:
5899 /* If this is called then the a literal has been referenced across
5900 a section boundary - possibly due to an implicit dump */
5901 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5902 _("Literal referenced across section boundary (Implicit dump?)"));
5906 case BFD_RELOC_ARM_GOT32
:
5907 case BFD_RELOC_ARM_GOTOFF
:
5908 case BFD_RELOC_ARM_PLT32
:
5909 code
= fixp
->fx_r_type
;
5913 case BFD_RELOC_ARM_IMMEDIATE
:
5914 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5915 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5919 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5920 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5921 _("ADRL used for a symbol not defined in the same file"),
5925 case BFD_RELOC_ARM_OFFSET_IMM
:
5926 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5927 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5934 switch (fixp
->fx_r_type
)
5936 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5937 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5938 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5939 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5940 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5941 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5942 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5943 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5944 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5945 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5946 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5947 default: type
= _("<unknown>"); break;
5949 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5950 _("Can not represent %s relocation in this object file format (%d)"),
5951 type
, fixp
->fx_pcrel
);
5957 if (code
== BFD_RELOC_32_PCREL
5959 && fixp
->fx_addsy
== GOT_symbol
)
5961 code
= BFD_RELOC_ARM_GOTPC
;
5962 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5966 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5968 if (reloc
->howto
== NULL
)
5970 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5971 _("Can not represent %s relocation in this object file format"),
5972 bfd_get_reloc_code_name (code
));
5976 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5977 vtable entry to be used in the relocation's section offset. */
5978 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5979 reloc
->address
= fixp
->fx_offset
;
5985 md_estimate_size_before_relax (fragP
, segtype
)
5989 as_fatal (_("md_estimate_size_before_relax\n"));
5994 output_inst
PARAMS ((void))
6000 as_bad (inst
.error
);
6004 to
= frag_more (inst
.size
);
6006 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6008 assert (inst
.size
== (2 * THUMB_SIZE
));
6009 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6010 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6012 else if (inst
.size
> INSN_SIZE
)
6014 assert (inst
.size
== (2 * INSN_SIZE
));
6015 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6016 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6019 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6021 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6022 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6023 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6038 /* Align the instruction.
6039 This may not be the right thing to do but ... */
6040 /* arm_align (2, 0); */
6041 listing_prev_line (); /* Defined in listing.h */
6043 /* Align the previous label if needed. */
6044 if (last_label_seen
!= NULL
)
6046 symbol_set_frag (last_label_seen
, frag_now
);
6047 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6048 S_SET_SEGMENT (last_label_seen
, now_seg
);
6051 memset (&inst
, '\0', sizeof (inst
));
6052 inst
.reloc
.type
= BFD_RELOC_NONE
;
6054 skip_whitespace (str
);
6056 /* Scan up to the end of the op-code, which must end in white space or
6058 for (start
= p
= str
; *p
!= '\0'; p
++)
6064 as_bad (_("No operator -- statement `%s'\n"), str
);
6070 CONST
struct thumb_opcode
* opcode
;
6074 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6079 /* Check that this instruction is supported for this CPU. */
6080 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6082 as_bad (_("selected processor does not support this opcode"));
6086 inst
.instruction
= opcode
->value
;
6087 inst
.size
= opcode
->size
;
6088 (*opcode
->parms
)(p
);
6095 CONST
struct asm_opcode
* opcode
;
6096 unsigned long cond_code
;
6098 inst
.size
= INSN_SIZE
;
6099 /* p now points to the end of the opcode, probably white space, but we
6100 have to break the opcode up in case it contains condionals and flags;
6101 keep trying with progressively smaller basic instructions until one
6102 matches, or we run out of opcode. */
6103 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6104 for (; q
!= str
; q
--)
6108 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6111 if (opcode
&& opcode
->template)
6113 unsigned long flag_bits
= 0;
6116 /* Check that this instruction is supported for this CPU. */
6117 if ((opcode
->variants
& cpu_variant
) == 0)
6120 inst
.instruction
= opcode
->value
;
6121 if (q
== p
) /* Just a simple opcode. */
6123 if (opcode
->comp_suffix
)
6125 if (*opcode
->comp_suffix
!= '\0')
6126 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6127 str
, opcode
->comp_suffix
);
6129 /* Not a conditional instruction. */
6130 (*opcode
->parms
)(q
, 0);
6134 /* A conditional instruction with default condition. */
6135 inst
.instruction
|= COND_ALWAYS
;
6136 (*opcode
->parms
)(q
, 0);
6142 /* Not just a simple opcode. Check if extra is a conditional. */
6146 CONST
struct asm_cond
*cond
;
6150 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6154 if (cond
->value
== 0xf0000000)
6156 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6158 cond_code
= cond
->value
;
6162 cond_code
= COND_ALWAYS
;
6165 cond_code
= COND_ALWAYS
;
6167 /* Apply the conditional, or complain it's not allowed. */
6168 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6170 /* Instruction isn't conditional */
6171 if (cond_code
!= COND_ALWAYS
)
6173 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6178 /* Instruction is conditional: set the condition into it. */
6179 inst
.instruction
|= cond_code
;
6182 /* If there is a compulsory suffix, it should come here, before
6183 any optional flags. */
6184 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6186 CONST
char *s
= opcode
->comp_suffix
;
6198 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6199 opcode
->comp_suffix
);
6206 /* The remainder, if any should now be flags for the instruction;
6207 Scan these checking each one found with the opcode. */
6211 CONST
struct asm_flg
*flag
= opcode
->flags
;
6220 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6222 if (streq (r
, flag
[flagno
].template))
6224 flag_bits
|= flag
[flagno
].set_bits
;
6230 if (! flag
[flagno
].template)
6237 (*opcode
->parms
) (p
, flag_bits
);
6247 /* It wasn't an instruction, but it might be a register alias of the form
6250 skip_whitespace (q
);
6255 if (*q
&& !strncmp (q
, ".req ", 4))
6258 char * copy_of_str
= str
;
6262 skip_whitespace (q
);
6264 for (r
= q
; *r
!= '\0'; r
++)
6274 regnum
= arm_reg_parse (& q
);
6277 reg
= arm_reg_parse (& str
);
6282 insert_reg_alias (str
, regnum
);
6284 as_warn (_("register '%s' does not exist\n"), q
);
6286 else if (regnum
!= FAIL
)
6289 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6291 /* Do not warn about redefinitions to the same alias. */
6294 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6298 as_warn (_("ignoring incomplete .req pseuso op"));
6305 as_bad (_("bad instruction `%s'"), start
);
6310 * Invocation line includes a switch not recognized by the base assembler.
6311 * See if it's a processor-specific option. These are:
6312 * Cpu variants, the arm part is optional:
6313 * -m[arm]1 Currently not supported.
6314 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6315 * -m[arm]3 Arm 3 processor
6316 * -m[arm]6[xx], Arm 6 processors
6317 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6318 * -m[arm]8[10] Arm 8 processors
6319 * -m[arm]9[20][tdmi] Arm 9 processors
6320 * -mstrongarm[110[0]] StrongARM processors
6321 * -m[arm]v[2345] Arm architectures
6322 * -mall All (except the ARM1)
6324 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6325 * -mfpe-old (No float load/store multiples)
6326 * -mno-fpu Disable all floating point instructions
6327 * Run-time endian selection:
6328 * -EB big endian cpu
6329 * -EL little endian cpu
6330 * ARM Procedure Calling Standard:
6331 * -mapcs-32 32 bit APCS
6332 * -mapcs-26 26 bit APCS
6333 * -mapcs-float Pass floats in float regs
6334 * -mapcs-reentrant Position independent code
6335 * -mthumb-interwork Code supports Arm/Thumb interworking
6336 * -moabi Old ELF ABI
6339 CONST
char * md_shortopts
= "m:k";
6340 struct option md_longopts
[] =
6342 #ifdef ARM_BI_ENDIAN
6343 #define OPTION_EB (OPTION_MD_BASE + 0)
6344 {"EB", no_argument
, NULL
, OPTION_EB
},
6345 #define OPTION_EL (OPTION_MD_BASE + 1)
6346 {"EL", no_argument
, NULL
, OPTION_EL
},
6348 #define OPTION_OABI (OPTION_MD_BASE +2)
6349 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6352 {NULL
, no_argument
, NULL
, 0}
6354 size_t md_longopts_size
= sizeof (md_longopts
);
6357 md_parse_option (c
, arg
)
6365 #ifdef ARM_BI_ENDIAN
6367 target_big_endian
= 1;
6370 target_big_endian
= 0;
6378 if (streq (str
, "fpa10"))
6379 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6380 else if (streq (str
, "fpa11"))
6381 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6382 else if (streq (str
, "fpe-old"))
6383 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6389 if (streq (str
, "no-fpu"))
6390 cpu_variant
&= ~FPU_ALL
;
6395 if (streq (str
, "oabi"))
6401 /* Limit assembler to generating only Thumb instructions: */
6402 if (streq (str
, "thumb"))
6404 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6405 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6408 else if (streq (str
, "thumb-interwork"))
6410 if ((cpu_variant
& ARM_THUMB
) == 0)
6411 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6412 #if defined OBJ_COFF || defined OBJ_ELF
6413 support_interwork
= true;
6421 if (streq (str
, "all"))
6423 cpu_variant
= ARM_ALL
| FPU_ALL
;
6426 #if defined OBJ_COFF || defined OBJ_ELF
6427 if (! strncmp (str
, "apcs-", 5))
6429 /* GCC passes on all command line options starting "-mapcs-..."
6430 to us, so we must parse them here. */
6434 if (streq (str
, "32"))
6436 uses_apcs_26
= false;
6439 else if (streq (str
, "26"))
6441 uses_apcs_26
= true;
6444 else if (streq (str
, "frame"))
6446 /* Stack frames are being generated - does not affect
6450 else if (streq (str
, "stack-check"))
6452 /* Stack checking is being performed - does not affect
6453 linkage, but does require that the functions
6454 __rt_stkovf_split_small and __rt_stkovf_split_big be
6455 present in the final link. */
6459 else if (streq (str
, "float"))
6461 /* Floating point arguments are being passed in the floating
6462 point registers. This does affect linking, since this
6463 version of the APCS is incompatible with the version that
6464 passes floating points in the integer registers. */
6466 uses_apcs_float
= true;
6469 else if (streq (str
, "reentrant"))
6471 /* Reentrant code has been generated. This does affect
6472 linking, since there is no point in linking reentrant/
6473 position independent code with absolute position code. */
6478 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6482 /* Strip off optional "arm" */
6483 if (! strncmp (str
, "arm", 3))
6489 if (streq (str
, "1"))
6490 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6496 if (streq (str
, "2"))
6497 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6498 else if (streq (str
, "250"))
6499 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6505 if (streq (str
, "3"))
6506 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6512 switch (strtol (str
, NULL
, 10))
6519 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6527 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6540 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6546 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6550 cpu_variant
|= ARM_LONGMUL
;
6553 case 'f': /* fe => fp enabled cpu. */
6559 case 'c': /* Left over from 710c processor name. */
6560 case 'd': /* Debug */
6561 case 'i': /* Embedded ICE */
6562 /* Included for completeness in ARM processor naming. */
6572 if (streq (str
, "8") || streq (str
, "810"))
6573 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6579 if (streq (str
, "9"))
6580 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6581 else if (streq (str
, "920"))
6582 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6583 else if (streq (str
, "920t"))
6584 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6585 else if (streq (str
, "9tdmi"))
6586 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6593 if (streq (str
, "strongarm")
6594 || streq (str
, "strongarm110")
6595 || streq (str
, "strongarm1100"))
6596 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6602 /* Select variant based on architecture rather than processor */
6608 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6609 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6610 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6615 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6619 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6621 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6626 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6630 case 't': cpu_variant
|= ARM_THUMB
; break;
6632 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6637 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6640 case 't': cpu_variant
|= ARM_THUMB
; break;
6641 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
6643 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6648 as_bad (_("Invalid architecture variant -m%s"), arg
);
6655 as_bad (_("Invalid processor variant -m%s"), arg
);
6661 #if defined OBJ_ELF || defined OBJ_COFF
6680 ARM Specific Assembler Options:\n\
6681 -m[arm][<processor name>] select processor variant\n\
6682 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6683 -mthumb only allow Thumb instructions\n\
6684 -mthumb-interwork mark the assembled code as supporting interworking\n\
6685 -mall allow any instruction\n\
6686 -mfpa10, -mfpa11 select floating point architecture\n\
6687 -mfpe-old don't allow floating-point multiple instructions\n\
6688 -mno-fpu don't allow any floating-point instructions.\n"));
6691 -k generate PIC code.\n"));
6692 #if defined OBJ_COFF || defined OBJ_ELF
6695 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6698 -mapcs-float floating point args are passed in FP regs\n"));
6701 -mapcs-reentrant the code is position independent/reentrant\n"));
6706 -moabi support the old ELF ABI\n"));
6708 #ifdef ARM_BI_ENDIAN
6711 -EB assemble code for a big endian cpu\n\
6712 -EL assemble code for a little endian cpu\n"));
6716 /* We need to be able to fix up arbitrary expressions in some statements.
6717 This is so that we can handle symbols that are an arbitrary distance from
6718 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6719 which returns part of an address in a form which will be valid for
6720 a data instruction. We do this by pushing the expression into a symbol
6721 in the expr_section, and creating a fix for that. */
6724 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6733 arm_fix_data
* arm_data
;
6741 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6745 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6750 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6751 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6752 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6753 arm_data
->thumb_mode
= thumb_mode
;
6759 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6761 cons_fix_new_arm (frag
, where
, size
, exp
)
6767 bfd_reloc_code_real_type type
;
6772 * @@ Should look at CPU word size.
6777 type
= BFD_RELOC_16
;
6781 type
= BFD_RELOC_32
;
6784 type
= BFD_RELOC_64
;
6788 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6791 /* A good place to do this, although this was probably not intended
6792 for this kind of use. We need to dump the literal pool before
6793 references are made to a null symbol pointer. */
6797 if (current_poolP
== NULL
)
6800 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6802 listing_prev_line ();
6806 arm_start_line_hook ()
6808 last_label_seen
= NULL
;
6812 arm_frob_label (sym
)
6815 last_label_seen
= sym
;
6817 ARM_SET_THUMB (sym
, thumb_mode
);
6819 #if defined OBJ_COFF || defined OBJ_ELF
6820 ARM_SET_INTERWORK (sym
, support_interwork
);
6823 if (label_is_thumb_function_name
)
6825 /* When the address of a Thumb function is taken the bottom
6826 bit of that address should be set. This will allow
6827 interworking between Arm and Thumb functions to work
6830 THUMB_SET_FUNC (sym
, 1);
6832 label_is_thumb_function_name
= false;
6836 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6840 arm_adjust_symtab ()
6845 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6847 if (ARM_IS_THUMB (sym
))
6849 if (THUMB_IS_FUNC (sym
))
6851 /* Mark the symbol as a Thumb function. */
6852 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6853 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6854 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6856 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6857 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6859 as_bad (_("%s: unexpected function type: %d"),
6860 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6862 else switch (S_GET_STORAGE_CLASS (sym
))
6865 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6868 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6871 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6873 default: /* do nothing */
6878 if (ARM_IS_INTERWORK (sym
))
6879 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6884 elf_symbol_type
* elf_sym
;
6887 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6889 if (ARM_IS_THUMB (sym
))
6891 if (THUMB_IS_FUNC (sym
))
6893 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6894 bind
= ELF_ST_BIND (elf_sym
);
6895 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6905 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6907 *input_line_pointer
= '/';
6908 input_line_pointer
+= 5;
6909 *input_line_pointer
= 0;
6917 arm_canonicalize_symbol_name (name
)
6922 if (thumb_mode
&& (len
= strlen (name
)) > 5
6923 && streq (name
+ len
- 5, "/data"))
6924 *(name
+ len
- 5) = 0;
6930 arm_validate_fix (fixP
)
6933 /* If the destination of the branch is a defined symbol which does not have
6934 the THUMB_FUNC attribute, then we must be calling a function which has
6935 the (interfacearm) attribute. We look for the Thumb entry point to that
6936 function and change the branch to refer to that function instead. */
6937 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6938 && fixP
->fx_addsy
!= NULL
6939 && S_IS_DEFINED (fixP
->fx_addsy
)
6940 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6942 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6950 /* Relocations against Thumb function names must be left unadjusted,
6951 so that the linker can use this information to correctly set the
6952 bottom bit of their addresses. The MIPS version of this function
6953 also prevents relocations that are mips-16 specific, but I do not
6954 know why it does this.
6957 There is one other problem that ought to be addressed here, but
6958 which currently is not: Taking the address of a label (rather
6959 than a function) and then later jumping to that address. Such
6960 addresses also ought to have their bottom bit set (assuming that
6961 they reside in Thumb code), but at the moment they will not. */
6964 arm_fix_adjustable (fixP
)
6967 if (fixP
->fx_addsy
== NULL
)
6970 /* Prevent all adjustments to global symbols. */
6971 if (S_IS_EXTERN (fixP
->fx_addsy
))
6974 if (S_IS_WEAK (fixP
->fx_addsy
))
6977 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6978 && fixP
->fx_subsy
== NULL
)
6981 /* We need the symbol name for the VTABLE entries */
6982 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6983 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6990 elf32_arm_target_format ()
6992 if (target_big_endian
)
6994 return "elf32-bigarm-oabi";
6996 return "elf32-bigarm";
6999 return "elf32-littlearm-oabi";
7001 return "elf32-littlearm";
7005 armelf_frob_symbol (symp
, puntp
)
7009 elf_frob_symbol (symp
, puntp
);
7013 arm_force_relocation (fixp
)
7016 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7017 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7018 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7019 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7025 static bfd_reloc_code_real_type
7035 bfd_reloc_code_real_type reloc
;
7039 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7040 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7041 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7042 /* ScottB: Jan 30, 1998 */
7043 /* Added support for parsing "var(PLT)" branch instructions */
7044 /* generated by GCC for PLT relocs */
7045 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7046 { NULL
, 0, BFD_RELOC_UNUSED
}
7050 for (i
= 0, ip
= input_line_pointer
;
7051 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7053 id
[i
] = tolower (*ip
);
7055 for (i
= 0; reloc_map
[i
].str
; i
++)
7056 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7059 input_line_pointer
+= reloc_map
[i
].len
;
7061 return reloc_map
[i
].reloc
;
7065 s_arm_elf_cons (nbytes
)
7070 #ifdef md_flush_pending_output
7071 md_flush_pending_output ();
7074 if (is_it_end_of_statement ())
7076 demand_empty_rest_of_line ();
7080 #ifdef md_cons_align
7081 md_cons_align (nbytes
);
7086 bfd_reloc_code_real_type reloc
;
7090 if (exp
.X_op
== O_symbol
7091 && * input_line_pointer
== '('
7092 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7094 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7095 int size
= bfd_get_reloc_size (howto
);
7098 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7101 register char * p
= frag_more ((int) nbytes
);
7102 int offset
= nbytes
- size
;
7104 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7109 emit_expr (& exp
, (unsigned int) nbytes
);
7111 while (*input_line_pointer
++ == ',');
7113 input_line_pointer
--; /* Put terminator back into stream. */
7114 demand_empty_rest_of_line ();
7117 #endif /* OBJ_ELF */