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 ((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 MULTI_SET_PSR 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
> 255))
1134 || (val
< -4095 || val
> 4095))
1144 as_bad (_("Invalid syntax for .req directive."));
1151 /* We don't support putting frags in the BSS segment, we fake it by
1152 marking in_bss, then looking at s_skip for clues?.. */
1153 subseg_set (bss_section
, 0);
1154 demand_empty_rest_of_line ();
1161 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1162 frag_align (1, 0, 0);
1164 record_alignment (now_seg
, 1);
1166 demand_empty_rest_of_line ();
1176 if (current_poolP
== NULL
)
1179 /* Align pool as you have word accesses */
1180 /* Only make a frag if we have to ... */
1182 frag_align (2, 0, 0);
1184 record_alignment (now_seg
, 2);
1186 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1188 symbol_locate (current_poolP
, sym_name
, now_seg
,
1189 (valueT
) frag_now_fix (), frag_now
);
1190 symbol_table_insert (current_poolP
);
1192 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1194 #if defined OBJ_COFF || defined OBJ_ELF
1195 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1198 while (lit_count
< next_literal_pool_place
)
1199 /* First output the expression in the instruction to the pool */
1200 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1202 next_literal_pool_place
= 0;
1203 current_poolP
= NULL
;
1207 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1211 register long temp_fill
;
1212 long max_alignment
= 15;
1214 temp
= get_absolute_expression ();
1215 if (temp
> max_alignment
)
1216 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1219 as_bad (_("Alignment negative. 0 assumed."));
1223 if (*input_line_pointer
== ',')
1225 input_line_pointer
++;
1226 temp_fill
= get_absolute_expression ();
1234 /* Only make a frag if we HAVE to. . . */
1235 if (temp
&& !need_pass_2
)
1236 frag_align (temp
, (int) temp_fill
, 0);
1237 demand_empty_rest_of_line ();
1239 record_alignment (now_seg
, temp
);
1243 s_force_thumb (ignore
)
1246 /* If we are not already in thumb mode go into it, EVEN if
1247 the target processor does not support thumb instructions.
1248 This is used by gcc/config/arm/lib1funcs.asm for example
1249 to compile interworking support functions even if the
1250 target processor should not support interworking. */
1256 record_alignment (now_seg
, 1);
1259 demand_empty_rest_of_line ();
1263 s_thumb_func (ignore
)
1266 /* The following label is the name/address of the start of a Thumb function.
1267 We need to know this for the interworking support. */
1269 label_is_thumb_function_name
= true;
1271 demand_empty_rest_of_line ();
1274 /* Perform a .set directive, but also mark the alias as
1275 being a thumb function. */
1281 /* XXX the following is a duplicate of the code for s_set() in read.c
1282 We cannot just call that code as we need to get at the symbol that
1284 register char * name
;
1285 register char delim
;
1286 register char * end_name
;
1287 register symbolS
* symbolP
;
1290 * Especial apologies for the random logic:
1291 * this just grew, and could be parsed much more simply!
1294 name
= input_line_pointer
;
1295 delim
= get_symbol_end ();
1296 end_name
= input_line_pointer
;
1301 if (*input_line_pointer
!= ',')
1304 as_bad (_("Expected comma after name \"%s\""), name
);
1306 ignore_rest_of_line ();
1310 input_line_pointer
++;
1313 if (name
[0] == '.' && name
[1] == '\0')
1315 /* XXX - this should not happen to .thumb_set */
1319 if ((symbolP
= symbol_find (name
)) == NULL
1320 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1323 /* When doing symbol listings, play games with dummy fragments living
1324 outside the normal fragment chain to record the file and line info
1326 if (listing
& LISTING_SYMBOLS
)
1328 extern struct list_info_struct
* listing_tail
;
1329 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1330 memset (dummy_frag
, 0, sizeof(fragS
));
1331 dummy_frag
->fr_type
= rs_fill
;
1332 dummy_frag
->line
= listing_tail
;
1333 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1334 dummy_frag
->fr_symbol
= symbolP
;
1338 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1341 /* "set" symbols are local unless otherwise specified. */
1342 SF_SET_LOCAL (symbolP
);
1343 #endif /* OBJ_COFF */
1344 } /* make a new symbol */
1346 symbol_table_insert (symbolP
);
1351 && S_IS_DEFINED (symbolP
)
1352 && S_GET_SEGMENT (symbolP
) != reg_section
)
1353 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1355 pseudo_set (symbolP
);
1357 demand_empty_rest_of_line ();
1359 /* XXX Now we come to the Thumb specific bit of code. */
1361 THUMB_SET_FUNC (symbolP
, 1);
1362 ARM_SET_THUMB (symbolP
, 1);
1363 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1366 /* If we change section we must dump the literal pool first. */
1371 if (now_seg
!= text_section
)
1381 if (flag_readonly_data_in_text
)
1383 if (now_seg
!= text_section
)
1386 else if (now_seg
!= data_section
)
1394 arm_s_section (ignore
)
1399 obj_elf_section (ignore
);
1404 opcode_select (width
)
1412 if (! (cpu_variant
& ARM_THUMB
))
1413 as_bad (_("selected processor does not support THUMB opcodes"));
1415 /* No need to force the alignment, since we will have been
1416 coming from ARM mode, which is word-aligned. */
1417 record_alignment (now_seg
, 1);
1424 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1425 as_bad (_("selected processor does not support ARM opcodes"));
1428 frag_align (2, 0, 0);
1429 record_alignment (now_seg
, 1);
1434 as_bad (_("invalid instruction size selected (%d)"), width
);
1443 demand_empty_rest_of_line ();
1451 demand_empty_rest_of_line ();
1460 temp
= get_absolute_expression ();
1465 opcode_select (temp
);
1469 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1477 skip_whitespace (str
);
1480 inst
.error
= _("Garbage following instruction");
1484 skip_past_comma (str
)
1490 while ((c
= *p
) == ' ' || c
== ',')
1493 if (c
== ',' && comma
++)
1501 return comma
? SUCCESS
: FAIL
;
1504 /* A standard register must be given at this point. Shift is the place to
1505 put it in the instruction. */
1508 reg_required_here (str
, shift
)
1512 static char buff
[128]; /* XXX */
1514 char * start
= *str
;
1516 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1519 inst
.instruction
|= reg
<< shift
;
1523 /* Restore the start point, we may have got a reg of the wrong class. */
1526 /* In the few cases where we might be able to accept something else
1527 this error can be overridden. */
1528 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1535 psr_required_here (str
, cpsr
, spsr
)
1541 char * start
= *str
;
1542 psr
= arm_psr_parse (str
);
1544 if (psr
== cpsr
|| psr
== spsr
)
1547 inst
.instruction
|= 1 << 22;
1552 /* In the few cases where we might be able to accept something else
1553 this error can be overridden. */
1554 inst
.error
= _("<psr(f)> expected");
1556 /* Restore the start point. */
1562 co_proc_number (str
)
1565 int processor
, pchar
;
1567 skip_whitespace (* str
);
1569 /* The data sheet seems to imply that just a number on its own is valid
1570 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1572 if (**str
== 'p' || **str
== 'P')
1576 if (pchar
>= '0' && pchar
<= '9')
1578 processor
= pchar
- '0';
1579 if (**str
>= '0' && **str
<= '9')
1581 processor
= processor
* 10 + *(*str
)++ - '0';
1584 inst
.error
= _("Illegal co-processor number");
1591 inst
.error
= _("Bad or missing co-processor number");
1595 inst
.instruction
|= processor
<< 8;
1600 cp_opc_expr (str
, where
, length
)
1607 skip_whitespace (* str
);
1609 memset (&expr
, '\0', sizeof (expr
));
1611 if (my_get_expression (&expr
, str
))
1613 if (expr
.X_op
!= O_constant
)
1615 inst
.error
= _("bad or missing expression");
1619 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1621 inst
.error
= _("immediate co-processor expression too large");
1625 inst
.instruction
|= expr
.X_add_number
<< where
;
1630 cp_reg_required_here (str
, where
)
1635 char * start
= *str
;
1637 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1640 inst
.instruction
|= reg
<< where
;
1644 /* In the few cases where we might be able to accept something else
1645 this error can be overridden. */
1646 inst
.error
= _("Co-processor register expected");
1648 /* Restore the start point. */
1654 fp_reg_required_here (str
, where
)
1659 char * start
= *str
;
1661 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1664 inst
.instruction
|= reg
<< where
;
1668 /* In the few cases where we might be able to accept something else
1669 this error can be overridden. */
1670 inst
.error
= _("Floating point register expected");
1672 /* Restore the start point. */
1678 cp_address_offset (str
)
1683 skip_whitespace (* str
);
1685 if (! is_immediate_prefix (**str
))
1687 inst
.error
= _("immediate expression expected");
1693 if (my_get_expression (& inst
.reloc
.exp
, str
))
1696 if (inst
.reloc
.exp
.X_op
== O_constant
)
1698 offset
= inst
.reloc
.exp
.X_add_number
;
1702 inst
.error
= _("co-processor address must be word aligned");
1706 if (offset
> 1023 || offset
< -1023)
1708 inst
.error
= _("offset too large");
1713 inst
.instruction
|= INDEX_UP
;
1717 inst
.instruction
|= offset
>> 2;
1720 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1726 cp_address_required_here (str
)
1738 skip_whitespace (p
);
1740 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1743 skip_whitespace (p
);
1749 if (skip_past_comma (& p
) == SUCCESS
)
1752 write_back
= WRITE_BACK
;
1756 inst
.error
= _("pc may not be used in post-increment");
1760 if (cp_address_offset (& p
) == FAIL
)
1764 pre_inc
= PRE_INDEX
| INDEX_UP
;
1768 /* '['Rn, #expr']'[!] */
1770 if (skip_past_comma (& p
) == FAIL
)
1772 inst
.error
= _("pre-indexed expression expected");
1776 pre_inc
= PRE_INDEX
;
1778 if (cp_address_offset (& p
) == FAIL
)
1781 skip_whitespace (p
);
1785 inst
.error
= _("missing ]");
1789 skip_whitespace (p
);
1795 inst
.error
= _("pc may not be used with write-back");
1800 write_back
= WRITE_BACK
;
1806 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1809 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1810 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1811 inst
.reloc
.pc_rel
= 1;
1812 inst
.instruction
|= (REG_PC
<< 16);
1813 pre_inc
= PRE_INDEX
;
1816 inst
.instruction
|= write_back
| pre_inc
;
1824 unsigned long flags
;
1826 /* Do nothing really. */
1827 inst
.instruction
|= flags
; /* This is pointless. */
1835 unsigned long flags
;
1837 /* Only one syntax. */
1838 skip_whitespace (str
);
1840 if (reg_required_here (&str
, 12) == FAIL
)
1842 inst
.error
= bad_args
;
1846 if (skip_past_comma (&str
) == FAIL
1847 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1849 inst
.error
= _("<psr> expected");
1853 inst
.instruction
|= flags
;
1858 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1862 unsigned long flags
;
1866 skip_whitespace (str
);
1868 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1870 inst
.instruction
|= PSR_ALL
;
1872 /* Sytax should be "<psr>, Rm" */
1873 if (skip_past_comma (&str
) == FAIL
1874 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1876 inst
.error
= bad_args
;
1882 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1883 inst
.instruction
|= PSR_FLAGS
;
1884 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1885 inst
.instruction
|= PSR_CONTROL
;
1888 inst
.error
= bad_args
;
1892 if (skip_past_comma (&str
) == FAIL
)
1894 inst
.error
= bad_args
;
1898 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1900 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1902 /* Immediate expression. */
1903 else if (is_immediate_prefix (* str
))
1908 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1910 inst
.error
= _("Register or shift expression expected");
1914 if (inst
.reloc
.exp
.X_add_symbol
)
1916 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1917 inst
.reloc
.pc_rel
= 0;
1921 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1924 inst
.error
= _("Invalid constant");
1928 inst
.instruction
|= value
;
1931 flags
|= INST_IMMEDIATE
;
1935 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1941 inst
.instruction
|= flags
;
1946 /* Long Multiply Parser
1947 UMULL RdLo, RdHi, Rm, Rs
1948 SMULL RdLo, RdHi, Rm, Rs
1949 UMLAL RdLo, RdHi, Rm, Rs
1950 SMLAL RdLo, RdHi, Rm, Rs
1953 do_mull (str
, flags
)
1955 unsigned long flags
;
1957 int rdlo
, rdhi
, rm
, rs
;
1959 /* Only one format "rdlo, rdhi, rm, rs" */
1960 skip_whitespace (str
);
1962 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1964 inst
.error
= bad_args
;
1968 if (skip_past_comma (&str
) == FAIL
1969 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1971 inst
.error
= bad_args
;
1975 if (skip_past_comma (&str
) == FAIL
1976 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1978 inst
.error
= bad_args
;
1982 /* rdhi, rdlo and rm must all be different */
1983 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1984 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1986 if (skip_past_comma (&str
) == FAIL
1987 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1989 inst
.error
= bad_args
;
1993 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1995 inst
.error
= bad_pc
;
1999 inst
.instruction
|= flags
;
2007 unsigned long flags
;
2011 /* Only one format "rd, rm, rs" */
2012 skip_whitespace (str
);
2014 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2016 inst
.error
= bad_args
;
2022 inst
.error
= bad_pc
;
2026 if (skip_past_comma (&str
) == FAIL
2027 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2029 inst
.error
= bad_args
;
2035 inst
.error
= bad_pc
;
2040 as_tsktsk (_("rd and rm should be different in mul"));
2042 if (skip_past_comma (&str
) == FAIL
2043 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2045 inst
.error
= bad_args
;
2051 inst
.error
= bad_pc
;
2055 inst
.instruction
|= flags
;
2063 unsigned long flags
;
2067 /* Only one format "rd, rm, rs, rn" */
2068 skip_whitespace (str
);
2070 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2072 inst
.error
= bad_args
;
2078 inst
.error
= bad_pc
;
2082 if (skip_past_comma (&str
) == FAIL
2083 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2085 inst
.error
= bad_args
;
2091 inst
.error
= bad_pc
;
2096 as_tsktsk (_("rd and rm should be different in mla"));
2098 if (skip_past_comma (&str
) == FAIL
2099 || (rd
= reg_required_here (&str
, 8)) == FAIL
2100 || skip_past_comma (&str
) == FAIL
2101 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2103 inst
.error
= bad_args
;
2107 if (rd
== REG_PC
|| rm
== REG_PC
)
2109 inst
.error
= bad_pc
;
2113 inst
.instruction
|= flags
;
2118 /* Returns the index into fp_values of a floating point number, or -1 if
2119 not in the table. */
2121 my_get_float_expression (str
)
2124 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2130 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2131 /* Look for a raw floating point number */
2132 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2133 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2135 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2137 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2139 if (words
[j
] != fp_values
[i
][j
])
2143 if (j
== MAX_LITTLENUMS
)
2151 /* Try and parse a more complex expression, this will probably fail
2152 unless the code uses a floating point prefix (eg "0f") */
2153 save_in
= input_line_pointer
;
2154 input_line_pointer
= *str
;
2155 if (expression (&exp
) == absolute_section
2156 && exp
.X_op
== O_big
2157 && exp
.X_add_number
< 0)
2159 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2161 if (gen_to_words (words
, 5, (long)15) == 0)
2163 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2165 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2167 if (words
[j
] != fp_values
[i
][j
])
2171 if (j
== MAX_LITTLENUMS
)
2173 *str
= input_line_pointer
;
2174 input_line_pointer
= save_in
;
2181 *str
= input_line_pointer
;
2182 input_line_pointer
= save_in
;
2186 /* Return true if anything in the expression is a bignum */
2188 walk_no_bignums (sp
)
2191 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2194 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2196 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2197 || (symbol_get_value_expression (sp
)->X_op_symbol
2198 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2205 my_get_expression (ep
, str
)
2212 save_in
= input_line_pointer
;
2213 input_line_pointer
= *str
;
2214 seg
= expression (ep
);
2217 if (seg
!= absolute_section
2218 && seg
!= text_section
2219 && seg
!= data_section
2220 && seg
!= bss_section
2221 && seg
!= undefined_section
)
2223 inst
.error
= _("bad_segment");
2224 *str
= input_line_pointer
;
2225 input_line_pointer
= save_in
;
2230 /* Get rid of any bignums now, so that we don't generate an error for which
2231 we can't establish a line number later on. Big numbers are never valid
2232 in instructions, which is where this routine is always called. */
2233 if (ep
->X_op
== O_big
2234 || (ep
->X_add_symbol
2235 && (walk_no_bignums (ep
->X_add_symbol
)
2237 && walk_no_bignums (ep
->X_op_symbol
)))))
2239 inst
.error
= _("Invalid constant");
2240 *str
= input_line_pointer
;
2241 input_line_pointer
= save_in
;
2245 *str
= input_line_pointer
;
2246 input_line_pointer
= save_in
;
2250 /* unrestrict should be one if <shift> <register> is permitted for this
2254 decode_shift (str
, unrestrict
)
2258 struct asm_shift
* shft
;
2262 skip_whitespace (* str
);
2264 for (p
= *str
; isalpha (*p
); p
++)
2269 inst
.error
= _("Shift expression expected");
2275 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2279 if (!strncmp (*str
, "rrx", 3)
2280 || !strncmp (*str
, "RRX", 3))
2283 inst
.instruction
|= shft
->value
;
2287 skip_whitespace (p
);
2289 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2291 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2295 else if (is_immediate_prefix (* p
))
2299 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2302 /* Validate some simple #expressions */
2303 if (inst
.reloc
.exp
.X_op
== O_constant
)
2305 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2307 /* Reject operations greater than 32, or lsl #32 */
2308 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2310 inst
.error
= _("Invalid immediate shift");
2314 /* Shifts of zero should be converted to lsl (which is zero)*/
2321 /* Shifts of 32 are encoded as 0, for those shifts that
2326 inst
.instruction
|= (num
<< 7) | shft
->value
;
2331 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2332 inst
.reloc
.pc_rel
= 0;
2333 inst
.instruction
|= shft
->value
;
2339 inst
.error
= unrestrict
? _("shift requires register or #expression")
2340 : _("shift requires #expression");
2346 inst
.error
= _("Shift expression expected");
2350 /* Do those data_ops which can take a negative immediate constant */
2351 /* by altering the instuction. A bit of a hack really */
2355 by inverting the second operand, and
2358 by negating the second operand.
2361 negate_data_op (instruction
, value
)
2362 unsigned long * instruction
;
2363 unsigned long value
;
2366 unsigned long negated
, inverted
;
2368 negated
= validate_immediate (-value
);
2369 inverted
= validate_immediate (~value
);
2371 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2375 case OPCODE_SUB
: /* ADD <-> SUB */
2376 new_inst
= OPCODE_ADD
;
2381 new_inst
= OPCODE_SUB
;
2385 case OPCODE_CMP
: /* CMP <-> CMN */
2386 new_inst
= OPCODE_CMN
;
2391 new_inst
= OPCODE_CMP
;
2395 /* Now Inverted ops */
2396 case OPCODE_MOV
: /* MOV <-> MVN */
2397 new_inst
= OPCODE_MVN
;
2402 new_inst
= OPCODE_MOV
;
2406 case OPCODE_AND
: /* AND <-> BIC */
2407 new_inst
= OPCODE_BIC
;
2412 new_inst
= OPCODE_AND
;
2416 case OPCODE_ADC
: /* ADC <-> SBC */
2417 new_inst
= OPCODE_SBC
;
2422 new_inst
= OPCODE_ADC
;
2426 /* We cannot do anything */
2434 *instruction
&= OPCODE_MASK
;
2435 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2446 skip_whitespace (* str
);
2448 if (reg_required_here (str
, 0) != FAIL
)
2450 if (skip_past_comma (str
) == SUCCESS
)
2451 /* Shift operation on register. */
2452 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2458 /* Immediate expression */
2459 if (is_immediate_prefix (**str
))
2464 if (my_get_expression (&inst
.reloc
.exp
, str
))
2467 if (inst
.reloc
.exp
.X_add_symbol
)
2469 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2470 inst
.reloc
.pc_rel
= 0;
2474 if (skip_past_comma (str
) == SUCCESS
)
2476 /* #x, y -- ie explicit rotation by Y */
2477 if (my_get_expression (&expr
, str
))
2480 if (expr
.X_op
!= O_constant
)
2482 inst
.error
= _("Constant expression expected");
2486 /* Rotate must be a multiple of 2 */
2487 if (((unsigned) expr
.X_add_number
) > 30
2488 || (expr
.X_add_number
& 1) != 0
2489 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2491 inst
.error
= _("Invalid constant");
2494 inst
.instruction
|= INST_IMMEDIATE
;
2495 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2496 inst
.instruction
|= expr
.X_add_number
<< 7;
2500 /* Implicit rotation, select a suitable one */
2501 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2505 /* Can't be done, perhaps the code reads something like
2506 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2507 if ((value
= negate_data_op (&inst
.instruction
,
2508 inst
.reloc
.exp
.X_add_number
))
2511 inst
.error
= _("Invalid constant");
2516 inst
.instruction
|= value
;
2519 inst
.instruction
|= INST_IMMEDIATE
;
2524 inst
.error
= _("Register or shift expression expected");
2533 skip_whitespace (* str
);
2535 if (fp_reg_required_here (str
, 0) != FAIL
)
2539 /* Immediate expression */
2540 if (*((*str
)++) == '#')
2546 skip_whitespace (* str
);
2548 /* First try and match exact strings, this is to guarantee that
2549 some formats will work even for cross assembly */
2551 for (i
= 0; fp_const
[i
]; i
++)
2553 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2557 *str
+= strlen (fp_const
[i
]);
2558 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2560 inst
.instruction
|= i
+ 8;
2567 /* Just because we didn't get a match doesn't mean that the
2568 constant isn't valid, just that it is in a format that we
2569 don't automatically recognize. Try parsing it with
2570 the standard expression routines. */
2571 if ((i
= my_get_float_expression (str
)) >= 0)
2573 inst
.instruction
|= i
+ 8;
2577 inst
.error
= _("Invalid floating point immediate expression");
2580 inst
.error
= _("Floating point register or immediate expression expected");
2586 do_arit (str
, flags
)
2588 unsigned long flags
;
2590 skip_whitespace (str
);
2592 if (reg_required_here (&str
, 12) == FAIL
2593 || skip_past_comma (&str
) == FAIL
2594 || reg_required_here (&str
, 16) == FAIL
2595 || skip_past_comma (&str
) == FAIL
2596 || data_op2 (&str
) == FAIL
)
2599 inst
.error
= bad_args
;
2603 inst
.instruction
|= flags
;
2611 unsigned long flags
;
2613 /* This is a pseudo-op of the form "adr rd, label" to be converted
2614 into a relative address of the form "add rd, pc, #label-.-8" */
2616 skip_whitespace (str
);
2618 if (reg_required_here (&str
, 12) == FAIL
2619 || skip_past_comma (&str
) == FAIL
2620 || my_get_expression (&inst
.reloc
.exp
, &str
))
2623 inst
.error
= bad_args
;
2626 /* Frag hacking will turn this into a sub instruction if the offset turns
2627 out to be negative. */
2628 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2629 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2630 inst
.reloc
.pc_rel
= 1;
2631 inst
.instruction
|= flags
;
2637 do_adrl (str
, flags
)
2639 unsigned long flags
;
2641 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2642 into a relative address of the form:
2643 add rd, pc, #low(label-.-8)"
2644 add rd, rd, #high(label-.-8)" */
2646 skip_whitespace (str
);
2648 if (reg_required_here (& str
, 12) == FAIL
2649 || skip_past_comma (& str
) == FAIL
2650 || my_get_expression (& inst
.reloc
.exp
, & str
))
2653 inst
.error
= bad_args
;
2659 /* Frag hacking will turn this into a sub instruction if the offset turns
2660 out to be negative. */
2661 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2662 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2663 inst
.reloc
.pc_rel
= 1;
2664 inst
.instruction
|= flags
;
2665 inst
.size
= INSN_SIZE
* 2;
2673 unsigned long flags
;
2675 skip_whitespace (str
);
2677 if (reg_required_here (&str
, 16) == FAIL
)
2680 inst
.error
= bad_args
;
2684 if (skip_past_comma (&str
) == FAIL
2685 || data_op2 (&str
) == FAIL
)
2688 inst
.error
= bad_args
;
2692 inst
.instruction
|= flags
;
2693 if ((flags
& 0x0000f000) == 0)
2694 inst
.instruction
|= CONDS_BIT
;
2703 unsigned long flags
;
2705 skip_whitespace (str
);
2707 if (reg_required_here (&str
, 12) == FAIL
)
2710 inst
.error
= bad_args
;
2714 if (skip_past_comma (&str
) == FAIL
2715 || data_op2 (&str
) == FAIL
)
2718 inst
.error
= bad_args
;
2722 inst
.instruction
|= flags
;
2728 ldst_extend (str
, hwse
)
2739 if (my_get_expression (& inst
.reloc
.exp
, str
))
2742 if (inst
.reloc
.exp
.X_op
== O_constant
)
2744 int value
= inst
.reloc
.exp
.X_add_number
;
2746 if ((hwse
&& (value
< -255 || value
> 255))
2747 || (value
< -4095 || value
> 4095))
2749 inst
.error
= _("address offset too large");
2759 /* Halfword and signextension instructions have the
2760 immediate value split across bits 11..8 and bits 3..0 */
2762 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2764 inst
.instruction
|= add
| value
;
2770 inst
.instruction
|= HWOFFSET_IMM
;
2771 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2774 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2775 inst
.reloc
.pc_rel
= 0;
2780 add
= 0; /* and fall through */
2782 (*str
)++; /* and fall through */
2784 if (reg_required_here (str
, 0) == FAIL
)
2788 inst
.instruction
|= add
;
2791 inst
.instruction
|= add
| OFFSET_REG
;
2792 if (skip_past_comma (str
) == SUCCESS
)
2793 return decode_shift (str
, SHIFT_RESTRICT
);
2801 do_ldst (str
, flags
)
2803 unsigned long flags
;
2810 /* This is not ideal, but it is the simplest way of dealing with the
2811 ARM7T halfword instructions (since they use a different
2812 encoding, but the same mnemonic): */
2813 halfword
= (flags
& 0x80000000) != 0;
2816 /* This is actually a load/store of a halfword, or a
2817 signed-extension load */
2818 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2821 = _("Processor does not support halfwords or signed bytes");
2825 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2826 | (flags
& ~COND_MASK
);
2831 skip_whitespace (str
);
2833 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2836 inst
.error
= bad_args
;
2840 if (skip_past_comma (& str
) == FAIL
)
2842 inst
.error
= _("Address expected");
2852 skip_whitespace (str
);
2854 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2857 conflict_reg
= (((conflict_reg
== reg
)
2858 && (inst
.instruction
& LOAD_BIT
))
2861 skip_whitespace (str
);
2866 if (skip_past_comma (&str
) == SUCCESS
)
2868 /* [Rn],... (post inc) */
2869 if (ldst_extend (&str
, halfword
) == FAIL
)
2872 as_warn (_("destination register same as write-back base\n"));
2878 inst
.instruction
|= HWOFFSET_IMM
;
2880 skip_whitespace (str
);
2885 as_warn (_("destination register same as write-back base\n"));
2887 inst
.instruction
|= WRITE_BACK
;
2891 if (! (flags
& TRANS_BIT
))
2898 if (skip_past_comma (&str
) == FAIL
)
2900 inst
.error
= _("pre-indexed expression expected");
2905 if (ldst_extend (&str
, halfword
) == FAIL
)
2908 skip_whitespace (str
);
2912 inst
.error
= _("missing ]");
2916 skip_whitespace (str
);
2921 as_tsktsk (_("destination register same as write-back base\n"));
2923 inst
.instruction
|= WRITE_BACK
;
2927 else if (*str
== '=')
2929 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2932 skip_whitespace (str
);
2934 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2937 if (inst
.reloc
.exp
.X_op
!= O_constant
2938 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2940 inst
.error
= _("Constant expression expected");
2944 if (inst
.reloc
.exp
.X_op
== O_constant
2945 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2947 /* This can be done with a mov instruction */
2948 inst
.instruction
&= LITERAL_MASK
;
2949 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2950 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2956 /* Insert into literal pool */
2957 if (add_to_lit_pool () == FAIL
)
2960 inst
.error
= _("literal pool insertion failed");
2964 /* Change the instruction exp to point to the pool */
2967 inst
.instruction
|= HWOFFSET_IMM
;
2968 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2971 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2972 inst
.reloc
.pc_rel
= 1;
2973 inst
.instruction
|= (REG_PC
<< 16);
2979 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2984 inst
.instruction
|= HWOFFSET_IMM
;
2985 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2988 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2989 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2990 inst
.reloc
.pc_rel
= 1;
2991 inst
.instruction
|= (REG_PC
<< 16);
2995 if (pre_inc
&& (flags
& TRANS_BIT
))
2996 inst
.error
= _("Pre-increment instruction with translate");
2998 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3011 /* We come back here if we get ranges concatenated by '+' or '|' */
3026 skip_whitespace (str
);
3028 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3037 inst
.error
= _("Bad range in register list");
3041 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3043 if (range
& (1 << i
))
3045 (_("Warning: Duplicated register (r%d) in register list"),
3053 if (range
& (1 << reg
))
3054 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3056 else if (reg
<= cur_reg
)
3057 as_tsktsk (_("Warning: Register range not in ascending order"));
3061 } while (skip_past_comma (&str
) != FAIL
3062 || (in_range
= 1, *str
++ == '-'));
3064 skip_whitespace (str
);
3068 inst
.error
= _("Missing `}'");
3076 if (my_get_expression (&expr
, &str
))
3079 if (expr
.X_op
== O_constant
)
3081 if (expr
.X_add_number
3082 != (expr
.X_add_number
& 0x0000ffff))
3084 inst
.error
= _("invalid register mask");
3088 if ((range
& expr
.X_add_number
) != 0)
3090 int regno
= range
& expr
.X_add_number
;
3093 regno
= (1 << regno
) - 1;
3095 (_("Warning: Duplicated register (r%d) in register list"),
3099 range
|= expr
.X_add_number
;
3103 if (inst
.reloc
.type
!= 0)
3105 inst
.error
= _("expression too complex");
3109 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3110 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3111 inst
.reloc
.pc_rel
= 0;
3115 skip_whitespace (str
);
3117 if (*str
== '|' || *str
== '+')
3122 } while (another_range
);
3129 do_ldmstm (str
, flags
)
3131 unsigned long flags
;
3136 skip_whitespace (str
);
3138 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3141 if (base_reg
== REG_PC
)
3143 inst
.error
= _("r15 not allowed as base register");
3147 skip_whitespace (str
);
3151 flags
|= WRITE_BACK
;
3155 if (skip_past_comma (&str
) == FAIL
3156 || (range
= reg_list (&str
)) == FAIL
)
3159 inst
.error
= bad_args
;
3166 flags
|= MULTI_SET_PSR
;
3169 inst
.instruction
|= flags
| range
;
3177 unsigned long flags
;
3179 skip_whitespace (str
);
3181 /* Allow optional leading '#'. */
3182 if (is_immediate_prefix (*str
))
3185 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3188 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3189 inst
.reloc
.pc_rel
= 0;
3190 inst
.instruction
|= flags
;
3198 do_swap (str
, flags
)
3200 unsigned long flags
;
3204 skip_whitespace (str
);
3206 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3211 inst
.error
= _("r15 not allowed in swap");
3215 if (skip_past_comma (&str
) == FAIL
3216 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3219 inst
.error
= bad_args
;
3225 inst
.error
= _("r15 not allowed in swap");
3229 if (skip_past_comma (&str
) == FAIL
3232 inst
.error
= bad_args
;
3236 skip_whitespace (str
);
3238 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3243 inst
.error
= bad_pc
;
3247 skip_whitespace (str
);
3251 inst
.error
= _("missing ]");
3255 inst
.instruction
|= flags
;
3261 do_branch (str
, flags
)
3263 unsigned long flags
;
3265 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3272 /* ScottB: February 5, 1998 */
3273 /* Check to see of PLT32 reloc required for the instruction. */
3275 /* arm_parse_reloc() works on input_line_pointer.
3276 We actually want to parse the operands to the branch instruction
3277 passed in 'str'. Save the input pointer and restore it later. */
3278 save_in
= input_line_pointer
;
3279 input_line_pointer
= str
;
3280 if (inst
.reloc
.exp
.X_op
== O_symbol
3282 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3284 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3285 inst
.reloc
.pc_rel
= 0;
3286 /* Modify str to point to after parsed operands, otherwise
3287 end_of_line() will complain about the (PLT) left in str. */
3288 str
= input_line_pointer
;
3292 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3293 inst
.reloc
.pc_rel
= 1;
3295 input_line_pointer
= save_in
;
3298 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3299 inst
.reloc
.pc_rel
= 1;
3300 #endif /* OBJ_ELF */
3309 unsigned long flags
;
3313 skip_whitespace (str
);
3315 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3319 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3328 unsigned long flags
;
3330 /* Co-processor data operation.
3331 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3332 skip_whitespace (str
);
3334 if (co_proc_number (&str
) == FAIL
)
3337 inst
.error
= bad_args
;
3341 if (skip_past_comma (&str
) == FAIL
3342 || cp_opc_expr (&str
, 20,4) == FAIL
)
3345 inst
.error
= bad_args
;
3349 if (skip_past_comma (&str
) == FAIL
3350 || cp_reg_required_here (&str
, 12) == FAIL
)
3353 inst
.error
= bad_args
;
3357 if (skip_past_comma (&str
) == FAIL
3358 || cp_reg_required_here (&str
, 16) == FAIL
)
3361 inst
.error
= bad_args
;
3365 if (skip_past_comma (&str
) == FAIL
3366 || cp_reg_required_here (&str
, 0) == FAIL
)
3369 inst
.error
= bad_args
;
3373 if (skip_past_comma (&str
) == SUCCESS
)
3375 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3378 inst
.error
= bad_args
;
3388 do_lstc (str
, flags
)
3390 unsigned long flags
;
3392 /* Co-processor register load/store.
3393 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3395 skip_whitespace (str
);
3397 if (co_proc_number (&str
) == FAIL
)
3400 inst
.error
= bad_args
;
3404 if (skip_past_comma (&str
) == FAIL
3405 || cp_reg_required_here (&str
, 12) == FAIL
)
3408 inst
.error
= bad_args
;
3412 if (skip_past_comma (&str
) == FAIL
3413 || cp_address_required_here (&str
) == FAIL
)
3416 inst
.error
= bad_args
;
3420 inst
.instruction
|= flags
;
3426 do_co_reg (str
, flags
)
3428 unsigned long flags
;
3430 /* Co-processor register transfer.
3431 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3433 skip_whitespace (str
);
3435 if (co_proc_number (&str
) == FAIL
)
3438 inst
.error
= bad_args
;
3442 if (skip_past_comma (&str
) == FAIL
3443 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3446 inst
.error
= bad_args
;
3450 if (skip_past_comma (&str
) == FAIL
3451 || reg_required_here (&str
, 12) == FAIL
)
3454 inst
.error
= bad_args
;
3458 if (skip_past_comma (&str
) == FAIL
3459 || cp_reg_required_here (&str
, 16) == FAIL
)
3462 inst
.error
= bad_args
;
3466 if (skip_past_comma (&str
) == FAIL
3467 || cp_reg_required_here (&str
, 0) == FAIL
)
3470 inst
.error
= bad_args
;
3474 if (skip_past_comma (&str
) == SUCCESS
)
3476 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3479 inst
.error
= bad_args
;
3489 do_fp_ctrl (str
, flags
)
3491 unsigned long flags
;
3493 /* FP control registers.
3494 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3496 skip_whitespace (str
);
3498 if (reg_required_here (&str
, 12) == FAIL
)
3501 inst
.error
= bad_args
;
3510 do_fp_ldst (str
, flags
)
3512 unsigned long flags
;
3514 skip_whitespace (str
);
3516 switch (inst
.suffix
)
3521 inst
.instruction
|= CP_T_X
;
3524 inst
.instruction
|= CP_T_Y
;
3527 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3533 if (fp_reg_required_here (&str
, 12) == FAIL
)
3536 inst
.error
= bad_args
;
3540 if (skip_past_comma (&str
) == FAIL
3541 || cp_address_required_here (&str
) == FAIL
)
3544 inst
.error
= bad_args
;
3552 do_fp_ldmstm (str
, flags
)
3554 unsigned long flags
;
3558 skip_whitespace (str
);
3560 if (fp_reg_required_here (&str
, 12) == FAIL
)
3563 inst
.error
= bad_args
;
3567 /* Get Number of registers to transfer */
3568 if (skip_past_comma (&str
) == FAIL
3569 || my_get_expression (&inst
.reloc
.exp
, &str
))
3572 inst
.error
= _("constant expression expected");
3576 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3578 inst
.error
= _("Constant value required for number of registers");
3582 num_regs
= inst
.reloc
.exp
.X_add_number
;
3584 if (num_regs
< 1 || num_regs
> 4)
3586 inst
.error
= _("number of registers must be in the range [1:4]");
3593 inst
.instruction
|= CP_T_X
;
3596 inst
.instruction
|= CP_T_Y
;
3599 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3613 /* The instruction specified "ea" or "fd", so we can only accept
3614 [Rn]{!}. The instruction does not really support stacking or
3615 unstacking, so we have to emulate these by setting appropriate
3616 bits and offsets. */
3617 if (skip_past_comma (&str
) == FAIL
3621 inst
.error
= bad_args
;
3626 skip_whitespace (str
);
3628 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3631 skip_whitespace (str
);
3635 inst
.error
= bad_args
;
3646 inst
.error
= _("R15 not allowed as base register with write-back");
3653 if (flags
& CP_T_Pre
)
3656 offset
= 3 * num_regs
;
3662 /* Post-increment */
3666 offset
= 3 * num_regs
;
3670 /* No write-back, so convert this into a standard pre-increment
3671 instruction -- aesthetically more pleasing. */
3672 flags
= CP_T_Pre
| CP_T_UD
;
3677 inst
.instruction
|= flags
| offset
;
3679 else if (skip_past_comma (&str
) == FAIL
3680 || cp_address_required_here (&str
) == FAIL
)
3683 inst
.error
= bad_args
;
3691 do_fp_dyadic (str
, flags
)
3693 unsigned long flags
;
3695 skip_whitespace (str
);
3697 switch (inst
.suffix
)
3702 inst
.instruction
|= 0x00000080;
3705 inst
.instruction
|= 0x00080000;
3711 if (fp_reg_required_here (&str
, 12) == FAIL
)
3714 inst
.error
= bad_args
;
3718 if (skip_past_comma (&str
) == FAIL
3719 || fp_reg_required_here (&str
, 16) == FAIL
)
3722 inst
.error
= bad_args
;
3726 if (skip_past_comma (&str
) == FAIL
3727 || fp_op2 (&str
) == FAIL
)
3730 inst
.error
= bad_args
;
3734 inst
.instruction
|= flags
;
3740 do_fp_monadic (str
, flags
)
3742 unsigned long flags
;
3744 skip_whitespace (str
);
3746 switch (inst
.suffix
)
3751 inst
.instruction
|= 0x00000080;
3754 inst
.instruction
|= 0x00080000;
3760 if (fp_reg_required_here (&str
, 12) == FAIL
)
3763 inst
.error
= bad_args
;
3767 if (skip_past_comma (&str
) == FAIL
3768 || fp_op2 (&str
) == FAIL
)
3771 inst
.error
= bad_args
;
3775 inst
.instruction
|= flags
;
3781 do_fp_cmp (str
, flags
)
3783 unsigned long flags
;
3785 skip_whitespace (str
);
3787 if (fp_reg_required_here (&str
, 16) == FAIL
)
3790 inst
.error
= bad_args
;
3794 if (skip_past_comma (&str
) == FAIL
3795 || fp_op2 (&str
) == FAIL
)
3798 inst
.error
= bad_args
;
3802 inst
.instruction
|= flags
;
3808 do_fp_from_reg (str
, flags
)
3810 unsigned long flags
;
3812 skip_whitespace (str
);
3814 switch (inst
.suffix
)
3819 inst
.instruction
|= 0x00000080;
3822 inst
.instruction
|= 0x00080000;
3828 if (fp_reg_required_here (&str
, 16) == FAIL
)
3831 inst
.error
= bad_args
;
3835 if (skip_past_comma (&str
) == FAIL
3836 || reg_required_here (&str
, 12) == FAIL
)
3839 inst
.error
= bad_args
;
3843 inst
.instruction
|= flags
;
3849 do_fp_to_reg (str
, flags
)
3851 unsigned long flags
;
3853 skip_whitespace (str
);
3855 if (reg_required_here (&str
, 12) == FAIL
)
3858 if (skip_past_comma (&str
) == FAIL
3859 || fp_reg_required_here (&str
, 0) == FAIL
)
3862 inst
.error
= bad_args
;
3866 inst
.instruction
|= flags
;
3871 /* Thumb specific routines */
3873 /* Parse and validate that a register is of the right form, this saves
3874 repeated checking of this information in many similar cases.
3875 Unlike the 32-bit case we do not insert the register into the opcode
3876 here, since the position is often unknown until the full instruction
3879 thumb_reg (strp
, hi_lo
)
3885 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3893 inst
.error
= _("lo register required");
3901 inst
.error
= _("hi register required");
3913 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3916 thumb_add_sub (str
, subtract
)
3920 int Rd
, Rs
, Rn
= FAIL
;
3922 skip_whitespace (str
);
3924 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3925 || skip_past_comma (&str
) == FAIL
)
3928 inst
.error
= bad_args
;
3932 if (is_immediate_prefix (*str
))
3936 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3941 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3944 if (skip_past_comma (&str
) == FAIL
)
3946 /* Two operand format, shuffle the registers and pretend there
3951 else if (is_immediate_prefix (*str
))
3954 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3957 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3961 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3962 for the latter case, EXPR contains the immediate that was found. */
3965 /* All register format. */
3966 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3970 inst
.error
= _("dest and source1 must be the same register");
3974 /* Can't do this for SUB */
3977 inst
.error
= _("subtract valid only on lo regs");
3981 inst
.instruction
= (T_OPCODE_ADD_HI
3982 | (Rd
> 7 ? THUMB_H1
: 0)
3983 | (Rn
> 7 ? THUMB_H2
: 0));
3984 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3988 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3989 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3994 /* Immediate expression, now things start to get nasty. */
3996 /* First deal with HI regs, only very restricted cases allowed:
3997 Adjusting SP, and using PC or SP to get an address. */
3998 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3999 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4001 inst
.error
= _("invalid Hi register with immediate");
4005 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4007 /* Value isn't known yet, all we can do is store all the fragments
4008 we know about in the instruction and let the reloc hacking
4010 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4011 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4015 int offset
= inst
.reloc
.exp
.X_add_number
;
4025 /* Quick check, in case offset is MIN_INT */
4028 inst
.error
= _("immediate value out of range");
4037 if (offset
& ~0x1fc)
4039 inst
.error
= _("invalid immediate value for stack adjust");
4042 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4043 inst
.instruction
|= offset
>> 2;
4045 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4048 || (offset
& ~0x3fc))
4050 inst
.error
= _("invalid immediate for address calculation");
4053 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4055 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4061 inst
.error
= _("immediate value out of range");
4064 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4065 inst
.instruction
|= (Rd
<< 8) | offset
;
4071 inst
.error
= _("immediate value out of range");
4074 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4075 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4083 thumb_shift (str
, shift
)
4087 int Rd
, Rs
, Rn
= FAIL
;
4089 skip_whitespace (str
);
4091 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4092 || skip_past_comma (&str
) == FAIL
)
4095 inst
.error
= bad_args
;
4099 if (is_immediate_prefix (*str
))
4101 /* Two operand immediate format, set Rs to Rd. */
4104 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4109 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4112 if (skip_past_comma (&str
) == FAIL
)
4114 /* Two operand format, shuffle the registers and pretend there
4119 else if (is_immediate_prefix (*str
))
4122 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4125 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4129 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4130 for the latter case, EXPR contains the immediate that was found. */
4136 inst
.error
= _("source1 and dest must be same register");
4142 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4143 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4144 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4147 inst
.instruction
|= Rd
| (Rn
<< 3);
4153 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4154 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4155 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4158 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4160 /* Value isn't known yet, create a dummy reloc and let reloc
4161 hacking fix it up */
4163 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4167 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4169 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4171 inst
.error
= _("Invalid immediate for shift");
4175 /* Shifts of zero are handled by converting to LSL */
4176 if (shift_value
== 0)
4177 inst
.instruction
= T_OPCODE_LSL_I
;
4179 /* Shifts of 32 are encoded as a shift of zero */
4180 if (shift_value
== 32)
4183 inst
.instruction
|= shift_value
<< 6;
4186 inst
.instruction
|= Rd
| (Rs
<< 3);
4192 thumb_mov_compare (str
, move
)
4198 skip_whitespace (str
);
4200 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4201 || skip_past_comma (&str
) == FAIL
)
4204 inst
.error
= bad_args
;
4208 if (is_immediate_prefix (*str
))
4211 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4214 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4219 if (Rs
< 8 && Rd
< 8)
4221 if (move
== THUMB_MOVE
)
4222 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4223 since a MOV instruction produces unpredictable results */
4224 inst
.instruction
= T_OPCODE_ADD_I3
;
4226 inst
.instruction
= T_OPCODE_CMP_LR
;
4227 inst
.instruction
|= Rd
| (Rs
<< 3);
4231 if (move
== THUMB_MOVE
)
4232 inst
.instruction
= T_OPCODE_MOV_HR
;
4234 inst
.instruction
= T_OPCODE_CMP_HR
;
4237 inst
.instruction
|= THUMB_H1
;
4240 inst
.instruction
|= THUMB_H2
;
4242 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4249 inst
.error
= _("only lo regs allowed with immediate");
4253 if (move
== THUMB_MOVE
)
4254 inst
.instruction
= T_OPCODE_MOV_I8
;
4256 inst
.instruction
= T_OPCODE_CMP_I8
;
4258 inst
.instruction
|= Rd
<< 8;
4260 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4261 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4264 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4268 inst
.error
= _("invalid immediate");
4272 inst
.instruction
|= value
;
4280 thumb_load_store (str
, load_store
, size
)
4285 int Rd
, Rb
, Ro
= FAIL
;
4287 skip_whitespace (str
);
4289 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4290 || skip_past_comma (&str
) == FAIL
)
4293 inst
.error
= bad_args
;
4300 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4303 if (skip_past_comma (&str
) != FAIL
)
4305 if (is_immediate_prefix (*str
))
4308 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4311 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4316 inst
.reloc
.exp
.X_op
= O_constant
;
4317 inst
.reloc
.exp
.X_add_number
= 0;
4322 inst
.error
= _("expected ']'");
4327 else if (*str
== '=')
4329 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4332 skip_whitespace (str
);
4334 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4339 if ( inst
.reloc
.exp
.X_op
!= O_constant
4340 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4342 inst
.error
= "Constant expression expected";
4346 if (inst
.reloc
.exp
.X_op
== O_constant
4347 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4349 /* This can be done with a mov instruction */
4351 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4352 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4356 /* Insert into literal pool */
4357 if (add_to_lit_pool () == FAIL
)
4360 inst
.error
= "literal pool insertion failed";
4364 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4365 inst
.reloc
.pc_rel
= 1;
4366 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4367 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4373 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4376 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4377 inst
.reloc
.pc_rel
= 1;
4378 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4379 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4384 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4386 if (size
!= THUMB_WORD
)
4388 inst
.error
= _("byte or halfword not valid for base register");
4391 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4393 inst
.error
= _("R15 based store not allowed");
4396 else if (Ro
!= FAIL
)
4398 inst
.error
= _("Invalid base register for register offset");
4403 inst
.instruction
= T_OPCODE_LDR_PC
;
4404 else if (load_store
== THUMB_LOAD
)
4405 inst
.instruction
= T_OPCODE_LDR_SP
;
4407 inst
.instruction
= T_OPCODE_STR_SP
;
4409 inst
.instruction
|= Rd
<< 8;
4410 if (inst
.reloc
.exp
.X_op
== O_constant
)
4412 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4414 if (offset
& ~0x3fc)
4416 inst
.error
= _("invalid offset");
4420 inst
.instruction
|= offset
>> 2;
4423 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4427 inst
.error
= _("invalid base register in load/store");
4430 else if (Ro
== FAIL
)
4432 /* Immediate offset */
4433 if (size
== THUMB_WORD
)
4434 inst
.instruction
= (load_store
== THUMB_LOAD
4435 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4436 else if (size
== THUMB_HALFWORD
)
4437 inst
.instruction
= (load_store
== THUMB_LOAD
4438 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4440 inst
.instruction
= (load_store
== THUMB_LOAD
4441 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4443 inst
.instruction
|= Rd
| (Rb
<< 3);
4445 if (inst
.reloc
.exp
.X_op
== O_constant
)
4447 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4449 if (offset
& ~(0x1f << size
))
4451 inst
.error
= _("Invalid offset");
4454 inst
.instruction
|= (offset
>> size
) << 6;
4457 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4461 /* Register offset */
4462 if (size
== THUMB_WORD
)
4463 inst
.instruction
= (load_store
== THUMB_LOAD
4464 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4465 else if (size
== THUMB_HALFWORD
)
4466 inst
.instruction
= (load_store
== THUMB_LOAD
4467 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4469 inst
.instruction
= (load_store
== THUMB_LOAD
4470 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4472 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4487 /* Handle the Format 4 instructions that do not have equivalents in other
4488 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4496 skip_whitespace (str
);
4498 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4501 if (skip_past_comma (&str
) == FAIL
4502 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4505 inst
.error
= bad_args
;
4509 if (skip_past_comma (&str
) != FAIL
)
4511 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4512 (It isn't allowed for CMP either, but that isn't handled by this
4514 if (inst
.instruction
== T_OPCODE_TST
4515 || inst
.instruction
== T_OPCODE_CMN
4516 || inst
.instruction
== T_OPCODE_NEG
4517 || inst
.instruction
== T_OPCODE_MVN
)
4519 inst
.error
= bad_args
;
4523 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4528 inst
.error
= _("dest and source1 one must be the same register");
4534 if (inst
.instruction
== T_OPCODE_MUL
4536 as_tsktsk (_("Rs and Rd must be different in MUL"));
4538 inst
.instruction
|= Rd
| (Rs
<< 3);
4546 thumb_add_sub (str
, 0);
4553 thumb_shift (str
, THUMB_ASR
);
4560 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4562 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4563 inst
.reloc
.pc_rel
= 1;
4571 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4573 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4574 inst
.reloc
.pc_rel
= 1;
4578 /* Find the real, Thumb encoded start of a Thumb function. */
4581 find_real_start (symbolP
)
4585 const char * name
= S_GET_NAME (symbolP
);
4586 symbolS
* new_target
;
4588 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4589 #define STUB_NAME ".real_start_of"
4594 /* Names that start with '.' are local labels, not function entry points.
4595 The compiler may generate BL instructions to these labels because it
4596 needs to perform a branch to a far away location. */
4600 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4601 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4603 new_target
= symbol_find (real_start
);
4605 if (new_target
== NULL
)
4607 as_warn ("Failed to find real start of function: %s\n", name
);
4608 new_target
= symbolP
;
4621 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4624 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4625 inst
.reloc
.pc_rel
= 1;
4628 /* If the destination of the branch is a defined symbol which does not have
4629 the THUMB_FUNC attribute, then we must be calling a function which has
4630 the (interfacearm) attribute. We look for the Thumb entry point to that
4631 function and change the branch to refer to that function instead. */
4632 if ( inst
.reloc
.exp
.X_op
== O_symbol
4633 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4634 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4635 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4636 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4645 skip_whitespace (str
);
4647 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4650 /* This sets THUMB_H2 from the top bit of reg. */
4651 inst
.instruction
|= reg
<< 3;
4653 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4654 should cause the alignment to be checked once it is known. This is
4655 because BX PC only works if the instruction is word aligned. */
4664 thumb_mov_compare (str
, THUMB_COMPARE
);
4674 skip_whitespace (str
);
4676 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4680 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4684 if (skip_past_comma (&str
) == FAIL
4685 || (range
= reg_list (&str
)) == FAIL
)
4688 inst
.error
= bad_args
;
4692 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4694 /* This really doesn't seem worth it. */
4695 inst
.reloc
.type
= BFD_RELOC_NONE
;
4696 inst
.error
= _("Expression too complex");
4702 inst
.error
= _("only lo-regs valid in load/store multiple");
4706 inst
.instruction
|= (Rb
<< 8) | range
;
4714 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4721 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4728 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4737 skip_whitespace (str
);
4739 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4740 || skip_past_comma (&str
) == FAIL
4742 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4743 || skip_past_comma (&str
) == FAIL
4744 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4748 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4752 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4760 thumb_shift (str
, THUMB_LSL
);
4767 thumb_shift (str
, THUMB_LSR
);
4774 thumb_mov_compare (str
, THUMB_MOVE
);
4783 skip_whitespace (str
);
4785 if ((range
= reg_list (&str
)) == FAIL
)
4788 inst
.error
= bad_args
;
4792 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4794 /* This really doesn't seem worth it. */
4795 inst
.reloc
.type
= BFD_RELOC_NONE
;
4796 inst
.error
= _("Expression too complex");
4802 if ((inst
.instruction
== T_OPCODE_PUSH
4803 && (range
& ~0xff) == 1 << REG_LR
)
4804 || (inst
.instruction
== T_OPCODE_POP
4805 && (range
& ~0xff) == 1 << REG_PC
))
4807 inst
.instruction
|= THUMB_PP_PC_LR
;
4812 inst
.error
= _("invalid register list to push/pop instruction");
4817 inst
.instruction
|= range
;
4825 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4832 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4839 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4846 thumb_add_sub (str
, 1);
4853 skip_whitespace (str
);
4855 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4858 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4867 /* This is a pseudo-op of the form "adr rd, label" to be converted
4868 into a relative address of the form "add rd, pc, #label-.-4" */
4869 skip_whitespace (str
);
4871 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4872 || skip_past_comma (&str
) == FAIL
4873 || my_get_expression (&inst
.reloc
.exp
, &str
))
4876 inst
.error
= bad_args
;
4880 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4881 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4882 inst
.reloc
.pc_rel
= 1;
4883 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4891 int len
= strlen (reg_table
[entry
].name
) + 2;
4892 char * buf
= (char *) xmalloc (len
);
4893 char * buf2
= (char *) xmalloc (len
);
4896 #ifdef REGISTER_PREFIX
4897 buf
[i
++] = REGISTER_PREFIX
;
4900 strcpy (buf
+ i
, reg_table
[entry
].name
);
4902 for (i
= 0; buf
[i
]; i
++)
4903 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4907 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4908 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4912 insert_reg_alias (str
, regnum
)
4916 struct reg_entry
*new =
4917 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4918 char *name
= xmalloc (strlen (str
) + 1);
4922 new->number
= regnum
;
4924 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4928 set_constant_flonums ()
4932 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4933 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4942 if ( (arm_ops_hsh
= hash_new ()) == NULL
4943 || (arm_tops_hsh
= hash_new ()) == NULL
4944 || (arm_cond_hsh
= hash_new ()) == NULL
4945 || (arm_shift_hsh
= hash_new ()) == NULL
4946 || (arm_reg_hsh
= hash_new ()) == NULL
4947 || (arm_psr_hsh
= hash_new ()) == NULL
)
4948 as_fatal (_("Virtual memory exhausted"));
4950 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4951 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4952 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4953 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4954 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4955 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4956 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4957 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4958 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4959 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4961 for (i
= 0; reg_table
[i
].name
; i
++)
4964 set_constant_flonums ();
4966 #if defined OBJ_COFF || defined OBJ_ELF
4968 unsigned int flags
= 0;
4970 /* Set the flags in the private structure */
4971 if (uses_apcs_26
) flags
|= F_APCS26
;
4972 if (support_interwork
) flags
|= F_INTERWORK
;
4973 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4974 if (pic_code
) flags
|= F_PIC
;
4975 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
4977 bfd_set_private_flags (stdoutput
, flags
);
4984 /* Record the CPU type as well */
4985 switch (cpu_variant
& ARM_CPU_MASK
)
4988 mach
= bfd_mach_arm_2
;
4991 case ARM_3
: /* also ARM_250 */
4992 mach
= bfd_mach_arm_2a
;
4996 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4997 mach
= bfd_mach_arm_4
;
5000 case ARM_7
: /* also ARM_6 */
5001 mach
= bfd_mach_arm_3
;
5005 /* Catch special cases. */
5006 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5008 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5009 mach
= bfd_mach_arm_5T
;
5010 else if (cpu_variant
& ARM_EXT_V5
)
5011 mach
= bfd_mach_arm_5
;
5012 else if (cpu_variant
& ARM_THUMB
)
5013 mach
= bfd_mach_arm_4T
;
5014 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5015 mach
= bfd_mach_arm_4
;
5016 else if (cpu_variant
& ARM_LONGMUL
)
5017 mach
= bfd_mach_arm_3M
;
5020 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5024 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5025 for use in the a.out file, and stores them in the array pointed to by buf.
5026 This knows about the endian-ness of the target machine and does
5027 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5028 2 (short) and 4 (long) Floating numbers are put out as a series of
5029 LITTLENUMS (shorts, here at least). */
5031 md_number_to_chars (buf
, val
, n
)
5036 if (target_big_endian
)
5037 number_to_chars_bigendian (buf
, val
, n
);
5039 number_to_chars_littleendian (buf
, val
, n
);
5043 md_chars_to_number (buf
, n
)
5048 unsigned char * where
= (unsigned char *) buf
;
5050 if (target_big_endian
)
5055 result
|= (*where
++ & 255);
5063 result
|= (where
[n
] & 255);
5070 /* Turn a string in input_line_pointer into a floating point constant
5071 of type TYPE, and store the appropriate bytes in *litP. The number
5072 of LITTLENUMS emitted is stored in *sizeP . An error message is
5073 returned, or NULL on OK.
5075 Note that fp constants aren't represent in the normal way on the ARM.
5076 In big endian mode, things are as expected. However, in little endian
5077 mode fp constants are big-endian word-wise, and little-endian byte-wise
5078 within the words. For example, (double) 1.1 in big endian mode is
5079 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5080 the byte sequence 99 99 f1 3f 9a 99 99 99.
5082 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5085 md_atof (type
, litP
, sizeP
)
5091 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5123 return _("Bad call to MD_ATOF()");
5126 t
= atof_ieee (input_line_pointer
, type
, words
);
5128 input_line_pointer
= t
;
5131 if (target_big_endian
)
5133 for (i
= 0; i
< prec
; i
++)
5135 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5141 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5142 8 byte float the order is 1 0 3 2. */
5143 for (i
= 0; i
< prec
; i
+= 2)
5145 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5146 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5154 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5156 md_pcrel_from (fixP
)
5160 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5161 && fixP
->fx_subsy
== NULL
)
5164 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5166 /* PC relative addressing on the Thumb is slightly odd
5167 as the bottom two bits of the PC are forced to zero
5168 for the calculation. */
5169 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5172 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5175 /* Round up a section size to the appropriate boundary. */
5177 md_section_align (segment
, size
)
5182 /* Don't align the dwarf2 debug sections */
5183 if (!strncmp (segment
->name
, ".debug", 5))
5186 /* Round all sects to multiple of 4 */
5187 return (size
+ 3) & ~3;
5190 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5191 we have no need to default values of symbols. */
5195 md_undefined_symbol (name
)
5199 if (name
[0] == '_' && name
[1] == 'G'
5200 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5204 if (symbol_find (name
))
5205 as_bad ("GOT already in the symbol table");
5207 GOT_symbol
= symbol_new (name
, undefined_section
,
5208 (valueT
)0, & zero_address_frag
);
5218 /* arm_reg_parse () := if it looks like a register, return its token and
5219 advance the pointer. */
5223 register char ** ccp
;
5225 char * start
= * ccp
;
5228 struct reg_entry
* reg
;
5230 #ifdef REGISTER_PREFIX
5231 if (*start
!= REGISTER_PREFIX
)
5236 #ifdef OPTIONAL_REGISTER_PREFIX
5237 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5241 if (!isalpha (*p
) || !is_name_beginner (*p
))
5245 while (isalpha (c
) || isdigit (c
) || c
== '_')
5249 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5263 register char ** ccp
;
5265 char * start
= * ccp
;
5268 CONST
struct asm_psr
* psr
;
5272 while (isalpha (c
) || c
== '_')
5276 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5289 md_apply_fix3 (fixP
, val
, seg
)
5294 offsetT value
= * val
;
5296 unsigned int newimm
;
5299 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5300 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5302 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5304 /* Note whether this will delete the relocation. */
5305 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5306 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5309 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5313 /* If this symbol is in a different section then we need to leave it for
5314 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5315 so we have to undo it's effects here. */
5318 if (fixP
->fx_addsy
!= NULL
5319 && S_IS_DEFINED (fixP
->fx_addsy
)
5320 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5323 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5326 value
+= md_pcrel_from (fixP
);
5330 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5332 switch (fixP
->fx_r_type
)
5334 case BFD_RELOC_ARM_IMMEDIATE
:
5335 newimm
= validate_immediate (value
);
5336 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5338 /* If the instruction will fail, see if we can fix things up by
5339 changing the opcode. */
5340 if (newimm
== (unsigned int) FAIL
5341 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5343 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5344 _("invalid constant (%lx) after fixup\n"),
5345 (unsigned long) value
);
5349 newimm
|= (temp
& 0xfffff000);
5350 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5353 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5355 unsigned int highpart
= 0;
5356 unsigned int newinsn
= 0xe1a00000; /* nop */
5357 newimm
= validate_immediate (value
);
5358 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5360 /* If the instruction will fail, see if we can fix things up by
5361 changing the opcode. */
5362 if (newimm
== (unsigned int) FAIL
5363 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5365 /* No ? OK - try using two ADD instructions to generate the value. */
5366 newimm
= validate_immediate_twopart (value
, & highpart
);
5368 /* Yes - then make sure that the second instruction is also an add. */
5369 if (newimm
!= (unsigned int) FAIL
)
5371 /* Still No ? Try using a negated value. */
5372 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5373 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5374 /* Otherwise - give up. */
5377 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5378 _("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value
);
5382 /* Replace the first operand in the 2nd instruction (which is the PC)
5383 with the destination register. We have already added in the PC in the
5384 first instruction and we do not want to do it again. */
5385 newinsn
&= ~ 0xf0000;
5386 newinsn
|= ((newinsn
& 0x0f000) << 4);
5389 newimm
|= (temp
& 0xfffff000);
5390 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5392 highpart
|= (newinsn
& 0xfffff000);
5393 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5397 case BFD_RELOC_ARM_OFFSET_IMM
:
5399 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5401 as_bad (_("bad immediate value for offset (%ld)"), (long) value
);
5407 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5408 newval
&= 0xff7ff000;
5409 newval
|= value
| (sign
? INDEX_UP
: 0);
5410 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5413 case BFD_RELOC_ARM_OFFSET_IMM8
:
5414 case BFD_RELOC_ARM_HWLITERAL
:
5416 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5418 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5419 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5420 _("invalid literal constant: pool needs to be closer\n"));
5422 as_bad (_("bad immediate value for offset (%ld)"), (long) value
);
5429 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5430 newval
&= 0xff7ff0f0;
5431 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5432 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5435 case BFD_RELOC_ARM_LITERAL
:
5440 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5442 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5443 _("invalid literal constant: pool needs to be closer\n"));
5447 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5448 newval
&= 0xff7ff000;
5449 newval
|= value
| (sign
? INDEX_UP
: 0);
5450 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5453 case BFD_RELOC_ARM_SHIFT_IMM
:
5454 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5455 if (((unsigned long) value
) > 32
5457 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5459 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5460 _("shift expression is too large"));
5465 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5466 else if (value
== 32)
5468 newval
&= 0xfffff07f;
5469 newval
|= (value
& 0x1f) << 7;
5470 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5473 case BFD_RELOC_ARM_SWI
:
5474 if (arm_data
->thumb_mode
)
5476 if (((unsigned long) value
) > 0xff)
5477 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5478 _("Invalid swi expression"));
5479 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5481 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5485 if (((unsigned long) value
) > 0x00ffffff)
5486 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5487 _("Invalid swi expression"));
5488 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5490 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5494 case BFD_RELOC_ARM_MULTI
:
5495 if (((unsigned long) value
) > 0xffff)
5496 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5497 _("Invalid expression in load/store multiple"));
5498 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5499 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5502 case BFD_RELOC_ARM_PCREL_BRANCH
:
5503 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5507 value
= fixP
->fx_offset
;
5509 value
= (value
>> 2) & 0x00ffffff;
5510 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5511 newval
= value
| (newval
& 0xff000000);
5512 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5515 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5516 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5518 addressT diff
= (newval
& 0xff) << 1;
5523 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5524 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5525 _("Branch out of range"));
5526 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5528 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5531 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5532 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5534 addressT diff
= (newval
& 0x7ff) << 1;
5539 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5540 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5541 _("Branch out of range"));
5542 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5544 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5547 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5552 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5553 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5554 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5555 if (diff
& 0x400000)
5558 value
= fixP
->fx_offset
;
5561 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5562 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5563 _("Branch with link out of range"));
5565 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5566 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5567 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5568 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5573 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5574 md_number_to_chars (buf
, value
, 1);
5576 else if (!target_oabi
)
5578 value
= fixP
->fx_offset
;
5579 md_number_to_chars (buf
, value
, 1);
5585 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5586 md_number_to_chars (buf
, value
, 2);
5588 else if (!target_oabi
)
5590 value
= fixP
->fx_offset
;
5591 md_number_to_chars (buf
, value
, 2);
5597 case BFD_RELOC_ARM_GOT32
:
5598 case BFD_RELOC_ARM_GOTOFF
:
5599 md_number_to_chars (buf
, 0, 4);
5605 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5606 md_number_to_chars (buf
, value
, 4);
5608 else if (!target_oabi
)
5610 value
= fixP
->fx_offset
;
5611 md_number_to_chars (buf
, value
, 4);
5617 case BFD_RELOC_ARM_PLT32
:
5618 /* It appears the instruction is fully prepared at this point. */
5622 case BFD_RELOC_ARM_GOTPC
:
5623 md_number_to_chars (buf
, value
, 4);
5626 case BFD_RELOC_ARM_CP_OFF_IMM
:
5628 if (value
< -1023 || value
> 1023 || (value
& 3))
5629 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5630 _("Illegal value for co-processor offset"));
5633 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5634 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5635 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5638 case BFD_RELOC_ARM_THUMB_OFFSET
:
5639 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5640 /* Exactly what ranges, and where the offset is inserted depends on
5641 the type of instruction, we can establish this from the top 4 bits */
5642 switch (newval
>> 12)
5644 case 4: /* PC load */
5645 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5646 forced to zero for these loads, so we will need to round
5647 up the offset if the instruction address is not word
5648 aligned (since the final address produced must be, and
5649 we can only describe word-aligned immediate offsets). */
5651 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5652 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5653 _("Invalid offset, target not word aligned (0x%08X)"),
5654 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5656 if ((value
+ 2) & ~0x3fe)
5657 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5658 _("Invalid offset"));
5660 /* Round up, since pc will be rounded down. */
5661 newval
|= (value
+ 2) >> 2;
5664 case 9: /* SP load/store */
5666 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5667 _("Invalid offset"));
5668 newval
|= value
>> 2;
5671 case 6: /* Word load/store */
5673 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5674 _("Invalid offset"));
5675 newval
|= value
<< 4; /* 6 - 2 */
5678 case 7: /* Byte load/store */
5680 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5681 _("Invalid offset"));
5682 newval
|= value
<< 6;
5685 case 8: /* Halfword load/store */
5687 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5688 _("Invalid offset"));
5689 newval
|= value
<< 5; /* 6 - 1 */
5693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5694 "Unable to process relocation for thumb opcode: %lx",
5695 (unsigned long) newval
);
5698 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5701 case BFD_RELOC_ARM_THUMB_ADD
:
5702 /* This is a complicated relocation, since we use it for all of
5703 the following immediate relocations:
5706 9bit ADD/SUB SP word-aligned
5707 10bit ADD PC/SP word-aligned
5709 The type of instruction being processed is encoded in the
5715 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5717 int rd
= (newval
>> 4) & 0xf;
5718 int rs
= newval
& 0xf;
5719 int subtract
= newval
& 0x8000;
5724 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5725 _("Invalid immediate for stack address calculation"));
5726 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5727 newval
|= value
>> 2;
5729 else if (rs
== REG_PC
|| rs
== REG_SP
)
5733 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5734 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5735 (unsigned long) value
);
5736 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5738 newval
|= value
>> 2;
5743 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5744 _("Invalid 8bit immediate"));
5745 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5746 newval
|= (rd
<< 8) | value
;
5751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5752 _("Invalid 3bit immediate"));
5753 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5754 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5757 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5760 case BFD_RELOC_ARM_THUMB_IMM
:
5761 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5762 switch (newval
>> 11)
5764 case 0x04: /* 8bit immediate MOV */
5765 case 0x05: /* 8bit immediate CMP */
5766 if (value
< 0 || value
> 255)
5767 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5768 _("Invalid immediate: %ld is too large"),
5776 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5779 case BFD_RELOC_ARM_THUMB_SHIFT
:
5780 /* 5bit shift value (0..31) */
5781 if (value
< 0 || value
> 31)
5782 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5783 _("Illegal Thumb shift value: %ld"), (long) value
);
5784 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5785 newval
|= value
<< 6;
5786 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5789 case BFD_RELOC_VTABLE_INHERIT
:
5790 case BFD_RELOC_VTABLE_ENTRY
:
5794 case BFD_RELOC_NONE
:
5796 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5797 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5803 /* Translate internal representation of relocation info to BFD target
5806 tc_gen_reloc (section
, fixp
)
5811 bfd_reloc_code_real_type code
;
5813 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5815 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5816 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5817 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5819 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5821 if (fixp
->fx_pcrel
== 0)
5822 reloc
->addend
= fixp
->fx_offset
;
5824 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5826 reloc
->addend
= fixp
->fx_offset
;
5829 switch (fixp
->fx_r_type
)
5834 code
= BFD_RELOC_8_PCREL
;
5841 code
= BFD_RELOC_16_PCREL
;
5848 code
= BFD_RELOC_32_PCREL
;
5852 case BFD_RELOC_ARM_PCREL_BRANCH
:
5854 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5855 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5856 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5857 case BFD_RELOC_VTABLE_ENTRY
:
5858 case BFD_RELOC_VTABLE_INHERIT
:
5859 code
= fixp
->fx_r_type
;
5862 case BFD_RELOC_ARM_LITERAL
:
5863 case BFD_RELOC_ARM_HWLITERAL
:
5864 /* If this is called then the a literal has been referenced across
5865 a section boundary - possibly due to an implicit dump */
5866 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5867 _("Literal referenced across section boundary (Implicit dump?)"));
5871 case BFD_RELOC_ARM_GOT32
:
5872 case BFD_RELOC_ARM_GOTOFF
:
5873 case BFD_RELOC_ARM_PLT32
:
5874 code
= fixp
->fx_r_type
;
5878 case BFD_RELOC_ARM_IMMEDIATE
:
5879 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5880 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5884 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5885 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5886 _("ADRL used for a symbol not defined in the same file"),
5890 case BFD_RELOC_ARM_OFFSET_IMM
:
5891 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5892 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5899 switch (fixp
->fx_r_type
)
5901 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5902 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5903 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5904 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5905 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5906 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5907 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5908 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5909 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5910 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5911 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5912 default: type
= _("<unknown>"); break;
5914 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5915 _("Can not represent %s relocation in this object file format (%d)"),
5916 type
, fixp
->fx_pcrel
);
5922 if (code
== BFD_RELOC_32_PCREL
5924 && fixp
->fx_addsy
== GOT_symbol
)
5926 code
= BFD_RELOC_ARM_GOTPC
;
5927 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5931 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5933 if (reloc
->howto
== NULL
)
5935 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5936 _("Can not represent %s relocation in this object file format"),
5937 bfd_get_reloc_code_name (code
));
5941 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5942 vtable entry to be used in the relocation's section offset. */
5943 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5944 reloc
->address
= fixp
->fx_offset
;
5950 md_estimate_size_before_relax (fragP
, segtype
)
5954 as_fatal (_("md_estimate_size_before_relax\n"));
5959 output_inst
PARAMS ((void))
5965 as_bad (inst
.error
);
5969 to
= frag_more (inst
.size
);
5971 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5973 assert (inst
.size
== (2 * THUMB_SIZE
));
5974 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5975 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
5977 else if (inst
.size
> INSN_SIZE
)
5979 assert (inst
.size
== (2 * INSN_SIZE
));
5980 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
5981 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
5984 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5986 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5987 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5988 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6003 /* Align the instruction.
6004 This may not be the right thing to do but ... */
6005 /* arm_align (2, 0); */
6006 listing_prev_line (); /* Defined in listing.h */
6008 /* Align the previous label if needed. */
6009 if (last_label_seen
!= NULL
)
6011 symbol_set_frag (last_label_seen
, frag_now
);
6012 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6013 S_SET_SEGMENT (last_label_seen
, now_seg
);
6016 memset (&inst
, '\0', sizeof (inst
));
6017 inst
.reloc
.type
= BFD_RELOC_NONE
;
6019 skip_whitespace (str
);
6021 /* Scan up to the end of the op-code, which must end in white space or
6023 for (start
= p
= str
; *p
!= '\0'; p
++)
6029 as_bad (_("No operator -- statement `%s'\n"), str
);
6035 CONST
struct thumb_opcode
* opcode
;
6039 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6044 inst
.instruction
= opcode
->value
;
6045 inst
.size
= opcode
->size
;
6046 (*opcode
->parms
)(p
);
6053 CONST
struct asm_opcode
* opcode
;
6055 inst
.size
= INSN_SIZE
;
6056 /* p now points to the end of the opcode, probably white space, but we
6057 have to break the opcode up in case it contains condionals and flags;
6058 keep trying with progressively smaller basic instructions until one
6059 matches, or we run out of opcode. */
6060 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6061 for (; q
!= str
; q
--)
6065 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6068 if (opcode
&& opcode
->template)
6070 unsigned long flag_bits
= 0;
6073 /* Check that this instruction is supported for this CPU. */
6074 if ((opcode
->variants
& cpu_variant
) == 0)
6077 inst
.instruction
= opcode
->value
;
6078 if (q
== p
) /* Just a simple opcode. */
6080 if (opcode
->comp_suffix
!= 0)
6081 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6082 opcode
->comp_suffix
);
6085 inst
.instruction
|= COND_ALWAYS
;
6086 (*opcode
->parms
)(q
, 0);
6092 /* Now check for a conditional. */
6096 CONST
struct asm_cond
*cond
;
6100 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6104 if (cond
->value
== 0xf0000000)
6106 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6108 inst
.instruction
|= cond
->value
;
6112 inst
.instruction
|= COND_ALWAYS
;
6115 inst
.instruction
|= COND_ALWAYS
;
6117 /* If there is a compulsory suffix, it should come here, before
6118 any optional flags. */
6119 if (opcode
->comp_suffix
)
6121 CONST
char *s
= opcode
->comp_suffix
;
6133 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6134 opcode
->comp_suffix
);
6141 /* The remainder, if any should now be flags for the instruction;
6142 Scan these checking each one found with the opcode. */
6146 CONST
struct asm_flg
*flag
= opcode
->flags
;
6155 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6157 if (streq (r
, flag
[flagno
].template))
6159 flag_bits
|= flag
[flagno
].set_bits
;
6165 if (! flag
[flagno
].template)
6172 (*opcode
->parms
) (p
, flag_bits
);
6182 /* It wasn't an instruction, but it might be a register alias of the form
6185 skip_whitespace (q
);
6190 if (*q
&& !strncmp (q
, ".req ", 4))
6193 char * copy_of_str
= str
;
6197 skip_whitespace (q
);
6199 for (r
= q
; *r
!= '\0'; r
++)
6209 regnum
= arm_reg_parse (& q
);
6212 reg
= arm_reg_parse (& str
);
6218 insert_reg_alias (str
, regnum
);
6222 as_warn (_("register '%s' does not exist\n"), q
);
6225 else if (regnum
!= FAIL
)
6228 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6230 /* Do not warn about redefinitions to the same alias. */
6233 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6237 as_warn (_("ignoring incomplete .req pseuso op"));
6244 as_bad (_("bad instruction `%s'"), start
);
6249 * Invocation line includes a switch not recognized by the base assembler.
6250 * See if it's a processor-specific option. These are:
6251 * Cpu variants, the arm part is optional:
6252 * -m[arm]1 Currently not supported.
6253 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6254 * -m[arm]3 Arm 3 processor
6255 * -m[arm]6[xx], Arm 6 processors
6256 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6257 * -m[arm]8[10] Arm 8 processors
6258 * -m[arm]9[20][tdmi] Arm 9 processors
6259 * -mstrongarm[110[0]] StrongARM processors
6260 * -m[arm]v[2345] Arm architecures
6261 * -mall All (except the ARM1)
6263 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6264 * -mfpe-old (No float load/store multiples)
6265 * -mno-fpu Disable all floating point instructions
6266 * Run-time endian selection:
6267 * -EB big endian cpu
6268 * -EL little endian cpu
6269 * ARM Procedure Calling Standard:
6270 * -mapcs-32 32 bit APCS
6271 * -mapcs-26 26 bit APCS
6272 * -mapcs-float Pass floats in float regs
6273 * -mapcs-reentrant Position independent code
6274 * -mthumb-interwork Code supports Arm/Thumb interworking
6275 * -moabi Old ELF ABI
6278 CONST
char * md_shortopts
= "m:k";
6279 struct option md_longopts
[] =
6281 #ifdef ARM_BI_ENDIAN
6282 #define OPTION_EB (OPTION_MD_BASE + 0)
6283 {"EB", no_argument
, NULL
, OPTION_EB
},
6284 #define OPTION_EL (OPTION_MD_BASE + 1)
6285 {"EL", no_argument
, NULL
, OPTION_EL
},
6287 #define OPTION_OABI (OPTION_MD_BASE +2)
6288 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6291 {NULL
, no_argument
, NULL
, 0}
6293 size_t md_longopts_size
= sizeof (md_longopts
);
6296 md_parse_option (c
, arg
)
6304 #ifdef ARM_BI_ENDIAN
6306 target_big_endian
= 1;
6309 target_big_endian
= 0;
6317 if (streq (str
, "fpa10"))
6318 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6319 else if (streq (str
, "fpa11"))
6320 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6321 else if (streq (str
, "fpe-old"))
6322 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6328 if (streq (str
, "no-fpu"))
6329 cpu_variant
&= ~FPU_ALL
;
6334 if (streq (str
, "oabi"))
6340 /* Limit assembler to generating only Thumb instructions: */
6341 if (streq (str
, "thumb"))
6343 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6344 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6347 else if (streq (str
, "thumb-interwork"))
6349 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCH_V4
;
6350 #if defined OBJ_COFF || defined OBJ_ELF
6351 support_interwork
= true;
6359 if (streq (str
, "all"))
6361 cpu_variant
= ARM_ALL
| FPU_ALL
;
6364 #if defined OBJ_COFF || defined OBJ_ELF
6365 if (! strncmp (str
, "apcs-", 5))
6367 /* GCC passes on all command line options starting "-mapcs-..."
6368 to us, so we must parse them here. */
6372 if (streq (str
, "32"))
6374 uses_apcs_26
= false;
6377 else if (streq (str
, "26"))
6379 uses_apcs_26
= true;
6382 else if (streq (str
, "frame"))
6384 /* Stack frames are being generated - does not affect
6388 else if (streq (str
, "stack-check"))
6390 /* Stack checking is being performed - does not affect
6391 linkage, but does require that the functions
6392 __rt_stkovf_split_small and __rt_stkovf_split_big be
6393 present in the final link. */
6397 else if (streq (str
, "float"))
6399 /* Floating point arguments are being passed in the floating
6400 point registers. This does affect linking, since this
6401 version of the APCS is incompatible with the version that
6402 passes floating points in the integer registers. */
6404 uses_apcs_float
= true;
6407 else if (streq (str
, "reentrant"))
6409 /* Reentrant code has been generated. This does affect
6410 linking, since there is no point in linking reentrant/
6411 position independent code with absolute position code. */
6416 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6420 /* Strip off optional "arm" */
6421 if (! strncmp (str
, "arm", 3))
6427 if (streq (str
, "1"))
6428 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6434 if (streq (str
, "2"))
6435 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6436 else if (streq (str
, "250"))
6437 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6443 if (streq (str
, "3"))
6444 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6450 switch (strtol (str
, NULL
, 10))
6457 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6465 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6477 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6483 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6487 cpu_variant
|= ARM_LONGMUL
;
6490 case 'f': /* fe => fp enabled cpu. */
6496 case 'c': /* Left over from 710c processor name. */
6497 case 'd': /* Debug */
6498 case 'i': /* Embedded ICE */
6499 /* Included for completeness in ARM processor naming. */
6509 if (streq (str
, "8") || streq (str
, "810"))
6510 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6516 if (streq (str
, "9"))
6517 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6518 else if (streq (str
, "920"))
6519 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6520 else if (streq (str
, "920t"))
6521 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6522 else if (streq (str
, "9tdmi"))
6523 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6529 if (streq (str
, "strongarm")
6530 || streq (str
, "strongarm110")
6531 || streq (str
, "strongarm1100"))
6532 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6538 /* Select variant based on architecture rather than processor */
6544 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6545 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6546 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6551 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6555 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6557 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6562 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6566 case 't': cpu_variant
|= ARM_THUMB
; break;
6568 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6573 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6577 case 't': cpu_variant
|= ARM_THUMB
; break;
6579 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6584 as_bad (_("Invalid architecture variant -m%s"), arg
);
6591 as_bad (_("Invalid processor variant -m%s"), arg
);
6614 ARM Specific Assembler Options:\n\
6615 -m[arm][<processor name>] select processor variant\n\
6616 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6617 -mthumb only allow Thumb instructions\n\
6618 -mthumb-interwork mark the assembled code as supporting interworking\n\
6619 -mall allow any instruction\n\
6620 -mfpa10, -mfpa11 select floating point architecture\n\
6621 -mfpe-old don't allow floating-point multiple instructions\n\
6622 -mno-fpu don't allow any floating-point instructions.\n"));
6625 -k generate PIC code.\n"));
6626 #if defined OBJ_COFF || defined OBJ_ELF
6629 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6632 -mapcs-float floating point args are passed in FP regs\n"));
6635 -mapcs-reentrant the code is position independent/reentrant\n"));
6640 -moabi support the old ELF ABI\n"));
6642 #ifdef ARM_BI_ENDIAN
6645 -EB assemble code for a big endian cpu\n\
6646 -EL assemble code for a little endian cpu\n"));
6650 /* We need to be able to fix up arbitrary expressions in some statements.
6651 This is so that we can handle symbols that are an arbitrary distance from
6652 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6653 which returns part of an address in a form which will be valid for
6654 a data instruction. We do this by pushing the expression into a symbol
6655 in the expr_section, and creating a fix for that. */
6658 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6667 arm_fix_data
* arm_data
;
6675 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6679 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6684 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6685 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6686 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6687 arm_data
->thumb_mode
= thumb_mode
;
6693 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6695 cons_fix_new_arm (frag
, where
, size
, exp
)
6701 bfd_reloc_code_real_type type
;
6706 * @@ Should look at CPU word size.
6711 type
= BFD_RELOC_16
;
6715 type
= BFD_RELOC_32
;
6718 type
= BFD_RELOC_64
;
6722 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6725 /* A good place to do this, although this was probably not intended
6726 for this kind of use. We need to dump the literal pool before
6727 references are made to a null symbol pointer. */
6731 if (current_poolP
== NULL
)
6734 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6736 listing_prev_line ();
6740 arm_start_line_hook ()
6742 last_label_seen
= NULL
;
6746 arm_frob_label (sym
)
6749 last_label_seen
= sym
;
6751 ARM_SET_THUMB (sym
, thumb_mode
);
6753 #if defined OBJ_COFF || defined OBJ_ELF
6754 ARM_SET_INTERWORK (sym
, support_interwork
);
6757 if (label_is_thumb_function_name
)
6759 /* When the address of a Thumb function is taken the bottom
6760 bit of that address should be set. This will allow
6761 interworking between Arm and Thumb functions to work
6764 THUMB_SET_FUNC (sym
, 1);
6766 label_is_thumb_function_name
= false;
6770 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6774 arm_adjust_symtab ()
6779 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6781 if (ARM_IS_THUMB (sym
))
6783 if (THUMB_IS_FUNC (sym
))
6785 /* Mark the symbol as a Thumb function. */
6786 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6787 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6788 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6790 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6791 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6793 as_bad (_("%s: unexpected function type: %d"),
6794 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6796 else switch (S_GET_STORAGE_CLASS (sym
))
6799 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6802 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6805 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6807 default: /* do nothing */
6812 if (ARM_IS_INTERWORK (sym
))
6813 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6818 elf_symbol_type
* elf_sym
;
6821 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6823 if (ARM_IS_THUMB (sym
))
6825 if (THUMB_IS_FUNC (sym
))
6827 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6828 bind
= ELF_ST_BIND (elf_sym
);
6829 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6839 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6841 *input_line_pointer
= '/';
6842 input_line_pointer
+= 5;
6843 *input_line_pointer
= 0;
6851 arm_canonicalize_symbol_name (name
)
6856 if (thumb_mode
&& (len
= strlen (name
)) > 5
6857 && streq (name
+ len
- 5, "/data"))
6858 *(name
+ len
- 5) = 0;
6864 arm_validate_fix (fixP
)
6867 /* If the destination of the branch is a defined symbol which does not have
6868 the THUMB_FUNC attribute, then we must be calling a function which has
6869 the (interfacearm) attribute. We look for the Thumb entry point to that
6870 function and change the branch to refer to that function instead. */
6871 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6872 && fixP
->fx_addsy
!= NULL
6873 && S_IS_DEFINED (fixP
->fx_addsy
)
6874 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6876 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6884 /* Relocations against Thumb function names must be left unadjusted,
6885 so that the linker can use this information to correctly set the
6886 bottom bit of their addresses. The MIPS version of this function
6887 also prevents relocations that are mips-16 specific, but I do not
6888 know why it does this.
6891 There is one other problem that ought to be addressed here, but
6892 which currently is not: Taking the address of a label (rather
6893 than a function) and then later jumping to that address. Such
6894 addresses also ought to have their bottom bit set (assuming that
6895 they reside in Thumb code), but at the moment they will not. */
6898 arm_fix_adjustable (fixP
)
6901 if (fixP
->fx_addsy
== NULL
)
6904 /* Prevent all adjustments to global symbols. */
6905 if (S_IS_EXTERN (fixP
->fx_addsy
))
6908 if (S_IS_WEAK (fixP
->fx_addsy
))
6911 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6912 && fixP
->fx_subsy
== NULL
)
6915 /* We need the symbol name for the VTABLE entries */
6916 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6917 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6924 elf32_arm_target_format ()
6926 if (target_big_endian
)
6928 return "elf32-bigarm-oabi";
6930 return "elf32-bigarm";
6933 return "elf32-littlearm-oabi";
6935 return "elf32-littlearm";
6939 armelf_frob_symbol (symp
, puntp
)
6943 elf_frob_symbol (symp
, puntp
);
6947 arm_force_relocation (fixp
)
6950 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6951 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6952 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
6953 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
6959 static bfd_reloc_code_real_type
6969 bfd_reloc_code_real_type reloc
;
6973 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6974 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6975 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6976 /* ScottB: Jan 30, 1998 */
6977 /* Added support for parsing "var(PLT)" branch instructions */
6978 /* generated by GCC for PLT relocs */
6979 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6980 NULL
, 0, BFD_RELOC_UNUSED
6984 for (i
= 0, ip
= input_line_pointer
;
6985 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6987 id
[i
] = tolower (*ip
);
6989 for (i
= 0; reloc_map
[i
].str
; i
++)
6990 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6993 input_line_pointer
+= reloc_map
[i
].len
;
6995 return reloc_map
[i
].reloc
;
6999 s_arm_elf_cons (nbytes
)
7004 #ifdef md_flush_pending_output
7005 md_flush_pending_output ();
7008 if (is_it_end_of_statement ())
7010 demand_empty_rest_of_line ();
7014 #ifdef md_cons_align
7015 md_cons_align (nbytes
);
7020 bfd_reloc_code_real_type reloc
;
7024 if (exp
.X_op
== O_symbol
7025 && * input_line_pointer
== '('
7026 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7028 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7029 int size
= bfd_get_reloc_size (howto
);
7032 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7035 register char * p
= frag_more ((int) nbytes
);
7036 int offset
= nbytes
- size
;
7038 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7043 emit_expr (& exp
, (unsigned int) nbytes
);
7045 while (*input_line_pointer
++ == ',');
7047 input_line_pointer
--; /* Put terminator back into stream. */
7048 demand_empty_rest_of_line ();
7051 #endif /* OBJ_ELF */