1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
56 /* Architectures are the sum of the base and extensions */
57 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
59 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
60 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
62 /* Some useful combinations: */
63 #define ARM_ANY 0x00ffffff
64 #define ARM_2UP (ARM_ANY - ARM_1)
65 #define ARM_ALL ARM_2UP /* Not arm1 only */
66 #define ARM_3UP 0x00fffffc
67 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
69 #define FPU_CORE 0x80000000
70 #define FPU_FPA10 0x40000000
71 #define FPU_FPA11 0x40000000
74 /* Some useful combinations */
75 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
76 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #define CPU_DEFAULT ARM_ALL
88 #define FPU_DEFAULT FPU_ALL
91 #define streq(a, b) (strcmp (a, b) == 0)
92 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
94 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
95 static int target_oabi
= 0;
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure */
99 static boolean uses_apcs_26
= false;
100 static boolean support_interwork
= false;
101 static boolean uses_apcs_float
= false;
102 static boolean pic_code
= false;
105 /* This array holds the chars that always start a comment. If the
106 pre-processor is disabled, these aren't very useful */
107 CONST
char comment_chars
[] = "@";
109 /* This array holds the chars that only start a comment at the beginning of
110 a line. If the line seems to have the form '# 123 filename'
111 .line and .file directives will appear in the pre-processed output */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113 first line of the input file. This is because the compiler outputs
114 #NO_APP at the beginning of its output. */
115 /* Also note that comments like this one will always work. */
116 CONST
char line_comment_chars
[] = "#";
119 CONST
char line_separator_chars
[] = ";";
121 CONST
char line_separator_chars
[] = "";
124 /* Chars that can be used to separate mant from exp in floating point nums */
125 CONST
char EXP_CHARS
[] = "eE";
127 /* Chars that mean this number is a floating point constant */
131 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
133 /* Prefix characters that indicate the start of an immediate
135 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
138 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
141 CONST
int md_reloc_size
= 8; /* Size of relocation record */
143 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
145 typedef struct arm_fix
153 unsigned long instruction
;
158 bfd_reloc_code_real_type type
;
168 CONST
char * template;
172 static CONST
struct asm_shift shift
[] =
188 #define NO_SHIFT_RESTRICT 1
189 #define SHIFT_RESTRICT 0
191 #define NUM_FLOAT_VALS 8
193 CONST
char * fp_const
[] =
195 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
198 /* Number of littlenums required to hold an extended precision number */
199 #define MAX_LITTLENUMS 6
201 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
211 #define CP_T_X 0x00008000
212 #define CP_T_Y 0x00400000
213 #define CP_T_Pre 0x01000000
214 #define CP_T_UD 0x00800000
215 #define CP_T_WB 0x00200000
217 #define CONDS_BIT (0x00100000)
218 #define LOAD_BIT (0x00100000)
219 #define TRANS_BIT (0x00200000)
223 CONST
char * template;
227 /* This is to save a hash look-up in the common case */
228 #define COND_ALWAYS 0xe0000000
230 static CONST
struct asm_cond conds
[] =
234 {"cs", 0x20000000}, {"hs", 0x20000000},
235 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
250 /* Warning: If the top bit of the set_bits is set, then the standard
251 instruction bitmask is ignored, and the new bitmask is taken from
255 CONST
char * template; /* Basic flag string */
256 unsigned long set_bits
; /* Bits to set */
259 static CONST
struct asm_flg s_flag
[] =
265 static CONST
struct asm_flg ldr_flags
[] =
269 {"bt", 0x00400000 | TRANS_BIT
},
276 static CONST
struct asm_flg str_flags
[] =
280 {"bt", 0x00400000 | TRANS_BIT
},
285 static CONST
struct asm_flg byte_flag
[] =
291 static CONST
struct asm_flg cmp_flags
[] =
298 static CONST
struct asm_flg ldm_flags
[] =
311 static CONST
struct asm_flg stm_flags
[] =
324 static CONST
struct asm_flg lfm_flags
[] =
331 static CONST
struct asm_flg sfm_flags
[] =
338 static CONST
struct asm_flg round_flags
[] =
346 /* The implementation of the FIX instruction is broken on some assemblers,
347 in that it accepts a precision specifier as well as a rounding specifier,
348 despite the fact that this is meaningless. To be more compatible, we
349 accept it as well, though of course it does not set any bits. */
350 static CONST
struct asm_flg fix_flags
[] =
367 static CONST
struct asm_flg except_flag
[] =
373 static CONST
struct asm_flg cplong_flag
[] =
381 CONST
char * template;
382 unsigned long number
;
385 #define PSR_FIELD_MASK 0x000f0000
387 #define PSR_FLAGS 0x00080000
388 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
389 #define PSR_ALL 0x00090000
398 static CONST
struct asm_psr psrs
[] =
402 {"cpsr_all", CPSR_ALL
},
404 {"spsr_all", SPSR_ALL
},
407 {"cpsr_flg", CPSR_FLG
},
408 {"spsr_flg", SPSR_FLG
},
411 {"cpsr_c", CPSR_CTL
},
412 {"cpsr_ctl", CPSR_CTL
},
413 {"spsr_c", SPSR_CTL
},
414 {"spsr_ctl", SPSR_CTL
}
417 /* Functions called by parser */
418 /* ARM instructions */
419 static void do_arit
PARAMS ((char *, unsigned long));
420 static void do_cmp
PARAMS ((char *, unsigned long));
421 static void do_mov
PARAMS ((char *, unsigned long));
422 static void do_ldst
PARAMS ((char *, unsigned long));
423 static void do_ldmstm
PARAMS ((char *, unsigned long));
424 static void do_branch
PARAMS ((char *, unsigned long));
425 static void do_swi
PARAMS ((char *, unsigned long));
426 /* Pseudo Op codes */
427 static void do_adr
PARAMS ((char *, unsigned long));
428 static void do_adrl
PARAMS ((char *, unsigned long));
429 static void do_nop
PARAMS ((char *, unsigned long));
431 static void do_mul
PARAMS ((char *, unsigned long));
432 static void do_mla
PARAMS ((char *, unsigned long));
434 static void do_swap
PARAMS ((char *, unsigned long));
436 static void do_msr
PARAMS ((char *, unsigned long));
437 static void do_mrs
PARAMS ((char *, unsigned long));
439 static void do_mull
PARAMS ((char *, unsigned long));
441 static void do_bx
PARAMS ((char *, unsigned long));
443 /* Coprocessor Instructions */
444 static void do_cdp
PARAMS ((char *, unsigned long));
445 static void do_lstc
PARAMS ((char *, unsigned long));
446 static void do_co_reg
PARAMS ((char *, unsigned long));
447 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
448 static void do_fp_ldst
PARAMS ((char *, unsigned long));
449 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
450 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
451 static void do_fp_monadic
PARAMS ((char *, unsigned long));
452 static void do_fp_cmp
PARAMS ((char *, unsigned long));
453 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
454 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
456 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
457 static int arm_reg_parse
PARAMS ((char **));
458 static int arm_psr_parse
PARAMS ((char **));
459 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
460 static int add_to_lit_pool
PARAMS ((void));
461 static unsigned validate_immediate
PARAMS ((unsigned));
462 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
463 static int validate_offset_imm
PARAMS ((unsigned int, int));
464 static void opcode_select
PARAMS ((int));
465 static void end_of_line
PARAMS ((char *));
466 static int reg_required_here
PARAMS ((char **, int));
467 static int psr_required_here
PARAMS ((char **, int, int));
468 static int co_proc_number
PARAMS ((char **));
469 static int cp_opc_expr
PARAMS ((char **, int, int));
470 static int cp_reg_required_here
PARAMS ((char **, int));
471 static int fp_reg_required_here
PARAMS ((char **, int));
472 static int cp_address_offset
PARAMS ((char **));
473 static int cp_address_required_here
PARAMS ((char **));
474 static int my_get_float_expression
PARAMS ((char **));
475 static int skip_past_comma
PARAMS ((char **));
476 static int walk_no_bignums
PARAMS ((symbolS
*));
477 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
478 static int data_op2
PARAMS ((char **));
479 static int fp_op2
PARAMS ((char **));
480 static long reg_list
PARAMS ((char **));
481 static void thumb_load_store
PARAMS ((char *, int, int));
482 static int decode_shift
PARAMS ((char **, int));
483 static int ldst_extend
PARAMS ((char **, int));
484 static void thumb_add_sub
PARAMS ((char *, int));
485 static void insert_reg
PARAMS ((int));
486 static void thumb_shift
PARAMS ((char *, int));
487 static void thumb_mov_compare
PARAMS ((char *, int));
488 static void set_constant_flonums
PARAMS ((void));
489 static valueT md_chars_to_number
PARAMS ((char *, int));
490 static void insert_reg_alias
PARAMS ((char *, int));
491 static void output_inst
PARAMS ((void));
493 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
496 /* ARM instructions take 4bytes in the object file, Thumb instructions
500 /* LONGEST_INST is the longest basic instruction name without conditions or
502 * ARM7M has 4 of length 5
505 #define LONGEST_INST 5
509 CONST
char * template; /* Basic string to match */
510 unsigned long value
; /* Basic instruction code */
511 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
512 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
513 unsigned long variants
; /* Which CPU variants this exists for */
514 /* Function to call to parse args */
515 void (* parms
) PARAMS ((char *, unsigned long));
518 static CONST
struct asm_opcode insns
[] =
520 /* ARM Instructions */
521 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
522 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
523 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
524 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
525 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
526 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
527 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
528 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
529 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
530 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
531 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
532 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
533 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
534 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
535 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
536 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
537 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
538 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
539 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
540 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
541 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
542 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
543 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
546 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
547 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
548 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
550 /* ARM 2 multiplies */
551 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
552 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
554 /* ARM 3 - swp instructions */
555 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
557 /* ARM 6 Coprocessor instructions */
558 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
559 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
560 /* ScottB: our code uses 0x0128f000 for msr.
561 NickC: but this is wrong because the bits 16 and 19 are handled
562 by the PSR_xxx defines above. */
564 /* ARM 7M long multiplies - need signed/unsigned flags! */
565 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
566 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
567 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
568 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
570 /* ARM THUMB interworking */
571 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
573 /* Floating point instructions */
574 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
575 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
576 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
577 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
578 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
579 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
580 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
581 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
582 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
583 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
584 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
585 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
586 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
587 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
588 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
589 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
590 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
595 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
596 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
597 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
598 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
599 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
600 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
601 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
602 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
603 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
604 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
605 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
606 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
607 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
608 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
609 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
610 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
611 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
612 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
613 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
614 be an optional suffix, but part of the instruction. To be compatible,
616 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
617 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
618 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
619 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
621 /* Generic copressor instructions */
622 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
623 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
624 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
625 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
626 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
629 /* defines for various bits that we will want to toggle */
631 #define INST_IMMEDIATE 0x02000000
632 #define OFFSET_REG 0x02000000
633 #define HWOFFSET_IMM 0x00400000
634 #define SHIFT_BY_REG 0x00000010
635 #define PRE_INDEX 0x01000000
636 #define INDEX_UP 0x00800000
637 #define WRITE_BACK 0x00200000
638 #define 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
> 4095)
1143 as_bad (_("Invalid syntax for .req directive."));
1150 /* We don't support putting frags in the BSS segment, we fake it by
1151 marking in_bss, then looking at s_skip for clues?.. */
1152 subseg_set (bss_section
, 0);
1153 demand_empty_rest_of_line ();
1160 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1161 frag_align (1, 0, 0);
1163 record_alignment (now_seg
, 1);
1165 demand_empty_rest_of_line ();
1175 if (current_poolP
== NULL
)
1178 /* Align pool as you have word accesses */
1179 /* Only make a frag if we have to ... */
1181 frag_align (2, 0, 0);
1183 record_alignment (now_seg
, 2);
1185 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1187 symbol_locate (current_poolP
, sym_name
, now_seg
,
1188 (valueT
) frag_now_fix (), frag_now
);
1189 symbol_table_insert (current_poolP
);
1191 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1193 #if defined OBJ_COFF || defined OBJ_ELF
1194 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1197 while (lit_count
< next_literal_pool_place
)
1198 /* First output the expression in the instruction to the pool */
1199 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1201 next_literal_pool_place
= 0;
1202 current_poolP
= NULL
;
1206 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1210 register long temp_fill
;
1211 long max_alignment
= 15;
1213 temp
= get_absolute_expression ();
1214 if (temp
> max_alignment
)
1215 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1218 as_bad (_("Alignment negative. 0 assumed."));
1222 if (*input_line_pointer
== ',')
1224 input_line_pointer
++;
1225 temp_fill
= get_absolute_expression ();
1233 /* Only make a frag if we HAVE to. . . */
1234 if (temp
&& !need_pass_2
)
1235 frag_align (temp
, (int) temp_fill
, 0);
1236 demand_empty_rest_of_line ();
1238 record_alignment (now_seg
, temp
);
1242 s_force_thumb (ignore
)
1245 /* If we are not already in thumb mode go into it, EVEN if
1246 the target processor does not support thumb instructions.
1247 This is used by gcc/config/arm/lib1funcs.asm for example
1248 to compile interworking support functions even if the
1249 target processor should not support interworking. */
1255 record_alignment (now_seg
, 1);
1258 demand_empty_rest_of_line ();
1262 s_thumb_func (ignore
)
1265 /* The following label is the name/address of the start of a Thumb function.
1266 We need to know this for the interworking support. */
1268 label_is_thumb_function_name
= true;
1270 demand_empty_rest_of_line ();
1273 /* Perform a .set directive, but also mark the alias as
1274 being a thumb function. */
1280 /* XXX the following is a duplicate of the code for s_set() in read.c
1281 We cannot just call that code as we need to get at the symbol that
1283 register char * name
;
1284 register char delim
;
1285 register char * end_name
;
1286 register symbolS
* symbolP
;
1289 * Especial apologies for the random logic:
1290 * this just grew, and could be parsed much more simply!
1293 name
= input_line_pointer
;
1294 delim
= get_symbol_end ();
1295 end_name
= input_line_pointer
;
1300 if (*input_line_pointer
!= ',')
1303 as_bad (_("Expected comma after name \"%s\""), name
);
1305 ignore_rest_of_line ();
1309 input_line_pointer
++;
1312 if (name
[0] == '.' && name
[1] == '\0')
1314 /* XXX - this should not happen to .thumb_set */
1318 if ((symbolP
= symbol_find (name
)) == NULL
1319 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1322 /* When doing symbol listings, play games with dummy fragments living
1323 outside the normal fragment chain to record the file and line info
1325 if (listing
& LISTING_SYMBOLS
)
1327 extern struct list_info_struct
* listing_tail
;
1328 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1329 memset (dummy_frag
, 0, sizeof(fragS
));
1330 dummy_frag
->fr_type
= rs_fill
;
1331 dummy_frag
->line
= listing_tail
;
1332 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1333 dummy_frag
->fr_symbol
= symbolP
;
1337 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1340 /* "set" symbols are local unless otherwise specified. */
1341 SF_SET_LOCAL (symbolP
);
1342 #endif /* OBJ_COFF */
1343 } /* make a new symbol */
1345 symbol_table_insert (symbolP
);
1350 && S_IS_DEFINED (symbolP
)
1351 && S_GET_SEGMENT (symbolP
) != reg_section
)
1352 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1354 pseudo_set (symbolP
);
1356 demand_empty_rest_of_line ();
1358 /* XXX Now we come to the Thumb specific bit of code. */
1360 THUMB_SET_FUNC (symbolP
, 1);
1361 ARM_SET_THUMB (symbolP
, 1);
1362 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1365 /* If we change section we must dump the literal pool first. */
1370 if (now_seg
!= text_section
)
1380 if (flag_readonly_data_in_text
)
1382 if (now_seg
!= text_section
)
1385 else if (now_seg
!= data_section
)
1393 arm_s_section (ignore
)
1398 obj_elf_section (ignore
);
1403 opcode_select (width
)
1411 if (! (cpu_variant
& ARM_THUMB
))
1412 as_bad (_("selected processor does not support THUMB opcodes"));
1414 /* No need to force the alignment, since we will have been
1415 coming from ARM mode, which is word-aligned. */
1416 record_alignment (now_seg
, 1);
1423 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1424 as_bad (_("selected processor does not support ARM opcodes"));
1427 frag_align (2, 0, 0);
1428 record_alignment (now_seg
, 1);
1433 as_bad (_("invalid instruction size selected (%d)"), width
);
1442 demand_empty_rest_of_line ();
1450 demand_empty_rest_of_line ();
1459 temp
= get_absolute_expression ();
1464 opcode_select (temp
);
1468 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1476 skip_whitespace (str
);
1479 inst
.error
= _("Garbage following instruction");
1483 skip_past_comma (str
)
1489 while ((c
= *p
) == ' ' || c
== ',')
1492 if (c
== ',' && comma
++)
1500 return comma
? SUCCESS
: FAIL
;
1503 /* A standard register must be given at this point. Shift is the place to
1504 put it in the instruction. */
1507 reg_required_here (str
, shift
)
1511 static char buff
[128]; /* XXX */
1513 char * start
= *str
;
1515 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1518 inst
.instruction
|= reg
<< shift
;
1522 /* Restore the start point, we may have got a reg of the wrong class. */
1525 /* In the few cases where we might be able to accept something else
1526 this error can be overridden. */
1527 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1534 psr_required_here (str
, cpsr
, spsr
)
1540 char * start
= *str
;
1541 psr
= arm_psr_parse (str
);
1543 if (psr
== cpsr
|| psr
== spsr
)
1546 inst
.instruction
|= 1 << 22;
1551 /* In the few cases where we might be able to accept something else
1552 this error can be overridden. */
1553 inst
.error
= _("<psr(f)> expected");
1555 /* Restore the start point. */
1561 co_proc_number (str
)
1564 int processor
, pchar
;
1566 skip_whitespace (* str
);
1568 /* The data sheet seems to imply that just a number on its own is valid
1569 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1571 if (**str
== 'p' || **str
== 'P')
1575 if (pchar
>= '0' && pchar
<= '9')
1577 processor
= pchar
- '0';
1578 if (**str
>= '0' && **str
<= '9')
1580 processor
= processor
* 10 + *(*str
)++ - '0';
1583 inst
.error
= _("Illegal co-processor number");
1590 inst
.error
= _("Bad or missing co-processor number");
1594 inst
.instruction
|= processor
<< 8;
1599 cp_opc_expr (str
, where
, length
)
1606 skip_whitespace (* str
);
1608 memset (&expr
, '\0', sizeof (expr
));
1610 if (my_get_expression (&expr
, str
))
1612 if (expr
.X_op
!= O_constant
)
1614 inst
.error
= _("bad or missing expression");
1618 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1620 inst
.error
= _("immediate co-processor expression too large");
1624 inst
.instruction
|= expr
.X_add_number
<< where
;
1629 cp_reg_required_here (str
, where
)
1634 char * start
= *str
;
1636 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1639 inst
.instruction
|= reg
<< where
;
1643 /* In the few cases where we might be able to accept something else
1644 this error can be overridden. */
1645 inst
.error
= _("Co-processor register expected");
1647 /* Restore the start point. */
1653 fp_reg_required_here (str
, where
)
1658 char * start
= *str
;
1660 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1663 inst
.instruction
|= reg
<< where
;
1667 /* In the few cases where we might be able to accept something else
1668 this error can be overridden. */
1669 inst
.error
= _("Floating point register expected");
1671 /* Restore the start point. */
1677 cp_address_offset (str
)
1682 skip_whitespace (* str
);
1684 if (! is_immediate_prefix (**str
))
1686 inst
.error
= _("immediate expression expected");
1692 if (my_get_expression (& inst
.reloc
.exp
, str
))
1695 if (inst
.reloc
.exp
.X_op
== O_constant
)
1697 offset
= inst
.reloc
.exp
.X_add_number
;
1701 inst
.error
= _("co-processor address must be word aligned");
1705 if (offset
> 1023 || offset
< -1023)
1707 inst
.error
= _("offset too large");
1712 inst
.instruction
|= INDEX_UP
;
1716 inst
.instruction
|= offset
>> 2;
1719 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1725 cp_address_required_here (str
)
1737 skip_whitespace (p
);
1739 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1742 skip_whitespace (p
);
1748 if (skip_past_comma (& p
) == SUCCESS
)
1751 write_back
= WRITE_BACK
;
1755 inst
.error
= _("pc may not be used in post-increment");
1759 if (cp_address_offset (& p
) == FAIL
)
1763 pre_inc
= PRE_INDEX
| INDEX_UP
;
1767 /* '['Rn, #expr']'[!] */
1769 if (skip_past_comma (& p
) == FAIL
)
1771 inst
.error
= _("pre-indexed expression expected");
1775 pre_inc
= PRE_INDEX
;
1777 if (cp_address_offset (& p
) == FAIL
)
1780 skip_whitespace (p
);
1784 inst
.error
= _("missing ]");
1788 skip_whitespace (p
);
1794 inst
.error
= _("pc may not be used with write-back");
1799 write_back
= WRITE_BACK
;
1805 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1808 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1809 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1810 inst
.reloc
.pc_rel
= 1;
1811 inst
.instruction
|= (REG_PC
<< 16);
1812 pre_inc
= PRE_INDEX
;
1815 inst
.instruction
|= write_back
| pre_inc
;
1823 unsigned long flags
;
1825 /* Do nothing really. */
1826 inst
.instruction
|= flags
; /* This is pointless. */
1834 unsigned long flags
;
1836 /* Only one syntax. */
1837 skip_whitespace (str
);
1839 if (reg_required_here (&str
, 12) == FAIL
)
1841 inst
.error
= bad_args
;
1845 if (skip_past_comma (&str
) == FAIL
1846 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1848 inst
.error
= _("<psr> expected");
1852 inst
.instruction
|= flags
;
1857 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1861 unsigned long flags
;
1865 skip_whitespace (str
);
1867 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1869 inst
.instruction
|= PSR_ALL
;
1871 /* Sytax should be "<psr>, Rm" */
1872 if (skip_past_comma (&str
) == FAIL
1873 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1875 inst
.error
= bad_args
;
1881 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1882 inst
.instruction
|= PSR_FLAGS
;
1883 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1884 inst
.instruction
|= PSR_CONTROL
;
1887 inst
.error
= bad_args
;
1891 if (skip_past_comma (&str
) == FAIL
)
1893 inst
.error
= bad_args
;
1897 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1899 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1901 /* Immediate expression. */
1902 else if (is_immediate_prefix (* str
))
1907 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1909 inst
.error
= _("Register or shift expression expected");
1913 if (inst
.reloc
.exp
.X_add_symbol
)
1915 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1916 inst
.reloc
.pc_rel
= 0;
1920 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1923 inst
.error
= _("Invalid constant");
1927 inst
.instruction
|= value
;
1930 flags
|= INST_IMMEDIATE
;
1934 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1940 inst
.instruction
|= flags
;
1945 /* Long Multiply Parser
1946 UMULL RdLo, RdHi, Rm, Rs
1947 SMULL RdLo, RdHi, Rm, Rs
1948 UMLAL RdLo, RdHi, Rm, Rs
1949 SMLAL RdLo, RdHi, Rm, Rs
1952 do_mull (str
, flags
)
1954 unsigned long flags
;
1956 int rdlo
, rdhi
, rm
, rs
;
1958 /* Only one format "rdlo, rdhi, rm, rs" */
1959 skip_whitespace (str
);
1961 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1963 inst
.error
= bad_args
;
1967 if (skip_past_comma (&str
) == FAIL
1968 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1970 inst
.error
= bad_args
;
1974 if (skip_past_comma (&str
) == FAIL
1975 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1977 inst
.error
= bad_args
;
1981 /* rdhi, rdlo and rm must all be different */
1982 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1983 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1985 if (skip_past_comma (&str
) == FAIL
1986 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1988 inst
.error
= bad_args
;
1992 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1994 inst
.error
= bad_pc
;
1998 inst
.instruction
|= flags
;
2006 unsigned long flags
;
2010 /* Only one format "rd, rm, rs" */
2011 skip_whitespace (str
);
2013 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2015 inst
.error
= bad_args
;
2021 inst
.error
= bad_pc
;
2025 if (skip_past_comma (&str
) == FAIL
2026 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2028 inst
.error
= bad_args
;
2034 inst
.error
= bad_pc
;
2039 as_tsktsk (_("rd and rm should be different in mul"));
2041 if (skip_past_comma (&str
) == FAIL
2042 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2044 inst
.error
= bad_args
;
2050 inst
.error
= bad_pc
;
2054 inst
.instruction
|= flags
;
2062 unsigned long flags
;
2066 /* Only one format "rd, rm, rs, rn" */
2067 skip_whitespace (str
);
2069 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2071 inst
.error
= bad_args
;
2077 inst
.error
= bad_pc
;
2081 if (skip_past_comma (&str
) == FAIL
2082 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2084 inst
.error
= bad_args
;
2090 inst
.error
= bad_pc
;
2095 as_tsktsk (_("rd and rm should be different in mla"));
2097 if (skip_past_comma (&str
) == FAIL
2098 || (rd
= reg_required_here (&str
, 8)) == FAIL
2099 || skip_past_comma (&str
) == FAIL
2100 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2102 inst
.error
= bad_args
;
2106 if (rd
== REG_PC
|| rm
== REG_PC
)
2108 inst
.error
= bad_pc
;
2112 inst
.instruction
|= flags
;
2117 /* Returns the index into fp_values of a floating point number, or -1 if
2118 not in the table. */
2120 my_get_float_expression (str
)
2123 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2129 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2130 /* Look for a raw floating point number */
2131 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2132 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2134 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2136 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2138 if (words
[j
] != fp_values
[i
][j
])
2142 if (j
== MAX_LITTLENUMS
)
2150 /* Try and parse a more complex expression, this will probably fail
2151 unless the code uses a floating point prefix (eg "0f") */
2152 save_in
= input_line_pointer
;
2153 input_line_pointer
= *str
;
2154 if (expression (&exp
) == absolute_section
2155 && exp
.X_op
== O_big
2156 && exp
.X_add_number
< 0)
2158 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2160 if (gen_to_words (words
, 5, (long)15) == 0)
2162 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2164 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2166 if (words
[j
] != fp_values
[i
][j
])
2170 if (j
== MAX_LITTLENUMS
)
2172 *str
= input_line_pointer
;
2173 input_line_pointer
= save_in
;
2180 *str
= input_line_pointer
;
2181 input_line_pointer
= save_in
;
2185 /* Return true if anything in the expression is a bignum */
2187 walk_no_bignums (sp
)
2190 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2193 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2195 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2196 || (symbol_get_value_expression (sp
)->X_op_symbol
2197 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2204 my_get_expression (ep
, str
)
2211 save_in
= input_line_pointer
;
2212 input_line_pointer
= *str
;
2213 seg
= expression (ep
);
2216 if (seg
!= absolute_section
2217 && seg
!= text_section
2218 && seg
!= data_section
2219 && seg
!= bss_section
2220 && seg
!= undefined_section
)
2222 inst
.error
= _("bad_segment");
2223 *str
= input_line_pointer
;
2224 input_line_pointer
= save_in
;
2229 /* Get rid of any bignums now, so that we don't generate an error for which
2230 we can't establish a line number later on. Big numbers are never valid
2231 in instructions, which is where this routine is always called. */
2232 if (ep
->X_op
== O_big
2233 || (ep
->X_add_symbol
2234 && (walk_no_bignums (ep
->X_add_symbol
)
2236 && walk_no_bignums (ep
->X_op_symbol
)))))
2238 inst
.error
= _("Invalid constant");
2239 *str
= input_line_pointer
;
2240 input_line_pointer
= save_in
;
2244 *str
= input_line_pointer
;
2245 input_line_pointer
= save_in
;
2249 /* unrestrict should be one if <shift> <register> is permitted for this
2253 decode_shift (str
, unrestrict
)
2257 struct asm_shift
* shft
;
2261 skip_whitespace (* str
);
2263 for (p
= *str
; isalpha (*p
); p
++)
2268 inst
.error
= _("Shift expression expected");
2274 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2278 if (!strncmp (*str
, "rrx", 3)
2279 || !strncmp (*str
, "RRX", 3))
2282 inst
.instruction
|= shft
->value
;
2286 skip_whitespace (p
);
2288 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2290 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2294 else if (is_immediate_prefix (* p
))
2298 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2301 /* Validate some simple #expressions */
2302 if (inst
.reloc
.exp
.X_op
== O_constant
)
2304 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2306 /* Reject operations greater than 32, or lsl #32 */
2307 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2309 inst
.error
= _("Invalid immediate shift");
2313 /* Shifts of zero should be converted to lsl (which is zero)*/
2320 /* Shifts of 32 are encoded as 0, for those shifts that
2325 inst
.instruction
|= (num
<< 7) | shft
->value
;
2330 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2331 inst
.reloc
.pc_rel
= 0;
2332 inst
.instruction
|= shft
->value
;
2338 inst
.error
= unrestrict
? _("shift requires register or #expression")
2339 : _("shift requires #expression");
2345 inst
.error
= _("Shift expression expected");
2349 /* Do those data_ops which can take a negative immediate constant */
2350 /* by altering the instuction. A bit of a hack really */
2354 by inverting the second operand, and
2357 by negating the second operand.
2360 negate_data_op (instruction
, value
)
2361 unsigned long * instruction
;
2362 unsigned long value
;
2365 unsigned long negated
, inverted
;
2367 negated
= validate_immediate (-value
);
2368 inverted
= validate_immediate (~value
);
2370 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2374 case OPCODE_SUB
: /* ADD <-> SUB */
2375 new_inst
= OPCODE_ADD
;
2380 new_inst
= OPCODE_SUB
;
2384 case OPCODE_CMP
: /* CMP <-> CMN */
2385 new_inst
= OPCODE_CMN
;
2390 new_inst
= OPCODE_CMP
;
2394 /* Now Inverted ops */
2395 case OPCODE_MOV
: /* MOV <-> MVN */
2396 new_inst
= OPCODE_MVN
;
2401 new_inst
= OPCODE_MOV
;
2405 case OPCODE_AND
: /* AND <-> BIC */
2406 new_inst
= OPCODE_BIC
;
2411 new_inst
= OPCODE_AND
;
2415 case OPCODE_ADC
: /* ADC <-> SBC */
2416 new_inst
= OPCODE_SBC
;
2421 new_inst
= OPCODE_ADC
;
2425 /* We cannot do anything */
2433 *instruction
&= OPCODE_MASK
;
2434 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2445 skip_whitespace (* str
);
2447 if (reg_required_here (str
, 0) != FAIL
)
2449 if (skip_past_comma (str
) == SUCCESS
)
2450 /* Shift operation on register. */
2451 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2457 /* Immediate expression */
2458 if (is_immediate_prefix (**str
))
2463 if (my_get_expression (&inst
.reloc
.exp
, str
))
2466 if (inst
.reloc
.exp
.X_add_symbol
)
2468 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2469 inst
.reloc
.pc_rel
= 0;
2473 if (skip_past_comma (str
) == SUCCESS
)
2475 /* #x, y -- ie explicit rotation by Y */
2476 if (my_get_expression (&expr
, str
))
2479 if (expr
.X_op
!= O_constant
)
2481 inst
.error
= _("Constant expression expected");
2485 /* Rotate must be a multiple of 2 */
2486 if (((unsigned) expr
.X_add_number
) > 30
2487 || (expr
.X_add_number
& 1) != 0
2488 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2490 inst
.error
= _("Invalid constant");
2493 inst
.instruction
|= INST_IMMEDIATE
;
2494 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2495 inst
.instruction
|= expr
.X_add_number
<< 7;
2499 /* Implicit rotation, select a suitable one */
2500 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2504 /* Can't be done, perhaps the code reads something like
2505 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2506 if ((value
= negate_data_op (&inst
.instruction
,
2507 inst
.reloc
.exp
.X_add_number
))
2510 inst
.error
= _("Invalid constant");
2515 inst
.instruction
|= value
;
2518 inst
.instruction
|= INST_IMMEDIATE
;
2523 inst
.error
= _("Register or shift expression expected");
2532 skip_whitespace (* str
);
2534 if (fp_reg_required_here (str
, 0) != FAIL
)
2538 /* Immediate expression */
2539 if (*((*str
)++) == '#')
2545 skip_whitespace (* str
);
2547 /* First try and match exact strings, this is to guarantee that
2548 some formats will work even for cross assembly */
2550 for (i
= 0; fp_const
[i
]; i
++)
2552 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2556 *str
+= strlen (fp_const
[i
]);
2557 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2559 inst
.instruction
|= i
+ 8;
2566 /* Just because we didn't get a match doesn't mean that the
2567 constant isn't valid, just that it is in a format that we
2568 don't automatically recognize. Try parsing it with
2569 the standard expression routines. */
2570 if ((i
= my_get_float_expression (str
)) >= 0)
2572 inst
.instruction
|= i
+ 8;
2576 inst
.error
= _("Invalid floating point immediate expression");
2579 inst
.error
= _("Floating point register or immediate expression expected");
2585 do_arit (str
, flags
)
2587 unsigned long flags
;
2589 skip_whitespace (str
);
2591 if (reg_required_here (&str
, 12) == FAIL
2592 || skip_past_comma (&str
) == FAIL
2593 || reg_required_here (&str
, 16) == FAIL
2594 || skip_past_comma (&str
) == FAIL
2595 || data_op2 (&str
) == FAIL
)
2598 inst
.error
= bad_args
;
2602 inst
.instruction
|= flags
;
2610 unsigned long flags
;
2612 /* This is a pseudo-op of the form "adr rd, label" to be converted
2613 into a relative address of the form "add rd, pc, #label-.-8" */
2615 skip_whitespace (str
);
2617 if (reg_required_here (&str
, 12) == FAIL
2618 || skip_past_comma (&str
) == FAIL
2619 || my_get_expression (&inst
.reloc
.exp
, &str
))
2622 inst
.error
= bad_args
;
2625 /* Frag hacking will turn this into a sub instruction if the offset turns
2626 out to be negative. */
2627 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2628 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2629 inst
.reloc
.pc_rel
= 1;
2630 inst
.instruction
|= flags
;
2636 do_adrl (str
, flags
)
2638 unsigned long flags
;
2640 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2641 into a relative address of the form:
2642 add rd, pc, #low(label-.-8)"
2643 add rd, rd, #high(label-.-8)" */
2645 skip_whitespace (str
);
2647 if (reg_required_here (& str
, 12) == FAIL
2648 || skip_past_comma (& str
) == FAIL
2649 || my_get_expression (& inst
.reloc
.exp
, & str
))
2652 inst
.error
= bad_args
;
2658 /* Frag hacking will turn this into a sub instruction if the offset turns
2659 out to be negative. */
2660 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2661 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2662 inst
.reloc
.pc_rel
= 1;
2663 inst
.instruction
|= flags
;
2664 inst
.size
= INSN_SIZE
* 2;
2672 unsigned long flags
;
2674 skip_whitespace (str
);
2676 if (reg_required_here (&str
, 16) == FAIL
)
2679 inst
.error
= bad_args
;
2683 if (skip_past_comma (&str
) == FAIL
2684 || data_op2 (&str
) == FAIL
)
2687 inst
.error
= bad_args
;
2691 inst
.instruction
|= flags
;
2692 if ((flags
& 0x0000f000) == 0)
2693 inst
.instruction
|= CONDS_BIT
;
2702 unsigned long flags
;
2704 skip_whitespace (str
);
2706 if (reg_required_here (&str
, 12) == FAIL
)
2709 inst
.error
= bad_args
;
2713 if (skip_past_comma (&str
) == FAIL
2714 || data_op2 (&str
) == FAIL
)
2717 inst
.error
= bad_args
;
2721 inst
.instruction
|= flags
;
2727 ldst_extend (str
, hwse
)
2738 if (my_get_expression (& inst
.reloc
.exp
, str
))
2741 if (inst
.reloc
.exp
.X_op
== O_constant
)
2743 int value
= inst
.reloc
.exp
.X_add_number
;
2745 if ((hwse
&& (value
< -255 || value
> 255))
2746 || (value
< -4095 || value
> 4095))
2748 inst
.error
= _("address offset too large");
2758 /* Halfword and signextension instructions have the
2759 immediate value split across bits 11..8 and bits 3..0 */
2761 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2763 inst
.instruction
|= add
| value
;
2769 inst
.instruction
|= HWOFFSET_IMM
;
2770 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2773 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2774 inst
.reloc
.pc_rel
= 0;
2779 add
= 0; /* and fall through */
2781 (*str
)++; /* and fall through */
2783 if (reg_required_here (str
, 0) == FAIL
)
2787 inst
.instruction
|= add
;
2790 inst
.instruction
|= add
| OFFSET_REG
;
2791 if (skip_past_comma (str
) == SUCCESS
)
2792 return decode_shift (str
, SHIFT_RESTRICT
);
2800 do_ldst (str
, flags
)
2802 unsigned long flags
;
2809 /* This is not ideal, but it is the simplest way of dealing with the
2810 ARM7T halfword instructions (since they use a different
2811 encoding, but the same mnemonic): */
2812 halfword
= (flags
& 0x80000000) != 0;
2815 /* This is actually a load/store of a halfword, or a
2816 signed-extension load */
2817 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2820 = _("Processor does not support halfwords or signed bytes");
2824 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2825 | (flags
& ~COND_MASK
);
2830 skip_whitespace (str
);
2832 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2835 inst
.error
= bad_args
;
2839 if (skip_past_comma (& str
) == FAIL
)
2841 inst
.error
= _("Address expected");
2851 skip_whitespace (str
);
2853 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2856 conflict_reg
= (((conflict_reg
== reg
)
2857 && (inst
.instruction
& LOAD_BIT
))
2860 skip_whitespace (str
);
2865 if (skip_past_comma (&str
) == SUCCESS
)
2867 /* [Rn],... (post inc) */
2868 if (ldst_extend (&str
, halfword
) == FAIL
)
2871 as_warn (_("destination register same as write-back base\n"));
2877 inst
.instruction
|= HWOFFSET_IMM
;
2879 skip_whitespace (str
);
2884 as_warn (_("destination register same as write-back base\n"));
2886 inst
.instruction
|= WRITE_BACK
;
2890 if (! (flags
& TRANS_BIT
))
2897 if (skip_past_comma (&str
) == FAIL
)
2899 inst
.error
= _("pre-indexed expression expected");
2904 if (ldst_extend (&str
, halfword
) == FAIL
)
2907 skip_whitespace (str
);
2911 inst
.error
= _("missing ]");
2915 skip_whitespace (str
);
2920 as_tsktsk (_("destination register same as write-back base\n"));
2922 inst
.instruction
|= WRITE_BACK
;
2926 else if (*str
== '=')
2928 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2931 skip_whitespace (str
);
2933 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2936 if (inst
.reloc
.exp
.X_op
!= O_constant
2937 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2939 inst
.error
= _("Constant expression expected");
2943 if (inst
.reloc
.exp
.X_op
== O_constant
2944 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2946 /* This can be done with a mov instruction */
2947 inst
.instruction
&= LITERAL_MASK
;
2948 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2949 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2955 /* Insert into literal pool */
2956 if (add_to_lit_pool () == FAIL
)
2959 inst
.error
= _("literal pool insertion failed");
2963 /* Change the instruction exp to point to the pool */
2966 inst
.instruction
|= HWOFFSET_IMM
;
2967 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2970 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2971 inst
.reloc
.pc_rel
= 1;
2972 inst
.instruction
|= (REG_PC
<< 16);
2978 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2983 inst
.instruction
|= HWOFFSET_IMM
;
2984 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2987 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2988 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2989 inst
.reloc
.pc_rel
= 1;
2990 inst
.instruction
|= (REG_PC
<< 16);
2994 if (pre_inc
&& (flags
& TRANS_BIT
))
2995 inst
.error
= _("Pre-increment instruction with translate");
2997 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3010 /* We come back here if we get ranges concatenated by '+' or '|' */
3025 skip_whitespace (str
);
3027 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3036 inst
.error
= _("Bad range in register list");
3040 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3042 if (range
& (1 << i
))
3044 (_("Warning: Duplicated register (r%d) in register list"),
3052 if (range
& (1 << reg
))
3053 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3055 else if (reg
<= cur_reg
)
3056 as_tsktsk (_("Warning: Register range not in ascending order"));
3060 } while (skip_past_comma (&str
) != FAIL
3061 || (in_range
= 1, *str
++ == '-'));
3063 skip_whitespace (str
);
3067 inst
.error
= _("Missing `}'");
3075 if (my_get_expression (&expr
, &str
))
3078 if (expr
.X_op
== O_constant
)
3080 if (expr
.X_add_number
3081 != (expr
.X_add_number
& 0x0000ffff))
3083 inst
.error
= _("invalid register mask");
3087 if ((range
& expr
.X_add_number
) != 0)
3089 int regno
= range
& expr
.X_add_number
;
3092 regno
= (1 << regno
) - 1;
3094 (_("Warning: Duplicated register (r%d) in register list"),
3098 range
|= expr
.X_add_number
;
3102 if (inst
.reloc
.type
!= 0)
3104 inst
.error
= _("expression too complex");
3108 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3109 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3110 inst
.reloc
.pc_rel
= 0;
3114 skip_whitespace (str
);
3116 if (*str
== '|' || *str
== '+')
3121 } while (another_range
);
3128 do_ldmstm (str
, flags
)
3130 unsigned long flags
;
3135 skip_whitespace (str
);
3137 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3140 if (base_reg
== REG_PC
)
3142 inst
.error
= _("r15 not allowed as base register");
3146 skip_whitespace (str
);
3150 flags
|= WRITE_BACK
;
3154 if (skip_past_comma (&str
) == FAIL
3155 || (range
= reg_list (&str
)) == FAIL
)
3158 inst
.error
= bad_args
;
3165 flags
|= MULTI_SET_PSR
;
3168 inst
.instruction
|= flags
| range
;
3176 unsigned long flags
;
3178 skip_whitespace (str
);
3180 /* Allow optional leading '#'. */
3181 if (is_immediate_prefix (*str
))
3184 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3187 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3188 inst
.reloc
.pc_rel
= 0;
3189 inst
.instruction
|= flags
;
3197 do_swap (str
, flags
)
3199 unsigned long flags
;
3203 skip_whitespace (str
);
3205 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3210 inst
.error
= _("r15 not allowed in swap");
3214 if (skip_past_comma (&str
) == FAIL
3215 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3218 inst
.error
= bad_args
;
3224 inst
.error
= _("r15 not allowed in swap");
3228 if (skip_past_comma (&str
) == FAIL
3231 inst
.error
= bad_args
;
3235 skip_whitespace (str
);
3237 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3242 inst
.error
= bad_pc
;
3246 skip_whitespace (str
);
3250 inst
.error
= _("missing ]");
3254 inst
.instruction
|= flags
;
3260 do_branch (str
, flags
)
3262 unsigned long flags
;
3264 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3271 /* ScottB: February 5, 1998 */
3272 /* Check to see of PLT32 reloc required for the instruction. */
3274 /* arm_parse_reloc() works on input_line_pointer.
3275 We actually want to parse the operands to the branch instruction
3276 passed in 'str'. Save the input pointer and restore it later. */
3277 save_in
= input_line_pointer
;
3278 input_line_pointer
= str
;
3279 if (inst
.reloc
.exp
.X_op
== O_symbol
3281 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3283 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3284 inst
.reloc
.pc_rel
= 0;
3285 /* Modify str to point to after parsed operands, otherwise
3286 end_of_line() will complain about the (PLT) left in str. */
3287 str
= input_line_pointer
;
3291 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3292 inst
.reloc
.pc_rel
= 1;
3294 input_line_pointer
= save_in
;
3297 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3298 inst
.reloc
.pc_rel
= 1;
3299 #endif /* OBJ_ELF */
3308 unsigned long flags
;
3312 skip_whitespace (str
);
3314 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3318 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3327 unsigned long flags
;
3329 /* Co-processor data operation.
3330 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3331 skip_whitespace (str
);
3333 if (co_proc_number (&str
) == FAIL
)
3336 inst
.error
= bad_args
;
3340 if (skip_past_comma (&str
) == FAIL
3341 || cp_opc_expr (&str
, 20,4) == FAIL
)
3344 inst
.error
= bad_args
;
3348 if (skip_past_comma (&str
) == FAIL
3349 || cp_reg_required_here (&str
, 12) == FAIL
)
3352 inst
.error
= bad_args
;
3356 if (skip_past_comma (&str
) == FAIL
3357 || cp_reg_required_here (&str
, 16) == FAIL
)
3360 inst
.error
= bad_args
;
3364 if (skip_past_comma (&str
) == FAIL
3365 || cp_reg_required_here (&str
, 0) == FAIL
)
3368 inst
.error
= bad_args
;
3372 if (skip_past_comma (&str
) == SUCCESS
)
3374 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3377 inst
.error
= bad_args
;
3387 do_lstc (str
, flags
)
3389 unsigned long flags
;
3391 /* Co-processor register load/store.
3392 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3394 skip_whitespace (str
);
3396 if (co_proc_number (&str
) == FAIL
)
3399 inst
.error
= bad_args
;
3403 if (skip_past_comma (&str
) == FAIL
3404 || cp_reg_required_here (&str
, 12) == FAIL
)
3407 inst
.error
= bad_args
;
3411 if (skip_past_comma (&str
) == FAIL
3412 || cp_address_required_here (&str
) == FAIL
)
3415 inst
.error
= bad_args
;
3419 inst
.instruction
|= flags
;
3425 do_co_reg (str
, flags
)
3427 unsigned long flags
;
3429 /* Co-processor register transfer.
3430 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3432 skip_whitespace (str
);
3434 if (co_proc_number (&str
) == FAIL
)
3437 inst
.error
= bad_args
;
3441 if (skip_past_comma (&str
) == FAIL
3442 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3445 inst
.error
= bad_args
;
3449 if (skip_past_comma (&str
) == FAIL
3450 || reg_required_here (&str
, 12) == FAIL
)
3453 inst
.error
= bad_args
;
3457 if (skip_past_comma (&str
) == FAIL
3458 || cp_reg_required_here (&str
, 16) == FAIL
)
3461 inst
.error
= bad_args
;
3465 if (skip_past_comma (&str
) == FAIL
3466 || cp_reg_required_here (&str
, 0) == FAIL
)
3469 inst
.error
= bad_args
;
3473 if (skip_past_comma (&str
) == SUCCESS
)
3475 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3478 inst
.error
= bad_args
;
3488 do_fp_ctrl (str
, flags
)
3490 unsigned long flags
;
3492 /* FP control registers.
3493 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3495 skip_whitespace (str
);
3497 if (reg_required_here (&str
, 12) == FAIL
)
3500 inst
.error
= bad_args
;
3509 do_fp_ldst (str
, flags
)
3511 unsigned long flags
;
3513 skip_whitespace (str
);
3515 switch (inst
.suffix
)
3520 inst
.instruction
|= CP_T_X
;
3523 inst
.instruction
|= CP_T_Y
;
3526 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3532 if (fp_reg_required_here (&str
, 12) == FAIL
)
3535 inst
.error
= bad_args
;
3539 if (skip_past_comma (&str
) == FAIL
3540 || cp_address_required_here (&str
) == FAIL
)
3543 inst
.error
= bad_args
;
3551 do_fp_ldmstm (str
, flags
)
3553 unsigned long flags
;
3557 skip_whitespace (str
);
3559 if (fp_reg_required_here (&str
, 12) == FAIL
)
3562 inst
.error
= bad_args
;
3566 /* Get Number of registers to transfer */
3567 if (skip_past_comma (&str
) == FAIL
3568 || my_get_expression (&inst
.reloc
.exp
, &str
))
3571 inst
.error
= _("constant expression expected");
3575 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3577 inst
.error
= _("Constant value required for number of registers");
3581 num_regs
= inst
.reloc
.exp
.X_add_number
;
3583 if (num_regs
< 1 || num_regs
> 4)
3585 inst
.error
= _("number of registers must be in the range [1:4]");
3592 inst
.instruction
|= CP_T_X
;
3595 inst
.instruction
|= CP_T_Y
;
3598 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3612 /* The instruction specified "ea" or "fd", so we can only accept
3613 [Rn]{!}. The instruction does not really support stacking or
3614 unstacking, so we have to emulate these by setting appropriate
3615 bits and offsets. */
3616 if (skip_past_comma (&str
) == FAIL
3620 inst
.error
= bad_args
;
3625 skip_whitespace (str
);
3627 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3630 skip_whitespace (str
);
3634 inst
.error
= bad_args
;
3645 inst
.error
= _("R15 not allowed as base register with write-back");
3652 if (flags
& CP_T_Pre
)
3655 offset
= 3 * num_regs
;
3661 /* Post-increment */
3665 offset
= 3 * num_regs
;
3669 /* No write-back, so convert this into a standard pre-increment
3670 instruction -- aesthetically more pleasing. */
3671 flags
= CP_T_Pre
| CP_T_UD
;
3676 inst
.instruction
|= flags
| offset
;
3678 else if (skip_past_comma (&str
) == FAIL
3679 || cp_address_required_here (&str
) == FAIL
)
3682 inst
.error
= bad_args
;
3690 do_fp_dyadic (str
, flags
)
3692 unsigned long flags
;
3694 skip_whitespace (str
);
3696 switch (inst
.suffix
)
3701 inst
.instruction
|= 0x00000080;
3704 inst
.instruction
|= 0x00080000;
3710 if (fp_reg_required_here (&str
, 12) == FAIL
)
3713 inst
.error
= bad_args
;
3717 if (skip_past_comma (&str
) == FAIL
3718 || fp_reg_required_here (&str
, 16) == FAIL
)
3721 inst
.error
= bad_args
;
3725 if (skip_past_comma (&str
) == FAIL
3726 || fp_op2 (&str
) == FAIL
)
3729 inst
.error
= bad_args
;
3733 inst
.instruction
|= flags
;
3739 do_fp_monadic (str
, flags
)
3741 unsigned long flags
;
3743 skip_whitespace (str
);
3745 switch (inst
.suffix
)
3750 inst
.instruction
|= 0x00000080;
3753 inst
.instruction
|= 0x00080000;
3759 if (fp_reg_required_here (&str
, 12) == FAIL
)
3762 inst
.error
= bad_args
;
3766 if (skip_past_comma (&str
) == FAIL
3767 || fp_op2 (&str
) == FAIL
)
3770 inst
.error
= bad_args
;
3774 inst
.instruction
|= flags
;
3780 do_fp_cmp (str
, flags
)
3782 unsigned long flags
;
3784 skip_whitespace (str
);
3786 if (fp_reg_required_here (&str
, 16) == FAIL
)
3789 inst
.error
= bad_args
;
3793 if (skip_past_comma (&str
) == FAIL
3794 || fp_op2 (&str
) == FAIL
)
3797 inst
.error
= bad_args
;
3801 inst
.instruction
|= flags
;
3807 do_fp_from_reg (str
, flags
)
3809 unsigned long flags
;
3811 skip_whitespace (str
);
3813 switch (inst
.suffix
)
3818 inst
.instruction
|= 0x00000080;
3821 inst
.instruction
|= 0x00080000;
3827 if (fp_reg_required_here (&str
, 16) == FAIL
)
3830 inst
.error
= bad_args
;
3834 if (skip_past_comma (&str
) == FAIL
3835 || reg_required_here (&str
, 12) == FAIL
)
3838 inst
.error
= bad_args
;
3842 inst
.instruction
|= flags
;
3848 do_fp_to_reg (str
, flags
)
3850 unsigned long flags
;
3852 skip_whitespace (str
);
3854 if (reg_required_here (&str
, 12) == FAIL
)
3857 if (skip_past_comma (&str
) == FAIL
3858 || fp_reg_required_here (&str
, 0) == FAIL
)
3861 inst
.error
= bad_args
;
3865 inst
.instruction
|= flags
;
3870 /* Thumb specific routines */
3872 /* Parse and validate that a register is of the right form, this saves
3873 repeated checking of this information in many similar cases.
3874 Unlike the 32-bit case we do not insert the register into the opcode
3875 here, since the position is often unknown until the full instruction
3878 thumb_reg (strp
, hi_lo
)
3884 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3892 inst
.error
= _("lo register required");
3900 inst
.error
= _("hi register required");
3912 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3915 thumb_add_sub (str
, subtract
)
3919 int Rd
, Rs
, Rn
= FAIL
;
3921 skip_whitespace (str
);
3923 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3924 || skip_past_comma (&str
) == FAIL
)
3927 inst
.error
= bad_args
;
3931 if (is_immediate_prefix (*str
))
3935 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3940 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3943 if (skip_past_comma (&str
) == FAIL
)
3945 /* Two operand format, shuffle the registers and pretend there
3950 else if (is_immediate_prefix (*str
))
3953 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3956 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3960 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3961 for the latter case, EXPR contains the immediate that was found. */
3964 /* All register format. */
3965 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3969 inst
.error
= _("dest and source1 must be the same register");
3973 /* Can't do this for SUB */
3976 inst
.error
= _("subtract valid only on lo regs");
3980 inst
.instruction
= (T_OPCODE_ADD_HI
3981 | (Rd
> 7 ? THUMB_H1
: 0)
3982 | (Rn
> 7 ? THUMB_H2
: 0));
3983 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3987 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3988 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3993 /* Immediate expression, now things start to get nasty. */
3995 /* First deal with HI regs, only very restricted cases allowed:
3996 Adjusting SP, and using PC or SP to get an address. */
3997 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3998 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4000 inst
.error
= _("invalid Hi register with immediate");
4004 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4006 /* Value isn't known yet, all we can do is store all the fragments
4007 we know about in the instruction and let the reloc hacking
4009 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4010 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4014 int offset
= inst
.reloc
.exp
.X_add_number
;
4024 /* Quick check, in case offset is MIN_INT */
4027 inst
.error
= _("immediate value out of range");
4036 if (offset
& ~0x1fc)
4038 inst
.error
= _("invalid immediate value for stack adjust");
4041 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4042 inst
.instruction
|= offset
>> 2;
4044 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4047 || (offset
& ~0x3fc))
4049 inst
.error
= _("invalid immediate for address calculation");
4052 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4054 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4060 inst
.error
= _("immediate value out of range");
4063 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4064 inst
.instruction
|= (Rd
<< 8) | offset
;
4070 inst
.error
= _("immediate value out of range");
4073 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4074 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4082 thumb_shift (str
, shift
)
4086 int Rd
, Rs
, Rn
= FAIL
;
4088 skip_whitespace (str
);
4090 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4091 || skip_past_comma (&str
) == FAIL
)
4094 inst
.error
= bad_args
;
4098 if (is_immediate_prefix (*str
))
4100 /* Two operand immediate format, set Rs to Rd. */
4103 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4108 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4111 if (skip_past_comma (&str
) == FAIL
)
4113 /* Two operand format, shuffle the registers and pretend there
4118 else if (is_immediate_prefix (*str
))
4121 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4124 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4128 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4129 for the latter case, EXPR contains the immediate that was found. */
4135 inst
.error
= _("source1 and dest must be same register");
4141 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4142 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4143 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4146 inst
.instruction
|= Rd
| (Rn
<< 3);
4152 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4153 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4154 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4157 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4159 /* Value isn't known yet, create a dummy reloc and let reloc
4160 hacking fix it up */
4162 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4166 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4168 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4170 inst
.error
= _("Invalid immediate for shift");
4174 /* Shifts of zero are handled by converting to LSL */
4175 if (shift_value
== 0)
4176 inst
.instruction
= T_OPCODE_LSL_I
;
4178 /* Shifts of 32 are encoded as a shift of zero */
4179 if (shift_value
== 32)
4182 inst
.instruction
|= shift_value
<< 6;
4185 inst
.instruction
|= Rd
| (Rs
<< 3);
4191 thumb_mov_compare (str
, move
)
4197 skip_whitespace (str
);
4199 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4200 || skip_past_comma (&str
) == FAIL
)
4203 inst
.error
= bad_args
;
4207 if (is_immediate_prefix (*str
))
4210 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4213 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4218 if (Rs
< 8 && Rd
< 8)
4220 if (move
== THUMB_MOVE
)
4221 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4222 since a MOV instruction produces unpredictable results */
4223 inst
.instruction
= T_OPCODE_ADD_I3
;
4225 inst
.instruction
= T_OPCODE_CMP_LR
;
4226 inst
.instruction
|= Rd
| (Rs
<< 3);
4230 if (move
== THUMB_MOVE
)
4231 inst
.instruction
= T_OPCODE_MOV_HR
;
4233 inst
.instruction
= T_OPCODE_CMP_HR
;
4236 inst
.instruction
|= THUMB_H1
;
4239 inst
.instruction
|= THUMB_H2
;
4241 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4248 inst
.error
= _("only lo regs allowed with immediate");
4252 if (move
== THUMB_MOVE
)
4253 inst
.instruction
= T_OPCODE_MOV_I8
;
4255 inst
.instruction
= T_OPCODE_CMP_I8
;
4257 inst
.instruction
|= Rd
<< 8;
4259 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4260 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4263 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4267 inst
.error
= _("invalid immediate");
4271 inst
.instruction
|= value
;
4279 thumb_load_store (str
, load_store
, size
)
4284 int Rd
, Rb
, Ro
= FAIL
;
4286 skip_whitespace (str
);
4288 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4289 || skip_past_comma (&str
) == FAIL
)
4292 inst
.error
= bad_args
;
4299 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4302 if (skip_past_comma (&str
) != FAIL
)
4304 if (is_immediate_prefix (*str
))
4307 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4310 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4315 inst
.reloc
.exp
.X_op
= O_constant
;
4316 inst
.reloc
.exp
.X_add_number
= 0;
4321 inst
.error
= _("expected ']'");
4326 else if (*str
== '=')
4328 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4331 skip_whitespace (str
);
4333 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4338 if ( inst
.reloc
.exp
.X_op
!= O_constant
4339 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4341 inst
.error
= "Constant expression expected";
4345 if (inst
.reloc
.exp
.X_op
== O_constant
4346 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4348 /* This can be done with a mov instruction */
4350 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4351 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4355 /* Insert into literal pool */
4356 if (add_to_lit_pool () == FAIL
)
4359 inst
.error
= "literal pool insertion failed";
4363 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4364 inst
.reloc
.pc_rel
= 1;
4365 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4366 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4372 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4375 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4376 inst
.reloc
.pc_rel
= 1;
4377 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4378 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4383 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4385 if (size
!= THUMB_WORD
)
4387 inst
.error
= _("byte or halfword not valid for base register");
4390 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4392 inst
.error
= _("R15 based store not allowed");
4395 else if (Ro
!= FAIL
)
4397 inst
.error
= _("Invalid base register for register offset");
4402 inst
.instruction
= T_OPCODE_LDR_PC
;
4403 else if (load_store
== THUMB_LOAD
)
4404 inst
.instruction
= T_OPCODE_LDR_SP
;
4406 inst
.instruction
= T_OPCODE_STR_SP
;
4408 inst
.instruction
|= Rd
<< 8;
4409 if (inst
.reloc
.exp
.X_op
== O_constant
)
4411 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4413 if (offset
& ~0x3fc)
4415 inst
.error
= _("invalid offset");
4419 inst
.instruction
|= offset
>> 2;
4422 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4426 inst
.error
= _("invalid base register in load/store");
4429 else if (Ro
== FAIL
)
4431 /* Immediate offset */
4432 if (size
== THUMB_WORD
)
4433 inst
.instruction
= (load_store
== THUMB_LOAD
4434 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4435 else if (size
== THUMB_HALFWORD
)
4436 inst
.instruction
= (load_store
== THUMB_LOAD
4437 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4439 inst
.instruction
= (load_store
== THUMB_LOAD
4440 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4442 inst
.instruction
|= Rd
| (Rb
<< 3);
4444 if (inst
.reloc
.exp
.X_op
== O_constant
)
4446 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4448 if (offset
& ~(0x1f << size
))
4450 inst
.error
= _("Invalid offset");
4453 inst
.instruction
|= (offset
>> size
) << 6;
4456 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4460 /* Register offset */
4461 if (size
== THUMB_WORD
)
4462 inst
.instruction
= (load_store
== THUMB_LOAD
4463 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4464 else if (size
== THUMB_HALFWORD
)
4465 inst
.instruction
= (load_store
== THUMB_LOAD
4466 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4468 inst
.instruction
= (load_store
== THUMB_LOAD
4469 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4471 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4486 /* Handle the Format 4 instructions that do not have equivalents in other
4487 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4495 skip_whitespace (str
);
4497 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4500 if (skip_past_comma (&str
) == FAIL
4501 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4504 inst
.error
= bad_args
;
4508 if (skip_past_comma (&str
) != FAIL
)
4510 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4511 (It isn't allowed for CMP either, but that isn't handled by this
4513 if (inst
.instruction
== T_OPCODE_TST
4514 || inst
.instruction
== T_OPCODE_CMN
4515 || inst
.instruction
== T_OPCODE_NEG
4516 || inst
.instruction
== T_OPCODE_MVN
)
4518 inst
.error
= bad_args
;
4522 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4527 inst
.error
= _("dest and source1 one must be the same register");
4533 if (inst
.instruction
== T_OPCODE_MUL
4535 as_tsktsk (_("Rs and Rd must be different in MUL"));
4537 inst
.instruction
|= Rd
| (Rs
<< 3);
4545 thumb_add_sub (str
, 0);
4552 thumb_shift (str
, THUMB_ASR
);
4559 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4561 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4562 inst
.reloc
.pc_rel
= 1;
4570 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4572 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4573 inst
.reloc
.pc_rel
= 1;
4577 /* Find the real, Thumb encoded start of a Thumb function. */
4580 find_real_start (symbolP
)
4584 const char * name
= S_GET_NAME (symbolP
);
4585 symbolS
* new_target
;
4587 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4588 #define STUB_NAME ".real_start_of"
4593 /* Names that start with '.' are local labels, not function entry points.
4594 The compiler may generate BL instructions to these labels because it
4595 needs to perform a branch to a far away location. */
4599 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4600 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4602 new_target
= symbol_find (real_start
);
4604 if (new_target
== NULL
)
4606 as_warn ("Failed to find real start of function: %s\n", name
);
4607 new_target
= symbolP
;
4620 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4623 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4624 inst
.reloc
.pc_rel
= 1;
4627 /* If the destination of the branch is a defined symbol which does not have
4628 the THUMB_FUNC attribute, then we must be calling a function which has
4629 the (interfacearm) attribute. We look for the Thumb entry point to that
4630 function and change the branch to refer to that function instead. */
4631 if ( inst
.reloc
.exp
.X_op
== O_symbol
4632 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4633 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4634 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4635 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4644 skip_whitespace (str
);
4646 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4649 /* This sets THUMB_H2 from the top bit of reg. */
4650 inst
.instruction
|= reg
<< 3;
4652 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4653 should cause the alignment to be checked once it is known. This is
4654 because BX PC only works if the instruction is word aligned. */
4663 thumb_mov_compare (str
, THUMB_COMPARE
);
4673 skip_whitespace (str
);
4675 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4679 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4683 if (skip_past_comma (&str
) == FAIL
4684 || (range
= reg_list (&str
)) == FAIL
)
4687 inst
.error
= bad_args
;
4691 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4693 /* This really doesn't seem worth it. */
4694 inst
.reloc
.type
= BFD_RELOC_NONE
;
4695 inst
.error
= _("Expression too complex");
4701 inst
.error
= _("only lo-regs valid in load/store multiple");
4705 inst
.instruction
|= (Rb
<< 8) | range
;
4713 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4720 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4727 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4736 skip_whitespace (str
);
4738 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4739 || skip_past_comma (&str
) == FAIL
4741 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4742 || skip_past_comma (&str
) == FAIL
4743 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4747 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4751 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4759 thumb_shift (str
, THUMB_LSL
);
4766 thumb_shift (str
, THUMB_LSR
);
4773 thumb_mov_compare (str
, THUMB_MOVE
);
4782 skip_whitespace (str
);
4784 if ((range
= reg_list (&str
)) == FAIL
)
4787 inst
.error
= bad_args
;
4791 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4793 /* This really doesn't seem worth it. */
4794 inst
.reloc
.type
= BFD_RELOC_NONE
;
4795 inst
.error
= _("Expression too complex");
4801 if ((inst
.instruction
== T_OPCODE_PUSH
4802 && (range
& ~0xff) == 1 << REG_LR
)
4803 || (inst
.instruction
== T_OPCODE_POP
4804 && (range
& ~0xff) == 1 << REG_PC
))
4806 inst
.instruction
|= THUMB_PP_PC_LR
;
4811 inst
.error
= _("invalid register list to push/pop instruction");
4816 inst
.instruction
|= range
;
4824 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4831 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4838 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4845 thumb_add_sub (str
, 1);
4852 skip_whitespace (str
);
4854 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4857 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4866 /* This is a pseudo-op of the form "adr rd, label" to be converted
4867 into a relative address of the form "add rd, pc, #label-.-4" */
4868 skip_whitespace (str
);
4870 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4871 || skip_past_comma (&str
) == FAIL
4872 || my_get_expression (&inst
.reloc
.exp
, &str
))
4875 inst
.error
= bad_args
;
4879 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4880 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4881 inst
.reloc
.pc_rel
= 1;
4882 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4890 int len
= strlen (reg_table
[entry
].name
) + 2;
4891 char * buf
= (char *) xmalloc (len
);
4892 char * buf2
= (char *) xmalloc (len
);
4895 #ifdef REGISTER_PREFIX
4896 buf
[i
++] = REGISTER_PREFIX
;
4899 strcpy (buf
+ i
, reg_table
[entry
].name
);
4901 for (i
= 0; buf
[i
]; i
++)
4902 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4906 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4907 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4911 insert_reg_alias (str
, regnum
)
4915 struct reg_entry
*new =
4916 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4917 char *name
= xmalloc (strlen (str
) + 1);
4921 new->number
= regnum
;
4923 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4927 set_constant_flonums ()
4931 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4932 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4941 if ( (arm_ops_hsh
= hash_new ()) == NULL
4942 || (arm_tops_hsh
= hash_new ()) == NULL
4943 || (arm_cond_hsh
= hash_new ()) == NULL
4944 || (arm_shift_hsh
= hash_new ()) == NULL
4945 || (arm_reg_hsh
= hash_new ()) == NULL
4946 || (arm_psr_hsh
= hash_new ()) == NULL
)
4947 as_fatal (_("Virtual memory exhausted"));
4949 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4950 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4951 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4952 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4953 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4954 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4955 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4956 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4957 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4958 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4960 for (i
= 0; reg_table
[i
].name
; i
++)
4963 set_constant_flonums ();
4965 #if defined OBJ_COFF || defined OBJ_ELF
4967 unsigned int flags
= 0;
4969 /* Set the flags in the private structure */
4970 if (uses_apcs_26
) flags
|= F_APCS26
;
4971 if (support_interwork
) flags
|= F_INTERWORK
;
4972 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4973 if (pic_code
) flags
|= F_PIC
;
4974 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
4976 bfd_set_private_flags (stdoutput
, flags
);
4983 /* Record the CPU type as well */
4984 switch (cpu_variant
& ARM_CPU_MASK
)
4987 mach
= bfd_mach_arm_2
;
4990 case ARM_3
: /* also ARM_250 */
4991 mach
= bfd_mach_arm_2a
;
4995 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4996 mach
= bfd_mach_arm_4
;
4999 case ARM_7
: /* also ARM_6 */
5000 mach
= bfd_mach_arm_3
;
5004 /* Catch special cases. */
5005 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5007 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5008 mach
= bfd_mach_arm_5T
;
5009 else if (cpu_variant
& ARM_EXT_V5
)
5010 mach
= bfd_mach_arm_5
;
5011 else if (cpu_variant
& ARM_THUMB
)
5012 mach
= bfd_mach_arm_4T
;
5013 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5014 mach
= bfd_mach_arm_4
;
5015 else if (cpu_variant
& ARM_LONGMUL
)
5016 mach
= bfd_mach_arm_3M
;
5019 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5023 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5024 for use in the a.out file, and stores them in the array pointed to by buf.
5025 This knows about the endian-ness of the target machine and does
5026 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5027 2 (short) and 4 (long) Floating numbers are put out as a series of
5028 LITTLENUMS (shorts, here at least). */
5030 md_number_to_chars (buf
, val
, n
)
5035 if (target_big_endian
)
5036 number_to_chars_bigendian (buf
, val
, n
);
5038 number_to_chars_littleendian (buf
, val
, n
);
5042 md_chars_to_number (buf
, n
)
5047 unsigned char * where
= (unsigned char *) buf
;
5049 if (target_big_endian
)
5054 result
|= (*where
++ & 255);
5062 result
|= (where
[n
] & 255);
5069 /* Turn a string in input_line_pointer into a floating point constant
5070 of type TYPE, and store the appropriate bytes in *litP. The number
5071 of LITTLENUMS emitted is stored in *sizeP . An error message is
5072 returned, or NULL on OK.
5074 Note that fp constants aren't represent in the normal way on the ARM.
5075 In big endian mode, things are as expected. However, in little endian
5076 mode fp constants are big-endian word-wise, and little-endian byte-wise
5077 within the words. For example, (double) 1.1 in big endian mode is
5078 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5079 the byte sequence 99 99 f1 3f 9a 99 99 99.
5081 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5084 md_atof (type
, litP
, sizeP
)
5090 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5122 return _("Bad call to MD_ATOF()");
5125 t
= atof_ieee (input_line_pointer
, type
, words
);
5127 input_line_pointer
= t
;
5130 if (target_big_endian
)
5132 for (i
= 0; i
< prec
; i
++)
5134 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5140 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5141 8 byte float the order is 1 0 3 2. */
5142 for (i
= 0; i
< prec
; i
+= 2)
5144 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5145 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5153 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5155 md_pcrel_from (fixP
)
5159 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5160 && fixP
->fx_subsy
== NULL
)
5163 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5165 /* PC relative addressing on the Thumb is slightly odd
5166 as the bottom two bits of the PC are forced to zero
5167 for the calculation. */
5168 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5171 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5174 /* Round up a section size to the appropriate boundary. */
5176 md_section_align (segment
, size
)
5181 /* Don't align the dwarf2 debug sections */
5182 if (!strncmp (segment
->name
, ".debug", 5))
5185 /* Round all sects to multiple of 4 */
5186 return (size
+ 3) & ~3;
5189 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5190 we have no need to default values of symbols. */
5194 md_undefined_symbol (name
)
5198 if (name
[0] == '_' && name
[1] == 'G'
5199 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5203 if (symbol_find (name
))
5204 as_bad ("GOT already in the symbol table");
5206 GOT_symbol
= symbol_new (name
, undefined_section
,
5207 (valueT
)0, & zero_address_frag
);
5217 /* arm_reg_parse () := if it looks like a register, return its token and
5218 advance the pointer. */
5222 register char ** ccp
;
5224 char * start
= * ccp
;
5227 struct reg_entry
* reg
;
5229 #ifdef REGISTER_PREFIX
5230 if (*start
!= REGISTER_PREFIX
)
5235 #ifdef OPTIONAL_REGISTER_PREFIX
5236 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5240 if (!isalpha (*p
) || !is_name_beginner (*p
))
5244 while (isalpha (c
) || isdigit (c
) || c
== '_')
5248 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5262 register char ** ccp
;
5264 char * start
= * ccp
;
5267 CONST
struct asm_psr
* psr
;
5271 while (isalpha (c
) || c
== '_')
5275 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5288 md_apply_fix3 (fixP
, val
, seg
)
5293 offsetT value
= * val
;
5295 unsigned int newimm
;
5298 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5299 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5301 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5303 /* Note whether this will delete the relocation. */
5304 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5305 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5308 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5312 /* If this symbol is in a different section then we need to leave it for
5313 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5314 so we have to undo it's effects here. */
5317 if (fixP
->fx_addsy
!= NULL
5318 && S_IS_DEFINED (fixP
->fx_addsy
)
5319 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5322 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5325 value
+= md_pcrel_from (fixP
);
5329 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5331 switch (fixP
->fx_r_type
)
5333 case BFD_RELOC_ARM_IMMEDIATE
:
5334 newimm
= validate_immediate (value
);
5335 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5337 /* If the instruction will fail, see if we can fix things up by
5338 changing the opcode. */
5339 if (newimm
== (unsigned int) FAIL
5340 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5342 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5343 _("invalid constant (%lx) after fixup\n"),
5344 (unsigned long) value
);
5348 newimm
|= (temp
& 0xfffff000);
5349 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5352 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5354 unsigned int highpart
= 0;
5355 unsigned int newinsn
= 0xe1a00000; /* nop */
5356 newimm
= validate_immediate (value
);
5357 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5359 /* If the instruction will fail, see if we can fix things up by
5360 changing the opcode. */
5361 if (newimm
== (unsigned int) FAIL
5362 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5364 /* No ? OK - try using two ADD instructions to generate the value. */
5365 newimm
= validate_immediate_twopart (value
, & highpart
);
5367 /* Yes - then make sure that the second instruction is also an add. */
5368 if (newimm
!= (unsigned int) FAIL
)
5370 /* Still No ? Try using a negated value. */
5371 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5372 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5373 /* Otherwise - give up. */
5376 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5377 _("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value
);
5381 /* Replace the first operand in the 2nd instruction (which is the PC)
5382 with the destination register. We have already added in the PC in the
5383 first instruction and we do not want to do it again. */
5384 newinsn
&= ~ 0xf0000;
5385 newinsn
|= ((newinsn
& 0x0f000) << 4);
5388 newimm
|= (temp
& 0xfffff000);
5389 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5391 highpart
|= (newinsn
& 0xfffff000);
5392 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5396 case BFD_RELOC_ARM_OFFSET_IMM
:
5402 if (validate_offset_imm (value
, 0) == FAIL
)
5404 as_bad (_("bad immediate value for offset (%ld)"), (long) value
);
5408 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5409 newval
&= 0xff7ff000;
5410 newval
|= value
| (sign
? INDEX_UP
: 0);
5411 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5414 case BFD_RELOC_ARM_OFFSET_IMM8
:
5415 case BFD_RELOC_ARM_HWLITERAL
:
5421 if (validate_offset_imm (value
, 1) == FAIL
)
5423 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5424 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5425 _("invalid literal constant: pool needs to be closer\n"));
5427 as_bad (_("bad immediate value for half-word offset (%ld)"), (long) value
);
5431 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5432 newval
&= 0xff7ff0f0;
5433 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5434 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5437 case BFD_RELOC_ARM_LITERAL
:
5443 if (validate_offset_imm (value
, 0) == FAIL
)
5445 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5446 _("invalid literal constant: pool needs to be closer\n"));
5450 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5451 newval
&= 0xff7ff000;
5452 newval
|= value
| (sign
? INDEX_UP
: 0);
5453 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5456 case BFD_RELOC_ARM_SHIFT_IMM
:
5457 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5458 if (((unsigned long) value
) > 32
5460 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5462 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5463 _("shift expression is too large"));
5468 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5469 else if (value
== 32)
5471 newval
&= 0xfffff07f;
5472 newval
|= (value
& 0x1f) << 7;
5473 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5476 case BFD_RELOC_ARM_SWI
:
5477 if (arm_data
->thumb_mode
)
5479 if (((unsigned long) value
) > 0xff)
5480 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5481 _("Invalid swi expression"));
5482 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5484 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5488 if (((unsigned long) value
) > 0x00ffffff)
5489 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5490 _("Invalid swi expression"));
5491 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5493 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5497 case BFD_RELOC_ARM_MULTI
:
5498 if (((unsigned long) value
) > 0xffff)
5499 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5500 _("Invalid expression in load/store multiple"));
5501 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5502 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5505 case BFD_RELOC_ARM_PCREL_BRANCH
:
5506 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5510 value
= fixP
->fx_offset
;
5512 value
= (value
>> 2) & 0x00ffffff;
5513 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5514 newval
= value
| (newval
& 0xff000000);
5515 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5518 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5519 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5521 addressT diff
= (newval
& 0xff) << 1;
5526 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5527 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5528 _("Branch out of range"));
5529 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5531 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5534 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5535 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5537 addressT diff
= (newval
& 0x7ff) << 1;
5542 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5543 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5544 _("Branch out of range"));
5545 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5547 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5550 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5555 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5556 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5557 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5558 if (diff
& 0x400000)
5561 value
= fixP
->fx_offset
;
5564 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5565 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5566 _("Branch with link out of range"));
5568 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5569 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5570 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5571 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5576 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5577 md_number_to_chars (buf
, value
, 1);
5579 else if (!target_oabi
)
5581 value
= fixP
->fx_offset
;
5582 md_number_to_chars (buf
, value
, 1);
5588 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5589 md_number_to_chars (buf
, value
, 2);
5591 else if (!target_oabi
)
5593 value
= fixP
->fx_offset
;
5594 md_number_to_chars (buf
, value
, 2);
5600 case BFD_RELOC_ARM_GOT32
:
5601 case BFD_RELOC_ARM_GOTOFF
:
5602 md_number_to_chars (buf
, 0, 4);
5608 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5609 md_number_to_chars (buf
, value
, 4);
5611 else if (!target_oabi
)
5613 value
= fixP
->fx_offset
;
5614 md_number_to_chars (buf
, value
, 4);
5620 case BFD_RELOC_ARM_PLT32
:
5621 /* It appears the instruction is fully prepared at this point. */
5625 case BFD_RELOC_ARM_GOTPC
:
5626 md_number_to_chars (buf
, value
, 4);
5629 case BFD_RELOC_ARM_CP_OFF_IMM
:
5631 if (value
< -1023 || value
> 1023 || (value
& 3))
5632 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5633 _("Illegal value for co-processor offset"));
5636 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5637 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5638 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5641 case BFD_RELOC_ARM_THUMB_OFFSET
:
5642 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5643 /* Exactly what ranges, and where the offset is inserted depends on
5644 the type of instruction, we can establish this from the top 4 bits */
5645 switch (newval
>> 12)
5647 case 4: /* PC load */
5648 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5649 forced to zero for these loads, so we will need to round
5650 up the offset if the instruction address is not word
5651 aligned (since the final address produced must be, and
5652 we can only describe word-aligned immediate offsets). */
5654 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5655 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5656 _("Invalid offset, target not word aligned (0x%08X)"),
5657 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5659 if ((value
+ 2) & ~0x3fe)
5660 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5661 _("Invalid offset"));
5663 /* Round up, since pc will be rounded down. */
5664 newval
|= (value
+ 2) >> 2;
5667 case 9: /* SP load/store */
5669 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5670 _("Invalid offset"));
5671 newval
|= value
>> 2;
5674 case 6: /* Word load/store */
5676 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5677 _("Invalid offset"));
5678 newval
|= value
<< 4; /* 6 - 2 */
5681 case 7: /* Byte load/store */
5683 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5684 _("Invalid offset"));
5685 newval
|= value
<< 6;
5688 case 8: /* Halfword load/store */
5690 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5691 _("Invalid offset"));
5692 newval
|= value
<< 5; /* 6 - 1 */
5696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5697 "Unable to process relocation for thumb opcode: %lx",
5698 (unsigned long) newval
);
5701 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5704 case BFD_RELOC_ARM_THUMB_ADD
:
5705 /* This is a complicated relocation, since we use it for all of
5706 the following immediate relocations:
5709 9bit ADD/SUB SP word-aligned
5710 10bit ADD PC/SP word-aligned
5712 The type of instruction being processed is encoded in the
5718 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5720 int rd
= (newval
>> 4) & 0xf;
5721 int rs
= newval
& 0xf;
5722 int subtract
= newval
& 0x8000;
5727 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5728 _("Invalid immediate for stack address calculation"));
5729 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5730 newval
|= value
>> 2;
5732 else if (rs
== REG_PC
|| rs
== REG_SP
)
5736 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5737 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5738 (unsigned long) value
);
5739 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5741 newval
|= value
>> 2;
5746 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5747 _("Invalid 8bit immediate"));
5748 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5749 newval
|= (rd
<< 8) | value
;
5754 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5755 _("Invalid 3bit immediate"));
5756 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5757 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5760 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5763 case BFD_RELOC_ARM_THUMB_IMM
:
5764 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5765 switch (newval
>> 11)
5767 case 0x04: /* 8bit immediate MOV */
5768 case 0x05: /* 8bit immediate CMP */
5769 if (value
< 0 || value
> 255)
5770 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5771 _("Invalid immediate: %ld is too large"),
5779 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5782 case BFD_RELOC_ARM_THUMB_SHIFT
:
5783 /* 5bit shift value (0..31) */
5784 if (value
< 0 || value
> 31)
5785 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5786 _("Illegal Thumb shift value: %ld"), (long) value
);
5787 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5788 newval
|= value
<< 6;
5789 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5792 case BFD_RELOC_VTABLE_INHERIT
:
5793 case BFD_RELOC_VTABLE_ENTRY
:
5797 case BFD_RELOC_NONE
:
5799 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5800 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5806 /* Translate internal representation of relocation info to BFD target
5809 tc_gen_reloc (section
, fixp
)
5814 bfd_reloc_code_real_type code
;
5816 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5818 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5819 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5820 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5822 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5824 if (fixp
->fx_pcrel
== 0)
5825 reloc
->addend
= fixp
->fx_offset
;
5827 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5829 reloc
->addend
= fixp
->fx_offset
;
5832 switch (fixp
->fx_r_type
)
5837 code
= BFD_RELOC_8_PCREL
;
5844 code
= BFD_RELOC_16_PCREL
;
5851 code
= BFD_RELOC_32_PCREL
;
5855 case BFD_RELOC_ARM_PCREL_BRANCH
:
5857 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5858 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5859 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5860 case BFD_RELOC_VTABLE_ENTRY
:
5861 case BFD_RELOC_VTABLE_INHERIT
:
5862 code
= fixp
->fx_r_type
;
5865 case BFD_RELOC_ARM_LITERAL
:
5866 case BFD_RELOC_ARM_HWLITERAL
:
5867 /* If this is called then the a literal has been referenced across
5868 a section boundary - possibly due to an implicit dump */
5869 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5870 _("Literal referenced across section boundary (Implicit dump?)"));
5874 case BFD_RELOC_ARM_GOT32
:
5875 case BFD_RELOC_ARM_GOTOFF
:
5876 case BFD_RELOC_ARM_PLT32
:
5877 code
= fixp
->fx_r_type
;
5881 case BFD_RELOC_ARM_IMMEDIATE
:
5882 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5883 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5887 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5888 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5889 _("ADRL used for a symbol not defined in the same file"),
5893 case BFD_RELOC_ARM_OFFSET_IMM
:
5894 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5895 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5902 switch (fixp
->fx_r_type
)
5904 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5905 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5906 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5907 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5908 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5909 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5910 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5911 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5912 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5913 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5914 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5915 default: type
= _("<unknown>"); break;
5917 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5918 _("Can not represent %s relocation in this object file format (%d)"),
5919 type
, fixp
->fx_pcrel
);
5925 if (code
== BFD_RELOC_32_PCREL
5927 && fixp
->fx_addsy
== GOT_symbol
)
5929 code
= BFD_RELOC_ARM_GOTPC
;
5930 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5934 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5936 if (reloc
->howto
== NULL
)
5938 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5939 _("Can not represent %s relocation in this object file format"),
5940 bfd_get_reloc_code_name (code
));
5944 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5945 vtable entry to be used in the relocation's section offset. */
5946 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5947 reloc
->address
= fixp
->fx_offset
;
5953 md_estimate_size_before_relax (fragP
, segtype
)
5957 as_fatal (_("md_estimate_size_before_relax\n"));
5962 output_inst
PARAMS ((void))
5968 as_bad (inst
.error
);
5972 to
= frag_more (inst
.size
);
5974 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5976 assert (inst
.size
== (2 * THUMB_SIZE
));
5977 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5978 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
5980 else if (inst
.size
> INSN_SIZE
)
5982 assert (inst
.size
== (2 * INSN_SIZE
));
5983 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
5984 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
5987 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5989 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5990 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5991 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6006 /* Align the instruction.
6007 This may not be the right thing to do but ... */
6008 /* arm_align (2, 0); */
6009 listing_prev_line (); /* Defined in listing.h */
6011 /* Align the previous label if needed. */
6012 if (last_label_seen
!= NULL
)
6014 symbol_set_frag (last_label_seen
, frag_now
);
6015 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6016 S_SET_SEGMENT (last_label_seen
, now_seg
);
6019 memset (&inst
, '\0', sizeof (inst
));
6020 inst
.reloc
.type
= BFD_RELOC_NONE
;
6022 skip_whitespace (str
);
6024 /* Scan up to the end of the op-code, which must end in white space or
6026 for (start
= p
= str
; *p
!= '\0'; p
++)
6032 as_bad (_("No operator -- statement `%s'\n"), str
);
6038 CONST
struct thumb_opcode
* opcode
;
6042 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6047 inst
.instruction
= opcode
->value
;
6048 inst
.size
= opcode
->size
;
6049 (*opcode
->parms
)(p
);
6056 CONST
struct asm_opcode
* opcode
;
6058 inst
.size
= INSN_SIZE
;
6059 /* p now points to the end of the opcode, probably white space, but we
6060 have to break the opcode up in case it contains condionals and flags;
6061 keep trying with progressively smaller basic instructions until one
6062 matches, or we run out of opcode. */
6063 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6064 for (; q
!= str
; q
--)
6068 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6071 if (opcode
&& opcode
->template)
6073 unsigned long flag_bits
= 0;
6076 /* Check that this instruction is supported for this CPU. */
6077 if ((opcode
->variants
& cpu_variant
) == 0)
6080 inst
.instruction
= opcode
->value
;
6081 if (q
== p
) /* Just a simple opcode. */
6083 if (opcode
->comp_suffix
!= 0)
6084 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6085 opcode
->comp_suffix
);
6088 inst
.instruction
|= COND_ALWAYS
;
6089 (*opcode
->parms
)(q
, 0);
6095 /* Now check for a conditional. */
6099 CONST
struct asm_cond
*cond
;
6103 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6107 if (cond
->value
== 0xf0000000)
6109 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6111 inst
.instruction
|= cond
->value
;
6115 inst
.instruction
|= COND_ALWAYS
;
6118 inst
.instruction
|= COND_ALWAYS
;
6120 /* If there is a compulsory suffix, it should come here, before
6121 any optional flags. */
6122 if (opcode
->comp_suffix
)
6124 CONST
char *s
= opcode
->comp_suffix
;
6136 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6137 opcode
->comp_suffix
);
6144 /* The remainder, if any should now be flags for the instruction;
6145 Scan these checking each one found with the opcode. */
6149 CONST
struct asm_flg
*flag
= opcode
->flags
;
6158 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6160 if (streq (r
, flag
[flagno
].template))
6162 flag_bits
|= flag
[flagno
].set_bits
;
6168 if (! flag
[flagno
].template)
6175 (*opcode
->parms
) (p
, flag_bits
);
6185 /* It wasn't an instruction, but it might be a register alias of the form
6188 skip_whitespace (q
);
6193 if (*q
&& !strncmp (q
, ".req ", 4))
6196 char * copy_of_str
= str
;
6200 skip_whitespace (q
);
6202 for (r
= q
; *r
!= '\0'; r
++)
6212 regnum
= arm_reg_parse (& q
);
6215 reg
= arm_reg_parse (& str
);
6221 insert_reg_alias (str
, regnum
);
6225 as_warn (_("register '%s' does not exist\n"), q
);
6228 else if (regnum
!= FAIL
)
6231 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6233 /* Do not warn about redefinitions to the same alias. */
6236 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6240 as_warn (_("ignoring incomplete .req pseuso op"));
6247 as_bad (_("bad instruction `%s'"), start
);
6252 * Invocation line includes a switch not recognized by the base assembler.
6253 * See if it's a processor-specific option. These are:
6254 * Cpu variants, the arm part is optional:
6255 * -m[arm]1 Currently not supported.
6256 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6257 * -m[arm]3 Arm 3 processor
6258 * -m[arm]6[xx], Arm 6 processors
6259 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6260 * -m[arm]8[10] Arm 8 processors
6261 * -m[arm]9[20][tdmi] Arm 9 processors
6262 * -mstrongarm[110[0]] StrongARM processors
6263 * -m[arm]v[2345] Arm architecures
6264 * -mall All (except the ARM1)
6266 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6267 * -mfpe-old (No float load/store multiples)
6268 * -mno-fpu Disable all floating point instructions
6269 * Run-time endian selection:
6270 * -EB big endian cpu
6271 * -EL little endian cpu
6272 * ARM Procedure Calling Standard:
6273 * -mapcs-32 32 bit APCS
6274 * -mapcs-26 26 bit APCS
6275 * -mapcs-float Pass floats in float regs
6276 * -mapcs-reentrant Position independent code
6277 * -mthumb-interwork Code supports Arm/Thumb interworking
6278 * -moabi Old ELF ABI
6281 CONST
char * md_shortopts
= "m:k";
6282 struct option md_longopts
[] =
6284 #ifdef ARM_BI_ENDIAN
6285 #define OPTION_EB (OPTION_MD_BASE + 0)
6286 {"EB", no_argument
, NULL
, OPTION_EB
},
6287 #define OPTION_EL (OPTION_MD_BASE + 1)
6288 {"EL", no_argument
, NULL
, OPTION_EL
},
6290 #define OPTION_OABI (OPTION_MD_BASE +2)
6291 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6294 {NULL
, no_argument
, NULL
, 0}
6296 size_t md_longopts_size
= sizeof (md_longopts
);
6299 md_parse_option (c
, arg
)
6307 #ifdef ARM_BI_ENDIAN
6309 target_big_endian
= 1;
6312 target_big_endian
= 0;
6320 if (streq (str
, "fpa10"))
6321 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6322 else if (streq (str
, "fpa11"))
6323 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6324 else if (streq (str
, "fpe-old"))
6325 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6331 if (streq (str
, "no-fpu"))
6332 cpu_variant
&= ~FPU_ALL
;
6337 if (streq (str
, "oabi"))
6343 /* Limit assembler to generating only Thumb instructions: */
6344 if (streq (str
, "thumb"))
6346 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6347 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6350 else if (streq (str
, "thumb-interwork"))
6352 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCH_V4
;
6353 #if defined OBJ_COFF || defined OBJ_ELF
6354 support_interwork
= true;
6362 if (streq (str
, "all"))
6364 cpu_variant
= ARM_ALL
| FPU_ALL
;
6367 #if defined OBJ_COFF || defined OBJ_ELF
6368 if (! strncmp (str
, "apcs-", 5))
6370 /* GCC passes on all command line options starting "-mapcs-..."
6371 to us, so we must parse them here. */
6375 if (streq (str
, "32"))
6377 uses_apcs_26
= false;
6380 else if (streq (str
, "26"))
6382 uses_apcs_26
= true;
6385 else if (streq (str
, "frame"))
6387 /* Stack frames are being generated - does not affect
6391 else if (streq (str
, "stack-check"))
6393 /* Stack checking is being performed - does not affect
6394 linkage, but does require that the functions
6395 __rt_stkovf_split_small and __rt_stkovf_split_big be
6396 present in the final link. */
6400 else if (streq (str
, "float"))
6402 /* Floating point arguments are being passed in the floating
6403 point registers. This does affect linking, since this
6404 version of the APCS is incompatible with the version that
6405 passes floating points in the integer registers. */
6407 uses_apcs_float
= true;
6410 else if (streq (str
, "reentrant"))
6412 /* Reentrant code has been generated. This does affect
6413 linking, since there is no point in linking reentrant/
6414 position independent code with absolute position code. */
6419 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6423 /* Strip off optional "arm" */
6424 if (! strncmp (str
, "arm", 3))
6430 if (streq (str
, "1"))
6431 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6437 if (streq (str
, "2"))
6438 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6439 else if (streq (str
, "250"))
6440 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6446 if (streq (str
, "3"))
6447 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6453 switch (strtol (str
, NULL
, 10))
6460 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6468 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6480 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6486 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6490 cpu_variant
|= ARM_LONGMUL
;
6493 case 'f': /* fe => fp enabled cpu. */
6499 case 'c': /* Left over from 710c processor name. */
6500 case 'd': /* Debug */
6501 case 'i': /* Embedded ICE */
6502 /* Included for completeness in ARM processor naming. */
6512 if (streq (str
, "8") || streq (str
, "810"))
6513 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6519 if (streq (str
, "9"))
6520 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6521 else if (streq (str
, "920"))
6522 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6523 else if (streq (str
, "920t"))
6524 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6525 else if (streq (str
, "9tdmi"))
6526 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6532 if (streq (str
, "strongarm")
6533 || streq (str
, "strongarm110")
6534 || streq (str
, "strongarm1100"))
6535 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6541 /* Select variant based on architecture rather than processor */
6547 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6548 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6549 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6554 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6558 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6560 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6565 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6569 case 't': cpu_variant
|= ARM_THUMB
; break;
6571 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6576 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6580 case 't': cpu_variant
|= ARM_THUMB
; break;
6582 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6587 as_bad (_("Invalid architecture variant -m%s"), arg
);
6594 as_bad (_("Invalid processor variant -m%s"), arg
);
6617 ARM Specific Assembler Options:\n\
6618 -m[arm][<processor name>] select processor variant\n\
6619 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6620 -mthumb only allow Thumb instructions\n\
6621 -mthumb-interwork mark the assembled code as supporting interworking\n\
6622 -mall allow any instruction\n\
6623 -mfpa10, -mfpa11 select floating point architecture\n\
6624 -mfpe-old don't allow floating-point multiple instructions\n\
6625 -mno-fpu don't allow any floating-point instructions.\n"));
6628 -k generate PIC code.\n"));
6629 #if defined OBJ_COFF || defined OBJ_ELF
6632 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6635 -mapcs-float floating point args are passed in FP regs\n"));
6638 -mapcs-reentrant the code is position independent/reentrant\n"));
6643 -moabi support the old ELF ABI\n"));
6645 #ifdef ARM_BI_ENDIAN
6648 -EB assemble code for a big endian cpu\n\
6649 -EL assemble code for a little endian cpu\n"));
6653 /* We need to be able to fix up arbitrary expressions in some statements.
6654 This is so that we can handle symbols that are an arbitrary distance from
6655 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6656 which returns part of an address in a form which will be valid for
6657 a data instruction. We do this by pushing the expression into a symbol
6658 in the expr_section, and creating a fix for that. */
6661 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6670 arm_fix_data
* arm_data
;
6678 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6682 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6687 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6688 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6689 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6690 arm_data
->thumb_mode
= thumb_mode
;
6696 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6698 cons_fix_new_arm (frag
, where
, size
, exp
)
6704 bfd_reloc_code_real_type type
;
6709 * @@ Should look at CPU word size.
6714 type
= BFD_RELOC_16
;
6718 type
= BFD_RELOC_32
;
6721 type
= BFD_RELOC_64
;
6725 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6728 /* A good place to do this, although this was probably not intended
6729 for this kind of use. We need to dump the literal pool before
6730 references are made to a null symbol pointer. */
6734 if (current_poolP
== NULL
)
6737 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6739 listing_prev_line ();
6743 arm_start_line_hook ()
6745 last_label_seen
= NULL
;
6749 arm_frob_label (sym
)
6752 last_label_seen
= sym
;
6754 ARM_SET_THUMB (sym
, thumb_mode
);
6756 #if defined OBJ_COFF || defined OBJ_ELF
6757 ARM_SET_INTERWORK (sym
, support_interwork
);
6760 if (label_is_thumb_function_name
)
6762 /* When the address of a Thumb function is taken the bottom
6763 bit of that address should be set. This will allow
6764 interworking between Arm and Thumb functions to work
6767 THUMB_SET_FUNC (sym
, 1);
6769 label_is_thumb_function_name
= false;
6773 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6777 arm_adjust_symtab ()
6782 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6784 if (ARM_IS_THUMB (sym
))
6786 if (THUMB_IS_FUNC (sym
))
6788 /* Mark the symbol as a Thumb function. */
6789 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6790 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6791 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6793 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6794 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6796 as_bad (_("%s: unexpected function type: %d"),
6797 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6799 else switch (S_GET_STORAGE_CLASS (sym
))
6802 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6805 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6808 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6810 default: /* do nothing */
6815 if (ARM_IS_INTERWORK (sym
))
6816 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6821 elf_symbol_type
* elf_sym
;
6824 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6826 if (ARM_IS_THUMB (sym
))
6828 if (THUMB_IS_FUNC (sym
))
6830 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6831 bind
= ELF_ST_BIND (elf_sym
);
6832 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6842 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6844 *input_line_pointer
= '/';
6845 input_line_pointer
+= 5;
6846 *input_line_pointer
= 0;
6854 arm_canonicalize_symbol_name (name
)
6859 if (thumb_mode
&& (len
= strlen (name
)) > 5
6860 && streq (name
+ len
- 5, "/data"))
6861 *(name
+ len
- 5) = 0;
6867 arm_validate_fix (fixP
)
6870 /* If the destination of the branch is a defined symbol which does not have
6871 the THUMB_FUNC attribute, then we must be calling a function which has
6872 the (interfacearm) attribute. We look for the Thumb entry point to that
6873 function and change the branch to refer to that function instead. */
6874 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6875 && fixP
->fx_addsy
!= NULL
6876 && S_IS_DEFINED (fixP
->fx_addsy
)
6877 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6879 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6887 /* Relocations against Thumb function names must be left unadjusted,
6888 so that the linker can use this information to correctly set the
6889 bottom bit of their addresses. The MIPS version of this function
6890 also prevents relocations that are mips-16 specific, but I do not
6891 know why it does this.
6894 There is one other problem that ought to be addressed here, but
6895 which currently is not: Taking the address of a label (rather
6896 than a function) and then later jumping to that address. Such
6897 addresses also ought to have their bottom bit set (assuming that
6898 they reside in Thumb code), but at the moment they will not. */
6901 arm_fix_adjustable (fixP
)
6904 if (fixP
->fx_addsy
== NULL
)
6907 /* Prevent all adjustments to global symbols. */
6908 if (S_IS_EXTERN (fixP
->fx_addsy
))
6911 if (S_IS_WEAK (fixP
->fx_addsy
))
6914 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6915 && fixP
->fx_subsy
== NULL
)
6918 /* We need the symbol name for the VTABLE entries */
6919 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6920 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6927 elf32_arm_target_format ()
6929 if (target_big_endian
)
6931 return "elf32-bigarm-oabi";
6933 return "elf32-bigarm";
6936 return "elf32-littlearm-oabi";
6938 return "elf32-littlearm";
6942 armelf_frob_symbol (symp
, puntp
)
6946 elf_frob_symbol (symp
, puntp
);
6950 arm_force_relocation (fixp
)
6953 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6954 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6955 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
6956 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
6962 static bfd_reloc_code_real_type
6972 bfd_reloc_code_real_type reloc
;
6976 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6977 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6978 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6979 /* ScottB: Jan 30, 1998 */
6980 /* Added support for parsing "var(PLT)" branch instructions */
6981 /* generated by GCC for PLT relocs */
6982 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6983 NULL
, 0, BFD_RELOC_UNUSED
6987 for (i
= 0, ip
= input_line_pointer
;
6988 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6990 id
[i
] = tolower (*ip
);
6992 for (i
= 0; reloc_map
[i
].str
; i
++)
6993 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6996 input_line_pointer
+= reloc_map
[i
].len
;
6998 return reloc_map
[i
].reloc
;
7002 s_arm_elf_cons (nbytes
)
7007 #ifdef md_flush_pending_output
7008 md_flush_pending_output ();
7011 if (is_it_end_of_statement ())
7013 demand_empty_rest_of_line ();
7017 #ifdef md_cons_align
7018 md_cons_align (nbytes
);
7023 bfd_reloc_code_real_type reloc
;
7027 if (exp
.X_op
== O_symbol
7028 && * input_line_pointer
== '('
7029 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7031 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7032 int size
= bfd_get_reloc_size (howto
);
7035 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
7038 register char * p
= frag_more ((int) nbytes
);
7039 int offset
= nbytes
- size
;
7041 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7046 emit_expr (& exp
, (unsigned int) nbytes
);
7048 while (*input_line_pointer
++ == ',');
7050 input_line_pointer
--; /* Put terminator back into stream. */
7051 demand_empty_rest_of_line ();
7054 #endif /* OBJ_ELF */