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 */
56 /* Architectures are the sum of the base and extensions */
57 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
59 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
60 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
62 /* Some useful combinations: */
63 #define ARM_ANY 0x00ffffff
64 #define ARM_2UP (ARM_ANY - ARM_1)
65 #define ARM_ALL ARM_2UP /* Not arm1 only */
66 #define ARM_3UP 0x00fffffc
67 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
69 #define FPU_CORE 0x80000000
70 #define FPU_FPA10 0x40000000
71 #define FPU_FPA11 0x40000000
74 /* Some useful combinations */
75 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
76 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #define CPU_DEFAULT ARM_ALL
88 #define FPU_DEFAULT FPU_ALL
91 #define streq(a, b) (strcmp (a, b) == 0)
92 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
94 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
95 static int target_oabi
= 0;
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure */
99 static boolean uses_apcs_26
= false;
100 static boolean support_interwork
= false;
101 static boolean uses_apcs_float
= false;
102 static boolean pic_code
= false;
105 /* This array holds the chars that always start a comment. If the
106 pre-processor is disabled, these aren't very useful */
107 CONST
char comment_chars
[] = "@";
109 /* This array holds the chars that only start a comment at the beginning of
110 a line. If the line seems to have the form '# 123 filename'
111 .line and .file directives will appear in the pre-processed output */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113 first line of the input file. This is because the compiler outputs
114 #NO_APP at the beginning of its output. */
115 /* Also note that comments like this one will always work. */
116 CONST
char line_comment_chars
[] = "#";
119 CONST
char line_separator_chars
[] = ";";
121 CONST
char line_separator_chars
[] = "";
124 /* Chars that can be used to separate mant from exp in floating point nums */
125 CONST
char EXP_CHARS
[] = "eE";
127 /* Chars that mean this number is a floating point constant */
131 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
133 /* Prefix characters that indicate the start of an immediate
135 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
138 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
141 CONST
int md_reloc_size
= 8; /* Size of relocation record */
143 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
145 typedef struct arm_fix
153 unsigned long instruction
;
158 bfd_reloc_code_real_type type
;
168 CONST
char * template;
172 static CONST
struct asm_shift shift
[] =
188 #define NO_SHIFT_RESTRICT 1
189 #define SHIFT_RESTRICT 0
191 #define NUM_FLOAT_VALS 8
193 CONST
char * fp_const
[] =
195 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
198 /* Number of littlenums required to hold an extended precision number */
199 #define MAX_LITTLENUMS 6
201 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
211 #define CP_T_X 0x00008000
212 #define CP_T_Y 0x00400000
213 #define CP_T_Pre 0x01000000
214 #define CP_T_UD 0x00800000
215 #define CP_T_WB 0x00200000
217 #define CONDS_BIT (0x00100000)
218 #define LOAD_BIT (0x00100000)
219 #define TRANS_BIT (0x00200000)
223 CONST
char * template;
227 /* This is to save a hash look-up in the common case */
228 #define COND_ALWAYS 0xe0000000
230 static CONST
struct asm_cond conds
[] =
234 {"cs", 0x20000000}, {"hs", 0x20000000},
235 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
250 /* Warning: If the top bit of the set_bits is set, then the standard
251 instruction bitmask is ignored, and the new bitmask is taken from
255 CONST
char * template; /* Basic flag string */
256 unsigned long set_bits
; /* Bits to set */
259 static CONST
struct asm_flg s_flag
[] =
265 static CONST
struct asm_flg ldr_flags
[] =
269 {"bt", 0x00400000 | TRANS_BIT
},
276 static CONST
struct asm_flg str_flags
[] =
280 {"bt", 0x00400000 | TRANS_BIT
},
285 static CONST
struct asm_flg byte_flag
[] =
291 static CONST
struct asm_flg cmp_flags
[] =
298 static CONST
struct asm_flg ldm_flags
[] =
311 static CONST
struct asm_flg stm_flags
[] =
324 static CONST
struct asm_flg lfm_flags
[] =
331 static CONST
struct asm_flg sfm_flags
[] =
338 static CONST
struct asm_flg round_flags
[] =
346 /* The implementation of the FIX instruction is broken on some assemblers,
347 in that it accepts a precision specifier as well as a rounding specifier,
348 despite the fact that this is meaningless. To be more compatible, we
349 accept it as well, though of course it does not set any bits. */
350 static CONST
struct asm_flg fix_flags
[] =
367 static CONST
struct asm_flg except_flag
[] =
373 static CONST
struct asm_flg cplong_flag
[] =
381 CONST
char * template;
382 unsigned long number
;
385 #define PSR_FIELD_MASK 0x000f0000
387 #define PSR_FLAGS 0x00080000
388 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
389 #define PSR_ALL 0x00090000
398 static CONST
struct asm_psr psrs
[] =
402 {"cpsr_all", CPSR_ALL
},
404 {"spsr_all", SPSR_ALL
},
407 {"cpsr_flg", CPSR_FLG
},
408 {"spsr_flg", SPSR_FLG
},
411 {"cpsr_c", CPSR_CTL
},
412 {"cpsr_ctl", CPSR_CTL
},
413 {"spsr_c", SPSR_CTL
},
414 {"spsr_ctl", SPSR_CTL
}
417 /* Functions called by parser */
418 /* ARM instructions */
419 static void do_arit
PARAMS ((char *, unsigned long));
420 static void do_cmp
PARAMS ((char *, unsigned long));
421 static void do_mov
PARAMS ((char *, unsigned long));
422 static void do_ldst
PARAMS ((char *, unsigned long));
423 static void do_ldmstm
PARAMS ((char *, unsigned long));
424 static void do_branch
PARAMS ((char *, unsigned long));
425 static void do_swi
PARAMS ((char *, unsigned long));
426 /* Pseudo Op codes */
427 static void do_adr
PARAMS ((char *, unsigned long));
428 static void do_adrl
PARAMS ((char *, unsigned long));
429 static void do_nop
PARAMS ((char *, unsigned long));
431 static void do_mul
PARAMS ((char *, unsigned long));
432 static void do_mla
PARAMS ((char *, unsigned long));
434 static void do_swap
PARAMS ((char *, unsigned long));
436 static void do_msr
PARAMS ((char *, unsigned long));
437 static void do_mrs
PARAMS ((char *, unsigned long));
439 static void do_mull
PARAMS ((char *, unsigned long));
441 static void do_bx
PARAMS ((char *, unsigned long));
443 /* Coprocessor Instructions */
444 static void do_cdp
PARAMS ((char *, unsigned long));
445 static void do_lstc
PARAMS ((char *, unsigned long));
446 static void do_co_reg
PARAMS ((char *, unsigned long));
447 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
448 static void do_fp_ldst
PARAMS ((char *, unsigned long));
449 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
450 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
451 static void do_fp_monadic
PARAMS ((char *, unsigned long));
452 static void do_fp_cmp
PARAMS ((char *, unsigned long));
453 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
454 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
456 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
457 static int arm_reg_parse
PARAMS ((char **));
458 static int arm_psr_parse
PARAMS ((char **));
459 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
460 static int add_to_lit_pool
PARAMS ((void));
461 static unsigned validate_immediate
PARAMS ((unsigned));
462 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
463 static int validate_offset_imm
PARAMS ((unsigned int, int));
464 static void opcode_select
PARAMS ((int));
465 static void end_of_line
PARAMS ((char *));
466 static int reg_required_here
PARAMS ((char **, int));
467 static int psr_required_here
PARAMS ((char **, int, int));
468 static int co_proc_number
PARAMS ((char **));
469 static int cp_opc_expr
PARAMS ((char **, int, int));
470 static int cp_reg_required_here
PARAMS ((char **, int));
471 static int fp_reg_required_here
PARAMS ((char **, int));
472 static int cp_address_offset
PARAMS ((char **));
473 static int cp_address_required_here
PARAMS ((char **));
474 static int my_get_float_expression
PARAMS ((char **));
475 static int skip_past_comma
PARAMS ((char **));
476 static int walk_no_bignums
PARAMS ((symbolS
*));
477 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
478 static int data_op2
PARAMS ((char **));
479 static int fp_op2
PARAMS ((char **));
480 static long reg_list
PARAMS ((char **));
481 static void thumb_load_store
PARAMS ((char *, int, int));
482 static int decode_shift
PARAMS ((char **, int));
483 static int ldst_extend
PARAMS ((char **, int));
484 static void thumb_add_sub
PARAMS ((char *, int));
485 static void insert_reg
PARAMS ((int));
486 static void thumb_shift
PARAMS ((char *, int));
487 static void thumb_mov_compare
PARAMS ((char *, int));
488 static void set_constant_flonums
PARAMS ((void));
489 static valueT md_chars_to_number
PARAMS ((char *, int));
490 static void insert_reg_alias
PARAMS ((char *, int));
491 static void output_inst
PARAMS ((void));
493 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
496 /* ARM instructions take 4bytes in the object file, Thumb instructions
500 /* LONGEST_INST is the longest basic instruction name without conditions or
502 * ARM7M has 4 of length 5
505 #define LONGEST_INST 5
509 CONST
char * template; /* Basic string to match */
510 unsigned long value
; /* Basic instruction code */
511 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
512 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
513 unsigned long variants
; /* Which CPU variants this exists for */
514 /* Function to call to parse args */
515 void (* parms
) PARAMS ((char *, unsigned long));
518 static CONST
struct asm_opcode insns
[] =
520 /* ARM Instructions */
521 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
522 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
523 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
524 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
525 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
526 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
527 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
528 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
529 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
530 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
531 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
532 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
533 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
534 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
535 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
536 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
537 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
538 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
539 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
540 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
541 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
542 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
543 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
546 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
547 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
548 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
550 /* ARM 2 multiplies */
551 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
552 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
554 /* ARM 3 - swp instructions */
555 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
557 /* ARM 6 Coprocessor instructions */
558 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
559 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
560 /* ScottB: our code uses 0x0128f000 for msr.
561 NickC: but this is wrong because the bits 16 and 19 are handled
562 by the PSR_xxx defines above. */
564 /* ARM 7M long multiplies - need signed/unsigned flags! */
565 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
566 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
567 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
568 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
570 /* ARM THUMB interworking */
571 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
573 /* Floating point instructions */
574 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
575 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
576 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
577 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
578 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
579 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
580 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
581 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
582 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
583 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
584 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
585 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
586 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
587 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
588 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
589 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
590 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
595 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
596 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
597 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
598 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
599 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
600 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
601 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
602 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
603 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
604 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
605 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
606 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
607 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
608 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
609 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
610 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
611 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
612 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
613 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
614 be an optional suffix, but part of the instruction. To be compatible,
616 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
617 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
618 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
619 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
621 /* Generic copressor instructions */
622 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
623 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
624 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
625 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
626 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
629 /* defines for various bits that we will want to toggle */
631 #define INST_IMMEDIATE 0x02000000
632 #define OFFSET_REG 0x02000000
633 #define HWOFFSET_IMM 0x00400000
634 #define SHIFT_BY_REG 0x00000010
635 #define PRE_INDEX 0x01000000
636 #define INDEX_UP 0x00800000
637 #define WRITE_BACK 0x00200000
638 #define LDM_TYPE_2_OR_3 0x00400000
640 #define LITERAL_MASK 0xf000f000
641 #define COND_MASK 0xf0000000
642 #define OPCODE_MASK 0xfe1fffff
643 #define DATA_OP_SHIFT 21
645 /* Codes to distinguish the arithmetic instructions */
657 #define OPCODE_CMP 10
658 #define OPCODE_CMN 11
659 #define OPCODE_ORR 12
660 #define OPCODE_MOV 13
661 #define OPCODE_BIC 14
662 #define OPCODE_MVN 15
664 static void do_t_nop
PARAMS ((char *));
665 static void do_t_arit
PARAMS ((char *));
666 static void do_t_add
PARAMS ((char *));
667 static void do_t_asr
PARAMS ((char *));
668 static void do_t_branch9
PARAMS ((char *));
669 static void do_t_branch12
PARAMS ((char *));
670 static void do_t_branch23
PARAMS ((char *));
671 static void do_t_bx
PARAMS ((char *));
672 static void do_t_compare
PARAMS ((char *));
673 static void do_t_ldmstm
PARAMS ((char *));
674 static void do_t_ldr
PARAMS ((char *));
675 static void do_t_ldrb
PARAMS ((char *));
676 static void do_t_ldrh
PARAMS ((char *));
677 static void do_t_lds
PARAMS ((char *));
678 static void do_t_lsl
PARAMS ((char *));
679 static void do_t_lsr
PARAMS ((char *));
680 static void do_t_mov
PARAMS ((char *));
681 static void do_t_push_pop
PARAMS ((char *));
682 static void do_t_str
PARAMS ((char *));
683 static void do_t_strb
PARAMS ((char *));
684 static void do_t_strh
PARAMS ((char *));
685 static void do_t_sub
PARAMS ((char *));
686 static void do_t_swi
PARAMS ((char *));
687 static void do_t_adr
PARAMS ((char *));
689 #define T_OPCODE_MUL 0x4340
690 #define T_OPCODE_TST 0x4200
691 #define T_OPCODE_CMN 0x42c0
692 #define T_OPCODE_NEG 0x4240
693 #define T_OPCODE_MVN 0x43c0
695 #define T_OPCODE_ADD_R3 0x1800
696 #define T_OPCODE_SUB_R3 0x1a00
697 #define T_OPCODE_ADD_HI 0x4400
698 #define T_OPCODE_ADD_ST 0xb000
699 #define T_OPCODE_SUB_ST 0xb080
700 #define T_OPCODE_ADD_SP 0xa800
701 #define T_OPCODE_ADD_PC 0xa000
702 #define T_OPCODE_ADD_I8 0x3000
703 #define T_OPCODE_SUB_I8 0x3800
704 #define T_OPCODE_ADD_I3 0x1c00
705 #define T_OPCODE_SUB_I3 0x1e00
707 #define T_OPCODE_ASR_R 0x4100
708 #define T_OPCODE_LSL_R 0x4080
709 #define T_OPCODE_LSR_R 0x40c0
710 #define T_OPCODE_ASR_I 0x1000
711 #define T_OPCODE_LSL_I 0x0000
712 #define T_OPCODE_LSR_I 0x0800
714 #define T_OPCODE_MOV_I8 0x2000
715 #define T_OPCODE_CMP_I8 0x2800
716 #define T_OPCODE_CMP_LR 0x4280
717 #define T_OPCODE_MOV_HR 0x4600
718 #define T_OPCODE_CMP_HR 0x4500
720 #define T_OPCODE_LDR_PC 0x4800
721 #define T_OPCODE_LDR_SP 0x9800
722 #define T_OPCODE_STR_SP 0x9000
723 #define T_OPCODE_LDR_IW 0x6800
724 #define T_OPCODE_STR_IW 0x6000
725 #define T_OPCODE_LDR_IH 0x8800
726 #define T_OPCODE_STR_IH 0x8000
727 #define T_OPCODE_LDR_IB 0x7800
728 #define T_OPCODE_STR_IB 0x7000
729 #define T_OPCODE_LDR_RW 0x5800
730 #define T_OPCODE_STR_RW 0x5000
731 #define T_OPCODE_LDR_RH 0x5a00
732 #define T_OPCODE_STR_RH 0x5200
733 #define T_OPCODE_LDR_RB 0x5c00
734 #define T_OPCODE_STR_RB 0x5400
736 #define T_OPCODE_PUSH 0xb400
737 #define T_OPCODE_POP 0xbc00
739 #define T_OPCODE_BRANCH 0xe7fe
741 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
743 #define THUMB_SIZE 2 /* Size of thumb instruction */
744 #define THUMB_REG_LO 0x1
745 #define THUMB_REG_HI 0x2
746 #define THUMB_REG_ANY 0x3
748 #define THUMB_H1 0x0080
749 #define THUMB_H2 0x0040
756 #define THUMB_COMPARE 1
759 #define THUMB_STORE 1
761 #define THUMB_PP_PC_LR 0x0100
763 /* These three are used for immediate shifts, do not alter */
765 #define THUMB_HALFWORD 1
770 CONST
char * template; /* Basic string to match */
771 unsigned long value
; /* Basic instruction code */
773 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
776 static CONST
struct thumb_opcode tinsns
[] =
778 {"adc", 0x4140, 2, do_t_arit
},
779 {"add", 0x0000, 2, do_t_add
},
780 {"and", 0x4000, 2, do_t_arit
},
781 {"asr", 0x0000, 2, do_t_asr
},
782 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
783 {"beq", 0xd0fe, 2, do_t_branch9
},
784 {"bne", 0xd1fe, 2, do_t_branch9
},
785 {"bcs", 0xd2fe, 2, do_t_branch9
},
786 {"bhs", 0xd2fe, 2, do_t_branch9
},
787 {"bcc", 0xd3fe, 2, do_t_branch9
},
788 {"bul", 0xd3fe, 2, do_t_branch9
},
789 {"blo", 0xd3fe, 2, do_t_branch9
},
790 {"bmi", 0xd4fe, 2, do_t_branch9
},
791 {"bpl", 0xd5fe, 2, do_t_branch9
},
792 {"bvs", 0xd6fe, 2, do_t_branch9
},
793 {"bvc", 0xd7fe, 2, do_t_branch9
},
794 {"bhi", 0xd8fe, 2, do_t_branch9
},
795 {"bls", 0xd9fe, 2, do_t_branch9
},
796 {"bge", 0xdafe, 2, do_t_branch9
},
797 {"blt", 0xdbfe, 2, do_t_branch9
},
798 {"bgt", 0xdcfe, 2, do_t_branch9
},
799 {"ble", 0xddfe, 2, do_t_branch9
},
800 {"bic", 0x4380, 2, do_t_arit
},
801 {"bl", 0xf7fffffe, 4, do_t_branch23
},
802 {"bx", 0x4700, 2, do_t_bx
},
803 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
804 {"cmp", 0x0000, 2, do_t_compare
},
805 {"eor", 0x4040, 2, do_t_arit
},
806 {"ldmia", 0xc800, 2, do_t_ldmstm
},
807 {"ldr", 0x0000, 2, do_t_ldr
},
808 {"ldrb", 0x0000, 2, do_t_ldrb
},
809 {"ldrh", 0x0000, 2, do_t_ldrh
},
810 {"ldrsb", 0x5600, 2, do_t_lds
},
811 {"ldrsh", 0x5e00, 2, do_t_lds
},
812 {"ldsb", 0x5600, 2, do_t_lds
},
813 {"ldsh", 0x5e00, 2, do_t_lds
},
814 {"lsl", 0x0000, 2, do_t_lsl
},
815 {"lsr", 0x0000, 2, do_t_lsr
},
816 {"mov", 0x0000, 2, do_t_mov
},
817 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
818 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
819 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
820 {"orr", 0x4300, 2, do_t_arit
},
821 {"pop", 0xbc00, 2, do_t_push_pop
},
822 {"push", 0xb400, 2, do_t_push_pop
},
823 {"ror", 0x41c0, 2, do_t_arit
},
824 {"sbc", 0x4180, 2, do_t_arit
},
825 {"stmia", 0xc000, 2, do_t_ldmstm
},
826 {"str", 0x0000, 2, do_t_str
},
827 {"strb", 0x0000, 2, do_t_strb
},
828 {"strh", 0x0000, 2, do_t_strh
},
829 {"swi", 0xdf00, 2, do_t_swi
},
830 {"sub", 0x0000, 2, do_t_sub
},
831 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
833 {"adr", 0x0000, 2, do_t_adr
},
834 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
843 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
844 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
845 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
851 /* These are the standard names; Users can add aliases with .req */
852 static CONST
struct reg_entry reg_table
[] =
854 /* Processor Register Numbers */
855 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
856 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
857 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
858 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
859 /* APCS conventions */
860 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
861 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
862 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
863 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
865 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
866 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
867 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
868 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
869 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
870 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
871 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
872 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
873 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
874 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
878 #define bad_args _("Bad arguments to instruction");
879 #define bad_pc _("r15 not allowed here");
881 static struct hash_control
* arm_ops_hsh
= NULL
;
882 static struct hash_control
* arm_tops_hsh
= NULL
;
883 static struct hash_control
* arm_cond_hsh
= NULL
;
884 static struct hash_control
* arm_shift_hsh
= NULL
;
885 static struct hash_control
* arm_reg_hsh
= NULL
;
886 static struct hash_control
* arm_psr_hsh
= NULL
;
888 /* This table describes all the machine specific pseudo-ops the assembler
889 has to support. The fields are:
890 pseudo-op name without dot
891 function to call to execute this pseudo-op
892 Integer arg to pass to the function
895 static void s_req
PARAMS ((int));
896 static void s_align
PARAMS ((int));
897 static void s_bss
PARAMS ((int));
898 static void s_even
PARAMS ((int));
899 static void s_ltorg
PARAMS ((int));
900 static void s_arm
PARAMS ((int));
901 static void s_thumb
PARAMS ((int));
902 static void s_code
PARAMS ((int));
903 static void s_force_thumb
PARAMS ((int));
904 static void s_thumb_func
PARAMS ((int));
905 static void s_thumb_set
PARAMS ((int));
906 static void arm_s_text
PARAMS ((int));
907 static void arm_s_data
PARAMS ((int));
909 static void arm_s_section
PARAMS ((int));
910 static void s_arm_elf_cons
PARAMS ((int));
913 static int my_get_expression
PARAMS ((expressionS
*, char **));
915 CONST pseudo_typeS md_pseudo_table
[] =
917 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
919 { "align", s_align
, 0 },
921 { "thumb", s_thumb
, 0 },
922 { "code", s_code
, 0 },
923 { "force_thumb", s_force_thumb
, 0 },
924 { "thumb_func", s_thumb_func
, 0 },
925 { "thumb_set", s_thumb_set
, 0 },
926 { "even", s_even
, 0 },
927 { "ltorg", s_ltorg
, 0 },
928 { "pool", s_ltorg
, 0 },
929 /* Allow for the effect of section changes. */
930 { "text", arm_s_text
, 0 },
931 { "data", arm_s_data
, 0 },
933 { "section", arm_s_section
, 0 },
934 { "section.s", arm_s_section
, 0 },
935 { "sect", arm_s_section
, 0 },
936 { "sect.s", arm_s_section
, 0 },
937 { "word", s_arm_elf_cons
, 4 },
938 { "long", s_arm_elf_cons
, 4 },
942 { "extend", float_cons
, 'x' },
943 { "ldouble", float_cons
, 'x' },
944 { "packed", float_cons
, 'p' },
948 /* Stuff needed to resolve the label ambiguity
958 symbolS
* last_label_seen
;
959 static int label_is_thumb_function_name
= false;
963 #define MAX_LITERAL_POOL_SIZE 1024
965 typedef struct literalS
967 struct expressionS exp
;
968 struct arm_it
* inst
;
971 literalT literals
[MAX_LITERAL_POOL_SIZE
];
972 int next_literal_pool_place
= 0; /* Next free entry in the pool */
973 int lit_pool_num
= 1; /* Next literal pool number */
974 symbolS
* current_poolP
= NULL
;
981 if (current_poolP
== NULL
)
982 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
983 (valueT
) 0, &zero_address_frag
);
985 /* Check if this literal value is already in the pool: */
986 while (lit_count
< next_literal_pool_place
)
988 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
989 && inst
.reloc
.exp
.X_op
== O_constant
990 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
991 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
996 if (lit_count
== next_literal_pool_place
) /* new entry */
998 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1000 inst
.error
= _("Literal Pool Overflow");
1004 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1005 lit_count
= next_literal_pool_place
++;
1008 inst
.reloc
.exp
.X_op
= O_symbol
;
1009 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1010 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1015 /* Can't use symbol_new here, so have to create a symbol and then at
1016 a later date assign it a value. Thats what these functions do. */
1018 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1020 CONST
char * name
; /* It is copied, the caller can modify */
1021 segT segment
; /* Segment identifier (SEG_<something>) */
1022 valueT valu
; /* Symbol value */
1023 fragS
* frag
; /* Associated fragment */
1025 unsigned int name_length
;
1026 char * preserved_copy_of_name
;
1028 name_length
= strlen (name
) + 1; /* +1 for \0 */
1029 obstack_grow (¬es
, name
, name_length
);
1030 preserved_copy_of_name
= obstack_finish (¬es
);
1031 #ifdef STRIP_UNDERSCORE
1032 if (preserved_copy_of_name
[0] == '_')
1033 preserved_copy_of_name
++;
1036 #ifdef tc_canonicalize_symbol_name
1037 preserved_copy_of_name
=
1038 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1041 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1043 S_SET_SEGMENT (symbolP
, segment
);
1044 S_SET_VALUE (symbolP
, valu
);
1045 symbol_clear_list_pointers(symbolP
);
1047 symbol_set_frag (symbolP
, frag
);
1049 /* Link to end of symbol chain. */
1051 extern int symbol_table_frozen
;
1052 if (symbol_table_frozen
)
1056 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1058 obj_symbol_new_hook (symbolP
);
1060 #ifdef tc_symbol_new_hook
1061 tc_symbol_new_hook (symbolP
);
1065 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1066 #endif /* DEBUG_SYMS */
1069 /* Check that an immediate is valid, and if so, convert it to the right format. */
1072 validate_immediate (val
)
1078 #define rotate_left(v, n) (v << n | v >> (32 - n))
1080 for (i
= 0; i
< 32; i
+= 2)
1081 if ((a
= rotate_left (val
, i
)) <= 0xff)
1082 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1087 /* Check to see if an immediate can be computed as two seperate immediate
1088 values, added together. We already know that this value cannot be
1089 computed by just one ARM instruction. */
1092 validate_immediate_twopart (val
, highpart
)
1094 unsigned int * highpart
;
1099 for (i
= 0; i
< 32; i
+= 2)
1100 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1106 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1108 else if (a
& 0xff0000)
1113 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1117 assert (a
& 0xff000000);
1119 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1122 return (a
& 0xff) | (i
<< 7);
1129 validate_offset_imm (val
, hwse
)
1133 if ((hwse
&& val
> 255) || val
> 4095)
1143 as_bad (_("Invalid syntax for .req directive."));
1150 /* We don't support putting frags in the BSS segment, we fake it by
1151 marking in_bss, then looking at s_skip for clues?.. */
1152 subseg_set (bss_section
, 0);
1153 demand_empty_rest_of_line ();
1160 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1161 frag_align (1, 0, 0);
1163 record_alignment (now_seg
, 1);
1165 demand_empty_rest_of_line ();
1175 if (current_poolP
== NULL
)
1178 /* Align pool as you have word accesses */
1179 /* Only make a frag if we have to ... */
1181 frag_align (2, 0, 0);
1183 record_alignment (now_seg
, 2);
1185 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1187 symbol_locate (current_poolP
, sym_name
, now_seg
,
1188 (valueT
) frag_now_fix (), frag_now
);
1189 symbol_table_insert (current_poolP
);
1191 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1193 #if defined OBJ_COFF || defined OBJ_ELF
1194 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1197 while (lit_count
< next_literal_pool_place
)
1198 /* First output the expression in the instruction to the pool */
1199 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1201 next_literal_pool_place
= 0;
1202 current_poolP
= NULL
;
1206 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1210 register long temp_fill
;
1211 long max_alignment
= 15;
1213 temp
= get_absolute_expression ();
1214 if (temp
> max_alignment
)
1215 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1218 as_bad (_("Alignment negative. 0 assumed."));
1222 if (*input_line_pointer
== ',')
1224 input_line_pointer
++;
1225 temp_fill
= get_absolute_expression ();
1233 /* Only make a frag if we HAVE to. . . */
1234 if (temp
&& !need_pass_2
)
1235 frag_align (temp
, (int) temp_fill
, 0);
1236 demand_empty_rest_of_line ();
1238 record_alignment (now_seg
, temp
);
1242 s_force_thumb (ignore
)
1245 /* If we are not already in thumb mode go into it, EVEN if
1246 the target processor does not support thumb instructions.
1247 This is used by gcc/config/arm/lib1funcs.asm for example
1248 to compile interworking support functions even if the
1249 target processor should not support interworking. */
1255 record_alignment (now_seg
, 1);
1258 demand_empty_rest_of_line ();
1262 s_thumb_func (ignore
)
1265 /* The following label is the name/address of the start of a Thumb function.
1266 We need to know this for the interworking support. */
1268 label_is_thumb_function_name
= true;
1270 demand_empty_rest_of_line ();
1273 /* Perform a .set directive, but also mark the alias as
1274 being a thumb function. */
1280 /* XXX the following is a duplicate of the code for s_set() in read.c
1281 We cannot just call that code as we need to get at the symbol that
1283 register char * name
;
1284 register char delim
;
1285 register char * end_name
;
1286 register symbolS
* symbolP
;
1289 * Especial apologies for the random logic:
1290 * this just grew, and could be parsed much more simply!
1293 name
= input_line_pointer
;
1294 delim
= get_symbol_end ();
1295 end_name
= input_line_pointer
;
1300 if (*input_line_pointer
!= ',')
1303 as_bad (_("Expected comma after name \"%s\""), name
);
1305 ignore_rest_of_line ();
1309 input_line_pointer
++;
1312 if (name
[0] == '.' && name
[1] == '\0')
1314 /* XXX - this should not happen to .thumb_set */
1318 if ((symbolP
= symbol_find (name
)) == NULL
1319 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1322 /* When doing symbol listings, play games with dummy fragments living
1323 outside the normal fragment chain to record the file and line info
1325 if (listing
& LISTING_SYMBOLS
)
1327 extern struct list_info_struct
* listing_tail
;
1328 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1329 memset (dummy_frag
, 0, sizeof(fragS
));
1330 dummy_frag
->fr_type
= rs_fill
;
1331 dummy_frag
->line
= listing_tail
;
1332 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1333 dummy_frag
->fr_symbol
= symbolP
;
1337 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1340 /* "set" symbols are local unless otherwise specified. */
1341 SF_SET_LOCAL (symbolP
);
1342 #endif /* OBJ_COFF */
1343 } /* make a new symbol */
1345 symbol_table_insert (symbolP
);
1350 && S_IS_DEFINED (symbolP
)
1351 && S_GET_SEGMENT (symbolP
) != reg_section
)
1352 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1354 pseudo_set (symbolP
);
1356 demand_empty_rest_of_line ();
1358 /* XXX Now we come to the Thumb specific bit of code. */
1360 THUMB_SET_FUNC (symbolP
, 1);
1361 ARM_SET_THUMB (symbolP
, 1);
1362 #if defined OBJ_COFF || defined OBJ_ELF
1363 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1367 /* If we change section we must dump the literal pool first. */
1372 if (now_seg
!= text_section
)
1382 if (flag_readonly_data_in_text
)
1384 if (now_seg
!= text_section
)
1387 else if (now_seg
!= data_section
)
1395 arm_s_section (ignore
)
1400 obj_elf_section (ignore
);
1405 opcode_select (width
)
1413 if (! (cpu_variant
& ARM_THUMB
))
1414 as_bad (_("selected processor does not support THUMB opcodes"));
1416 /* No need to force the alignment, since we will have been
1417 coming from ARM mode, which is word-aligned. */
1418 record_alignment (now_seg
, 1);
1425 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1426 as_bad (_("selected processor does not support ARM opcodes"));
1429 frag_align (2, 0, 0);
1430 record_alignment (now_seg
, 1);
1435 as_bad (_("invalid instruction size selected (%d)"), width
);
1444 demand_empty_rest_of_line ();
1452 demand_empty_rest_of_line ();
1461 temp
= get_absolute_expression ();
1466 opcode_select (temp
);
1470 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1478 skip_whitespace (str
);
1481 inst
.error
= _("Garbage following instruction");
1485 skip_past_comma (str
)
1491 while ((c
= *p
) == ' ' || c
== ',')
1494 if (c
== ',' && comma
++)
1502 return comma
? SUCCESS
: FAIL
;
1505 /* A standard register must be given at this point. Shift is the place to
1506 put it in the instruction. */
1509 reg_required_here (str
, shift
)
1513 static char buff
[128]; /* XXX */
1515 char * start
= *str
;
1517 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1520 inst
.instruction
|= reg
<< shift
;
1524 /* Restore the start point, we may have got a reg of the wrong class. */
1527 /* In the few cases where we might be able to accept something else
1528 this error can be overridden. */
1529 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1536 psr_required_here (str
, cpsr
, spsr
)
1542 char * start
= *str
;
1543 psr
= arm_psr_parse (str
);
1545 if (psr
== cpsr
|| psr
== spsr
)
1548 inst
.instruction
|= 1 << 22;
1553 /* In the few cases where we might be able to accept something else
1554 this error can be overridden. */
1555 inst
.error
= _("<psr(f)> expected");
1557 /* Restore the start point. */
1563 co_proc_number (str
)
1566 int processor
, pchar
;
1568 skip_whitespace (* str
);
1570 /* The data sheet seems to imply that just a number on its own is valid
1571 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1573 if (**str
== 'p' || **str
== 'P')
1577 if (pchar
>= '0' && pchar
<= '9')
1579 processor
= pchar
- '0';
1580 if (**str
>= '0' && **str
<= '9')
1582 processor
= processor
* 10 + *(*str
)++ - '0';
1585 inst
.error
= _("Illegal co-processor number");
1592 inst
.error
= _("Bad or missing co-processor number");
1596 inst
.instruction
|= processor
<< 8;
1601 cp_opc_expr (str
, where
, length
)
1608 skip_whitespace (* str
);
1610 memset (&expr
, '\0', sizeof (expr
));
1612 if (my_get_expression (&expr
, str
))
1614 if (expr
.X_op
!= O_constant
)
1616 inst
.error
= _("bad or missing expression");
1620 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1622 inst
.error
= _("immediate co-processor expression too large");
1626 inst
.instruction
|= expr
.X_add_number
<< where
;
1631 cp_reg_required_here (str
, where
)
1636 char * start
= *str
;
1638 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1641 inst
.instruction
|= reg
<< where
;
1645 /* In the few cases where we might be able to accept something else
1646 this error can be overridden. */
1647 inst
.error
= _("Co-processor register expected");
1649 /* Restore the start point. */
1655 fp_reg_required_here (str
, where
)
1660 char * start
= *str
;
1662 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1665 inst
.instruction
|= reg
<< where
;
1669 /* In the few cases where we might be able to accept something else
1670 this error can be overridden. */
1671 inst
.error
= _("Floating point register expected");
1673 /* Restore the start point. */
1679 cp_address_offset (str
)
1684 skip_whitespace (* str
);
1686 if (! is_immediate_prefix (**str
))
1688 inst
.error
= _("immediate expression expected");
1694 if (my_get_expression (& inst
.reloc
.exp
, str
))
1697 if (inst
.reloc
.exp
.X_op
== O_constant
)
1699 offset
= inst
.reloc
.exp
.X_add_number
;
1703 inst
.error
= _("co-processor address must be word aligned");
1707 if (offset
> 1023 || offset
< -1023)
1709 inst
.error
= _("offset too large");
1714 inst
.instruction
|= INDEX_UP
;
1718 inst
.instruction
|= offset
>> 2;
1721 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1727 cp_address_required_here (str
)
1739 skip_whitespace (p
);
1741 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1744 skip_whitespace (p
);
1750 if (skip_past_comma (& p
) == SUCCESS
)
1753 write_back
= WRITE_BACK
;
1757 inst
.error
= _("pc may not be used in post-increment");
1761 if (cp_address_offset (& p
) == FAIL
)
1765 pre_inc
= PRE_INDEX
| INDEX_UP
;
1769 /* '['Rn, #expr']'[!] */
1771 if (skip_past_comma (& p
) == FAIL
)
1773 inst
.error
= _("pre-indexed expression expected");
1777 pre_inc
= PRE_INDEX
;
1779 if (cp_address_offset (& p
) == FAIL
)
1782 skip_whitespace (p
);
1786 inst
.error
= _("missing ]");
1790 skip_whitespace (p
);
1796 inst
.error
= _("pc may not be used with write-back");
1801 write_back
= WRITE_BACK
;
1807 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1810 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1811 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1812 inst
.reloc
.pc_rel
= 1;
1813 inst
.instruction
|= (REG_PC
<< 16);
1814 pre_inc
= PRE_INDEX
;
1817 inst
.instruction
|= write_back
| pre_inc
;
1825 unsigned long flags
;
1827 /* Do nothing really. */
1828 inst
.instruction
|= flags
; /* This is pointless. */
1836 unsigned long flags
;
1838 /* Only one syntax. */
1839 skip_whitespace (str
);
1841 if (reg_required_here (&str
, 12) == FAIL
)
1843 inst
.error
= bad_args
;
1847 if (skip_past_comma (&str
) == FAIL
1848 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1850 inst
.error
= _("<psr> expected");
1854 inst
.instruction
|= flags
;
1859 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1863 unsigned long flags
;
1867 skip_whitespace (str
);
1869 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1871 inst
.instruction
|= PSR_ALL
;
1873 /* Sytax should be "<psr>, Rm" */
1874 if (skip_past_comma (&str
) == FAIL
1875 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1877 inst
.error
= bad_args
;
1883 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1884 inst
.instruction
|= PSR_FLAGS
;
1885 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1886 inst
.instruction
|= PSR_CONTROL
;
1889 inst
.error
= bad_args
;
1893 if (skip_past_comma (&str
) == FAIL
)
1895 inst
.error
= bad_args
;
1899 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1901 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1903 /* Immediate expression. */
1904 else if (is_immediate_prefix (* str
))
1909 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1911 inst
.error
= _("Register or shift expression expected");
1915 if (inst
.reloc
.exp
.X_add_symbol
)
1917 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1918 inst
.reloc
.pc_rel
= 0;
1922 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1925 inst
.error
= _("Invalid constant");
1929 inst
.instruction
|= value
;
1932 flags
|= INST_IMMEDIATE
;
1936 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1942 inst
.instruction
|= flags
;
1947 /* Long Multiply Parser
1948 UMULL RdLo, RdHi, Rm, Rs
1949 SMULL RdLo, RdHi, Rm, Rs
1950 UMLAL RdLo, RdHi, Rm, Rs
1951 SMLAL RdLo, RdHi, Rm, Rs
1954 do_mull (str
, flags
)
1956 unsigned long flags
;
1958 int rdlo
, rdhi
, rm
, rs
;
1960 /* Only one format "rdlo, rdhi, rm, rs" */
1961 skip_whitespace (str
);
1963 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1965 inst
.error
= bad_args
;
1969 if (skip_past_comma (&str
) == FAIL
1970 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1972 inst
.error
= bad_args
;
1976 if (skip_past_comma (&str
) == FAIL
1977 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1979 inst
.error
= bad_args
;
1983 /* rdhi, rdlo and rm must all be different */
1984 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1985 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1987 if (skip_past_comma (&str
) == FAIL
1988 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1990 inst
.error
= bad_args
;
1994 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1996 inst
.error
= bad_pc
;
2000 inst
.instruction
|= flags
;
2008 unsigned long flags
;
2012 /* Only one format "rd, rm, rs" */
2013 skip_whitespace (str
);
2015 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2017 inst
.error
= bad_args
;
2023 inst
.error
= bad_pc
;
2027 if (skip_past_comma (&str
) == FAIL
2028 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2030 inst
.error
= bad_args
;
2036 inst
.error
= bad_pc
;
2041 as_tsktsk (_("rd and rm should be different in mul"));
2043 if (skip_past_comma (&str
) == FAIL
2044 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2046 inst
.error
= bad_args
;
2052 inst
.error
= bad_pc
;
2056 inst
.instruction
|= flags
;
2064 unsigned long flags
;
2068 /* Only one format "rd, rm, rs, rn" */
2069 skip_whitespace (str
);
2071 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2073 inst
.error
= bad_args
;
2079 inst
.error
= bad_pc
;
2083 if (skip_past_comma (&str
) == FAIL
2084 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2086 inst
.error
= bad_args
;
2092 inst
.error
= bad_pc
;
2097 as_tsktsk (_("rd and rm should be different in mla"));
2099 if (skip_past_comma (&str
) == FAIL
2100 || (rd
= reg_required_here (&str
, 8)) == FAIL
2101 || skip_past_comma (&str
) == FAIL
2102 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2104 inst
.error
= bad_args
;
2108 if (rd
== REG_PC
|| rm
== REG_PC
)
2110 inst
.error
= bad_pc
;
2114 inst
.instruction
|= flags
;
2119 /* Returns the index into fp_values of a floating point number, or -1 if
2120 not in the table. */
2122 my_get_float_expression (str
)
2125 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2131 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2132 /* Look for a raw floating point number */
2133 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2134 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2136 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2138 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2140 if (words
[j
] != fp_values
[i
][j
])
2144 if (j
== MAX_LITTLENUMS
)
2152 /* Try and parse a more complex expression, this will probably fail
2153 unless the code uses a floating point prefix (eg "0f") */
2154 save_in
= input_line_pointer
;
2155 input_line_pointer
= *str
;
2156 if (expression (&exp
) == absolute_section
2157 && exp
.X_op
== O_big
2158 && exp
.X_add_number
< 0)
2160 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2162 if (gen_to_words (words
, 5, (long)15) == 0)
2164 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2166 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2168 if (words
[j
] != fp_values
[i
][j
])
2172 if (j
== MAX_LITTLENUMS
)
2174 *str
= input_line_pointer
;
2175 input_line_pointer
= save_in
;
2182 *str
= input_line_pointer
;
2183 input_line_pointer
= save_in
;
2187 /* Return true if anything in the expression is a bignum */
2189 walk_no_bignums (sp
)
2192 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2195 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2197 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2198 || (symbol_get_value_expression (sp
)->X_op_symbol
2199 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2206 my_get_expression (ep
, str
)
2213 save_in
= input_line_pointer
;
2214 input_line_pointer
= *str
;
2215 seg
= expression (ep
);
2218 if (seg
!= absolute_section
2219 && seg
!= text_section
2220 && seg
!= data_section
2221 && seg
!= bss_section
2222 && seg
!= undefined_section
)
2224 inst
.error
= _("bad_segment");
2225 *str
= input_line_pointer
;
2226 input_line_pointer
= save_in
;
2231 /* Get rid of any bignums now, so that we don't generate an error for which
2232 we can't establish a line number later on. Big numbers are never valid
2233 in instructions, which is where this routine is always called. */
2234 if (ep
->X_op
== O_big
2235 || (ep
->X_add_symbol
2236 && (walk_no_bignums (ep
->X_add_symbol
)
2238 && walk_no_bignums (ep
->X_op_symbol
)))))
2240 inst
.error
= _("Invalid constant");
2241 *str
= input_line_pointer
;
2242 input_line_pointer
= save_in
;
2246 *str
= input_line_pointer
;
2247 input_line_pointer
= save_in
;
2251 /* unrestrict should be one if <shift> <register> is permitted for this
2255 decode_shift (str
, unrestrict
)
2259 struct asm_shift
* shft
;
2263 skip_whitespace (* str
);
2265 for (p
= *str
; isalpha (*p
); p
++)
2270 inst
.error
= _("Shift expression expected");
2276 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2280 if (!strncmp (*str
, "rrx", 3)
2281 || !strncmp (*str
, "RRX", 3))
2284 inst
.instruction
|= shft
->value
;
2288 skip_whitespace (p
);
2290 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2292 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2296 else if (is_immediate_prefix (* p
))
2300 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2303 /* Validate some simple #expressions */
2304 if (inst
.reloc
.exp
.X_op
== O_constant
)
2306 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2308 /* Reject operations greater than 32, or lsl #32 */
2309 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2311 inst
.error
= _("Invalid immediate shift");
2315 /* Shifts of zero should be converted to lsl (which is zero)*/
2322 /* Shifts of 32 are encoded as 0, for those shifts that
2327 inst
.instruction
|= (num
<< 7) | shft
->value
;
2332 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2333 inst
.reloc
.pc_rel
= 0;
2334 inst
.instruction
|= shft
->value
;
2340 inst
.error
= unrestrict
? _("shift requires register or #expression")
2341 : _("shift requires #expression");
2347 inst
.error
= _("Shift expression expected");
2351 /* Do those data_ops which can take a negative immediate constant */
2352 /* by altering the instuction. A bit of a hack really */
2356 by inverting the second operand, and
2359 by negating the second operand.
2362 negate_data_op (instruction
, value
)
2363 unsigned long * instruction
;
2364 unsigned long value
;
2367 unsigned long negated
, inverted
;
2369 negated
= validate_immediate (-value
);
2370 inverted
= validate_immediate (~value
);
2372 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2376 case OPCODE_SUB
: /* ADD <-> SUB */
2377 new_inst
= OPCODE_ADD
;
2382 new_inst
= OPCODE_SUB
;
2386 case OPCODE_CMP
: /* CMP <-> CMN */
2387 new_inst
= OPCODE_CMN
;
2392 new_inst
= OPCODE_CMP
;
2396 /* Now Inverted ops */
2397 case OPCODE_MOV
: /* MOV <-> MVN */
2398 new_inst
= OPCODE_MVN
;
2403 new_inst
= OPCODE_MOV
;
2407 case OPCODE_AND
: /* AND <-> BIC */
2408 new_inst
= OPCODE_BIC
;
2413 new_inst
= OPCODE_AND
;
2417 case OPCODE_ADC
: /* ADC <-> SBC */
2418 new_inst
= OPCODE_SBC
;
2423 new_inst
= OPCODE_ADC
;
2427 /* We cannot do anything */
2435 *instruction
&= OPCODE_MASK
;
2436 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2447 skip_whitespace (* str
);
2449 if (reg_required_here (str
, 0) != FAIL
)
2451 if (skip_past_comma (str
) == SUCCESS
)
2452 /* Shift operation on register. */
2453 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2459 /* Immediate expression */
2460 if (is_immediate_prefix (**str
))
2465 if (my_get_expression (&inst
.reloc
.exp
, str
))
2468 if (inst
.reloc
.exp
.X_add_symbol
)
2470 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2471 inst
.reloc
.pc_rel
= 0;
2475 if (skip_past_comma (str
) == SUCCESS
)
2477 /* #x, y -- ie explicit rotation by Y */
2478 if (my_get_expression (&expr
, str
))
2481 if (expr
.X_op
!= O_constant
)
2483 inst
.error
= _("Constant expression expected");
2487 /* Rotate must be a multiple of 2 */
2488 if (((unsigned) expr
.X_add_number
) > 30
2489 || (expr
.X_add_number
& 1) != 0
2490 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2492 inst
.error
= _("Invalid constant");
2495 inst
.instruction
|= INST_IMMEDIATE
;
2496 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2497 inst
.instruction
|= expr
.X_add_number
<< 7;
2501 /* Implicit rotation, select a suitable one */
2502 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2506 /* Can't be done, perhaps the code reads something like
2507 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2508 if ((value
= negate_data_op (&inst
.instruction
,
2509 inst
.reloc
.exp
.X_add_number
))
2512 inst
.error
= _("Invalid constant");
2517 inst
.instruction
|= value
;
2520 inst
.instruction
|= INST_IMMEDIATE
;
2525 inst
.error
= _("Register or shift expression expected");
2534 skip_whitespace (* str
);
2536 if (fp_reg_required_here (str
, 0) != FAIL
)
2540 /* Immediate expression */
2541 if (*((*str
)++) == '#')
2547 skip_whitespace (* str
);
2549 /* First try and match exact strings, this is to guarantee that
2550 some formats will work even for cross assembly */
2552 for (i
= 0; fp_const
[i
]; i
++)
2554 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2558 *str
+= strlen (fp_const
[i
]);
2559 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2561 inst
.instruction
|= i
+ 8;
2568 /* Just because we didn't get a match doesn't mean that the
2569 constant isn't valid, just that it is in a format that we
2570 don't automatically recognize. Try parsing it with
2571 the standard expression routines. */
2572 if ((i
= my_get_float_expression (str
)) >= 0)
2574 inst
.instruction
|= i
+ 8;
2578 inst
.error
= _("Invalid floating point immediate expression");
2581 inst
.error
= _("Floating point register or immediate expression expected");
2587 do_arit (str
, flags
)
2589 unsigned long flags
;
2591 skip_whitespace (str
);
2593 if (reg_required_here (&str
, 12) == FAIL
2594 || skip_past_comma (&str
) == FAIL
2595 || reg_required_here (&str
, 16) == FAIL
2596 || skip_past_comma (&str
) == FAIL
2597 || data_op2 (&str
) == FAIL
)
2600 inst
.error
= bad_args
;
2604 inst
.instruction
|= flags
;
2612 unsigned long flags
;
2614 /* This is a pseudo-op of the form "adr rd, label" to be converted
2615 into a relative address of the form "add rd, pc, #label-.-8" */
2617 skip_whitespace (str
);
2619 if (reg_required_here (&str
, 12) == FAIL
2620 || skip_past_comma (&str
) == FAIL
2621 || my_get_expression (&inst
.reloc
.exp
, &str
))
2624 inst
.error
= bad_args
;
2627 /* Frag hacking will turn this into a sub instruction if the offset turns
2628 out to be negative. */
2629 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2630 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2631 inst
.reloc
.pc_rel
= 1;
2632 inst
.instruction
|= flags
;
2638 do_adrl (str
, flags
)
2640 unsigned long flags
;
2642 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2643 into a relative address of the form:
2644 add rd, pc, #low(label-.-8)"
2645 add rd, rd, #high(label-.-8)" */
2647 skip_whitespace (str
);
2649 if (reg_required_here (& str
, 12) == FAIL
2650 || skip_past_comma (& str
) == FAIL
2651 || my_get_expression (& inst
.reloc
.exp
, & str
))
2654 inst
.error
= bad_args
;
2660 /* Frag hacking will turn this into a sub instruction if the offset turns
2661 out to be negative. */
2662 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2663 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2664 inst
.reloc
.pc_rel
= 1;
2665 inst
.instruction
|= flags
;
2666 inst
.size
= INSN_SIZE
* 2;
2674 unsigned long flags
;
2676 skip_whitespace (str
);
2678 if (reg_required_here (&str
, 16) == FAIL
)
2681 inst
.error
= bad_args
;
2685 if (skip_past_comma (&str
) == FAIL
2686 || data_op2 (&str
) == FAIL
)
2689 inst
.error
= bad_args
;
2693 inst
.instruction
|= flags
;
2694 if ((flags
& 0x0000f000) == 0)
2695 inst
.instruction
|= CONDS_BIT
;
2704 unsigned long flags
;
2706 skip_whitespace (str
);
2708 if (reg_required_here (&str
, 12) == FAIL
)
2711 inst
.error
= bad_args
;
2715 if (skip_past_comma (&str
) == FAIL
2716 || data_op2 (&str
) == FAIL
)
2719 inst
.error
= bad_args
;
2723 inst
.instruction
|= flags
;
2729 ldst_extend (str
, hwse
)
2740 if (my_get_expression (& inst
.reloc
.exp
, str
))
2743 if (inst
.reloc
.exp
.X_op
== O_constant
)
2745 int value
= inst
.reloc
.exp
.X_add_number
;
2747 if ((hwse
&& (value
< -255 || value
> 255))
2748 || (value
< -4095 || value
> 4095))
2750 inst
.error
= _("address offset too large");
2760 /* Halfword and signextension instructions have the
2761 immediate value split across bits 11..8 and bits 3..0 */
2763 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2765 inst
.instruction
|= add
| value
;
2771 inst
.instruction
|= HWOFFSET_IMM
;
2772 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2775 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2776 inst
.reloc
.pc_rel
= 0;
2781 add
= 0; /* and fall through */
2783 (*str
)++; /* and fall through */
2785 if (reg_required_here (str
, 0) == FAIL
)
2789 inst
.instruction
|= add
;
2792 inst
.instruction
|= add
| OFFSET_REG
;
2793 if (skip_past_comma (str
) == SUCCESS
)
2794 return decode_shift (str
, SHIFT_RESTRICT
);
2802 do_ldst (str
, flags
)
2804 unsigned long flags
;
2811 /* This is not ideal, but it is the simplest way of dealing with the
2812 ARM7T halfword instructions (since they use a different
2813 encoding, but the same mnemonic): */
2814 halfword
= (flags
& 0x80000000) != 0;
2817 /* This is actually a load/store of a halfword, or a
2818 signed-extension load */
2819 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2822 = _("Processor does not support halfwords or signed bytes");
2826 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2827 | (flags
& ~COND_MASK
);
2832 skip_whitespace (str
);
2834 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2837 inst
.error
= bad_args
;
2841 if (skip_past_comma (& str
) == FAIL
)
2843 inst
.error
= _("Address expected");
2853 skip_whitespace (str
);
2855 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2858 /* Conflicts can occur on stores as well as loads. */
2859 conflict_reg
= (conflict_reg
== reg
);
2861 skip_whitespace (str
);
2867 if (skip_past_comma (&str
) == SUCCESS
)
2869 /* [Rn],... (post inc) */
2870 if (ldst_extend (&str
, halfword
) == FAIL
)
2873 as_warn (_("%s register same as write-back base"),
2874 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2880 inst
.instruction
|= HWOFFSET_IMM
;
2882 skip_whitespace (str
);
2887 as_warn (_("%s register same as write-back base"),
2888 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2890 inst
.instruction
|= WRITE_BACK
;
2894 if (! (flags
& TRANS_BIT
))
2901 if (skip_past_comma (&str
) == FAIL
)
2903 inst
.error
= _("pre-indexed expression expected");
2908 if (ldst_extend (&str
, halfword
) == FAIL
)
2911 skip_whitespace (str
);
2915 inst
.error
= _("missing ]");
2919 skip_whitespace (str
);
2924 as_warn (_("%s register same as write-back base"),
2925 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2927 inst
.instruction
|= WRITE_BACK
;
2931 else if (*str
== '=')
2933 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2936 skip_whitespace (str
);
2938 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2941 if (inst
.reloc
.exp
.X_op
!= O_constant
2942 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2944 inst
.error
= _("Constant expression expected");
2948 if (inst
.reloc
.exp
.X_op
== O_constant
2949 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2951 /* This can be done with a mov instruction */
2952 inst
.instruction
&= LITERAL_MASK
;
2953 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2954 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2960 /* Insert into literal pool */
2961 if (add_to_lit_pool () == FAIL
)
2964 inst
.error
= _("literal pool insertion failed");
2968 /* Change the instruction exp to point to the pool */
2971 inst
.instruction
|= HWOFFSET_IMM
;
2972 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2975 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2976 inst
.reloc
.pc_rel
= 1;
2977 inst
.instruction
|= (REG_PC
<< 16);
2983 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2988 inst
.instruction
|= HWOFFSET_IMM
;
2989 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2992 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2993 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2994 inst
.reloc
.pc_rel
= 1;
2995 inst
.instruction
|= (REG_PC
<< 16);
2999 if (pre_inc
&& (flags
& TRANS_BIT
))
3000 inst
.error
= _("Pre-increment instruction with translate");
3002 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3015 /* We come back here if we get ranges concatenated by '+' or '|' */
3030 skip_whitespace (str
);
3032 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3041 inst
.error
= _("Bad range in register list");
3045 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3047 if (range
& (1 << i
))
3049 (_("Warning: Duplicated register (r%d) in register list"),
3057 if (range
& (1 << reg
))
3058 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3060 else if (reg
<= cur_reg
)
3061 as_tsktsk (_("Warning: Register range not in ascending order"));
3065 } while (skip_past_comma (&str
) != FAIL
3066 || (in_range
= 1, *str
++ == '-'));
3068 skip_whitespace (str
);
3072 inst
.error
= _("Missing `}'");
3080 if (my_get_expression (&expr
, &str
))
3083 if (expr
.X_op
== O_constant
)
3085 if (expr
.X_add_number
3086 != (expr
.X_add_number
& 0x0000ffff))
3088 inst
.error
= _("invalid register mask");
3092 if ((range
& expr
.X_add_number
) != 0)
3094 int regno
= range
& expr
.X_add_number
;
3097 regno
= (1 << regno
) - 1;
3099 (_("Warning: Duplicated register (r%d) in register list"),
3103 range
|= expr
.X_add_number
;
3107 if (inst
.reloc
.type
!= 0)
3109 inst
.error
= _("expression too complex");
3113 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3114 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3115 inst
.reloc
.pc_rel
= 0;
3119 skip_whitespace (str
);
3121 if (*str
== '|' || *str
== '+')
3126 } while (another_range
);
3133 do_ldmstm (str
, flags
)
3135 unsigned long flags
;
3140 skip_whitespace (str
);
3142 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3145 if (base_reg
== REG_PC
)
3147 inst
.error
= _("r15 not allowed as base register");
3151 skip_whitespace (str
);
3155 flags
|= WRITE_BACK
;
3159 if (skip_past_comma (&str
) == FAIL
3160 || (range
= reg_list (&str
)) == FAIL
)
3163 inst
.error
= bad_args
;
3170 flags
|= LDM_TYPE_2_OR_3
;
3173 inst
.instruction
|= flags
| range
;
3181 unsigned long flags
;
3183 skip_whitespace (str
);
3185 /* Allow optional leading '#'. */
3186 if (is_immediate_prefix (*str
))
3189 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3192 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3193 inst
.reloc
.pc_rel
= 0;
3194 inst
.instruction
|= flags
;
3202 do_swap (str
, flags
)
3204 unsigned long flags
;
3208 skip_whitespace (str
);
3210 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3215 inst
.error
= _("r15 not allowed in swap");
3219 if (skip_past_comma (&str
) == FAIL
3220 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3223 inst
.error
= bad_args
;
3229 inst
.error
= _("r15 not allowed in swap");
3233 if (skip_past_comma (&str
) == FAIL
3236 inst
.error
= bad_args
;
3240 skip_whitespace (str
);
3242 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3247 inst
.error
= bad_pc
;
3251 skip_whitespace (str
);
3255 inst
.error
= _("missing ]");
3259 inst
.instruction
|= flags
;
3265 do_branch (str
, flags
)
3267 unsigned long flags
;
3269 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3276 /* ScottB: February 5, 1998 */
3277 /* Check to see of PLT32 reloc required for the instruction. */
3279 /* arm_parse_reloc() works on input_line_pointer.
3280 We actually want to parse the operands to the branch instruction
3281 passed in 'str'. Save the input pointer and restore it later. */
3282 save_in
= input_line_pointer
;
3283 input_line_pointer
= str
;
3284 if (inst
.reloc
.exp
.X_op
== O_symbol
3286 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3288 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3289 inst
.reloc
.pc_rel
= 0;
3290 /* Modify str to point to after parsed operands, otherwise
3291 end_of_line() will complain about the (PLT) left in str. */
3292 str
= input_line_pointer
;
3296 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3297 inst
.reloc
.pc_rel
= 1;
3299 input_line_pointer
= save_in
;
3302 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3303 inst
.reloc
.pc_rel
= 1;
3304 #endif /* OBJ_ELF */
3313 unsigned long flags
;
3317 skip_whitespace (str
);
3319 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3323 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3332 unsigned long flags
;
3334 /* Co-processor data operation.
3335 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3336 skip_whitespace (str
);
3338 if (co_proc_number (&str
) == FAIL
)
3341 inst
.error
= bad_args
;
3345 if (skip_past_comma (&str
) == FAIL
3346 || cp_opc_expr (&str
, 20,4) == FAIL
)
3349 inst
.error
= bad_args
;
3353 if (skip_past_comma (&str
) == FAIL
3354 || cp_reg_required_here (&str
, 12) == FAIL
)
3357 inst
.error
= bad_args
;
3361 if (skip_past_comma (&str
) == FAIL
3362 || cp_reg_required_here (&str
, 16) == FAIL
)
3365 inst
.error
= bad_args
;
3369 if (skip_past_comma (&str
) == FAIL
3370 || cp_reg_required_here (&str
, 0) == FAIL
)
3373 inst
.error
= bad_args
;
3377 if (skip_past_comma (&str
) == SUCCESS
)
3379 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3382 inst
.error
= bad_args
;
3392 do_lstc (str
, flags
)
3394 unsigned long flags
;
3396 /* Co-processor register load/store.
3397 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3399 skip_whitespace (str
);
3401 if (co_proc_number (&str
) == FAIL
)
3404 inst
.error
= bad_args
;
3408 if (skip_past_comma (&str
) == FAIL
3409 || cp_reg_required_here (&str
, 12) == FAIL
)
3412 inst
.error
= bad_args
;
3416 if (skip_past_comma (&str
) == FAIL
3417 || cp_address_required_here (&str
) == FAIL
)
3420 inst
.error
= bad_args
;
3424 inst
.instruction
|= flags
;
3430 do_co_reg (str
, flags
)
3432 unsigned long flags
;
3434 /* Co-processor register transfer.
3435 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3437 skip_whitespace (str
);
3439 if (co_proc_number (&str
) == FAIL
)
3442 inst
.error
= bad_args
;
3446 if (skip_past_comma (&str
) == FAIL
3447 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3450 inst
.error
= bad_args
;
3454 if (skip_past_comma (&str
) == FAIL
3455 || reg_required_here (&str
, 12) == FAIL
)
3458 inst
.error
= bad_args
;
3462 if (skip_past_comma (&str
) == FAIL
3463 || cp_reg_required_here (&str
, 16) == FAIL
)
3466 inst
.error
= bad_args
;
3470 if (skip_past_comma (&str
) == FAIL
3471 || cp_reg_required_here (&str
, 0) == FAIL
)
3474 inst
.error
= bad_args
;
3478 if (skip_past_comma (&str
) == SUCCESS
)
3480 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3483 inst
.error
= bad_args
;
3493 do_fp_ctrl (str
, flags
)
3495 unsigned long flags
;
3497 /* FP control registers.
3498 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3500 skip_whitespace (str
);
3502 if (reg_required_here (&str
, 12) == FAIL
)
3505 inst
.error
= bad_args
;
3514 do_fp_ldst (str
, flags
)
3516 unsigned long flags
;
3518 skip_whitespace (str
);
3520 switch (inst
.suffix
)
3525 inst
.instruction
|= CP_T_X
;
3528 inst
.instruction
|= CP_T_Y
;
3531 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3537 if (fp_reg_required_here (&str
, 12) == FAIL
)
3540 inst
.error
= bad_args
;
3544 if (skip_past_comma (&str
) == FAIL
3545 || cp_address_required_here (&str
) == FAIL
)
3548 inst
.error
= bad_args
;
3556 do_fp_ldmstm (str
, flags
)
3558 unsigned long flags
;
3562 skip_whitespace (str
);
3564 if (fp_reg_required_here (&str
, 12) == FAIL
)
3567 inst
.error
= bad_args
;
3571 /* Get Number of registers to transfer */
3572 if (skip_past_comma (&str
) == FAIL
3573 || my_get_expression (&inst
.reloc
.exp
, &str
))
3576 inst
.error
= _("constant expression expected");
3580 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3582 inst
.error
= _("Constant value required for number of registers");
3586 num_regs
= inst
.reloc
.exp
.X_add_number
;
3588 if (num_regs
< 1 || num_regs
> 4)
3590 inst
.error
= _("number of registers must be in the range [1:4]");
3597 inst
.instruction
|= CP_T_X
;
3600 inst
.instruction
|= CP_T_Y
;
3603 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3617 /* The instruction specified "ea" or "fd", so we can only accept
3618 [Rn]{!}. The instruction does not really support stacking or
3619 unstacking, so we have to emulate these by setting appropriate
3620 bits and offsets. */
3621 if (skip_past_comma (&str
) == FAIL
3625 inst
.error
= bad_args
;
3630 skip_whitespace (str
);
3632 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3635 skip_whitespace (str
);
3639 inst
.error
= bad_args
;
3650 inst
.error
= _("R15 not allowed as base register with write-back");
3657 if (flags
& CP_T_Pre
)
3660 offset
= 3 * num_regs
;
3666 /* Post-increment */
3670 offset
= 3 * num_regs
;
3674 /* No write-back, so convert this into a standard pre-increment
3675 instruction -- aesthetically more pleasing. */
3676 flags
= CP_T_Pre
| CP_T_UD
;
3681 inst
.instruction
|= flags
| offset
;
3683 else if (skip_past_comma (&str
) == FAIL
3684 || cp_address_required_here (&str
) == FAIL
)
3687 inst
.error
= bad_args
;
3695 do_fp_dyadic (str
, flags
)
3697 unsigned long flags
;
3699 skip_whitespace (str
);
3701 switch (inst
.suffix
)
3706 inst
.instruction
|= 0x00000080;
3709 inst
.instruction
|= 0x00080000;
3715 if (fp_reg_required_here (&str
, 12) == FAIL
)
3718 inst
.error
= bad_args
;
3722 if (skip_past_comma (&str
) == FAIL
3723 || fp_reg_required_here (&str
, 16) == FAIL
)
3726 inst
.error
= bad_args
;
3730 if (skip_past_comma (&str
) == FAIL
3731 || fp_op2 (&str
) == FAIL
)
3734 inst
.error
= bad_args
;
3738 inst
.instruction
|= flags
;
3744 do_fp_monadic (str
, flags
)
3746 unsigned long flags
;
3748 skip_whitespace (str
);
3750 switch (inst
.suffix
)
3755 inst
.instruction
|= 0x00000080;
3758 inst
.instruction
|= 0x00080000;
3764 if (fp_reg_required_here (&str
, 12) == FAIL
)
3767 inst
.error
= bad_args
;
3771 if (skip_past_comma (&str
) == FAIL
3772 || fp_op2 (&str
) == FAIL
)
3775 inst
.error
= bad_args
;
3779 inst
.instruction
|= flags
;
3785 do_fp_cmp (str
, flags
)
3787 unsigned long flags
;
3789 skip_whitespace (str
);
3791 if (fp_reg_required_here (&str
, 16) == 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_from_reg (str
, flags
)
3814 unsigned long flags
;
3816 skip_whitespace (str
);
3818 switch (inst
.suffix
)
3823 inst
.instruction
|= 0x00000080;
3826 inst
.instruction
|= 0x00080000;
3832 if (fp_reg_required_here (&str
, 16) == FAIL
)
3835 inst
.error
= bad_args
;
3839 if (skip_past_comma (&str
) == FAIL
3840 || reg_required_here (&str
, 12) == FAIL
)
3843 inst
.error
= bad_args
;
3847 inst
.instruction
|= flags
;
3853 do_fp_to_reg (str
, flags
)
3855 unsigned long flags
;
3857 skip_whitespace (str
);
3859 if (reg_required_here (&str
, 12) == FAIL
)
3862 if (skip_past_comma (&str
) == FAIL
3863 || fp_reg_required_here (&str
, 0) == FAIL
)
3866 inst
.error
= bad_args
;
3870 inst
.instruction
|= flags
;
3875 /* Thumb specific routines */
3877 /* Parse and validate that a register is of the right form, this saves
3878 repeated checking of this information in many similar cases.
3879 Unlike the 32-bit case we do not insert the register into the opcode
3880 here, since the position is often unknown until the full instruction
3883 thumb_reg (strp
, hi_lo
)
3889 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3897 inst
.error
= _("lo register required");
3905 inst
.error
= _("hi register required");
3917 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3920 thumb_add_sub (str
, subtract
)
3924 int Rd
, Rs
, Rn
= FAIL
;
3926 skip_whitespace (str
);
3928 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3929 || skip_past_comma (&str
) == FAIL
)
3932 inst
.error
= bad_args
;
3936 if (is_immediate_prefix (*str
))
3940 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3945 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3948 if (skip_past_comma (&str
) == FAIL
)
3950 /* Two operand format, shuffle the registers and pretend there
3955 else if (is_immediate_prefix (*str
))
3958 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3961 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3965 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3966 for the latter case, EXPR contains the immediate that was found. */
3969 /* All register format. */
3970 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3974 inst
.error
= _("dest and source1 must be the same register");
3978 /* Can't do this for SUB */
3981 inst
.error
= _("subtract valid only on lo regs");
3985 inst
.instruction
= (T_OPCODE_ADD_HI
3986 | (Rd
> 7 ? THUMB_H1
: 0)
3987 | (Rn
> 7 ? THUMB_H2
: 0));
3988 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3992 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3993 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3998 /* Immediate expression, now things start to get nasty. */
4000 /* First deal with HI regs, only very restricted cases allowed:
4001 Adjusting SP, and using PC or SP to get an address. */
4002 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4003 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4005 inst
.error
= _("invalid Hi register with immediate");
4009 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4011 /* Value isn't known yet, all we can do is store all the fragments
4012 we know about in the instruction and let the reloc hacking
4014 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4015 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4019 int offset
= inst
.reloc
.exp
.X_add_number
;
4029 /* Quick check, in case offset is MIN_INT */
4032 inst
.error
= _("immediate value out of range");
4041 if (offset
& ~0x1fc)
4043 inst
.error
= _("invalid immediate value for stack adjust");
4046 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4047 inst
.instruction
|= offset
>> 2;
4049 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4052 || (offset
& ~0x3fc))
4054 inst
.error
= _("invalid immediate for address calculation");
4057 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4059 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4065 inst
.error
= _("immediate value out of range");
4068 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4069 inst
.instruction
|= (Rd
<< 8) | offset
;
4075 inst
.error
= _("immediate value out of range");
4078 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4079 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4087 thumb_shift (str
, shift
)
4091 int Rd
, Rs
, Rn
= FAIL
;
4093 skip_whitespace (str
);
4095 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4096 || skip_past_comma (&str
) == FAIL
)
4099 inst
.error
= bad_args
;
4103 if (is_immediate_prefix (*str
))
4105 /* Two operand immediate format, set Rs to Rd. */
4108 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4113 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4116 if (skip_past_comma (&str
) == FAIL
)
4118 /* Two operand format, shuffle the registers and pretend there
4123 else if (is_immediate_prefix (*str
))
4126 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4129 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4133 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4134 for the latter case, EXPR contains the immediate that was found. */
4140 inst
.error
= _("source1 and dest must be same register");
4146 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4147 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4148 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4151 inst
.instruction
|= Rd
| (Rn
<< 3);
4157 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4158 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4159 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4162 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4164 /* Value isn't known yet, create a dummy reloc and let reloc
4165 hacking fix it up */
4167 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4171 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4173 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4175 inst
.error
= _("Invalid immediate for shift");
4179 /* Shifts of zero are handled by converting to LSL */
4180 if (shift_value
== 0)
4181 inst
.instruction
= T_OPCODE_LSL_I
;
4183 /* Shifts of 32 are encoded as a shift of zero */
4184 if (shift_value
== 32)
4187 inst
.instruction
|= shift_value
<< 6;
4190 inst
.instruction
|= Rd
| (Rs
<< 3);
4196 thumb_mov_compare (str
, move
)
4202 skip_whitespace (str
);
4204 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4205 || skip_past_comma (&str
) == FAIL
)
4208 inst
.error
= bad_args
;
4212 if (is_immediate_prefix (*str
))
4215 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4218 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4223 if (Rs
< 8 && Rd
< 8)
4225 if (move
== THUMB_MOVE
)
4226 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4227 since a MOV instruction produces unpredictable results */
4228 inst
.instruction
= T_OPCODE_ADD_I3
;
4230 inst
.instruction
= T_OPCODE_CMP_LR
;
4231 inst
.instruction
|= Rd
| (Rs
<< 3);
4235 if (move
== THUMB_MOVE
)
4236 inst
.instruction
= T_OPCODE_MOV_HR
;
4238 inst
.instruction
= T_OPCODE_CMP_HR
;
4241 inst
.instruction
|= THUMB_H1
;
4244 inst
.instruction
|= THUMB_H2
;
4246 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4253 inst
.error
= _("only lo regs allowed with immediate");
4257 if (move
== THUMB_MOVE
)
4258 inst
.instruction
= T_OPCODE_MOV_I8
;
4260 inst
.instruction
= T_OPCODE_CMP_I8
;
4262 inst
.instruction
|= Rd
<< 8;
4264 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4265 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4268 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4272 inst
.error
= _("invalid immediate");
4276 inst
.instruction
|= value
;
4284 thumb_load_store (str
, load_store
, size
)
4289 int Rd
, Rb
, Ro
= FAIL
;
4291 skip_whitespace (str
);
4293 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4294 || skip_past_comma (&str
) == FAIL
)
4297 inst
.error
= bad_args
;
4304 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4307 if (skip_past_comma (&str
) != FAIL
)
4309 if (is_immediate_prefix (*str
))
4312 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4315 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4320 inst
.reloc
.exp
.X_op
= O_constant
;
4321 inst
.reloc
.exp
.X_add_number
= 0;
4326 inst
.error
= _("expected ']'");
4331 else if (*str
== '=')
4333 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4336 skip_whitespace (str
);
4338 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4343 if ( inst
.reloc
.exp
.X_op
!= O_constant
4344 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4346 inst
.error
= "Constant expression expected";
4350 if (inst
.reloc
.exp
.X_op
== O_constant
4351 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4353 /* This can be done with a mov instruction */
4355 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4356 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4360 /* Insert into literal pool */
4361 if (add_to_lit_pool () == FAIL
)
4364 inst
.error
= "literal pool insertion failed";
4368 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4369 inst
.reloc
.pc_rel
= 1;
4370 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4371 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4377 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4380 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4381 inst
.reloc
.pc_rel
= 1;
4382 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4383 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4388 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4390 if (size
!= THUMB_WORD
)
4392 inst
.error
= _("byte or halfword not valid for base register");
4395 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4397 inst
.error
= _("R15 based store not allowed");
4400 else if (Ro
!= FAIL
)
4402 inst
.error
= _("Invalid base register for register offset");
4407 inst
.instruction
= T_OPCODE_LDR_PC
;
4408 else if (load_store
== THUMB_LOAD
)
4409 inst
.instruction
= T_OPCODE_LDR_SP
;
4411 inst
.instruction
= T_OPCODE_STR_SP
;
4413 inst
.instruction
|= Rd
<< 8;
4414 if (inst
.reloc
.exp
.X_op
== O_constant
)
4416 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4418 if (offset
& ~0x3fc)
4420 inst
.error
= _("invalid offset");
4424 inst
.instruction
|= offset
>> 2;
4427 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4431 inst
.error
= _("invalid base register in load/store");
4434 else if (Ro
== FAIL
)
4436 /* Immediate offset */
4437 if (size
== THUMB_WORD
)
4438 inst
.instruction
= (load_store
== THUMB_LOAD
4439 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4440 else if (size
== THUMB_HALFWORD
)
4441 inst
.instruction
= (load_store
== THUMB_LOAD
4442 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4444 inst
.instruction
= (load_store
== THUMB_LOAD
4445 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4447 inst
.instruction
|= Rd
| (Rb
<< 3);
4449 if (inst
.reloc
.exp
.X_op
== O_constant
)
4451 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4453 if (offset
& ~(0x1f << size
))
4455 inst
.error
= _("Invalid offset");
4458 inst
.instruction
|= (offset
>> size
) << 6;
4461 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4465 /* Register offset */
4466 if (size
== THUMB_WORD
)
4467 inst
.instruction
= (load_store
== THUMB_LOAD
4468 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4469 else if (size
== THUMB_HALFWORD
)
4470 inst
.instruction
= (load_store
== THUMB_LOAD
4471 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4473 inst
.instruction
= (load_store
== THUMB_LOAD
4474 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4476 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4491 /* Handle the Format 4 instructions that do not have equivalents in other
4492 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4500 skip_whitespace (str
);
4502 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4505 if (skip_past_comma (&str
) == FAIL
4506 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4509 inst
.error
= bad_args
;
4513 if (skip_past_comma (&str
) != FAIL
)
4515 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4516 (It isn't allowed for CMP either, but that isn't handled by this
4518 if (inst
.instruction
== T_OPCODE_TST
4519 || inst
.instruction
== T_OPCODE_CMN
4520 || inst
.instruction
== T_OPCODE_NEG
4521 || inst
.instruction
== T_OPCODE_MVN
)
4523 inst
.error
= bad_args
;
4527 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4532 inst
.error
= _("dest and source1 one must be the same register");
4538 if (inst
.instruction
== T_OPCODE_MUL
4540 as_tsktsk (_("Rs and Rd must be different in MUL"));
4542 inst
.instruction
|= Rd
| (Rs
<< 3);
4550 thumb_add_sub (str
, 0);
4557 thumb_shift (str
, THUMB_ASR
);
4564 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4566 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4567 inst
.reloc
.pc_rel
= 1;
4575 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4577 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4578 inst
.reloc
.pc_rel
= 1;
4582 /* Find the real, Thumb encoded start of a Thumb function. */
4585 find_real_start (symbolP
)
4589 const char * name
= S_GET_NAME (symbolP
);
4590 symbolS
* new_target
;
4592 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4593 #define STUB_NAME ".real_start_of"
4598 /* Names that start with '.' are local labels, not function entry points.
4599 The compiler may generate BL instructions to these labels because it
4600 needs to perform a branch to a far away location. */
4604 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4605 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4607 new_target
= symbol_find (real_start
);
4609 if (new_target
== NULL
)
4611 as_warn ("Failed to find real start of function: %s\n", name
);
4612 new_target
= symbolP
;
4625 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4628 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4629 inst
.reloc
.pc_rel
= 1;
4632 /* If the destination of the branch is a defined symbol which does not have
4633 the THUMB_FUNC attribute, then we must be calling a function which has
4634 the (interfacearm) attribute. We look for the Thumb entry point to that
4635 function and change the branch to refer to that function instead. */
4636 if ( inst
.reloc
.exp
.X_op
== O_symbol
4637 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4638 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4639 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4640 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4649 skip_whitespace (str
);
4651 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4654 /* This sets THUMB_H2 from the top bit of reg. */
4655 inst
.instruction
|= reg
<< 3;
4657 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4658 should cause the alignment to be checked once it is known. This is
4659 because BX PC only works if the instruction is word aligned. */
4668 thumb_mov_compare (str
, THUMB_COMPARE
);
4678 skip_whitespace (str
);
4680 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4684 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4688 if (skip_past_comma (&str
) == FAIL
4689 || (range
= reg_list (&str
)) == FAIL
)
4692 inst
.error
= bad_args
;
4696 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4698 /* This really doesn't seem worth it. */
4699 inst
.reloc
.type
= BFD_RELOC_NONE
;
4700 inst
.error
= _("Expression too complex");
4706 inst
.error
= _("only lo-regs valid in load/store multiple");
4710 inst
.instruction
|= (Rb
<< 8) | range
;
4718 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4725 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4732 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4741 skip_whitespace (str
);
4743 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4744 || skip_past_comma (&str
) == FAIL
4746 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4747 || skip_past_comma (&str
) == FAIL
4748 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4752 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4756 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4764 thumb_shift (str
, THUMB_LSL
);
4771 thumb_shift (str
, THUMB_LSR
);
4778 thumb_mov_compare (str
, THUMB_MOVE
);
4787 skip_whitespace (str
);
4789 if ((range
= reg_list (&str
)) == FAIL
)
4792 inst
.error
= bad_args
;
4796 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4798 /* This really doesn't seem worth it. */
4799 inst
.reloc
.type
= BFD_RELOC_NONE
;
4800 inst
.error
= _("Expression too complex");
4806 if ((inst
.instruction
== T_OPCODE_PUSH
4807 && (range
& ~0xff) == 1 << REG_LR
)
4808 || (inst
.instruction
== T_OPCODE_POP
4809 && (range
& ~0xff) == 1 << REG_PC
))
4811 inst
.instruction
|= THUMB_PP_PC_LR
;
4816 inst
.error
= _("invalid register list to push/pop instruction");
4821 inst
.instruction
|= range
;
4829 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4836 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4843 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4850 thumb_add_sub (str
, 1);
4857 skip_whitespace (str
);
4859 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4862 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4871 /* This is a pseudo-op of the form "adr rd, label" to be converted
4872 into a relative address of the form "add rd, pc, #label-.-4" */
4873 skip_whitespace (str
);
4875 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4876 || skip_past_comma (&str
) == FAIL
4877 || my_get_expression (&inst
.reloc
.exp
, &str
))
4880 inst
.error
= bad_args
;
4884 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4885 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4886 inst
.reloc
.pc_rel
= 1;
4887 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4895 int len
= strlen (reg_table
[entry
].name
) + 2;
4896 char * buf
= (char *) xmalloc (len
);
4897 char * buf2
= (char *) xmalloc (len
);
4900 #ifdef REGISTER_PREFIX
4901 buf
[i
++] = REGISTER_PREFIX
;
4904 strcpy (buf
+ i
, reg_table
[entry
].name
);
4906 for (i
= 0; buf
[i
]; i
++)
4907 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4911 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4912 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4916 insert_reg_alias (str
, regnum
)
4920 struct reg_entry
*new =
4921 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4922 char *name
= xmalloc (strlen (str
) + 1);
4926 new->number
= regnum
;
4928 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4932 set_constant_flonums ()
4936 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4937 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4946 if ( (arm_ops_hsh
= hash_new ()) == NULL
4947 || (arm_tops_hsh
= hash_new ()) == NULL
4948 || (arm_cond_hsh
= hash_new ()) == NULL
4949 || (arm_shift_hsh
= hash_new ()) == NULL
4950 || (arm_reg_hsh
= hash_new ()) == NULL
4951 || (arm_psr_hsh
= hash_new ()) == NULL
)
4952 as_fatal (_("Virtual memory exhausted"));
4954 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4955 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4956 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4957 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4958 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4959 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4960 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4961 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4962 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4963 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4965 for (i
= 0; reg_table
[i
].name
; i
++)
4968 set_constant_flonums ();
4970 #if defined OBJ_COFF || defined OBJ_ELF
4972 unsigned int flags
= 0;
4974 /* Set the flags in the private structure */
4975 if (uses_apcs_26
) flags
|= F_APCS26
;
4976 if (support_interwork
) flags
|= F_INTERWORK
;
4977 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4978 if (pic_code
) flags
|= F_PIC
;
4979 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
4981 bfd_set_private_flags (stdoutput
, flags
);
4988 /* Record the CPU type as well */
4989 switch (cpu_variant
& ARM_CPU_MASK
)
4992 mach
= bfd_mach_arm_2
;
4995 case ARM_3
: /* also ARM_250 */
4996 mach
= bfd_mach_arm_2a
;
5000 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
5001 mach
= bfd_mach_arm_4
;
5004 case ARM_7
: /* also ARM_6 */
5005 mach
= bfd_mach_arm_3
;
5009 /* Catch special cases. */
5010 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5012 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5013 mach
= bfd_mach_arm_5T
;
5014 else if (cpu_variant
& ARM_EXT_V5
)
5015 mach
= bfd_mach_arm_5
;
5016 else if (cpu_variant
& ARM_THUMB
)
5017 mach
= bfd_mach_arm_4T
;
5018 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5019 mach
= bfd_mach_arm_4
;
5020 else if (cpu_variant
& ARM_LONGMUL
)
5021 mach
= bfd_mach_arm_3M
;
5024 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5028 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5029 for use in the a.out file, and stores them in the array pointed to by buf.
5030 This knows about the endian-ness of the target machine and does
5031 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5032 2 (short) and 4 (long) Floating numbers are put out as a series of
5033 LITTLENUMS (shorts, here at least). */
5035 md_number_to_chars (buf
, val
, n
)
5040 if (target_big_endian
)
5041 number_to_chars_bigendian (buf
, val
, n
);
5043 number_to_chars_littleendian (buf
, val
, n
);
5047 md_chars_to_number (buf
, n
)
5052 unsigned char * where
= (unsigned char *) buf
;
5054 if (target_big_endian
)
5059 result
|= (*where
++ & 255);
5067 result
|= (where
[n
] & 255);
5074 /* Turn a string in input_line_pointer into a floating point constant
5075 of type TYPE, and store the appropriate bytes in *litP. The number
5076 of LITTLENUMS emitted is stored in *sizeP . An error message is
5077 returned, or NULL on OK.
5079 Note that fp constants aren't represent in the normal way on the ARM.
5080 In big endian mode, things are as expected. However, in little endian
5081 mode fp constants are big-endian word-wise, and little-endian byte-wise
5082 within the words. For example, (double) 1.1 in big endian mode is
5083 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5084 the byte sequence 99 99 f1 3f 9a 99 99 99.
5086 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5089 md_atof (type
, litP
, sizeP
)
5095 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5127 return _("Bad call to MD_ATOF()");
5130 t
= atof_ieee (input_line_pointer
, type
, words
);
5132 input_line_pointer
= t
;
5135 if (target_big_endian
)
5137 for (i
= 0; i
< prec
; i
++)
5139 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5145 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5146 8 byte float the order is 1 0 3 2. */
5147 for (i
= 0; i
< prec
; i
+= 2)
5149 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5150 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5158 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5160 md_pcrel_from (fixP
)
5164 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5165 && fixP
->fx_subsy
== NULL
)
5168 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5170 /* PC relative addressing on the Thumb is slightly odd
5171 as the bottom two bits of the PC are forced to zero
5172 for the calculation. */
5173 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5176 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5179 /* Round up a section size to the appropriate boundary. */
5181 md_section_align (segment
, size
)
5188 /* Round all sects to multiple of 4 */
5189 return (size
+ 3) & ~3;
5193 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5194 we have no need to default values of symbols. */
5198 md_undefined_symbol (name
)
5202 if (name
[0] == '_' && name
[1] == 'G'
5203 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5207 if (symbol_find (name
))
5208 as_bad ("GOT already in the symbol table");
5210 GOT_symbol
= symbol_new (name
, undefined_section
,
5211 (valueT
)0, & zero_address_frag
);
5221 /* arm_reg_parse () := if it looks like a register, return its token and
5222 advance the pointer. */
5226 register char ** ccp
;
5228 char * start
= * ccp
;
5231 struct reg_entry
* reg
;
5233 #ifdef REGISTER_PREFIX
5234 if (*start
!= REGISTER_PREFIX
)
5239 #ifdef OPTIONAL_REGISTER_PREFIX
5240 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5244 if (!isalpha (*p
) || !is_name_beginner (*p
))
5248 while (isalpha (c
) || isdigit (c
) || c
== '_')
5252 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5266 register char ** ccp
;
5268 char * start
= * ccp
;
5271 CONST
struct asm_psr
* psr
;
5275 while (isalpha (c
) || c
== '_')
5279 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5292 md_apply_fix3 (fixP
, val
, seg
)
5297 offsetT value
= * val
;
5299 unsigned int newimm
;
5302 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5303 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5305 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5307 /* Note whether this will delete the relocation. */
5308 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5309 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5312 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5316 /* If this symbol is in a different section then we need to leave it for
5317 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5318 so we have to undo it's effects here. */
5321 if (fixP
->fx_addsy
!= NULL
5322 && S_IS_DEFINED (fixP
->fx_addsy
)
5323 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5326 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5329 value
+= md_pcrel_from (fixP
);
5333 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5335 switch (fixP
->fx_r_type
)
5337 case BFD_RELOC_ARM_IMMEDIATE
:
5338 newimm
= validate_immediate (value
);
5339 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5341 /* If the instruction will fail, see if we can fix things up by
5342 changing the opcode. */
5343 if (newimm
== (unsigned int) FAIL
5344 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5346 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5347 _("invalid constant (%lx) after fixup"),
5348 (unsigned long) value
);
5352 newimm
|= (temp
& 0xfffff000);
5353 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5356 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5358 unsigned int highpart
= 0;
5359 unsigned int newinsn
= 0xe1a00000; /* nop */
5360 newimm
= validate_immediate (value
);
5361 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5363 /* If the instruction will fail, see if we can fix things up by
5364 changing the opcode. */
5365 if (newimm
== (unsigned int) FAIL
5366 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5368 /* No ? OK - try using two ADD instructions to generate the value. */
5369 newimm
= validate_immediate_twopart (value
, & highpart
);
5371 /* Yes - then make sure that the second instruction is also an add. */
5372 if (newimm
!= (unsigned int) FAIL
)
5374 /* Still No ? Try using a negated value. */
5375 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5376 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5377 /* Otherwise - give up. */
5380 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5381 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5385 /* Replace the first operand in the 2nd instruction (which is the PC)
5386 with the destination register. We have already added in the PC in the
5387 first instruction and we do not want to do it again. */
5388 newinsn
&= ~ 0xf0000;
5389 newinsn
|= ((newinsn
& 0x0f000) << 4);
5392 newimm
|= (temp
& 0xfffff000);
5393 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5395 highpart
|= (newinsn
& 0xfffff000);
5396 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5400 case BFD_RELOC_ARM_OFFSET_IMM
:
5406 if (validate_offset_imm (value
, 0) == FAIL
)
5408 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5409 _("bad immediate value for offset (%ld)"), (long) value
);
5413 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5414 newval
&= 0xff7ff000;
5415 newval
|= value
| (sign
? INDEX_UP
: 0);
5416 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5419 case BFD_RELOC_ARM_OFFSET_IMM8
:
5420 case BFD_RELOC_ARM_HWLITERAL
:
5426 if (validate_offset_imm (value
, 1) == FAIL
)
5428 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5429 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5430 _("invalid literal constant: pool needs to be closer"));
5432 as_bad (_("bad immediate value for half-word offset (%ld)"),
5437 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5438 newval
&= 0xff7ff0f0;
5439 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5440 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5443 case BFD_RELOC_ARM_LITERAL
:
5449 if (validate_offset_imm (value
, 0) == FAIL
)
5451 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5452 _("invalid literal constant: pool needs to be closer"));
5456 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5457 newval
&= 0xff7ff000;
5458 newval
|= value
| (sign
? INDEX_UP
: 0);
5459 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5462 case BFD_RELOC_ARM_SHIFT_IMM
:
5463 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5464 if (((unsigned long) value
) > 32
5466 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5468 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5469 _("shift expression is too large"));
5474 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5475 else if (value
== 32)
5477 newval
&= 0xfffff07f;
5478 newval
|= (value
& 0x1f) << 7;
5479 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5482 case BFD_RELOC_ARM_SWI
:
5483 if (arm_data
->thumb_mode
)
5485 if (((unsigned long) value
) > 0xff)
5486 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5487 _("Invalid swi expression"));
5488 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5490 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5494 if (((unsigned long) value
) > 0x00ffffff)
5495 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5496 _("Invalid swi expression"));
5497 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5499 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5503 case BFD_RELOC_ARM_MULTI
:
5504 if (((unsigned long) value
) > 0xffff)
5505 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5506 _("Invalid expression in load/store multiple"));
5507 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5508 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5511 case BFD_RELOC_ARM_PCREL_BRANCH
:
5512 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5516 value
= fixP
->fx_offset
;
5518 value
= (value
>> 2) & 0x00ffffff;
5519 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5520 newval
= value
| (newval
& 0xff000000);
5521 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5524 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5525 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5527 addressT diff
= (newval
& 0xff) << 1;
5532 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5533 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5534 _("Branch out of range"));
5535 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5537 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5540 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5541 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5543 addressT diff
= (newval
& 0x7ff) << 1;
5548 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5549 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5550 _("Branch out of range"));
5551 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5553 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5556 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5561 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5562 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5563 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5564 if (diff
& 0x400000)
5567 value
= fixP
->fx_offset
;
5570 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5571 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5572 _("Branch with link out of range"));
5574 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5575 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5576 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5577 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5582 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5583 md_number_to_chars (buf
, value
, 1);
5585 else if (!target_oabi
)
5587 value
= fixP
->fx_offset
;
5588 md_number_to_chars (buf
, value
, 1);
5594 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5595 md_number_to_chars (buf
, value
, 2);
5597 else if (!target_oabi
)
5599 value
= fixP
->fx_offset
;
5600 md_number_to_chars (buf
, value
, 2);
5606 case BFD_RELOC_ARM_GOT32
:
5607 case BFD_RELOC_ARM_GOTOFF
:
5608 md_number_to_chars (buf
, 0, 4);
5614 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5615 md_number_to_chars (buf
, value
, 4);
5617 else if (!target_oabi
)
5619 value
= fixP
->fx_offset
;
5620 md_number_to_chars (buf
, value
, 4);
5626 case BFD_RELOC_ARM_PLT32
:
5627 /* It appears the instruction is fully prepared at this point. */
5631 case BFD_RELOC_ARM_GOTPC
:
5632 md_number_to_chars (buf
, value
, 4);
5635 case BFD_RELOC_ARM_CP_OFF_IMM
:
5637 if (value
< -1023 || value
> 1023 || (value
& 3))
5638 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5639 _("Illegal value for co-processor offset"));
5642 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5643 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5644 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5647 case BFD_RELOC_ARM_THUMB_OFFSET
:
5648 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5649 /* Exactly what ranges, and where the offset is inserted depends on
5650 the type of instruction, we can establish this from the top 4 bits */
5651 switch (newval
>> 12)
5653 case 4: /* PC load */
5654 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5655 forced to zero for these loads, so we will need to round
5656 up the offset if the instruction address is not word
5657 aligned (since the final address produced must be, and
5658 we can only describe word-aligned immediate offsets). */
5660 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5661 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5662 _("Invalid offset, target not word aligned (0x%08X)"),
5663 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5665 if ((value
+ 2) & ~0x3fe)
5666 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5667 _("Invalid offset, value too big (0x%08X)"), value
);
5669 /* Round up, since pc will be rounded down. */
5670 newval
|= (value
+ 2) >> 2;
5673 case 9: /* SP load/store */
5675 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5676 _("Invalid offset, value too big (0x%08X)"), value
);
5677 newval
|= value
>> 2;
5680 case 6: /* Word load/store */
5682 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5683 _("Invalid offset, value too big (0x%08X)"), value
);
5684 newval
|= value
<< 4; /* 6 - 2 */
5687 case 7: /* Byte load/store */
5689 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5690 _("Invalid offset, value too big (0x%08X)"), value
);
5691 newval
|= value
<< 6;
5694 case 8: /* Halfword load/store */
5696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5697 _("Invalid offset, value too big (0x%08X)"), value
);
5698 newval
|= value
<< 5; /* 6 - 1 */
5702 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5703 "Unable to process relocation for thumb opcode: %lx",
5704 (unsigned long) newval
);
5707 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5710 case BFD_RELOC_ARM_THUMB_ADD
:
5711 /* This is a complicated relocation, since we use it for all of
5712 the following immediate relocations:
5715 9bit ADD/SUB SP word-aligned
5716 10bit ADD PC/SP word-aligned
5718 The type of instruction being processed is encoded in the
5724 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5726 int rd
= (newval
>> 4) & 0xf;
5727 int rs
= newval
& 0xf;
5728 int subtract
= newval
& 0x8000;
5733 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5734 _("Invalid immediate for stack address calculation"));
5735 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5736 newval
|= value
>> 2;
5738 else if (rs
== REG_PC
|| rs
== REG_SP
)
5742 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5743 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5744 (unsigned long) value
);
5745 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5747 newval
|= value
>> 2;
5752 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5753 _("Invalid 8bit immediate"));
5754 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5755 newval
|= (rd
<< 8) | value
;
5760 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5761 _("Invalid 3bit immediate"));
5762 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5763 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5766 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5769 case BFD_RELOC_ARM_THUMB_IMM
:
5770 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5771 switch (newval
>> 11)
5773 case 0x04: /* 8bit immediate MOV */
5774 case 0x05: /* 8bit immediate CMP */
5775 if (value
< 0 || value
> 255)
5776 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5777 _("Invalid immediate: %ld is too large"),
5785 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5788 case BFD_RELOC_ARM_THUMB_SHIFT
:
5789 /* 5bit shift value (0..31) */
5790 if (value
< 0 || value
> 31)
5791 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5792 _("Illegal Thumb shift value: %ld"), (long) value
);
5793 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5794 newval
|= value
<< 6;
5795 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5798 case BFD_RELOC_VTABLE_INHERIT
:
5799 case BFD_RELOC_VTABLE_ENTRY
:
5803 case BFD_RELOC_NONE
:
5805 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5806 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5812 /* Translate internal representation of relocation info to BFD target
5815 tc_gen_reloc (section
, fixp
)
5820 bfd_reloc_code_real_type code
;
5822 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5824 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5825 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5826 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5828 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5830 if (fixp
->fx_pcrel
== 0)
5831 reloc
->addend
= fixp
->fx_offset
;
5833 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5835 reloc
->addend
= fixp
->fx_offset
;
5838 switch (fixp
->fx_r_type
)
5843 code
= BFD_RELOC_8_PCREL
;
5850 code
= BFD_RELOC_16_PCREL
;
5857 code
= BFD_RELOC_32_PCREL
;
5861 case BFD_RELOC_ARM_PCREL_BRANCH
:
5863 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5864 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5865 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5866 case BFD_RELOC_VTABLE_ENTRY
:
5867 case BFD_RELOC_VTABLE_INHERIT
:
5868 code
= fixp
->fx_r_type
;
5871 case BFD_RELOC_ARM_LITERAL
:
5872 case BFD_RELOC_ARM_HWLITERAL
:
5873 /* If this is called then the a literal has been referenced across
5874 a section boundary - possibly due to an implicit dump */
5875 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5876 _("Literal referenced across section boundary (Implicit dump?)"));
5880 case BFD_RELOC_ARM_GOT32
:
5881 case BFD_RELOC_ARM_GOTOFF
:
5882 case BFD_RELOC_ARM_PLT32
:
5883 code
= fixp
->fx_r_type
;
5887 case BFD_RELOC_ARM_IMMEDIATE
:
5888 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5889 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5893 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5894 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5895 _("ADRL used for a symbol not defined in the same file"),
5899 case BFD_RELOC_ARM_OFFSET_IMM
:
5900 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5901 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5908 switch (fixp
->fx_r_type
)
5910 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5911 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5912 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5913 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5914 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5915 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5916 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5917 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5918 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5919 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5920 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5921 default: type
= _("<unknown>"); break;
5923 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5924 _("Can not represent %s relocation in this object file format (%d)"),
5925 type
, fixp
->fx_pcrel
);
5931 if (code
== BFD_RELOC_32_PCREL
5933 && fixp
->fx_addsy
== GOT_symbol
)
5935 code
= BFD_RELOC_ARM_GOTPC
;
5936 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5940 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5942 if (reloc
->howto
== NULL
)
5944 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5945 _("Can not represent %s relocation in this object file format"),
5946 bfd_get_reloc_code_name (code
));
5950 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5951 vtable entry to be used in the relocation's section offset. */
5952 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5953 reloc
->address
= fixp
->fx_offset
;
5959 md_estimate_size_before_relax (fragP
, segtype
)
5963 as_fatal (_("md_estimate_size_before_relax\n"));
5968 output_inst
PARAMS ((void))
5974 as_bad (inst
.error
);
5978 to
= frag_more (inst
.size
);
5980 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5982 assert (inst
.size
== (2 * THUMB_SIZE
));
5983 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5984 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
5986 else if (inst
.size
> INSN_SIZE
)
5988 assert (inst
.size
== (2 * INSN_SIZE
));
5989 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
5990 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
5993 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5995 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5996 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5997 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6012 /* Align the instruction.
6013 This may not be the right thing to do but ... */
6014 /* arm_align (2, 0); */
6015 listing_prev_line (); /* Defined in listing.h */
6017 /* Align the previous label if needed. */
6018 if (last_label_seen
!= NULL
)
6020 symbol_set_frag (last_label_seen
, frag_now
);
6021 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6022 S_SET_SEGMENT (last_label_seen
, now_seg
);
6025 memset (&inst
, '\0', sizeof (inst
));
6026 inst
.reloc
.type
= BFD_RELOC_NONE
;
6028 skip_whitespace (str
);
6030 /* Scan up to the end of the op-code, which must end in white space or
6032 for (start
= p
= str
; *p
!= '\0'; p
++)
6038 as_bad (_("No operator -- statement `%s'\n"), str
);
6044 CONST
struct thumb_opcode
* opcode
;
6048 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6053 inst
.instruction
= opcode
->value
;
6054 inst
.size
= opcode
->size
;
6055 (*opcode
->parms
)(p
);
6062 CONST
struct asm_opcode
* opcode
;
6064 inst
.size
= INSN_SIZE
;
6065 /* p now points to the end of the opcode, probably white space, but we
6066 have to break the opcode up in case it contains condionals and flags;
6067 keep trying with progressively smaller basic instructions until one
6068 matches, or we run out of opcode. */
6069 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6070 for (; q
!= str
; q
--)
6074 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6077 if (opcode
&& opcode
->template)
6079 unsigned long flag_bits
= 0;
6082 /* Check that this instruction is supported for this CPU. */
6083 if ((opcode
->variants
& cpu_variant
) == 0)
6086 inst
.instruction
= opcode
->value
;
6087 if (q
== p
) /* Just a simple opcode. */
6089 if (opcode
->comp_suffix
!= 0)
6090 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6091 opcode
->comp_suffix
);
6094 inst
.instruction
|= COND_ALWAYS
;
6095 (*opcode
->parms
)(q
, 0);
6101 /* Now check for a conditional. */
6105 CONST
struct asm_cond
*cond
;
6109 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6113 if (cond
->value
== 0xf0000000)
6115 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6117 inst
.instruction
|= cond
->value
;
6121 inst
.instruction
|= COND_ALWAYS
;
6124 inst
.instruction
|= COND_ALWAYS
;
6126 /* If there is a compulsory suffix, it should come here, before
6127 any optional flags. */
6128 if (opcode
->comp_suffix
)
6130 CONST
char *s
= opcode
->comp_suffix
;
6142 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6143 opcode
->comp_suffix
);
6150 /* The remainder, if any should now be flags for the instruction;
6151 Scan these checking each one found with the opcode. */
6155 CONST
struct asm_flg
*flag
= opcode
->flags
;
6164 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6166 if (streq (r
, flag
[flagno
].template))
6168 flag_bits
|= flag
[flagno
].set_bits
;
6174 if (! flag
[flagno
].template)
6181 (*opcode
->parms
) (p
, flag_bits
);
6191 /* It wasn't an instruction, but it might be a register alias of the form
6194 skip_whitespace (q
);
6199 if (*q
&& !strncmp (q
, ".req ", 4))
6202 char * copy_of_str
= str
;
6206 skip_whitespace (q
);
6208 for (r
= q
; *r
!= '\0'; r
++)
6218 regnum
= arm_reg_parse (& q
);
6221 reg
= arm_reg_parse (& str
);
6226 insert_reg_alias (str
, regnum
);
6228 as_warn (_("register '%s' does not exist"), q
);
6230 else if (regnum
!= FAIL
)
6233 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6235 /* Do not warn about redefinitions to the same alias. */
6238 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6242 as_warn (_("ignoring incomplete .req pseuso op"));
6249 as_bad (_("bad instruction `%s'"), start
);
6254 * Invocation line includes a switch not recognized by the base assembler.
6255 * See if it's a processor-specific option. These are:
6256 * Cpu variants, the arm part is optional:
6257 * -m[arm]1 Currently not supported.
6258 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6259 * -m[arm]3 Arm 3 processor
6260 * -m[arm]6[xx], Arm 6 processors
6261 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6262 * -m[arm]8[10] Arm 8 processors
6263 * -m[arm]9[20][tdmi] Arm 9 processors
6264 * -mstrongarm[110[0]] StrongARM processors
6265 * -m[arm]v[2345] Arm architecures
6266 * -mall All (except the ARM1)
6268 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6269 * -mfpe-old (No float load/store multiples)
6270 * -mno-fpu Disable all floating point instructions
6271 * Run-time endian selection:
6272 * -EB big endian cpu
6273 * -EL little endian cpu
6274 * ARM Procedure Calling Standard:
6275 * -mapcs-32 32 bit APCS
6276 * -mapcs-26 26 bit APCS
6277 * -mapcs-float Pass floats in float regs
6278 * -mapcs-reentrant Position independent code
6279 * -mthumb-interwork Code supports Arm/Thumb interworking
6280 * -moabi Old ELF ABI
6283 CONST
char * md_shortopts
= "m:k";
6284 struct option md_longopts
[] =
6286 #ifdef ARM_BI_ENDIAN
6287 #define OPTION_EB (OPTION_MD_BASE + 0)
6288 {"EB", no_argument
, NULL
, OPTION_EB
},
6289 #define OPTION_EL (OPTION_MD_BASE + 1)
6290 {"EL", no_argument
, NULL
, OPTION_EL
},
6292 #define OPTION_OABI (OPTION_MD_BASE +2)
6293 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6296 {NULL
, no_argument
, NULL
, 0}
6298 size_t md_longopts_size
= sizeof (md_longopts
);
6301 md_parse_option (c
, arg
)
6309 #ifdef ARM_BI_ENDIAN
6311 target_big_endian
= 1;
6314 target_big_endian
= 0;
6322 if (streq (str
, "fpa10"))
6323 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6324 else if (streq (str
, "fpa11"))
6325 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6326 else if (streq (str
, "fpe-old"))
6327 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6333 if (streq (str
, "no-fpu"))
6334 cpu_variant
&= ~FPU_ALL
;
6339 if (streq (str
, "oabi"))
6345 /* Limit assembler to generating only Thumb instructions: */
6346 if (streq (str
, "thumb"))
6348 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6349 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6352 else if (streq (str
, "thumb-interwork"))
6354 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCH_V4
;
6355 #if defined OBJ_COFF || defined OBJ_ELF
6356 support_interwork
= true;
6364 if (streq (str
, "all"))
6366 cpu_variant
= ARM_ALL
| FPU_ALL
;
6369 #if defined OBJ_COFF || defined OBJ_ELF
6370 if (! strncmp (str
, "apcs-", 5))
6372 /* GCC passes on all command line options starting "-mapcs-..."
6373 to us, so we must parse them here. */
6377 if (streq (str
, "32"))
6379 uses_apcs_26
= false;
6382 else if (streq (str
, "26"))
6384 uses_apcs_26
= true;
6387 else if (streq (str
, "frame"))
6389 /* Stack frames are being generated - does not affect
6393 else if (streq (str
, "stack-check"))
6395 /* Stack checking is being performed - does not affect
6396 linkage, but does require that the functions
6397 __rt_stkovf_split_small and __rt_stkovf_split_big be
6398 present in the final link. */
6402 else if (streq (str
, "float"))
6404 /* Floating point arguments are being passed in the floating
6405 point registers. This does affect linking, since this
6406 version of the APCS is incompatible with the version that
6407 passes floating points in the integer registers. */
6409 uses_apcs_float
= true;
6412 else if (streq (str
, "reentrant"))
6414 /* Reentrant code has been generated. This does affect
6415 linking, since there is no point in linking reentrant/
6416 position independent code with absolute position code. */
6421 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6425 /* Strip off optional "arm" */
6426 if (! strncmp (str
, "arm", 3))
6432 if (streq (str
, "1"))
6433 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6439 if (streq (str
, "2"))
6440 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6441 else if (streq (str
, "250"))
6442 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6448 if (streq (str
, "3"))
6449 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6455 switch (strtol (str
, NULL
, 10))
6462 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6470 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6482 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6488 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6492 cpu_variant
|= ARM_LONGMUL
;
6495 case 'f': /* fe => fp enabled cpu. */
6501 case 'c': /* Left over from 710c processor name. */
6502 case 'd': /* Debug */
6503 case 'i': /* Embedded ICE */
6504 /* Included for completeness in ARM processor naming. */
6514 if (streq (str
, "8") || streq (str
, "810"))
6515 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6521 if (streq (str
, "9"))
6522 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6523 else if (streq (str
, "920"))
6524 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6525 else if (streq (str
, "920t"))
6526 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6527 else if (streq (str
, "9tdmi"))
6528 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6534 if (streq (str
, "strongarm")
6535 || streq (str
, "strongarm110")
6536 || streq (str
, "strongarm1100"))
6537 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6543 /* Select variant based on architecture rather than processor */
6549 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6550 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6551 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6556 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6560 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6562 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6567 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6571 case 't': cpu_variant
|= ARM_THUMB
; break;
6573 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6578 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6582 case 't': cpu_variant
|= ARM_THUMB
; break;
6584 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6589 as_bad (_("Invalid architecture variant -m%s"), arg
);
6596 as_bad (_("Invalid processor variant -m%s"), arg
);
6602 #if defined OBJ_ELF || defined OBJ_COFF
6621 ARM Specific Assembler Options:\n\
6622 -m[arm][<processor name>] select processor variant\n\
6623 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6624 -mthumb only allow Thumb instructions\n\
6625 -mthumb-interwork mark the assembled code as supporting interworking\n\
6626 -mall allow any instruction\n\
6627 -mfpa10, -mfpa11 select floating point architecture\n\
6628 -mfpe-old don't allow floating-point multiple instructions\n\
6629 -mno-fpu don't allow any floating-point instructions.\n"));
6632 -k generate PIC code.\n"));
6633 #if defined OBJ_COFF || defined OBJ_ELF
6636 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6639 -mapcs-float floating point args are passed in FP regs\n"));
6642 -mapcs-reentrant the code is position independent/reentrant\n"));
6647 -moabi support the old ELF ABI\n"));
6649 #ifdef ARM_BI_ENDIAN
6652 -EB assemble code for a big endian cpu\n\
6653 -EL assemble code for a little endian cpu\n"));
6657 /* We need to be able to fix up arbitrary expressions in some statements.
6658 This is so that we can handle symbols that are an arbitrary distance from
6659 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6660 which returns part of an address in a form which will be valid for
6661 a data instruction. We do this by pushing the expression into a symbol
6662 in the expr_section, and creating a fix for that. */
6665 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6674 arm_fix_data
* arm_data
;
6682 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6686 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6691 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6692 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6693 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6694 arm_data
->thumb_mode
= thumb_mode
;
6700 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6702 cons_fix_new_arm (frag
, where
, size
, exp
)
6708 bfd_reloc_code_real_type type
;
6713 * @@ Should look at CPU word size.
6718 type
= BFD_RELOC_16
;
6722 type
= BFD_RELOC_32
;
6725 type
= BFD_RELOC_64
;
6729 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6732 /* A good place to do this, although this was probably not intended
6733 for this kind of use. We need to dump the literal pool before
6734 references are made to a null symbol pointer. */
6738 if (current_poolP
== NULL
)
6741 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6743 listing_prev_line ();
6747 arm_start_line_hook ()
6749 last_label_seen
= NULL
;
6753 arm_frob_label (sym
)
6756 last_label_seen
= sym
;
6758 ARM_SET_THUMB (sym
, thumb_mode
);
6760 #if defined OBJ_COFF || defined OBJ_ELF
6761 ARM_SET_INTERWORK (sym
, support_interwork
);
6764 if (label_is_thumb_function_name
)
6766 /* When the address of a Thumb function is taken the bottom
6767 bit of that address should be set. This will allow
6768 interworking between Arm and Thumb functions to work
6771 THUMB_SET_FUNC (sym
, 1);
6773 label_is_thumb_function_name
= false;
6777 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6781 arm_adjust_symtab ()
6786 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6788 if (ARM_IS_THUMB (sym
))
6790 if (THUMB_IS_FUNC (sym
))
6792 /* Mark the symbol as a Thumb function. */
6793 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6794 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6795 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6797 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6798 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6800 as_bad (_("%s: unexpected function type: %d"),
6801 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6803 else switch (S_GET_STORAGE_CLASS (sym
))
6806 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6809 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6812 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6814 default: /* do nothing */
6819 if (ARM_IS_INTERWORK (sym
))
6820 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6825 elf_symbol_type
* elf_sym
;
6828 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6830 if (ARM_IS_THUMB (sym
))
6832 if (THUMB_IS_FUNC (sym
))
6834 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6835 bind
= ELF_ST_BIND (elf_sym
);
6836 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6846 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6848 *input_line_pointer
= '/';
6849 input_line_pointer
+= 5;
6850 *input_line_pointer
= 0;
6858 arm_canonicalize_symbol_name (name
)
6863 if (thumb_mode
&& (len
= strlen (name
)) > 5
6864 && streq (name
+ len
- 5, "/data"))
6865 *(name
+ len
- 5) = 0;
6871 arm_validate_fix (fixP
)
6874 /* If the destination of the branch is a defined symbol which does not have
6875 the THUMB_FUNC attribute, then we must be calling a function which has
6876 the (interfacearm) attribute. We look for the Thumb entry point to that
6877 function and change the branch to refer to that function instead. */
6878 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6879 && fixP
->fx_addsy
!= NULL
6880 && S_IS_DEFINED (fixP
->fx_addsy
)
6881 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6883 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6891 /* Relocations against Thumb function names must be left unadjusted,
6892 so that the linker can use this information to correctly set the
6893 bottom bit of their addresses. The MIPS version of this function
6894 also prevents relocations that are mips-16 specific, but I do not
6895 know why it does this.
6898 There is one other problem that ought to be addressed here, but
6899 which currently is not: Taking the address of a label (rather
6900 than a function) and then later jumping to that address. Such
6901 addresses also ought to have their bottom bit set (assuming that
6902 they reside in Thumb code), but at the moment they will not. */
6905 arm_fix_adjustable (fixP
)
6908 if (fixP
->fx_addsy
== NULL
)
6911 /* Prevent all adjustments to global symbols. */
6912 if (S_IS_EXTERN (fixP
->fx_addsy
))
6915 if (S_IS_WEAK (fixP
->fx_addsy
))
6918 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6919 && fixP
->fx_subsy
== NULL
)
6922 /* We need the symbol name for the VTABLE entries */
6923 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6924 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6931 elf32_arm_target_format ()
6933 if (target_big_endian
)
6935 return "elf32-bigarm-oabi";
6937 return "elf32-bigarm";
6940 return "elf32-littlearm-oabi";
6942 return "elf32-littlearm";
6946 armelf_frob_symbol (symp
, puntp
)
6950 elf_frob_symbol (symp
, puntp
);
6954 arm_force_relocation (fixp
)
6957 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6958 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6959 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
6960 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
6966 static bfd_reloc_code_real_type
6976 bfd_reloc_code_real_type reloc
;
6980 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6981 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6982 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6983 /* ScottB: Jan 30, 1998 */
6984 /* Added support for parsing "var(PLT)" branch instructions */
6985 /* generated by GCC for PLT relocs */
6986 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6987 { NULL
, 0, BFD_RELOC_UNUSED
}
6991 for (i
= 0, ip
= input_line_pointer
;
6992 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6994 id
[i
] = tolower (*ip
);
6996 for (i
= 0; reloc_map
[i
].str
; i
++)
6997 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7000 input_line_pointer
+= reloc_map
[i
].len
;
7002 return reloc_map
[i
].reloc
;
7006 s_arm_elf_cons (nbytes
)
7011 #ifdef md_flush_pending_output
7012 md_flush_pending_output ();
7015 if (is_it_end_of_statement ())
7017 demand_empty_rest_of_line ();
7021 #ifdef md_cons_align
7022 md_cons_align (nbytes
);
7027 bfd_reloc_code_real_type reloc
;
7031 if (exp
.X_op
== O_symbol
7032 && * input_line_pointer
== '('
7033 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7035 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7036 int size
= bfd_get_reloc_size (howto
);
7039 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7042 register char * p
= frag_more ((int) nbytes
);
7043 int offset
= nbytes
- size
;
7045 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7050 emit_expr (& exp
, (unsigned int) nbytes
);
7052 while (*input_line_pointer
++ == ',');
7054 input_line_pointer
--; /* Put terminator back into stream. */
7055 demand_empty_rest_of_line ();
7058 #endif /* OBJ_ELF */