1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 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
125 from exp in floating point numbers. */
126 CONST
char EXP_CHARS
[] = "eE";
128 /* Chars that mean this number is a floating point constant */
132 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
134 /* Prefix characters that indicate the start of an immediate
136 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
139 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
142 CONST
int md_reloc_size
= 8; /* Size of relocation record */
144 static int thumb_mode
= 0; /* 0: assemble for ARM, 1: assemble for Thumb,
145 2: assemble for Thumb even though target cpu
146 does not support thumb instructions. */
147 typedef struct arm_fix
155 unsigned long instruction
;
160 bfd_reloc_code_real_type type
;
170 CONST
char * template;
174 static CONST
struct asm_shift shift
[] =
190 #define NO_SHIFT_RESTRICT 1
191 #define SHIFT_RESTRICT 0
193 #define NUM_FLOAT_VALS 8
195 CONST
char * fp_const
[] =
197 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
200 /* Number of littlenums required to hold an extended precision number. */
201 #define MAX_LITTLENUMS 6
203 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
213 #define CP_T_X 0x00008000
214 #define CP_T_Y 0x00400000
215 #define CP_T_Pre 0x01000000
216 #define CP_T_UD 0x00800000
217 #define CP_T_WB 0x00200000
219 #define CONDS_BIT (0x00100000)
220 #define LOAD_BIT (0x00100000)
221 #define TRANS_BIT (0x00200000)
225 CONST
char * template;
229 /* This is to save a hash look-up in the common case. */
230 #define COND_ALWAYS 0xe0000000
232 static CONST
struct asm_cond conds
[] =
236 {"cs", 0x20000000}, {"hs", 0x20000000},
237 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
252 /* Warning: If the top bit of the set_bits is set, then the standard
253 instruction bitmask is ignored, and the new bitmask is taken from
257 CONST
char * template; /* Basic flag string */
258 unsigned long set_bits
; /* Bits to set */
261 static CONST
struct asm_flg s_flag
[] =
267 static CONST
struct asm_flg ldr_flags
[] =
271 {"bt", 0x00400000 | TRANS_BIT
},
278 static CONST
struct asm_flg str_flags
[] =
282 {"bt", 0x00400000 | TRANS_BIT
},
287 static CONST
struct asm_flg byte_flag
[] =
293 static CONST
struct asm_flg cmp_flags
[] =
300 static CONST
struct asm_flg ldm_flags
[] =
313 static CONST
struct asm_flg stm_flags
[] =
326 static CONST
struct asm_flg lfm_flags
[] =
333 static CONST
struct asm_flg sfm_flags
[] =
340 static CONST
struct asm_flg round_flags
[] =
348 /* The implementation of the FIX instruction is broken on some assemblers,
349 in that it accepts a precision specifier as well as a rounding specifier,
350 despite the fact that this is meaningless. To be more compatible, we
351 accept it as well, though of course it does not set any bits. */
352 static CONST
struct asm_flg fix_flags
[] =
369 static CONST
struct asm_flg except_flag
[] =
375 static CONST
struct asm_flg cplong_flag
[] =
383 CONST
char * template;
384 unsigned long number
;
387 #define PSR_FIELD_MASK 0x000f0000
389 #define PSR_FLAGS 0x00080000
390 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
391 #define PSR_ALL 0x00090000
400 static CONST
struct asm_psr psrs
[] =
404 {"cpsr_all", CPSR_ALL
},
406 {"spsr_all", SPSR_ALL
},
409 {"cpsr_flg", CPSR_FLG
},
410 {"spsr_flg", SPSR_FLG
},
413 {"cpsr_c", CPSR_CTL
},
414 {"cpsr_ctl", CPSR_CTL
},
415 {"spsr_c", SPSR_CTL
},
416 {"spsr_ctl", SPSR_CTL
}
419 /* Functions called by parser. */
420 /* ARM instructions */
421 static void do_arit
PARAMS ((char *, unsigned long));
422 static void do_cmp
PARAMS ((char *, unsigned long));
423 static void do_mov
PARAMS ((char *, unsigned long));
424 static void do_ldst
PARAMS ((char *, unsigned long));
425 static void do_ldmstm
PARAMS ((char *, unsigned long));
426 static void do_branch
PARAMS ((char *, unsigned long));
427 static void do_swi
PARAMS ((char *, unsigned long));
428 /* Pseudo Op codes */
429 static void do_adr
PARAMS ((char *, unsigned long));
430 static void do_adrl
PARAMS ((char *, unsigned long));
431 static void do_nop
PARAMS ((char *, unsigned long));
433 static void do_mul
PARAMS ((char *, unsigned long));
434 static void do_mla
PARAMS ((char *, unsigned long));
436 static void do_swap
PARAMS ((char *, unsigned long));
438 static void do_msr
PARAMS ((char *, unsigned long));
439 static void do_mrs
PARAMS ((char *, unsigned long));
441 static void do_mull
PARAMS ((char *, unsigned long));
443 static void do_bx
PARAMS ((char *, unsigned long));
446 /* Coprocessor Instructions */
447 static void do_cdp
PARAMS ((char *, unsigned long));
448 static void do_lstc
PARAMS ((char *, unsigned long));
449 static void do_co_reg
PARAMS ((char *, unsigned long));
450 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
451 static void do_fp_ldst
PARAMS ((char *, unsigned long));
452 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
453 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
454 static void do_fp_monadic
PARAMS ((char *, unsigned long));
455 static void do_fp_cmp
PARAMS ((char *, unsigned long));
456 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
457 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
459 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
460 static int arm_reg_parse
PARAMS ((char **));
461 static int arm_psr_parse
PARAMS ((char **));
462 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
463 static int add_to_lit_pool
PARAMS ((void));
464 static unsigned validate_immediate
PARAMS ((unsigned));
465 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
466 static int validate_offset_imm
PARAMS ((unsigned int, int));
467 static void opcode_select
PARAMS ((int));
468 static void end_of_line
PARAMS ((char *));
469 static int reg_required_here
PARAMS ((char **, int));
470 static int psr_required_here
PARAMS ((char **, int, int));
471 static int co_proc_number
PARAMS ((char **));
472 static int cp_opc_expr
PARAMS ((char **, int, int));
473 static int cp_reg_required_here
PARAMS ((char **, int));
474 static int fp_reg_required_here
PARAMS ((char **, int));
475 static int cp_address_offset
PARAMS ((char **));
476 static int cp_address_required_here
PARAMS ((char **));
477 static int my_get_float_expression
PARAMS ((char **));
478 static int skip_past_comma
PARAMS ((char **));
479 static int walk_no_bignums
PARAMS ((symbolS
*));
480 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
481 static int data_op2
PARAMS ((char **));
482 static int fp_op2
PARAMS ((char **));
483 static long reg_list
PARAMS ((char **));
484 static void thumb_load_store
PARAMS ((char *, int, int));
485 static int decode_shift
PARAMS ((char **, int));
486 static int ldst_extend
PARAMS ((char **, int));
487 static void thumb_add_sub
PARAMS ((char *, int));
488 static void insert_reg
PARAMS ((int));
489 static void thumb_shift
PARAMS ((char *, int));
490 static void thumb_mov_compare
PARAMS ((char *, int));
491 static void set_constant_flonums
PARAMS ((void));
492 static valueT md_chars_to_number
PARAMS ((char *, int));
493 static void insert_reg_alias
PARAMS ((char *, int));
494 static void output_inst
PARAMS ((void));
496 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
499 /* ARM instructions take 4bytes in the object file, Thumb instructions
503 /* LONGEST_INST is the longest basic instruction name without conditions or
504 flags. ARM7M has 4 of length 5. */
506 #define LONGEST_INST 5
511 CONST
char * template; /* Basic string to match */
512 unsigned long value
; /* Basic instruction code */
514 /* Compulsory suffix that must follow conds. If "", then the
515 instruction is not conditional and must have no suffix. */
516 CONST
char * comp_suffix
;
518 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
519 unsigned long variants
; /* Which CPU variants this exists for */
520 /* Function to call to parse args */
521 void (* parms
) PARAMS ((char *, unsigned long));
524 static CONST
struct asm_opcode insns
[] =
526 /* ARM Instructions */
527 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
528 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
529 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
530 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
531 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
532 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
533 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
534 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
535 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
536 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
537 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
538 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
539 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
540 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
541 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
542 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
543 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
544 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
545 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
546 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
547 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
549 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
550 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
552 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
553 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
557 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
558 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
559 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
561 /* ARM 2 multiplies */
562 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
563 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
565 /* ARM 3 - swp instructions */
566 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
568 /* ARM 6 Coprocessor instructions */
569 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
570 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
571 /* ScottB: our code uses 0x0128f000 for msr.
572 NickC: but this is wrong because the bits 16 and 19 are handled
573 by the PSR_xxx defines above. */
575 /* ARM 7M long multiplies - need signed/unsigned flags! */
576 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
577 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
578 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
579 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
581 /* ARM THUMB interworking */
582 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
584 /* Floating point instructions */
585 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
586 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
587 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
588 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
589 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
590 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
591 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
592 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
593 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
595 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
596 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
597 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
598 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
599 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
600 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
601 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
602 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
603 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
604 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
605 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
607 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
608 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
609 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
610 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
611 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
612 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
613 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
614 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
615 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
616 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
617 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
618 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
619 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
620 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
621 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
622 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
623 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
624 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
625 be an optional suffix, but part of the instruction. To be compatible,
627 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
628 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
629 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
630 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
632 /* Generic copressor instructions. */
633 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
634 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
635 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
636 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
637 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
640 /* Defines for various bits that we will want to toggle. */
641 #define INST_IMMEDIATE 0x02000000
642 #define OFFSET_REG 0x02000000
643 #define HWOFFSET_IMM 0x00400000
644 #define SHIFT_BY_REG 0x00000010
645 #define PRE_INDEX 0x01000000
646 #define INDEX_UP 0x00800000
647 #define WRITE_BACK 0x00200000
648 #define LDM_TYPE_2_OR_3 0x00400000
650 #define LITERAL_MASK 0xf000f000
651 #define COND_MASK 0xf0000000
652 #define OPCODE_MASK 0xfe1fffff
653 #define DATA_OP_SHIFT 21
655 /* Codes to distinguish the arithmetic instructions. */
666 #define OPCODE_CMP 10
667 #define OPCODE_CMN 11
668 #define OPCODE_ORR 12
669 #define OPCODE_MOV 13
670 #define OPCODE_BIC 14
671 #define OPCODE_MVN 15
673 static void do_t_nop
PARAMS ((char *));
674 static void do_t_arit
PARAMS ((char *));
675 static void do_t_add
PARAMS ((char *));
676 static void do_t_asr
PARAMS ((char *));
677 static void do_t_branch9
PARAMS ((char *));
678 static void do_t_branch12
PARAMS ((char *));
679 static void do_t_branch23
PARAMS ((char *));
680 static void do_t_bx
PARAMS ((char *));
681 static void do_t_compare
PARAMS ((char *));
682 static void do_t_ldmstm
PARAMS ((char *));
683 static void do_t_ldr
PARAMS ((char *));
684 static void do_t_ldrb
PARAMS ((char *));
685 static void do_t_ldrh
PARAMS ((char *));
686 static void do_t_lds
PARAMS ((char *));
687 static void do_t_lsl
PARAMS ((char *));
688 static void do_t_lsr
PARAMS ((char *));
689 static void do_t_mov
PARAMS ((char *));
690 static void do_t_push_pop
PARAMS ((char *));
691 static void do_t_str
PARAMS ((char *));
692 static void do_t_strb
PARAMS ((char *));
693 static void do_t_strh
PARAMS ((char *));
694 static void do_t_sub
PARAMS ((char *));
695 static void do_t_swi
PARAMS ((char *));
696 static void do_t_adr
PARAMS ((char *));
698 #define T_OPCODE_MUL 0x4340
699 #define T_OPCODE_TST 0x4200
700 #define T_OPCODE_CMN 0x42c0
701 #define T_OPCODE_NEG 0x4240
702 #define T_OPCODE_MVN 0x43c0
704 #define T_OPCODE_ADD_R3 0x1800
705 #define T_OPCODE_SUB_R3 0x1a00
706 #define T_OPCODE_ADD_HI 0x4400
707 #define T_OPCODE_ADD_ST 0xb000
708 #define T_OPCODE_SUB_ST 0xb080
709 #define T_OPCODE_ADD_SP 0xa800
710 #define T_OPCODE_ADD_PC 0xa000
711 #define T_OPCODE_ADD_I8 0x3000
712 #define T_OPCODE_SUB_I8 0x3800
713 #define T_OPCODE_ADD_I3 0x1c00
714 #define T_OPCODE_SUB_I3 0x1e00
716 #define T_OPCODE_ASR_R 0x4100
717 #define T_OPCODE_LSL_R 0x4080
718 #define T_OPCODE_LSR_R 0x40c0
719 #define T_OPCODE_ASR_I 0x1000
720 #define T_OPCODE_LSL_I 0x0000
721 #define T_OPCODE_LSR_I 0x0800
723 #define T_OPCODE_MOV_I8 0x2000
724 #define T_OPCODE_CMP_I8 0x2800
725 #define T_OPCODE_CMP_LR 0x4280
726 #define T_OPCODE_MOV_HR 0x4600
727 #define T_OPCODE_CMP_HR 0x4500
729 #define T_OPCODE_LDR_PC 0x4800
730 #define T_OPCODE_LDR_SP 0x9800
731 #define T_OPCODE_STR_SP 0x9000
732 #define T_OPCODE_LDR_IW 0x6800
733 #define T_OPCODE_STR_IW 0x6000
734 #define T_OPCODE_LDR_IH 0x8800
735 #define T_OPCODE_STR_IH 0x8000
736 #define T_OPCODE_LDR_IB 0x7800
737 #define T_OPCODE_STR_IB 0x7000
738 #define T_OPCODE_LDR_RW 0x5800
739 #define T_OPCODE_STR_RW 0x5000
740 #define T_OPCODE_LDR_RH 0x5a00
741 #define T_OPCODE_STR_RH 0x5200
742 #define T_OPCODE_LDR_RB 0x5c00
743 #define T_OPCODE_STR_RB 0x5400
745 #define T_OPCODE_PUSH 0xb400
746 #define T_OPCODE_POP 0xbc00
748 #define T_OPCODE_BRANCH 0xe7fe
750 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
752 #define THUMB_SIZE 2 /* Size of thumb instruction. */
753 #define THUMB_REG_LO 0x1
754 #define THUMB_REG_HI 0x2
755 #define THUMB_REG_ANY 0x3
757 #define THUMB_H1 0x0080
758 #define THUMB_H2 0x0040
765 #define THUMB_COMPARE 1
768 #define THUMB_STORE 1
770 #define THUMB_PP_PC_LR 0x0100
772 /* These three are used for immediate shifts, do not alter. */
774 #define THUMB_HALFWORD 1
779 CONST
char * template; /* Basic string to match */
780 unsigned long value
; /* Basic instruction code */
782 unsigned long variants
; /* Which CPU variants this exists for */
783 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
786 static CONST
struct thumb_opcode tinsns
[] =
788 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
789 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
790 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
791 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
792 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
793 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
794 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
795 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
796 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
797 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
798 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
799 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
800 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
801 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
802 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
803 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
804 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
805 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
806 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
807 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
808 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
809 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
810 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
811 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
812 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
813 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
814 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
815 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
816 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
817 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
818 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
819 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
820 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
821 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
822 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
823 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
824 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
825 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
826 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
827 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
828 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
829 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
830 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
831 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
832 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
833 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
834 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
835 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
836 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
837 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
838 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
839 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
840 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
841 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
842 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
844 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
845 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
854 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
855 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
856 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
862 /* These are the standard names. Users can add aliases with .req */
863 static CONST
struct reg_entry reg_table
[] =
865 /* Processor Register Numbers. */
866 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
867 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
868 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
869 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
870 /* APCS conventions. */
871 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
872 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
873 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
874 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
875 /* ATPCS additions to APCS conventions. */
876 {"wr", 7}, {"v8", 11},
878 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
879 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
880 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
881 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
882 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
883 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
884 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
885 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
886 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
887 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
888 /* ATPCS additions to float register names. */
889 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
890 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
891 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
892 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
893 /* FIXME: At some point we need to add VFP register names. */
894 /* Array terminator. */
898 #define BAD_ARGS _("Bad arguments to instruction")
899 #define BAD_PC _("r15 not allowed here")
900 #define BAD_FLAGS _("Instruction should not have flags")
901 #define BAD_COND _("Instruction is not conditional")
903 static struct hash_control
* arm_ops_hsh
= NULL
;
904 static struct hash_control
* arm_tops_hsh
= NULL
;
905 static struct hash_control
* arm_cond_hsh
= NULL
;
906 static struct hash_control
* arm_shift_hsh
= NULL
;
907 static struct hash_control
* arm_reg_hsh
= NULL
;
908 static struct hash_control
* arm_psr_hsh
= NULL
;
910 /* This table describes all the machine specific pseudo-ops the assembler
911 has to support. The fields are:
912 pseudo-op name without dot
913 function to call to execute this pseudo-op
914 Integer arg to pass to the function. */
916 static void s_req
PARAMS ((int));
917 static void s_align
PARAMS ((int));
918 static void s_bss
PARAMS ((int));
919 static void s_even
PARAMS ((int));
920 static void s_ltorg
PARAMS ((int));
921 static void s_arm
PARAMS ((int));
922 static void s_thumb
PARAMS ((int));
923 static void s_code
PARAMS ((int));
924 static void s_force_thumb
PARAMS ((int));
925 static void s_thumb_func
PARAMS ((int));
926 static void s_thumb_set
PARAMS ((int));
927 static void arm_s_text
PARAMS ((int));
928 static void arm_s_data
PARAMS ((int));
930 static void arm_s_section
PARAMS ((int));
931 static void s_arm_elf_cons
PARAMS ((int));
934 static int my_get_expression
PARAMS ((expressionS
*, char **));
936 CONST pseudo_typeS md_pseudo_table
[] =
938 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
940 { "align", s_align
, 0 },
942 { "thumb", s_thumb
, 0 },
943 { "code", s_code
, 0 },
944 { "force_thumb", s_force_thumb
, 0 },
945 { "thumb_func", s_thumb_func
, 0 },
946 { "thumb_set", s_thumb_set
, 0 },
947 { "even", s_even
, 0 },
948 { "ltorg", s_ltorg
, 0 },
949 { "pool", s_ltorg
, 0 },
950 /* Allow for the effect of section changes. */
951 { "text", arm_s_text
, 0 },
952 { "data", arm_s_data
, 0 },
954 { "section", arm_s_section
, 0 },
955 { "section.s", arm_s_section
, 0 },
956 { "sect", arm_s_section
, 0 },
957 { "sect.s", arm_s_section
, 0 },
958 { "word", s_arm_elf_cons
, 4 },
959 { "long", s_arm_elf_cons
, 4 },
963 { "extend", float_cons
, 'x' },
964 { "ldouble", float_cons
, 'x' },
965 { "packed", float_cons
, 'p' },
969 /* Stuff needed to resolve the label ambiguity
979 symbolS
* last_label_seen
;
980 static int label_is_thumb_function_name
= false;
984 #define MAX_LITERAL_POOL_SIZE 1024
986 typedef struct literalS
988 struct expressionS exp
;
989 struct arm_it
* inst
;
992 literalT literals
[MAX_LITERAL_POOL_SIZE
];
993 int next_literal_pool_place
= 0; /* Next free entry in the pool */
994 int lit_pool_num
= 1; /* Next literal pool number */
995 symbolS
* current_poolP
= NULL
;
1002 if (current_poolP
== NULL
)
1003 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1004 (valueT
) 0, &zero_address_frag
);
1006 /* Check if this literal value is already in the pool: */
1007 while (lit_count
< next_literal_pool_place
)
1009 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1010 && inst
.reloc
.exp
.X_op
== O_constant
1011 && literals
[lit_count
].exp
.X_add_number
1012 == inst
.reloc
.exp
.X_add_number
1013 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1018 if (lit_count
== next_literal_pool_place
) /* new entry */
1020 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1022 inst
.error
= _("Literal Pool Overflow");
1026 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1027 lit_count
= next_literal_pool_place
++;
1030 inst
.reloc
.exp
.X_op
= O_symbol
;
1031 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1032 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1037 /* Can't use symbol_new here, so have to create a symbol and then at
1038 a later date assign it a value. Thats what these functions do. */
1040 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1042 CONST
char * name
; /* It is copied, the caller can modify */
1043 segT segment
; /* Segment identifier (SEG_<something>) */
1044 valueT valu
; /* Symbol value */
1045 fragS
* frag
; /* Associated fragment */
1047 unsigned int name_length
;
1048 char * preserved_copy_of_name
;
1050 name_length
= strlen (name
) + 1; /* +1 for \0 */
1051 obstack_grow (¬es
, name
, name_length
);
1052 preserved_copy_of_name
= obstack_finish (¬es
);
1053 #ifdef STRIP_UNDERSCORE
1054 if (preserved_copy_of_name
[0] == '_')
1055 preserved_copy_of_name
++;
1058 #ifdef tc_canonicalize_symbol_name
1059 preserved_copy_of_name
=
1060 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1063 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1065 S_SET_SEGMENT (symbolP
, segment
);
1066 S_SET_VALUE (symbolP
, valu
);
1067 symbol_clear_list_pointers(symbolP
);
1069 symbol_set_frag (symbolP
, frag
);
1071 /* Link to end of symbol chain. */
1073 extern int symbol_table_frozen
;
1074 if (symbol_table_frozen
)
1078 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1080 obj_symbol_new_hook (symbolP
);
1082 #ifdef tc_symbol_new_hook
1083 tc_symbol_new_hook (symbolP
);
1087 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1088 #endif /* DEBUG_SYMS */
1091 /* Check that an immediate is valid, and if so,
1092 convert it to the right format. */
1094 validate_immediate (val
)
1100 #define rotate_left(v, n) (v << n | v >> (32 - n))
1102 for (i
= 0; i
< 32; i
+= 2)
1103 if ((a
= rotate_left (val
, i
)) <= 0xff)
1104 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1109 /* Check to see if an immediate can be computed as two seperate immediate
1110 values, added together. We already know that this value cannot be
1111 computed by just one ARM instruction. */
1113 validate_immediate_twopart (val
, highpart
)
1115 unsigned int * highpart
;
1120 for (i
= 0; i
< 32; i
+= 2)
1121 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1127 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1129 else if (a
& 0xff0000)
1134 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1138 assert (a
& 0xff000000);
1140 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1143 return (a
& 0xff) | (i
<< 7);
1150 validate_offset_imm (val
, hwse
)
1154 if ((hwse
&& val
> 255) || val
> 4095)
1162 int a ATTRIBUTE_UNUSED
;
1164 as_bad (_("Invalid syntax for .req directive."));
1169 int ignore ATTRIBUTE_UNUSED
;
1171 /* We don't support putting frags in the BSS segment, we fake it by
1172 marking in_bss, then looking at s_skip for clues?.. */
1173 subseg_set (bss_section
, 0);
1174 demand_empty_rest_of_line ();
1179 int ignore ATTRIBUTE_UNUSED
;
1181 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1182 frag_align (1, 0, 0);
1184 record_alignment (now_seg
, 1);
1186 demand_empty_rest_of_line ();
1191 int ignored ATTRIBUTE_UNUSED
;
1196 if (current_poolP
== NULL
)
1199 /* Align pool as you have word accesses */
1200 /* Only make a frag if we have to ... */
1202 frag_align (2, 0, 0);
1204 record_alignment (now_seg
, 2);
1206 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1208 symbol_locate (current_poolP
, sym_name
, now_seg
,
1209 (valueT
) frag_now_fix (), frag_now
);
1210 symbol_table_insert (current_poolP
);
1212 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1214 #if defined OBJ_COFF || defined OBJ_ELF
1215 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1218 while (lit_count
< next_literal_pool_place
)
1219 /* First output the expression in the instruction to the pool. */
1220 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1222 next_literal_pool_place
= 0;
1223 current_poolP
= NULL
;
1227 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1228 int unused ATTRIBUTE_UNUSED
;
1231 register long temp_fill
;
1232 long max_alignment
= 15;
1234 temp
= get_absolute_expression ();
1235 if (temp
> max_alignment
)
1236 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1239 as_bad (_("Alignment negative. 0 assumed."));
1243 if (*input_line_pointer
== ',')
1245 input_line_pointer
++;
1246 temp_fill
= get_absolute_expression ();
1254 /* Only make a frag if we HAVE to. . . */
1255 if (temp
&& !need_pass_2
)
1256 frag_align (temp
, (int) temp_fill
, 0);
1257 demand_empty_rest_of_line ();
1259 record_alignment (now_seg
, temp
);
1263 s_force_thumb (ignore
)
1264 int ignore ATTRIBUTE_UNUSED
;
1266 /* If we are not already in thumb mode go into it, EVEN if
1267 the target processor does not support thumb instructions.
1268 This is used by gcc/config/arm/lib1funcs.asm for example
1269 to compile interworking support functions even if the
1270 target processor should not support interworking. */
1276 record_alignment (now_seg
, 1);
1279 demand_empty_rest_of_line ();
1283 s_thumb_func (ignore
)
1284 int ignore ATTRIBUTE_UNUSED
;
1286 /* The following label is the name/address of the start of a Thumb function.
1287 We need to know this for the interworking support. */
1289 label_is_thumb_function_name
= true;
1291 demand_empty_rest_of_line ();
1294 /* Perform a .set directive, but also mark the alias as
1295 being a thumb function. */
1301 /* XXX the following is a duplicate of the code for s_set() in read.c
1302 We cannot just call that code as we need to get at the symbol that
1304 register char * name
;
1305 register char delim
;
1306 register char * end_name
;
1307 register symbolS
* symbolP
;
1310 * Especial apologies for the random logic:
1311 * this just grew, and could be parsed much more simply!
1314 name
= input_line_pointer
;
1315 delim
= get_symbol_end ();
1316 end_name
= input_line_pointer
;
1321 if (*input_line_pointer
!= ',')
1324 as_bad (_("Expected comma after name \"%s\""), name
);
1326 ignore_rest_of_line ();
1330 input_line_pointer
++;
1333 if (name
[0] == '.' && name
[1] == '\0')
1335 /* XXX - this should not happen to .thumb_set */
1339 if ((symbolP
= symbol_find (name
)) == NULL
1340 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1343 /* When doing symbol listings, play games with dummy fragments living
1344 outside the normal fragment chain to record the file and line info
1346 if (listing
& LISTING_SYMBOLS
)
1348 extern struct list_info_struct
* listing_tail
;
1349 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1350 memset (dummy_frag
, 0, sizeof(fragS
));
1351 dummy_frag
->fr_type
= rs_fill
;
1352 dummy_frag
->line
= listing_tail
;
1353 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1354 dummy_frag
->fr_symbol
= symbolP
;
1358 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1361 /* "set" symbols are local unless otherwise specified. */
1362 SF_SET_LOCAL (symbolP
);
1363 #endif /* OBJ_COFF */
1364 } /* make a new symbol */
1366 symbol_table_insert (symbolP
);
1371 && S_IS_DEFINED (symbolP
)
1372 && S_GET_SEGMENT (symbolP
) != reg_section
)
1373 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1375 pseudo_set (symbolP
);
1377 demand_empty_rest_of_line ();
1379 /* XXX Now we come to the Thumb specific bit of code. */
1381 THUMB_SET_FUNC (symbolP
, 1);
1382 ARM_SET_THUMB (symbolP
, 1);
1383 #if defined OBJ_ELF || defined OBJ_COFF
1384 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1388 /* If we change section we must dump the literal pool first. */
1393 if (now_seg
!= text_section
)
1397 obj_elf_text (ignore
);
1407 if (flag_readonly_data_in_text
)
1409 if (now_seg
!= text_section
)
1412 else if (now_seg
!= data_section
)
1416 obj_elf_data (ignore
);
1424 arm_s_section (ignore
)
1429 obj_elf_section (ignore
);
1434 opcode_select (width
)
1442 if (! (cpu_variant
& ARM_THUMB
))
1443 as_bad (_("selected processor does not support THUMB opcodes"));
1445 /* No need to force the alignment, since we will have been
1446 coming from ARM mode, which is word-aligned. */
1447 record_alignment (now_seg
, 1);
1454 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1455 as_bad (_("selected processor does not support ARM opcodes"));
1458 frag_align (2, 0, 0);
1459 record_alignment (now_seg
, 1);
1464 as_bad (_("invalid instruction size selected (%d)"), width
);
1470 int ignore ATTRIBUTE_UNUSED
;
1473 demand_empty_rest_of_line ();
1478 int ignore ATTRIBUTE_UNUSED
;
1481 demand_empty_rest_of_line ();
1486 int unused ATTRIBUTE_UNUSED
;
1490 temp
= get_absolute_expression ();
1495 opcode_select (temp
);
1499 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1507 skip_whitespace (str
);
1510 inst
.error
= _("Garbage following instruction");
1514 skip_past_comma (str
)
1520 while ((c
= *p
) == ' ' || c
== ',')
1523 if (c
== ',' && comma
++)
1531 return comma
? SUCCESS
: FAIL
;
1534 /* A standard register must be given at this point.
1535 Shift is the place to put it in inst.instruction.
1536 Restores input start point on err.
1537 Returns the reg#, or FAIL. */
1539 reg_required_here (str
, shift
)
1543 static char buff
[128]; /* XXX */
1545 char * start
= *str
;
1547 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1550 inst
.instruction
|= reg
<< shift
;
1554 /* Restore the start point, we may have got a reg of the wrong class. */
1557 /* In the few cases where we might be able to accept something else
1558 this error can be overridden. */
1559 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1566 psr_required_here (str
, cpsr
, spsr
)
1572 char * start
= *str
;
1573 psr
= arm_psr_parse (str
);
1575 if (psr
== cpsr
|| psr
== spsr
)
1578 inst
.instruction
|= 1 << 22;
1583 /* In the few cases where we might be able to accept something else
1584 this error can be overridden. */
1585 inst
.error
= _("<psr(f)> expected");
1587 /* Restore the start point. */
1593 co_proc_number (str
)
1596 int processor
, pchar
;
1598 skip_whitespace (* str
);
1600 /* The data sheet seems to imply that just a number on its own is valid
1601 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1603 if (**str
== 'p' || **str
== 'P')
1607 if (pchar
>= '0' && pchar
<= '9')
1609 processor
= pchar
- '0';
1610 if (**str
>= '0' && **str
<= '9')
1612 processor
= processor
* 10 + *(*str
)++ - '0';
1615 inst
.error
= _("Illegal co-processor number");
1622 inst
.error
= _("Bad or missing co-processor number");
1626 inst
.instruction
|= processor
<< 8;
1631 cp_opc_expr (str
, where
, length
)
1638 skip_whitespace (* str
);
1640 memset (&expr
, '\0', sizeof (expr
));
1642 if (my_get_expression (&expr
, str
))
1644 if (expr
.X_op
!= O_constant
)
1646 inst
.error
= _("bad or missing expression");
1650 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1652 inst
.error
= _("immediate co-processor expression too large");
1656 inst
.instruction
|= expr
.X_add_number
<< where
;
1661 cp_reg_required_here (str
, where
)
1666 char * start
= *str
;
1668 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1671 inst
.instruction
|= reg
<< where
;
1675 /* In the few cases where we might be able to accept something else
1676 this error can be overridden. */
1677 inst
.error
= _("Co-processor register expected");
1679 /* Restore the start point. */
1685 fp_reg_required_here (str
, where
)
1690 char * start
= *str
;
1692 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1695 inst
.instruction
|= reg
<< where
;
1699 /* In the few cases where we might be able to accept something else
1700 this error can be overridden. */
1701 inst
.error
= _("Floating point register expected");
1703 /* Restore the start point. */
1709 cp_address_offset (str
)
1714 skip_whitespace (* str
);
1716 if (! is_immediate_prefix (**str
))
1718 inst
.error
= _("immediate expression expected");
1724 if (my_get_expression (& inst
.reloc
.exp
, str
))
1727 if (inst
.reloc
.exp
.X_op
== O_constant
)
1729 offset
= inst
.reloc
.exp
.X_add_number
;
1733 inst
.error
= _("co-processor address must be word aligned");
1737 if (offset
> 1023 || offset
< -1023)
1739 inst
.error
= _("offset too large");
1744 inst
.instruction
|= INDEX_UP
;
1748 inst
.instruction
|= offset
>> 2;
1751 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1757 cp_address_required_here (str
)
1769 skip_whitespace (p
);
1771 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1774 skip_whitespace (p
);
1780 if (skip_past_comma (& p
) == SUCCESS
)
1783 write_back
= WRITE_BACK
;
1787 inst
.error
= _("pc may not be used in post-increment");
1791 if (cp_address_offset (& p
) == FAIL
)
1795 pre_inc
= PRE_INDEX
| INDEX_UP
;
1799 /* '['Rn, #expr']'[!] */
1801 if (skip_past_comma (& p
) == FAIL
)
1803 inst
.error
= _("pre-indexed expression expected");
1807 pre_inc
= PRE_INDEX
;
1809 if (cp_address_offset (& p
) == FAIL
)
1812 skip_whitespace (p
);
1816 inst
.error
= _("missing ]");
1820 skip_whitespace (p
);
1826 inst
.error
= _("pc may not be used with write-back");
1831 write_back
= WRITE_BACK
;
1837 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1840 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1841 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1842 inst
.reloc
.pc_rel
= 1;
1843 inst
.instruction
|= (REG_PC
<< 16);
1844 pre_inc
= PRE_INDEX
;
1847 inst
.instruction
|= write_back
| pre_inc
;
1855 unsigned long flags
;
1857 /* Do nothing really. */
1858 inst
.instruction
|= flags
; /* This is pointless. */
1866 unsigned long flags
;
1868 /* Only one syntax. */
1869 skip_whitespace (str
);
1871 if (reg_required_here (&str
, 12) == FAIL
)
1873 inst
.error
= BAD_ARGS
;
1877 if (skip_past_comma (&str
) == FAIL
1878 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1880 inst
.error
= _("<psr> expected");
1884 inst
.instruction
|= flags
;
1889 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1893 unsigned long flags
;
1897 skip_whitespace (str
);
1899 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1901 inst
.instruction
|= PSR_ALL
;
1903 /* Sytax should be "<psr>, Rm" */
1904 if (skip_past_comma (&str
) == FAIL
1905 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1907 inst
.error
= BAD_ARGS
;
1913 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1914 inst
.instruction
|= PSR_FLAGS
;
1915 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1916 inst
.instruction
|= PSR_CONTROL
;
1919 inst
.error
= BAD_ARGS
;
1923 if (skip_past_comma (&str
) == FAIL
)
1925 inst
.error
= BAD_ARGS
;
1929 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1931 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1933 /* Immediate expression. */
1934 else if (is_immediate_prefix (* str
))
1939 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1941 inst
.error
= _("Register or shift expression expected");
1945 if (inst
.reloc
.exp
.X_add_symbol
)
1947 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1948 inst
.reloc
.pc_rel
= 0;
1952 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1953 if (value
== (unsigned) FAIL
)
1955 inst
.error
= _("Invalid constant");
1959 inst
.instruction
|= value
;
1962 flags
|= INST_IMMEDIATE
;
1966 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1972 inst
.instruction
|= flags
;
1977 /* Long Multiply Parser
1978 UMULL RdLo, RdHi, Rm, Rs
1979 SMULL RdLo, RdHi, Rm, Rs
1980 UMLAL RdLo, RdHi, Rm, Rs
1981 SMLAL RdLo, RdHi, Rm, Rs
1984 do_mull (str
, flags
)
1986 unsigned long flags
;
1988 int rdlo
, rdhi
, rm
, rs
;
1990 /* Only one format "rdlo, rdhi, rm, rs" */
1991 skip_whitespace (str
);
1993 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1995 inst
.error
= BAD_ARGS
;
1999 if (skip_past_comma (&str
) == FAIL
2000 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2002 inst
.error
= BAD_ARGS
;
2006 if (skip_past_comma (&str
) == FAIL
2007 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2009 inst
.error
= BAD_ARGS
;
2013 /* rdhi, rdlo and rm must all be different */
2014 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2015 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2017 if (skip_past_comma (&str
) == FAIL
2018 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2020 inst
.error
= BAD_ARGS
;
2024 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2026 inst
.error
= BAD_PC
;
2030 inst
.instruction
|= flags
;
2038 unsigned long flags
;
2042 /* Only one format "rd, rm, rs" */
2043 skip_whitespace (str
);
2045 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2047 inst
.error
= BAD_ARGS
;
2053 inst
.error
= BAD_PC
;
2057 if (skip_past_comma (&str
) == FAIL
2058 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2060 inst
.error
= BAD_ARGS
;
2066 inst
.error
= BAD_PC
;
2071 as_tsktsk (_("rd and rm should be different in mul"));
2073 if (skip_past_comma (&str
) == FAIL
2074 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2076 inst
.error
= BAD_ARGS
;
2082 inst
.error
= BAD_PC
;
2086 inst
.instruction
|= flags
;
2094 unsigned long flags
;
2098 /* Only one format "rd, rm, rs, rn" */
2099 skip_whitespace (str
);
2101 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2103 inst
.error
= BAD_ARGS
;
2109 inst
.error
= BAD_PC
;
2113 if (skip_past_comma (&str
) == FAIL
2114 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2116 inst
.error
= BAD_ARGS
;
2122 inst
.error
= BAD_PC
;
2127 as_tsktsk (_("rd and rm should be different in mla"));
2129 if (skip_past_comma (&str
) == FAIL
2130 || (rd
= reg_required_here (&str
, 8)) == FAIL
2131 || skip_past_comma (&str
) == FAIL
2132 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2134 inst
.error
= BAD_ARGS
;
2138 if (rd
== REG_PC
|| rm
== REG_PC
)
2140 inst
.error
= BAD_PC
;
2144 inst
.instruction
|= flags
;
2149 /* Returns the index into fp_values of a floating point number, or -1 if
2150 not in the table. */
2152 my_get_float_expression (str
)
2155 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2161 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2162 /* Look for a raw floating point number */
2163 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2164 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2166 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2168 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2170 if (words
[j
] != fp_values
[i
][j
])
2174 if (j
== MAX_LITTLENUMS
)
2182 /* Try and parse a more complex expression, this will probably fail
2183 unless the code uses a floating point prefix (eg "0f") */
2184 save_in
= input_line_pointer
;
2185 input_line_pointer
= *str
;
2186 if (expression (&exp
) == absolute_section
2187 && exp
.X_op
== O_big
2188 && exp
.X_add_number
< 0)
2190 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2192 if (gen_to_words (words
, 5, (long)15) == 0)
2194 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2196 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2198 if (words
[j
] != fp_values
[i
][j
])
2202 if (j
== MAX_LITTLENUMS
)
2204 *str
= input_line_pointer
;
2205 input_line_pointer
= save_in
;
2212 *str
= input_line_pointer
;
2213 input_line_pointer
= save_in
;
2217 /* Return true if anything in the expression is a bignum */
2219 walk_no_bignums (sp
)
2222 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2225 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2227 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2228 || (symbol_get_value_expression (sp
)->X_op_symbol
2229 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2236 my_get_expression (ep
, str
)
2243 save_in
= input_line_pointer
;
2244 input_line_pointer
= *str
;
2245 seg
= expression (ep
);
2248 if (seg
!= absolute_section
2249 && seg
!= text_section
2250 && seg
!= data_section
2251 && seg
!= bss_section
2252 && seg
!= undefined_section
)
2254 inst
.error
= _("bad_segment");
2255 *str
= input_line_pointer
;
2256 input_line_pointer
= save_in
;
2261 /* Get rid of any bignums now, so that we don't generate an error for which
2262 we can't establish a line number later on. Big numbers are never valid
2263 in instructions, which is where this routine is always called. */
2264 if (ep
->X_op
== O_big
2265 || (ep
->X_add_symbol
2266 && (walk_no_bignums (ep
->X_add_symbol
)
2268 && walk_no_bignums (ep
->X_op_symbol
)))))
2270 inst
.error
= _("Invalid constant");
2271 *str
= input_line_pointer
;
2272 input_line_pointer
= save_in
;
2276 *str
= input_line_pointer
;
2277 input_line_pointer
= save_in
;
2281 /* unrestrict should be one if <shift> <register> is permitted for this
2285 decode_shift (str
, unrestrict
)
2289 struct asm_shift
* shft
;
2293 skip_whitespace (* str
);
2295 for (p
= *str
; isalpha (*p
); p
++)
2300 inst
.error
= _("Shift expression expected");
2306 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2310 if (!strncmp (*str
, "rrx", 3)
2311 || !strncmp (*str
, "RRX", 3))
2314 inst
.instruction
|= shft
->value
;
2318 skip_whitespace (p
);
2320 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2322 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2326 else if (is_immediate_prefix (* p
))
2330 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2333 /* Validate some simple #expressions */
2334 if (inst
.reloc
.exp
.X_op
== O_constant
)
2336 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2338 /* Reject operations greater than 32, or lsl #32 */
2339 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2341 inst
.error
= _("Invalid immediate shift");
2345 /* Shifts of zero should be converted to lsl (which is zero)*/
2352 /* Shifts of 32 are encoded as 0, for those shifts that
2357 inst
.instruction
|= (num
<< 7) | shft
->value
;
2362 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2363 inst
.reloc
.pc_rel
= 0;
2364 inst
.instruction
|= shft
->value
;
2370 inst
.error
= unrestrict
? _("shift requires register or #expression")
2371 : _("shift requires #expression");
2377 inst
.error
= _("Shift expression expected");
2381 /* Do those data_ops which can take a negative immediate constant */
2382 /* by altering the instuction. A bit of a hack really */
2386 by inverting the second operand, and
2389 by negating the second operand.
2392 negate_data_op (instruction
, value
)
2393 unsigned long * instruction
;
2394 unsigned long value
;
2397 unsigned long negated
, inverted
;
2399 negated
= validate_immediate (-value
);
2400 inverted
= validate_immediate (~value
);
2402 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2406 case OPCODE_SUB
: /* ADD <-> SUB */
2407 new_inst
= OPCODE_ADD
;
2412 new_inst
= OPCODE_SUB
;
2416 case OPCODE_CMP
: /* CMP <-> CMN */
2417 new_inst
= OPCODE_CMN
;
2422 new_inst
= OPCODE_CMP
;
2426 /* Now Inverted ops */
2427 case OPCODE_MOV
: /* MOV <-> MVN */
2428 new_inst
= OPCODE_MVN
;
2433 new_inst
= OPCODE_MOV
;
2437 case OPCODE_AND
: /* AND <-> BIC */
2438 new_inst
= OPCODE_BIC
;
2443 new_inst
= OPCODE_AND
;
2447 case OPCODE_ADC
: /* ADC <-> SBC */
2448 new_inst
= OPCODE_SBC
;
2453 new_inst
= OPCODE_ADC
;
2457 /* We cannot do anything */
2462 if (value
== (unsigned) FAIL
)
2465 *instruction
&= OPCODE_MASK
;
2466 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2477 skip_whitespace (* str
);
2479 if (reg_required_here (str
, 0) != FAIL
)
2481 if (skip_past_comma (str
) == SUCCESS
)
2482 /* Shift operation on register. */
2483 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2489 /* Immediate expression */
2490 if (is_immediate_prefix (**str
))
2495 if (my_get_expression (&inst
.reloc
.exp
, str
))
2498 if (inst
.reloc
.exp
.X_add_symbol
)
2500 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2501 inst
.reloc
.pc_rel
= 0;
2505 if (skip_past_comma (str
) == SUCCESS
)
2507 /* #x, y -- ie explicit rotation by Y */
2508 if (my_get_expression (&expr
, str
))
2511 if (expr
.X_op
!= O_constant
)
2513 inst
.error
= _("Constant expression expected");
2517 /* Rotate must be a multiple of 2 */
2518 if (((unsigned) expr
.X_add_number
) > 30
2519 || (expr
.X_add_number
& 1) != 0
2520 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2522 inst
.error
= _("Invalid constant");
2525 inst
.instruction
|= INST_IMMEDIATE
;
2526 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2527 inst
.instruction
|= expr
.X_add_number
<< 7;
2531 /* Implicit rotation, select a suitable one */
2532 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2536 /* Can't be done, perhaps the code reads something like
2537 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2538 if ((value
= negate_data_op (&inst
.instruction
,
2539 inst
.reloc
.exp
.X_add_number
))
2542 inst
.error
= _("Invalid constant");
2547 inst
.instruction
|= value
;
2550 inst
.instruction
|= INST_IMMEDIATE
;
2555 inst
.error
= _("Register or shift expression expected");
2564 skip_whitespace (* str
);
2566 if (fp_reg_required_here (str
, 0) != FAIL
)
2570 /* Immediate expression */
2571 if (*((*str
)++) == '#')
2577 skip_whitespace (* str
);
2579 /* First try and match exact strings, this is to guarantee that
2580 some formats will work even for cross assembly */
2582 for (i
= 0; fp_const
[i
]; i
++)
2584 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2588 *str
+= strlen (fp_const
[i
]);
2589 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2591 inst
.instruction
|= i
+ 8;
2598 /* Just because we didn't get a match doesn't mean that the
2599 constant isn't valid, just that it is in a format that we
2600 don't automatically recognize. Try parsing it with
2601 the standard expression routines. */
2602 if ((i
= my_get_float_expression (str
)) >= 0)
2604 inst
.instruction
|= i
+ 8;
2608 inst
.error
= _("Invalid floating point immediate expression");
2611 inst
.error
= _("Floating point register or immediate expression expected");
2617 do_arit (str
, flags
)
2619 unsigned long flags
;
2621 skip_whitespace (str
);
2623 if (reg_required_here (&str
, 12) == FAIL
2624 || skip_past_comma (&str
) == FAIL
2625 || reg_required_here (&str
, 16) == FAIL
2626 || skip_past_comma (&str
) == FAIL
2627 || data_op2 (&str
) == FAIL
)
2630 inst
.error
= BAD_ARGS
;
2634 inst
.instruction
|= flags
;
2642 unsigned long flags
;
2644 /* This is a pseudo-op of the form "adr rd, label" to be converted
2645 into a relative address of the form "add rd, pc, #label-.-8". */
2646 skip_whitespace (str
);
2648 if (reg_required_here (&str
, 12) == FAIL
2649 || skip_past_comma (&str
) == FAIL
2650 || my_get_expression (&inst
.reloc
.exp
, &str
))
2653 inst
.error
= BAD_ARGS
;
2657 /* Frag hacking will turn this into a sub instruction if the offset turns
2658 out to be negative. */
2659 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2660 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2661 inst
.reloc
.pc_rel
= 1;
2662 inst
.instruction
|= flags
;
2668 do_adrl (str
, flags
)
2670 unsigned long flags
;
2672 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2673 into a relative address of the form:
2674 add rd, pc, #low(label-.-8)"
2675 add rd, rd, #high(label-.-8)" */
2677 skip_whitespace (str
);
2679 if (reg_required_here (& str
, 12) == FAIL
2680 || skip_past_comma (& str
) == FAIL
2681 || my_get_expression (& inst
.reloc
.exp
, & str
))
2684 inst
.error
= BAD_ARGS
;
2690 /* Frag hacking will turn this into a sub instruction if the offset turns
2691 out to be negative. */
2692 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2693 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2694 inst
.reloc
.pc_rel
= 1;
2695 inst
.instruction
|= flags
;
2696 inst
.size
= INSN_SIZE
* 2;
2704 unsigned long flags
;
2706 skip_whitespace (str
);
2708 if (reg_required_here (&str
, 16) == FAIL
)
2711 inst
.error
= BAD_ARGS
;
2715 if (skip_past_comma (&str
) == FAIL
2716 || data_op2 (&str
) == FAIL
)
2719 inst
.error
= BAD_ARGS
;
2723 inst
.instruction
|= flags
;
2724 if ((flags
& 0x0000f000) == 0)
2725 inst
.instruction
|= CONDS_BIT
;
2734 unsigned long flags
;
2736 skip_whitespace (str
);
2738 if (reg_required_here (&str
, 12) == FAIL
)
2741 inst
.error
= BAD_ARGS
;
2745 if (skip_past_comma (&str
) == FAIL
2746 || data_op2 (&str
) == FAIL
)
2749 inst
.error
= BAD_ARGS
;
2753 inst
.instruction
|= flags
;
2759 ldst_extend (str
, hwse
)
2770 if (my_get_expression (& inst
.reloc
.exp
, str
))
2773 if (inst
.reloc
.exp
.X_op
== O_constant
)
2775 int value
= inst
.reloc
.exp
.X_add_number
;
2777 if ((hwse
&& (value
< -255 || value
> 255))
2778 || (value
< -4095 || value
> 4095))
2780 inst
.error
= _("address offset too large");
2790 /* Halfword and signextension instructions have the
2791 immediate value split across bits 11..8 and bits 3..0 */
2793 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2795 inst
.instruction
|= add
| value
;
2801 inst
.instruction
|= HWOFFSET_IMM
;
2802 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2805 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2806 inst
.reloc
.pc_rel
= 0;
2811 add
= 0; /* and fall through */
2813 (*str
)++; /* and fall through */
2815 if (reg_required_here (str
, 0) == FAIL
)
2819 inst
.instruction
|= add
;
2822 inst
.instruction
|= add
| OFFSET_REG
;
2823 if (skip_past_comma (str
) == SUCCESS
)
2824 return decode_shift (str
, SHIFT_RESTRICT
);
2832 do_ldst (str
, flags
)
2834 unsigned long flags
;
2841 /* This is not ideal, but it is the simplest way of dealing with the
2842 ARM7T halfword instructions (since they use a different
2843 encoding, but the same mnemonic): */
2844 halfword
= (flags
& 0x80000000) != 0;
2847 /* This is actually a load/store of a halfword, or a
2848 signed-extension load */
2849 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2852 = _("Processor does not support halfwords or signed bytes");
2856 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2857 | (flags
& ~COND_MASK
);
2862 skip_whitespace (str
);
2864 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2867 inst
.error
= BAD_ARGS
;
2871 if (skip_past_comma (& str
) == FAIL
)
2873 inst
.error
= _("Address expected");
2883 skip_whitespace (str
);
2885 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2888 /* Conflicts can occur on stores as well as loads. */
2889 conflict_reg
= (conflict_reg
== reg
);
2891 skip_whitespace (str
);
2897 if (skip_past_comma (&str
) == SUCCESS
)
2899 /* [Rn],... (post inc) */
2900 if (ldst_extend (&str
, halfword
) == FAIL
)
2903 as_warn (_("%s register same as write-back base"),
2904 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2910 inst
.instruction
|= HWOFFSET_IMM
;
2912 skip_whitespace (str
);
2917 as_warn (_("%s register same as write-back base"),
2918 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2920 inst
.instruction
|= WRITE_BACK
;
2924 if (! (flags
& TRANS_BIT
))
2931 if (skip_past_comma (&str
) == FAIL
)
2933 inst
.error
= _("pre-indexed expression expected");
2938 if (ldst_extend (&str
, halfword
) == FAIL
)
2941 skip_whitespace (str
);
2945 inst
.error
= _("missing ]");
2949 skip_whitespace (str
);
2954 as_warn (_("%s register same as write-back base"),
2955 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2957 inst
.instruction
|= WRITE_BACK
;
2961 else if (*str
== '=')
2963 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2966 skip_whitespace (str
);
2968 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2971 if (inst
.reloc
.exp
.X_op
!= O_constant
2972 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2974 inst
.error
= _("Constant expression expected");
2978 if (inst
.reloc
.exp
.X_op
== O_constant
2979 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2981 /* This can be done with a mov instruction */
2982 inst
.instruction
&= LITERAL_MASK
;
2983 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2984 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2990 /* Insert into literal pool */
2991 if (add_to_lit_pool () == FAIL
)
2994 inst
.error
= _("literal pool insertion failed");
2998 /* Change the instruction exp to point to the pool */
3001 inst
.instruction
|= HWOFFSET_IMM
;
3002 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3005 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3006 inst
.reloc
.pc_rel
= 1;
3007 inst
.instruction
|= (REG_PC
<< 16);
3013 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3018 inst
.instruction
|= HWOFFSET_IMM
;
3019 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3022 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3024 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3026 inst
.reloc
.pc_rel
= 1;
3027 inst
.instruction
|= (REG_PC
<< 16);
3031 if (pre_inc
&& (flags
& TRANS_BIT
))
3032 inst
.error
= _("Pre-increment instruction with translate");
3034 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3047 /* We come back here if we get ranges concatenated by '+' or '|' */
3062 skip_whitespace (str
);
3064 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3073 inst
.error
= _("Bad range in register list");
3077 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3079 if (range
& (1 << i
))
3081 (_("Warning: Duplicated register (r%d) in register list"),
3089 if (range
& (1 << reg
))
3090 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3092 else if (reg
<= cur_reg
)
3093 as_tsktsk (_("Warning: Register range not in ascending order"));
3097 } while (skip_past_comma (&str
) != FAIL
3098 || (in_range
= 1, *str
++ == '-'));
3100 skip_whitespace (str
);
3104 inst
.error
= _("Missing `}'");
3112 if (my_get_expression (&expr
, &str
))
3115 if (expr
.X_op
== O_constant
)
3117 if (expr
.X_add_number
3118 != (expr
.X_add_number
& 0x0000ffff))
3120 inst
.error
= _("invalid register mask");
3124 if ((range
& expr
.X_add_number
) != 0)
3126 int regno
= range
& expr
.X_add_number
;
3129 regno
= (1 << regno
) - 1;
3131 (_("Warning: Duplicated register (r%d) in register list"),
3135 range
|= expr
.X_add_number
;
3139 if (inst
.reloc
.type
!= 0)
3141 inst
.error
= _("expression too complex");
3145 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3146 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3147 inst
.reloc
.pc_rel
= 0;
3151 skip_whitespace (str
);
3153 if (*str
== '|' || *str
== '+')
3158 } while (another_range
);
3165 do_ldmstm (str
, flags
)
3167 unsigned long flags
;
3172 skip_whitespace (str
);
3174 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3177 if (base_reg
== REG_PC
)
3179 inst
.error
= _("r15 not allowed as base register");
3183 skip_whitespace (str
);
3187 flags
|= WRITE_BACK
;
3191 if (skip_past_comma (&str
) == FAIL
3192 || (range
= reg_list (&str
)) == FAIL
)
3195 inst
.error
= BAD_ARGS
;
3202 flags
|= LDM_TYPE_2_OR_3
;
3205 inst
.instruction
|= flags
| range
;
3213 unsigned long flags
;
3215 skip_whitespace (str
);
3217 /* Allow optional leading '#'. */
3218 if (is_immediate_prefix (*str
))
3221 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3224 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3225 inst
.reloc
.pc_rel
= 0;
3226 inst
.instruction
|= flags
;
3234 do_swap (str
, flags
)
3236 unsigned long flags
;
3240 skip_whitespace (str
);
3242 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3247 inst
.error
= _("r15 not allowed in swap");
3251 if (skip_past_comma (&str
) == FAIL
3252 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3255 inst
.error
= BAD_ARGS
;
3261 inst
.error
= _("r15 not allowed in swap");
3265 if (skip_past_comma (&str
) == FAIL
3268 inst
.error
= BAD_ARGS
;
3272 skip_whitespace (str
);
3274 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3279 inst
.error
= BAD_PC
;
3283 skip_whitespace (str
);
3287 inst
.error
= _("missing ]");
3291 inst
.instruction
|= flags
;
3297 do_branch (str
, flags
)
3299 unsigned long flags ATTRIBUTE_UNUSED
;
3301 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3308 /* ScottB: February 5, 1998 */
3309 /* Check to see of PLT32 reloc required for the instruction. */
3311 /* arm_parse_reloc() works on input_line_pointer.
3312 We actually want to parse the operands to the branch instruction
3313 passed in 'str'. Save the input pointer and restore it later. */
3314 save_in
= input_line_pointer
;
3315 input_line_pointer
= str
;
3316 if (inst
.reloc
.exp
.X_op
== O_symbol
3318 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3320 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3321 inst
.reloc
.pc_rel
= 0;
3322 /* Modify str to point to after parsed operands, otherwise
3323 end_of_line() will complain about the (PLT) left in str. */
3324 str
= input_line_pointer
;
3328 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3329 inst
.reloc
.pc_rel
= 1;
3331 input_line_pointer
= save_in
;
3334 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3335 inst
.reloc
.pc_rel
= 1;
3336 #endif /* OBJ_ELF */
3345 unsigned long flags ATTRIBUTE_UNUSED
;
3349 skip_whitespace (str
);
3351 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3353 inst
.error
= BAD_ARGS
;
3358 inst
.error
= BAD_PC
;
3366 unsigned long flags ATTRIBUTE_UNUSED
;
3368 /* Co-processor data operation.
3369 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3370 skip_whitespace (str
);
3372 if (co_proc_number (&str
) == FAIL
)
3375 inst
.error
= BAD_ARGS
;
3379 if (skip_past_comma (&str
) == FAIL
3380 || cp_opc_expr (&str
, 20,4) == FAIL
)
3383 inst
.error
= BAD_ARGS
;
3387 if (skip_past_comma (&str
) == FAIL
3388 || cp_reg_required_here (&str
, 12) == FAIL
)
3391 inst
.error
= BAD_ARGS
;
3395 if (skip_past_comma (&str
) == FAIL
3396 || cp_reg_required_here (&str
, 16) == FAIL
)
3399 inst
.error
= BAD_ARGS
;
3403 if (skip_past_comma (&str
) == FAIL
3404 || cp_reg_required_here (&str
, 0) == FAIL
)
3407 inst
.error
= BAD_ARGS
;
3411 if (skip_past_comma (&str
) == SUCCESS
)
3413 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3416 inst
.error
= BAD_ARGS
;
3426 do_lstc (str
, flags
)
3428 unsigned long flags
;
3430 /* Co-processor register load/store.
3431 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3433 skip_whitespace (str
);
3435 if (co_proc_number (&str
) == FAIL
)
3438 inst
.error
= BAD_ARGS
;
3442 if (skip_past_comma (&str
) == FAIL
3443 || cp_reg_required_here (&str
, 12) == FAIL
)
3446 inst
.error
= BAD_ARGS
;
3450 if (skip_past_comma (&str
) == FAIL
3451 || cp_address_required_here (&str
) == FAIL
)
3454 inst
.error
= BAD_ARGS
;
3458 inst
.instruction
|= flags
;
3464 do_co_reg (str
, flags
)
3466 unsigned long flags
;
3468 /* Co-processor register transfer.
3469 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3471 skip_whitespace (str
);
3473 if (co_proc_number (&str
) == FAIL
)
3476 inst
.error
= BAD_ARGS
;
3480 if (skip_past_comma (&str
) == FAIL
3481 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3484 inst
.error
= BAD_ARGS
;
3488 if (skip_past_comma (&str
) == FAIL
3489 || reg_required_here (&str
, 12) == FAIL
)
3492 inst
.error
= BAD_ARGS
;
3496 if (skip_past_comma (&str
) == FAIL
3497 || cp_reg_required_here (&str
, 16) == FAIL
)
3500 inst
.error
= BAD_ARGS
;
3504 if (skip_past_comma (&str
) == FAIL
3505 || cp_reg_required_here (&str
, 0) == FAIL
)
3508 inst
.error
= BAD_ARGS
;
3512 if (skip_past_comma (&str
) == SUCCESS
)
3514 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3517 inst
.error
= BAD_ARGS
;
3523 inst
.error
= BAD_COND
;
3531 do_fp_ctrl (str
, flags
)
3533 unsigned long flags ATTRIBUTE_UNUSED
;
3535 /* FP control registers.
3536 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3538 skip_whitespace (str
);
3540 if (reg_required_here (&str
, 12) == FAIL
)
3543 inst
.error
= BAD_ARGS
;
3552 do_fp_ldst (str
, flags
)
3554 unsigned long flags ATTRIBUTE_UNUSED
;
3556 skip_whitespace (str
);
3558 switch (inst
.suffix
)
3563 inst
.instruction
|= CP_T_X
;
3566 inst
.instruction
|= CP_T_Y
;
3569 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3575 if (fp_reg_required_here (&str
, 12) == FAIL
)
3578 inst
.error
= BAD_ARGS
;
3582 if (skip_past_comma (&str
) == FAIL
3583 || cp_address_required_here (&str
) == FAIL
)
3586 inst
.error
= BAD_ARGS
;
3594 do_fp_ldmstm (str
, flags
)
3596 unsigned long flags
;
3600 skip_whitespace (str
);
3602 if (fp_reg_required_here (&str
, 12) == FAIL
)
3605 inst
.error
= BAD_ARGS
;
3609 /* Get Number of registers to transfer */
3610 if (skip_past_comma (&str
) == FAIL
3611 || my_get_expression (&inst
.reloc
.exp
, &str
))
3614 inst
.error
= _("constant expression expected");
3618 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3620 inst
.error
= _("Constant value required for number of registers");
3624 num_regs
= inst
.reloc
.exp
.X_add_number
;
3626 if (num_regs
< 1 || num_regs
> 4)
3628 inst
.error
= _("number of registers must be in the range [1:4]");
3635 inst
.instruction
|= CP_T_X
;
3638 inst
.instruction
|= CP_T_Y
;
3641 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3655 /* The instruction specified "ea" or "fd", so we can only accept
3656 [Rn]{!}. The instruction does not really support stacking or
3657 unstacking, so we have to emulate these by setting appropriate
3658 bits and offsets. */
3659 if (skip_past_comma (&str
) == FAIL
3663 inst
.error
= BAD_ARGS
;
3668 skip_whitespace (str
);
3670 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3673 skip_whitespace (str
);
3677 inst
.error
= BAD_ARGS
;
3688 inst
.error
= _("R15 not allowed as base register with write-back");
3695 if (flags
& CP_T_Pre
)
3698 offset
= 3 * num_regs
;
3704 /* Post-increment */
3708 offset
= 3 * num_regs
;
3712 /* No write-back, so convert this into a standard pre-increment
3713 instruction -- aesthetically more pleasing. */
3714 flags
= CP_T_Pre
| CP_T_UD
;
3719 inst
.instruction
|= flags
| offset
;
3721 else if (skip_past_comma (&str
) == FAIL
3722 || cp_address_required_here (&str
) == FAIL
)
3725 inst
.error
= BAD_ARGS
;
3733 do_fp_dyadic (str
, flags
)
3735 unsigned long flags
;
3737 skip_whitespace (str
);
3739 switch (inst
.suffix
)
3744 inst
.instruction
|= 0x00000080;
3747 inst
.instruction
|= 0x00080000;
3753 if (fp_reg_required_here (&str
, 12) == FAIL
)
3756 inst
.error
= BAD_ARGS
;
3760 if (skip_past_comma (&str
) == FAIL
3761 || fp_reg_required_here (&str
, 16) == FAIL
)
3764 inst
.error
= BAD_ARGS
;
3768 if (skip_past_comma (&str
) == FAIL
3769 || fp_op2 (&str
) == FAIL
)
3772 inst
.error
= BAD_ARGS
;
3776 inst
.instruction
|= flags
;
3782 do_fp_monadic (str
, flags
)
3784 unsigned long flags
;
3786 skip_whitespace (str
);
3788 switch (inst
.suffix
)
3793 inst
.instruction
|= 0x00000080;
3796 inst
.instruction
|= 0x00080000;
3802 if (fp_reg_required_here (&str
, 12) == FAIL
)
3805 inst
.error
= BAD_ARGS
;
3809 if (skip_past_comma (&str
) == FAIL
3810 || fp_op2 (&str
) == FAIL
)
3813 inst
.error
= BAD_ARGS
;
3817 inst
.instruction
|= flags
;
3823 do_fp_cmp (str
, flags
)
3825 unsigned long flags
;
3827 skip_whitespace (str
);
3829 if (fp_reg_required_here (&str
, 16) == FAIL
)
3832 inst
.error
= BAD_ARGS
;
3836 if (skip_past_comma (&str
) == FAIL
3837 || fp_op2 (&str
) == FAIL
)
3840 inst
.error
= BAD_ARGS
;
3844 inst
.instruction
|= flags
;
3850 do_fp_from_reg (str
, flags
)
3852 unsigned long flags
;
3854 skip_whitespace (str
);
3856 switch (inst
.suffix
)
3861 inst
.instruction
|= 0x00000080;
3864 inst
.instruction
|= 0x00080000;
3870 if (fp_reg_required_here (&str
, 16) == FAIL
)
3873 inst
.error
= BAD_ARGS
;
3877 if (skip_past_comma (&str
) == FAIL
3878 || reg_required_here (&str
, 12) == FAIL
)
3881 inst
.error
= BAD_ARGS
;
3885 inst
.instruction
|= flags
;
3891 do_fp_to_reg (str
, flags
)
3893 unsigned long flags
;
3895 skip_whitespace (str
);
3897 if (reg_required_here (&str
, 12) == FAIL
)
3900 if (skip_past_comma (&str
) == FAIL
3901 || fp_reg_required_here (&str
, 0) == FAIL
)
3904 inst
.error
= BAD_ARGS
;
3908 inst
.instruction
|= flags
;
3913 /* Thumb specific routines */
3915 /* Parse and validate that a register is of the right form, this saves
3916 repeated checking of this information in many similar cases.
3917 Unlike the 32-bit case we do not insert the register into the opcode
3918 here, since the position is often unknown until the full instruction
3921 thumb_reg (strp
, hi_lo
)
3927 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3935 inst
.error
= _("lo register required");
3943 inst
.error
= _("hi register required");
3955 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3958 thumb_add_sub (str
, subtract
)
3962 int Rd
, Rs
, Rn
= FAIL
;
3964 skip_whitespace (str
);
3966 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3967 || skip_past_comma (&str
) == FAIL
)
3970 inst
.error
= BAD_ARGS
;
3974 if (is_immediate_prefix (*str
))
3978 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3983 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3986 if (skip_past_comma (&str
) == FAIL
)
3988 /* Two operand format, shuffle the registers and pretend there
3993 else if (is_immediate_prefix (*str
))
3996 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3999 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4003 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4004 for the latter case, EXPR contains the immediate that was found. */
4007 /* All register format. */
4008 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4012 inst
.error
= _("dest and source1 must be the same register");
4016 /* Can't do this for SUB */
4019 inst
.error
= _("subtract valid only on lo regs");
4023 inst
.instruction
= (T_OPCODE_ADD_HI
4024 | (Rd
> 7 ? THUMB_H1
: 0)
4025 | (Rn
> 7 ? THUMB_H2
: 0));
4026 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4030 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4031 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4036 /* Immediate expression, now things start to get nasty. */
4038 /* First deal with HI regs, only very restricted cases allowed:
4039 Adjusting SP, and using PC or SP to get an address. */
4040 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4041 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4043 inst
.error
= _("invalid Hi register with immediate");
4047 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4049 /* Value isn't known yet, all we can do is store all the fragments
4050 we know about in the instruction and let the reloc hacking
4052 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4053 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4057 int offset
= inst
.reloc
.exp
.X_add_number
;
4067 /* Quick check, in case offset is MIN_INT */
4070 inst
.error
= _("immediate value out of range");
4079 if (offset
& ~0x1fc)
4081 inst
.error
= _("invalid immediate value for stack adjust");
4084 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4085 inst
.instruction
|= offset
>> 2;
4087 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4090 || (offset
& ~0x3fc))
4092 inst
.error
= _("invalid immediate for address calculation");
4095 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4097 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4103 inst
.error
= _("immediate value out of range");
4106 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4107 inst
.instruction
|= (Rd
<< 8) | offset
;
4113 inst
.error
= _("immediate value out of range");
4116 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4117 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4126 thumb_shift (str
, shift
)
4130 int Rd
, Rs
, Rn
= FAIL
;
4132 skip_whitespace (str
);
4134 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4135 || skip_past_comma (&str
) == FAIL
)
4138 inst
.error
= BAD_ARGS
;
4142 if (is_immediate_prefix (*str
))
4144 /* Two operand immediate format, set Rs to Rd. */
4147 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4152 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4155 if (skip_past_comma (&str
) == FAIL
)
4157 /* Two operand format, shuffle the registers and pretend there
4162 else if (is_immediate_prefix (*str
))
4165 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4168 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4172 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4173 for the latter case, EXPR contains the immediate that was found. */
4179 inst
.error
= _("source1 and dest must be same register");
4185 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4186 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4187 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4190 inst
.instruction
|= Rd
| (Rn
<< 3);
4196 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4197 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4198 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4201 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4203 /* Value isn't known yet, create a dummy reloc and let reloc
4204 hacking fix it up */
4206 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4210 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4212 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4214 inst
.error
= _("Invalid immediate for shift");
4218 /* Shifts of zero are handled by converting to LSL */
4219 if (shift_value
== 0)
4220 inst
.instruction
= T_OPCODE_LSL_I
;
4222 /* Shifts of 32 are encoded as a shift of zero */
4223 if (shift_value
== 32)
4226 inst
.instruction
|= shift_value
<< 6;
4229 inst
.instruction
|= Rd
| (Rs
<< 3);
4236 thumb_mov_compare (str
, move
)
4242 skip_whitespace (str
);
4244 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4245 || skip_past_comma (&str
) == FAIL
)
4248 inst
.error
= BAD_ARGS
;
4252 if (is_immediate_prefix (*str
))
4255 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4258 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4263 if (Rs
< 8 && Rd
< 8)
4265 if (move
== THUMB_MOVE
)
4266 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4267 since a MOV instruction produces unpredictable results */
4268 inst
.instruction
= T_OPCODE_ADD_I3
;
4270 inst
.instruction
= T_OPCODE_CMP_LR
;
4271 inst
.instruction
|= Rd
| (Rs
<< 3);
4275 if (move
== THUMB_MOVE
)
4276 inst
.instruction
= T_OPCODE_MOV_HR
;
4278 inst
.instruction
= T_OPCODE_CMP_HR
;
4281 inst
.instruction
|= THUMB_H1
;
4284 inst
.instruction
|= THUMB_H2
;
4286 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4293 inst
.error
= _("only lo regs allowed with immediate");
4297 if (move
== THUMB_MOVE
)
4298 inst
.instruction
= T_OPCODE_MOV_I8
;
4300 inst
.instruction
= T_OPCODE_CMP_I8
;
4302 inst
.instruction
|= Rd
<< 8;
4304 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4305 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4308 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4312 inst
.error
= _("invalid immediate");
4316 inst
.instruction
|= value
;
4324 thumb_load_store (str
, load_store
, size
)
4329 int Rd
, Rb
, Ro
= FAIL
;
4331 skip_whitespace (str
);
4333 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4334 || skip_past_comma (&str
) == FAIL
)
4337 inst
.error
= BAD_ARGS
;
4344 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4347 if (skip_past_comma (&str
) != FAIL
)
4349 if (is_immediate_prefix (*str
))
4352 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4355 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4360 inst
.reloc
.exp
.X_op
= O_constant
;
4361 inst
.reloc
.exp
.X_add_number
= 0;
4366 inst
.error
= _("expected ']'");
4371 else if (*str
== '=')
4373 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4376 skip_whitespace (str
);
4378 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4383 if ( inst
.reloc
.exp
.X_op
!= O_constant
4384 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4386 inst
.error
= "Constant expression expected";
4390 if (inst
.reloc
.exp
.X_op
== O_constant
4391 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4393 /* This can be done with a mov instruction */
4395 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4396 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4400 /* Insert into literal pool */
4401 if (add_to_lit_pool () == FAIL
)
4404 inst
.error
= "literal pool insertion failed";
4408 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4409 inst
.reloc
.pc_rel
= 1;
4410 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4411 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4417 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4420 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4421 inst
.reloc
.pc_rel
= 1;
4422 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4423 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4428 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4430 if (size
!= THUMB_WORD
)
4432 inst
.error
= _("byte or halfword not valid for base register");
4435 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4437 inst
.error
= _("R15 based store not allowed");
4440 else if (Ro
!= FAIL
)
4442 inst
.error
= _("Invalid base register for register offset");
4447 inst
.instruction
= T_OPCODE_LDR_PC
;
4448 else if (load_store
== THUMB_LOAD
)
4449 inst
.instruction
= T_OPCODE_LDR_SP
;
4451 inst
.instruction
= T_OPCODE_STR_SP
;
4453 inst
.instruction
|= Rd
<< 8;
4454 if (inst
.reloc
.exp
.X_op
== O_constant
)
4456 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4458 if (offset
& ~0x3fc)
4460 inst
.error
= _("invalid offset");
4464 inst
.instruction
|= offset
>> 2;
4467 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4471 inst
.error
= _("invalid base register in load/store");
4474 else if (Ro
== FAIL
)
4476 /* Immediate offset */
4477 if (size
== THUMB_WORD
)
4478 inst
.instruction
= (load_store
== THUMB_LOAD
4479 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4480 else if (size
== THUMB_HALFWORD
)
4481 inst
.instruction
= (load_store
== THUMB_LOAD
4482 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4484 inst
.instruction
= (load_store
== THUMB_LOAD
4485 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4487 inst
.instruction
|= Rd
| (Rb
<< 3);
4489 if (inst
.reloc
.exp
.X_op
== O_constant
)
4491 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4493 if (offset
& ~(0x1f << size
))
4495 inst
.error
= _("Invalid offset");
4498 inst
.instruction
|= (offset
>> size
) << 6;
4501 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4505 /* Register offset */
4506 if (size
== THUMB_WORD
)
4507 inst
.instruction
= (load_store
== THUMB_LOAD
4508 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4509 else if (size
== THUMB_HALFWORD
)
4510 inst
.instruction
= (load_store
== THUMB_LOAD
4511 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4513 inst
.instruction
= (load_store
== THUMB_LOAD
4514 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4516 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4531 /* Handle the Format 4 instructions that do not have equivalents in other
4532 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4540 skip_whitespace (str
);
4542 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4543 || skip_past_comma (&str
) == FAIL
4544 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4546 inst
.error
= BAD_ARGS
;
4550 if (skip_past_comma (&str
) != FAIL
)
4552 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4553 (It isn't allowed for CMP either, but that isn't handled by this
4555 if (inst
.instruction
== T_OPCODE_TST
4556 || inst
.instruction
== T_OPCODE_CMN
4557 || inst
.instruction
== T_OPCODE_NEG
4558 || inst
.instruction
== T_OPCODE_MVN
)
4560 inst
.error
= BAD_ARGS
;
4564 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4569 inst
.error
= _("dest and source1 one must be the same register");
4575 if (inst
.instruction
== T_OPCODE_MUL
4577 as_tsktsk (_("Rs and Rd must be different in MUL"));
4579 inst
.instruction
|= Rd
| (Rs
<< 3);
4587 thumb_add_sub (str
, 0);
4594 thumb_shift (str
, THUMB_ASR
);
4601 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4603 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4604 inst
.reloc
.pc_rel
= 1;
4612 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4614 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4615 inst
.reloc
.pc_rel
= 1;
4619 /* Find the real, Thumb encoded start of a Thumb function. */
4622 find_real_start (symbolP
)
4626 const char * name
= S_GET_NAME (symbolP
);
4627 symbolS
* new_target
;
4629 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4630 #define STUB_NAME ".real_start_of"
4635 /* Names that start with '.' are local labels, not function entry points.
4636 The compiler may generate BL instructions to these labels because it
4637 needs to perform a branch to a far away location. */
4641 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4642 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4644 new_target
= symbol_find (real_start
);
4646 if (new_target
== NULL
)
4648 as_warn ("Failed to find real start of function: %s\n", name
);
4649 new_target
= symbolP
;
4662 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4665 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4666 inst
.reloc
.pc_rel
= 1;
4669 /* If the destination of the branch is a defined symbol which does not have
4670 the THUMB_FUNC attribute, then we must be calling a function which has
4671 the (interfacearm) attribute. We look for the Thumb entry point to that
4672 function and change the branch to refer to that function instead. */
4673 if ( inst
.reloc
.exp
.X_op
== O_symbol
4674 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4675 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4676 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4677 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4686 skip_whitespace (str
);
4688 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4691 /* This sets THUMB_H2 from the top bit of reg. */
4692 inst
.instruction
|= reg
<< 3;
4694 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4695 should cause the alignment to be checked once it is known. This is
4696 because BX PC only works if the instruction is word aligned. */
4705 thumb_mov_compare (str
, THUMB_COMPARE
);
4715 skip_whitespace (str
);
4717 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4721 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4725 if (skip_past_comma (&str
) == FAIL
4726 || (range
= reg_list (&str
)) == FAIL
)
4729 inst
.error
= BAD_ARGS
;
4733 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4735 /* This really doesn't seem worth it. */
4736 inst
.reloc
.type
= BFD_RELOC_NONE
;
4737 inst
.error
= _("Expression too complex");
4743 inst
.error
= _("only lo-regs valid in load/store multiple");
4747 inst
.instruction
|= (Rb
<< 8) | range
;
4755 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4762 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4769 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4778 skip_whitespace (str
);
4780 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4781 || skip_past_comma (&str
) == FAIL
4783 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4784 || skip_past_comma (&str
) == FAIL
4785 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4789 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4793 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4801 thumb_shift (str
, THUMB_LSL
);
4808 thumb_shift (str
, THUMB_LSR
);
4815 thumb_mov_compare (str
, THUMB_MOVE
);
4824 skip_whitespace (str
);
4826 if ((range
= reg_list (&str
)) == FAIL
)
4829 inst
.error
= BAD_ARGS
;
4833 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4835 /* This really doesn't seem worth it. */
4836 inst
.reloc
.type
= BFD_RELOC_NONE
;
4837 inst
.error
= _("Expression too complex");
4843 if ((inst
.instruction
== T_OPCODE_PUSH
4844 && (range
& ~0xff) == 1 << REG_LR
)
4845 || (inst
.instruction
== T_OPCODE_POP
4846 && (range
& ~0xff) == 1 << REG_PC
))
4848 inst
.instruction
|= THUMB_PP_PC_LR
;
4853 inst
.error
= _("invalid register list to push/pop instruction");
4858 inst
.instruction
|= range
;
4866 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4873 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4880 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4887 thumb_add_sub (str
, 1);
4894 skip_whitespace (str
);
4896 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4899 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4910 /* This is a pseudo-op of the form "adr rd, label" to be converted
4911 into a relative address of the form "add rd, pc, #label-.-4". */
4912 skip_whitespace (str
);
4914 /* Store Rd in temporary location inside instruction. */
4915 if ((reg
= reg_required_here (&str
, 4)) == FAIL
4916 || (reg
> 7) /* For Thumb reg must be r0..r7. */
4917 || skip_past_comma (&str
) == FAIL
4918 || my_get_expression (&inst
.reloc
.exp
, &str
))
4921 inst
.error
= BAD_ARGS
;
4925 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4926 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
4927 inst
.reloc
.pc_rel
= 1;
4928 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
4937 int len
= strlen (reg_table
[entry
].name
) + 2;
4938 char * buf
= (char *) xmalloc (len
);
4939 char * buf2
= (char *) xmalloc (len
);
4942 #ifdef REGISTER_PREFIX
4943 buf
[i
++] = REGISTER_PREFIX
;
4946 strcpy (buf
+ i
, reg_table
[entry
].name
);
4948 for (i
= 0; buf
[i
]; i
++)
4949 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4953 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4954 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4958 insert_reg_alias (str
, regnum
)
4962 struct reg_entry
*new =
4963 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4964 char *name
= xmalloc (strlen (str
) + 1);
4968 new->number
= regnum
;
4970 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4974 set_constant_flonums ()
4978 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4979 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4989 if ( (arm_ops_hsh
= hash_new ()) == NULL
4990 || (arm_tops_hsh
= hash_new ()) == NULL
4991 || (arm_cond_hsh
= hash_new ()) == NULL
4992 || (arm_shift_hsh
= hash_new ()) == NULL
4993 || (arm_reg_hsh
= hash_new ()) == NULL
4994 || (arm_psr_hsh
= hash_new ()) == NULL
)
4995 as_fatal (_("Virtual memory exhausted"));
4997 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4998 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4999 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5000 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5001 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5002 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5003 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
5004 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
5005 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5006 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5008 for (i
= 0; reg_table
[i
].name
; i
++)
5011 set_constant_flonums ();
5013 #if defined OBJ_COFF || defined OBJ_ELF
5015 unsigned int flags
= 0;
5017 /* Set the flags in the private structure. */
5018 if (uses_apcs_26
) flags
|= F_APCS26
;
5019 if (support_interwork
) flags
|= F_INTERWORK
;
5020 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5021 if (pic_code
) flags
|= F_PIC
;
5022 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5024 bfd_set_private_flags (stdoutput
, flags
);
5028 /* Record the CPU type as well. */
5029 switch (cpu_variant
& ARM_CPU_MASK
)
5032 mach
= bfd_mach_arm_2
;
5035 case ARM_3
: /* Also ARM_250. */
5036 mach
= bfd_mach_arm_2a
;
5040 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5041 mach
= bfd_mach_arm_4
;
5044 case ARM_7
: /* Also ARM_6. */
5045 mach
= bfd_mach_arm_3
;
5049 /* Catch special cases. */
5050 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5052 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5053 mach
= bfd_mach_arm_5T
;
5054 else if (cpu_variant
& ARM_EXT_V5
)
5055 mach
= bfd_mach_arm_5
;
5056 else if (cpu_variant
& ARM_THUMB
)
5057 mach
= bfd_mach_arm_4T
;
5058 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5059 mach
= bfd_mach_arm_4
;
5060 else if (cpu_variant
& ARM_LONGMUL
)
5061 mach
= bfd_mach_arm_3M
;
5064 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5067 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5068 for use in the a.out file, and stores them in the array pointed to by buf.
5069 This knows about the endian-ness of the target machine and does
5070 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5071 2 (short) and 4 (long) Floating numbers are put out as a series of
5072 LITTLENUMS (shorts, here at least). */
5074 md_number_to_chars (buf
, val
, n
)
5079 if (target_big_endian
)
5080 number_to_chars_bigendian (buf
, val
, n
);
5082 number_to_chars_littleendian (buf
, val
, n
);
5086 md_chars_to_number (buf
, n
)
5091 unsigned char * where
= (unsigned char *) buf
;
5093 if (target_big_endian
)
5098 result
|= (*where
++ & 255);
5106 result
|= (where
[n
] & 255);
5113 /* Turn a string in input_line_pointer into a floating point constant
5114 of type TYPE, and store the appropriate bytes in *litP. The number
5115 of LITTLENUMS emitted is stored in *sizeP . An error message is
5116 returned, or NULL on OK.
5118 Note that fp constants aren't represent in the normal way on the ARM.
5119 In big endian mode, things are as expected. However, in little endian
5120 mode fp constants are big-endian word-wise, and little-endian byte-wise
5121 within the words. For example, (double) 1.1 in big endian mode is
5122 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5123 the byte sequence 99 99 f1 3f 9a 99 99 99.
5125 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5128 md_atof (type
, litP
, sizeP
)
5134 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5166 return _("Bad call to MD_ATOF()");
5169 t
= atof_ieee (input_line_pointer
, type
, words
);
5171 input_line_pointer
= t
;
5174 if (target_big_endian
)
5176 for (i
= 0; i
< prec
; i
++)
5178 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5184 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5185 8 byte float the order is 1 0 3 2. */
5186 for (i
= 0; i
< prec
; i
+= 2)
5188 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5189 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5197 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5199 md_pcrel_from (fixP
)
5203 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5204 && fixP
->fx_subsy
== NULL
)
5207 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5209 /* PC relative addressing on the Thumb is slightly odd
5210 as the bottom two bits of the PC are forced to zero
5211 for the calculation. */
5212 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5216 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5217 so we un-adjust here to compensate for the accomodation. */
5218 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5220 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5224 /* Round up a section size to the appropriate boundary. */
5226 md_section_align (segment
, size
)
5227 segT segment ATTRIBUTE_UNUSED
;
5233 /* Round all sects to multiple of 4 */
5234 return (size
+ 3) & ~3;
5238 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5239 we have no need to default values of symbols. */
5243 md_undefined_symbol (name
)
5247 if (name
[0] == '_' && name
[1] == 'G'
5248 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5252 if (symbol_find (name
))
5253 as_bad ("GOT already in the symbol table");
5255 GOT_symbol
= symbol_new (name
, undefined_section
,
5256 (valueT
)0, & zero_address_frag
);
5266 /* arm_reg_parse () := if it looks like a register, return its token and
5267 advance the pointer. */
5271 register char ** ccp
;
5273 char * start
= * ccp
;
5276 struct reg_entry
* reg
;
5278 #ifdef REGISTER_PREFIX
5279 if (*start
!= REGISTER_PREFIX
)
5284 #ifdef OPTIONAL_REGISTER_PREFIX
5285 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5289 if (!isalpha (*p
) || !is_name_beginner (*p
))
5293 while (isalpha (c
) || isdigit (c
) || c
== '_')
5297 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5311 register char ** ccp
;
5313 char * start
= * ccp
;
5316 CONST
struct asm_psr
* psr
;
5320 while (isalpha (c
) || c
== '_')
5324 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5337 md_apply_fix3 (fixP
, val
, seg
)
5342 offsetT value
= * val
;
5344 unsigned int newimm
;
5347 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5348 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5350 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5352 /* Note whether this will delete the relocation. */
5353 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5354 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5357 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5361 /* If this symbol is in a different section then we need to leave it for
5362 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5363 so we have to undo it's effects here. */
5366 if (fixP
->fx_addsy
!= NULL
5367 && S_IS_DEFINED (fixP
->fx_addsy
)
5368 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5371 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5372 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5376 value
+= md_pcrel_from (fixP
);
5380 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5382 switch (fixP
->fx_r_type
)
5384 case BFD_RELOC_ARM_IMMEDIATE
:
5385 newimm
= validate_immediate (value
);
5386 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5388 /* If the instruction will fail, see if we can fix things up by
5389 changing the opcode. */
5390 if (newimm
== (unsigned int) FAIL
5391 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5393 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5394 _("invalid constant (%lx) after fixup"),
5395 (unsigned long) value
);
5399 newimm
|= (temp
& 0xfffff000);
5400 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5403 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5405 unsigned int highpart
= 0;
5406 unsigned int newinsn
= 0xe1a00000; /* nop */
5407 newimm
= validate_immediate (value
);
5408 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5410 /* If the instruction will fail, see if we can fix things up by
5411 changing the opcode. */
5412 if (newimm
== (unsigned int) FAIL
5413 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5415 /* No ? OK - try using two ADD instructions to generate the value. */
5416 newimm
= validate_immediate_twopart (value
, & highpart
);
5418 /* Yes - then make sure that the second instruction is also an add. */
5419 if (newimm
!= (unsigned int) FAIL
)
5421 /* Still No ? Try using a negated value. */
5422 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5423 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5424 /* Otherwise - give up. */
5427 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5428 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5432 /* Replace the first operand in the 2nd instruction (which is the PC)
5433 with the destination register. We have already added in the PC in the
5434 first instruction and we do not want to do it again. */
5435 newinsn
&= ~ 0xf0000;
5436 newinsn
|= ((newinsn
& 0x0f000) << 4);
5439 newimm
|= (temp
& 0xfffff000);
5440 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5442 highpart
|= (newinsn
& 0xfffff000);
5443 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5447 case BFD_RELOC_ARM_OFFSET_IMM
:
5453 if (validate_offset_imm (value
, 0) == FAIL
)
5455 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5456 _("bad immediate value for offset (%ld)"), (long) value
);
5460 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5461 newval
&= 0xff7ff000;
5462 newval
|= value
| (sign
? INDEX_UP
: 0);
5463 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5466 case BFD_RELOC_ARM_OFFSET_IMM8
:
5467 case BFD_RELOC_ARM_HWLITERAL
:
5473 if (validate_offset_imm (value
, 1) == FAIL
)
5475 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5476 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5477 _("invalid literal constant: pool needs to be closer"));
5479 as_bad (_("bad immediate value for half-word offset (%ld)"),
5484 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5485 newval
&= 0xff7ff0f0;
5486 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5487 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5490 case BFD_RELOC_ARM_LITERAL
:
5496 if (validate_offset_imm (value
, 0) == FAIL
)
5498 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5499 _("invalid literal constant: pool needs to be closer"));
5503 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5504 newval
&= 0xff7ff000;
5505 newval
|= value
| (sign
? INDEX_UP
: 0);
5506 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5509 case BFD_RELOC_ARM_SHIFT_IMM
:
5510 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5511 if (((unsigned long) value
) > 32
5513 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5515 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5516 _("shift expression is too large"));
5521 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5522 else if (value
== 32)
5524 newval
&= 0xfffff07f;
5525 newval
|= (value
& 0x1f) << 7;
5526 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5529 case BFD_RELOC_ARM_SWI
:
5530 if (arm_data
->thumb_mode
)
5532 if (((unsigned long) value
) > 0xff)
5533 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5534 _("Invalid swi expression"));
5535 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5537 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5541 if (((unsigned long) value
) > 0x00ffffff)
5542 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5543 _("Invalid swi expression"));
5544 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5546 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5550 case BFD_RELOC_ARM_MULTI
:
5551 if (((unsigned long) value
) > 0xffff)
5552 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5553 _("Invalid expression in load/store multiple"));
5554 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5555 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5558 case BFD_RELOC_ARM_PCREL_BRANCH
:
5559 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5561 /* Sign-extend a 24-bit number. */
5562 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5566 value
= fixP
->fx_offset
;
5569 /* We are going to store value (shifted right by two) in the
5570 instruction, in a 24 bit, signed field. Thus we need to check
5571 that none of the top 8 bits of the shifted value (top 7 bits of
5572 the unshifted, unsigned value) are set, or that they are all set. */
5573 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5574 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5577 /* Normally we would be stuck at this point, since we cannot store
5578 the absolute address that is the destination of the branch in the
5579 24 bits of the branch instruction. If however, we happen to know
5580 that the destination of the branch is in the same section as the
5581 branch instruciton itself, then we can compute the relocation for
5582 ourselves and not have to bother the linker with it.
5584 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5585 because I have not worked out how to do this for OBJ_COFF or
5588 && fixP
->fx_addsy
!= NULL
5589 && S_IS_DEFINED (fixP
->fx_addsy
)
5590 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5592 /* Get pc relative value to go into the branch. */
5595 /* Permit a backward branch provided that enough bits are set.
5596 Allow a forwards branch, provided that enough bits are clear. */
5597 if ((value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5598 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5602 if (! fixP
->fx_done
)
5604 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5605 _("gas can't handle same-section branch dest >= 0x04000000"));
5609 value
+= SEXT24 (newval
);
5611 if ((value
& ~ ((offsetT
) 0xffffff)) != 0
5612 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5613 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5614 _("out of range branch"));
5616 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5617 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5620 case BFD_RELOC_ARM_PCREL_BLX
:
5623 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5627 value
= fixP
->fx_offset
;
5629 hbit
= (value
>> 1) & 1;
5630 value
= (value
>> 2) & 0x00ffffff;
5631 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5632 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5633 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5637 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5638 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5640 addressT diff
= (newval
& 0xff) << 1;
5645 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5646 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5647 _("Branch out of range"));
5648 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5650 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5653 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5654 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5656 addressT diff
= (newval
& 0x7ff) << 1;
5661 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5662 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5663 _("Branch out of range"));
5664 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5666 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5669 case BFD_RELOC_THUMB_PCREL_BLX
:
5670 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5675 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5676 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5677 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5678 if (diff
& 0x400000)
5681 value
= fixP
->fx_offset
;
5684 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5685 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5686 _("Branch with link out of range"));
5688 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5689 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5690 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5691 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5696 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5697 md_number_to_chars (buf
, value
, 1);
5699 else if (!target_oabi
)
5701 value
= fixP
->fx_offset
;
5702 md_number_to_chars (buf
, value
, 1);
5708 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5709 md_number_to_chars (buf
, value
, 2);
5711 else if (!target_oabi
)
5713 value
= fixP
->fx_offset
;
5714 md_number_to_chars (buf
, value
, 2);
5720 case BFD_RELOC_ARM_GOT32
:
5721 case BFD_RELOC_ARM_GOTOFF
:
5722 md_number_to_chars (buf
, 0, 4);
5728 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5729 md_number_to_chars (buf
, value
, 4);
5731 else if (!target_oabi
)
5733 value
= fixP
->fx_offset
;
5734 md_number_to_chars (buf
, value
, 4);
5740 case BFD_RELOC_ARM_PLT32
:
5741 /* It appears the instruction is fully prepared at this point. */
5745 case BFD_RELOC_ARM_GOTPC
:
5746 md_number_to_chars (buf
, value
, 4);
5749 case BFD_RELOC_ARM_CP_OFF_IMM
:
5751 if (value
< -1023 || value
> 1023 || (value
& 3))
5752 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5753 _("Illegal value for co-processor offset"));
5756 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5757 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5758 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5761 case BFD_RELOC_ARM_THUMB_OFFSET
:
5762 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5763 /* Exactly what ranges, and where the offset is inserted depends on
5764 the type of instruction, we can establish this from the top 4 bits */
5765 switch (newval
>> 12)
5767 case 4: /* PC load */
5768 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5769 forced to zero for these loads, so we will need to round
5770 up the offset if the instruction address is not word
5771 aligned (since the final address produced must be, and
5772 we can only describe word-aligned immediate offsets). */
5774 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5775 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5776 _("Invalid offset, target not word aligned (0x%08X)"),
5777 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5779 if ((value
+ 2) & ~0x3fe)
5780 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5781 _("Invalid offset, value too big (0x%08X)"), value
);
5783 /* Round up, since pc will be rounded down. */
5784 newval
|= (value
+ 2) >> 2;
5787 case 9: /* SP load/store */
5789 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5790 _("Invalid offset, value too big (0x%08X)"), value
);
5791 newval
|= value
>> 2;
5794 case 6: /* Word load/store */
5796 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5797 _("Invalid offset, value too big (0x%08X)"), value
);
5798 newval
|= value
<< 4; /* 6 - 2 */
5801 case 7: /* Byte load/store */
5803 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5804 _("Invalid offset, value too big (0x%08X)"), value
);
5805 newval
|= value
<< 6;
5808 case 8: /* Halfword load/store */
5810 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5811 _("Invalid offset, value too big (0x%08X)"), value
);
5812 newval
|= value
<< 5; /* 6 - 1 */
5816 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5817 "Unable to process relocation for thumb opcode: %lx",
5818 (unsigned long) newval
);
5821 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5824 case BFD_RELOC_ARM_THUMB_ADD
:
5825 /* This is a complicated relocation, since we use it for all of
5826 the following immediate relocations:
5829 9bit ADD/SUB SP word-aligned
5830 10bit ADD PC/SP word-aligned
5832 The type of instruction being processed is encoded in the
5838 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5840 int rd
= (newval
>> 4) & 0xf;
5841 int rs
= newval
& 0xf;
5842 int subtract
= newval
& 0x8000;
5847 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5848 _("Invalid immediate for stack address calculation"));
5849 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5850 newval
|= value
>> 2;
5852 else if (rs
== REG_PC
|| rs
== REG_SP
)
5856 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5857 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5858 (unsigned long) value
);
5859 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5861 newval
|= value
>> 2;
5866 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5867 _("Invalid 8bit immediate"));
5868 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5869 newval
|= (rd
<< 8) | value
;
5874 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5875 _("Invalid 3bit immediate"));
5876 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5877 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5880 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5883 case BFD_RELOC_ARM_THUMB_IMM
:
5884 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5885 switch (newval
>> 11)
5887 case 0x04: /* 8bit immediate MOV */
5888 case 0x05: /* 8bit immediate CMP */
5889 if (value
< 0 || value
> 255)
5890 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5891 _("Invalid immediate: %ld is too large"),
5899 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5902 case BFD_RELOC_ARM_THUMB_SHIFT
:
5903 /* 5bit shift value (0..31) */
5904 if (value
< 0 || value
> 31)
5905 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5906 _("Illegal Thumb shift value: %ld"), (long) value
);
5907 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5908 newval
|= value
<< 6;
5909 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5912 case BFD_RELOC_VTABLE_INHERIT
:
5913 case BFD_RELOC_VTABLE_ENTRY
:
5917 case BFD_RELOC_NONE
:
5919 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5920 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5926 /* Translate internal representation of relocation info to BFD target
5929 tc_gen_reloc (section
, fixp
)
5930 asection
* section ATTRIBUTE_UNUSED
;
5934 bfd_reloc_code_real_type code
;
5936 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5938 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5939 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5940 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5942 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5944 if (fixp
->fx_pcrel
== 0)
5945 reloc
->addend
= fixp
->fx_offset
;
5947 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5949 reloc
->addend
= fixp
->fx_offset
;
5952 switch (fixp
->fx_r_type
)
5957 code
= BFD_RELOC_8_PCREL
;
5964 code
= BFD_RELOC_16_PCREL
;
5971 code
= BFD_RELOC_32_PCREL
;
5975 case BFD_RELOC_ARM_PCREL_BRANCH
:
5976 case BFD_RELOC_ARM_PCREL_BLX
:
5978 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5979 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5980 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5981 case BFD_RELOC_THUMB_PCREL_BLX
:
5982 case BFD_RELOC_VTABLE_ENTRY
:
5983 case BFD_RELOC_VTABLE_INHERIT
:
5984 code
= fixp
->fx_r_type
;
5987 case BFD_RELOC_ARM_LITERAL
:
5988 case BFD_RELOC_ARM_HWLITERAL
:
5989 /* If this is called then the a literal has been referenced across
5990 a section boundary - possibly due to an implicit dump */
5991 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5992 _("Literal referenced across section boundary (Implicit dump?)"));
5996 case BFD_RELOC_ARM_GOT32
:
5997 case BFD_RELOC_ARM_GOTOFF
:
5998 case BFD_RELOC_ARM_PLT32
:
5999 code
= fixp
->fx_r_type
;
6003 case BFD_RELOC_ARM_IMMEDIATE
:
6004 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6005 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6009 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6010 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6011 _("ADRL used for a symbol not defined in the same file"),
6015 case BFD_RELOC_ARM_OFFSET_IMM
:
6016 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6017 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6024 switch (fixp
->fx_r_type
)
6026 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6027 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6028 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6029 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6030 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6031 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6032 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6033 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6034 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6035 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6036 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6037 default: type
= _("<unknown>"); break;
6039 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6040 _("Can not represent %s relocation in this object file format (%d)"),
6041 type
, fixp
->fx_pcrel
);
6047 if (code
== BFD_RELOC_32_PCREL
6049 && fixp
->fx_addsy
== GOT_symbol
)
6051 code
= BFD_RELOC_ARM_GOTPC
;
6052 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6056 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6058 if (reloc
->howto
== NULL
)
6060 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6061 _("Can not represent %s relocation in this object file format"),
6062 bfd_get_reloc_code_name (code
));
6066 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6067 vtable entry to be used in the relocation's section offset. */
6068 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6069 reloc
->address
= fixp
->fx_offset
;
6075 md_estimate_size_before_relax (fragP
, segtype
)
6076 fragS
* fragP ATTRIBUTE_UNUSED
;
6077 segT segtype ATTRIBUTE_UNUSED
;
6079 as_fatal (_("md_estimate_size_before_relax\n"));
6084 output_inst
PARAMS ((void))
6090 as_bad (inst
.error
);
6094 to
= frag_more (inst
.size
);
6096 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6098 assert (inst
.size
== (2 * THUMB_SIZE
));
6099 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6100 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6102 else if (inst
.size
> INSN_SIZE
)
6104 assert (inst
.size
== (2 * INSN_SIZE
));
6105 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6106 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6109 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6111 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6112 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6113 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6128 /* Align the instruction.
6129 This may not be the right thing to do but ... */
6130 /* arm_align (2, 0); */
6131 listing_prev_line (); /* Defined in listing.h */
6133 /* Align the previous label if needed. */
6134 if (last_label_seen
!= NULL
)
6136 symbol_set_frag (last_label_seen
, frag_now
);
6137 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6138 S_SET_SEGMENT (last_label_seen
, now_seg
);
6141 memset (&inst
, '\0', sizeof (inst
));
6142 inst
.reloc
.type
= BFD_RELOC_NONE
;
6144 skip_whitespace (str
);
6146 /* Scan up to the end of the op-code, which must end in white space or
6148 for (start
= p
= str
; *p
!= '\0'; p
++)
6154 as_bad (_("No operator -- statement `%s'\n"), str
);
6160 CONST
struct thumb_opcode
* opcode
;
6164 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6169 /* Check that this instruction is supported for this CPU. */
6170 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6172 as_bad (_("selected processor does not support this opcode"));
6176 inst
.instruction
= opcode
->value
;
6177 inst
.size
= opcode
->size
;
6178 (*opcode
->parms
)(p
);
6185 CONST
struct asm_opcode
* opcode
;
6186 unsigned long cond_code
;
6188 inst
.size
= INSN_SIZE
;
6189 /* p now points to the end of the opcode, probably white space, but we
6190 have to break the opcode up in case it contains condionals and flags;
6191 keep trying with progressively smaller basic instructions until one
6192 matches, or we run out of opcode. */
6193 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6195 for (; q
!= str
; q
--)
6200 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6203 if (opcode
&& opcode
->template)
6205 unsigned long flag_bits
= 0;
6208 /* Check that this instruction is supported for this CPU. */
6209 if ((opcode
->variants
& cpu_variant
) == 0)
6212 inst
.instruction
= opcode
->value
;
6213 if (q
== p
) /* Just a simple opcode. */
6215 if (opcode
->comp_suffix
)
6217 if (*opcode
->comp_suffix
!= '\0')
6218 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6219 str
, opcode
->comp_suffix
);
6221 /* Not a conditional instruction. */
6222 (*opcode
->parms
)(q
, 0);
6226 /* A conditional instruction with default condition. */
6227 inst
.instruction
|= COND_ALWAYS
;
6228 (*opcode
->parms
)(q
, 0);
6234 /* Not just a simple opcode. Check if extra is a conditional. */
6238 CONST
struct asm_cond
*cond
;
6242 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6246 if (cond
->value
== 0xf0000000)
6248 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6250 cond_code
= cond
->value
;
6254 cond_code
= COND_ALWAYS
;
6257 cond_code
= COND_ALWAYS
;
6259 /* Apply the conditional, or complain it's not allowed. */
6260 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6262 /* Instruction isn't conditional */
6263 if (cond_code
!= COND_ALWAYS
)
6265 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6270 /* Instruction is conditional: set the condition into it. */
6271 inst
.instruction
|= cond_code
;
6274 /* If there is a compulsory suffix, it should come here, before
6275 any optional flags. */
6276 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6278 CONST
char *s
= opcode
->comp_suffix
;
6290 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6291 opcode
->comp_suffix
);
6298 /* The remainder, if any should now be flags for the instruction;
6299 Scan these checking each one found with the opcode. */
6303 CONST
struct asm_flg
*flag
= opcode
->flags
;
6312 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6314 if (streq (r
, flag
[flagno
].template))
6316 flag_bits
|= flag
[flagno
].set_bits
;
6322 if (! flag
[flagno
].template)
6329 (*opcode
->parms
) (p
, flag_bits
);
6339 /* It wasn't an instruction, but it might be a register alias of the form
6342 skip_whitespace (q
);
6347 if (*q
&& !strncmp (q
, ".req ", 4))
6350 char * copy_of_str
= str
;
6354 skip_whitespace (q
);
6356 for (r
= q
; *r
!= '\0'; r
++)
6366 regnum
= arm_reg_parse (& q
);
6369 reg
= arm_reg_parse (& str
);
6374 insert_reg_alias (str
, regnum
);
6376 as_warn (_("register '%s' does not exist\n"), q
);
6378 else if (regnum
!= FAIL
)
6381 as_warn (_("ignoring redefinition of register alias '%s'"),
6384 /* Do not warn about redefinitions to the same alias. */
6387 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6391 as_warn (_("ignoring incomplete .req pseuso op"));
6398 as_bad (_("bad instruction `%s'"), start
);
6403 * Invocation line includes a switch not recognized by the base assembler.
6404 * See if it's a processor-specific option. These are:
6405 * Cpu variants, the arm part is optional:
6406 * -m[arm]1 Currently not supported.
6407 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6408 * -m[arm]3 Arm 3 processor
6409 * -m[arm]6[xx], Arm 6 processors
6410 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6411 * -m[arm]8[10] Arm 8 processors
6412 * -m[arm]9[20][tdmi] Arm 9 processors
6413 * -mstrongarm[110[0]] StrongARM processors
6414 * -m[arm]v[2345] Arm architectures
6415 * -mall All (except the ARM1)
6417 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6418 * -mfpe-old (No float load/store multiples)
6419 * -mno-fpu Disable all floating point instructions
6420 * Run-time endian selection:
6421 * -EB big endian cpu
6422 * -EL little endian cpu
6423 * ARM Procedure Calling Standard:
6424 * -mapcs-32 32 bit APCS
6425 * -mapcs-26 26 bit APCS
6426 * -mapcs-float Pass floats in float regs
6427 * -mapcs-reentrant Position independent code
6428 * -mthumb-interwork Code supports Arm/Thumb interworking
6429 * -moabi Old ELF ABI
6432 CONST
char * md_shortopts
= "m:k";
6433 struct option md_longopts
[] =
6435 #ifdef ARM_BI_ENDIAN
6436 #define OPTION_EB (OPTION_MD_BASE + 0)
6437 {"EB", no_argument
, NULL
, OPTION_EB
},
6438 #define OPTION_EL (OPTION_MD_BASE + 1)
6439 {"EL", no_argument
, NULL
, OPTION_EL
},
6441 #define OPTION_OABI (OPTION_MD_BASE +2)
6442 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6445 {NULL
, no_argument
, NULL
, 0}
6447 size_t md_longopts_size
= sizeof (md_longopts
);
6450 md_parse_option (c
, arg
)
6458 #ifdef ARM_BI_ENDIAN
6460 target_big_endian
= 1;
6463 target_big_endian
= 0;
6471 if (streq (str
, "fpa10"))
6472 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6473 else if (streq (str
, "fpa11"))
6474 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6475 else if (streq (str
, "fpe-old"))
6476 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6482 if (streq (str
, "no-fpu"))
6483 cpu_variant
&= ~FPU_ALL
;
6488 if (streq (str
, "oabi"))
6494 /* Limit assembler to generating only Thumb instructions: */
6495 if (streq (str
, "thumb"))
6497 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6498 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6501 else if (streq (str
, "thumb-interwork"))
6503 if ((cpu_variant
& ARM_THUMB
) == 0)
6504 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6505 #if defined OBJ_COFF || defined OBJ_ELF
6506 support_interwork
= true;
6514 if (streq (str
, "all"))
6516 cpu_variant
= ARM_ALL
| FPU_ALL
;
6519 #if defined OBJ_COFF || defined OBJ_ELF
6520 if (! strncmp (str
, "apcs-", 5))
6522 /* GCC passes on all command line options starting "-mapcs-..."
6523 to us, so we must parse them here. */
6527 if (streq (str
, "32"))
6529 uses_apcs_26
= false;
6532 else if (streq (str
, "26"))
6534 uses_apcs_26
= true;
6537 else if (streq (str
, "frame"))
6539 /* Stack frames are being generated - does not affect
6543 else if (streq (str
, "stack-check"))
6545 /* Stack checking is being performed - does not affect
6546 linkage, but does require that the functions
6547 __rt_stkovf_split_small and __rt_stkovf_split_big be
6548 present in the final link. */
6552 else if (streq (str
, "float"))
6554 /* Floating point arguments are being passed in the floating
6555 point registers. This does affect linking, since this
6556 version of the APCS is incompatible with the version that
6557 passes floating points in the integer registers. */
6559 uses_apcs_float
= true;
6562 else if (streq (str
, "reentrant"))
6564 /* Reentrant code has been generated. This does affect
6565 linking, since there is no point in linking reentrant/
6566 position independent code with absolute position code. */
6571 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6575 /* Strip off optional "arm" */
6576 if (! strncmp (str
, "arm", 3))
6582 if (streq (str
, "1"))
6583 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6589 if (streq (str
, "2"))
6590 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6591 else if (streq (str
, "250"))
6592 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6598 if (streq (str
, "3"))
6599 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6605 switch (strtol (str
, NULL
, 10))
6612 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6620 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6633 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6639 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6643 cpu_variant
|= ARM_LONGMUL
;
6646 case 'f': /* fe => fp enabled cpu. */
6652 case 'c': /* Left over from 710c processor name. */
6653 case 'd': /* Debug */
6654 case 'i': /* Embedded ICE */
6655 /* Included for completeness in ARM processor naming. */
6665 if (streq (str
, "8") || streq (str
, "810"))
6666 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6667 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6673 if (streq (str
, "9"))
6674 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6675 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6676 else if (streq (str
, "920"))
6677 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6678 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6679 else if (streq (str
, "920t"))
6680 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6681 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6682 else if (streq (str
, "9tdmi"))
6683 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6684 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6691 if (streq (str
, "strongarm")
6692 || streq (str
, "strongarm110")
6693 || streq (str
, "strongarm1100"))
6694 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6695 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6701 /* Select variant based on architecture rather than processor. */
6708 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6711 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6714 as_bad (_("Invalid architecture variant -m%s"), arg
);
6720 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6724 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6727 as_bad (_("Invalid architecture variant -m%s"), arg
);
6733 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6737 case 't': cpu_variant
|= ARM_THUMB
; break;
6740 as_bad (_("Invalid architecture variant -m%s"), arg
);
6746 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6749 case 't': cpu_variant
|= ARM_THUMB
; break;
6752 as_bad (_("Invalid architecture variant -m%s"), arg
);
6758 as_bad (_("Invalid architecture variant -m%s"), arg
);
6765 as_bad (_("Invalid processor variant -m%s"), arg
);
6771 #if defined OBJ_ELF || defined OBJ_COFF
6789 ARM Specific Assembler Options:\n\
6790 -m[arm][<processor name>] select processor variant\n\
6791 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6792 -mthumb only allow Thumb instructions\n\
6793 -mthumb-interwork mark the assembled code as supporting interworking\n\
6794 -mall allow any instruction\n\
6795 -mfpa10, -mfpa11 select floating point architecture\n\
6796 -mfpe-old don't allow floating-point multiple instructions\n\
6797 -mno-fpu don't allow any floating-point instructions.\n\
6798 -k generate PIC code.\n"));
6799 #if defined OBJ_COFF || defined OBJ_ELF
6801 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6802 -mapcs-float floating point args are passed in FP regs\n\
6803 -mapcs-reentrant the code is position independent/reentrant\n"));
6807 -moabi support the old ELF ABI\n"));
6809 #ifdef ARM_BI_ENDIAN
6811 -EB assemble code for a big endian cpu\n\
6812 -EL assemble code for a little endian cpu\n"));
6816 /* We need to be able to fix up arbitrary expressions in some statements.
6817 This is so that we can handle symbols that are an arbitrary distance from
6818 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6819 which returns part of an address in a form which will be valid for
6820 a data instruction. We do this by pushing the expression into a symbol
6821 in the expr_section, and creating a fix for that. */
6824 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6833 arm_fix_data
* arm_data
;
6841 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6845 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6850 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6851 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6852 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6853 arm_data
->thumb_mode
= thumb_mode
;
6859 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6861 cons_fix_new_arm (frag
, where
, size
, exp
)
6867 bfd_reloc_code_real_type type
;
6872 * @@ Should look at CPU word size.
6877 type
= BFD_RELOC_16
;
6881 type
= BFD_RELOC_32
;
6884 type
= BFD_RELOC_64
;
6888 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6891 /* A good place to do this, although this was probably not intended
6892 for this kind of use. We need to dump the literal pool before
6893 references are made to a null symbol pointer. */
6897 if (current_poolP
== NULL
)
6900 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6902 listing_prev_line ();
6906 arm_start_line_hook ()
6908 last_label_seen
= NULL
;
6912 arm_frob_label (sym
)
6915 last_label_seen
= sym
;
6917 ARM_SET_THUMB (sym
, thumb_mode
);
6919 #if defined OBJ_COFF || defined OBJ_ELF
6920 ARM_SET_INTERWORK (sym
, support_interwork
);
6923 if (label_is_thumb_function_name
)
6925 /* When the address of a Thumb function is taken the bottom
6926 bit of that address should be set. This will allow
6927 interworking between Arm and Thumb functions to work
6930 THUMB_SET_FUNC (sym
, 1);
6932 label_is_thumb_function_name
= false;
6936 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6940 arm_adjust_symtab ()
6945 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6947 if (ARM_IS_THUMB (sym
))
6949 if (THUMB_IS_FUNC (sym
))
6951 /* Mark the symbol as a Thumb function. */
6952 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6953 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6954 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6956 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6957 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6959 as_bad (_("%s: unexpected function type: %d"),
6960 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6962 else switch (S_GET_STORAGE_CLASS (sym
))
6965 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6968 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6971 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6973 default: /* do nothing */
6978 if (ARM_IS_INTERWORK (sym
))
6979 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6986 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6988 if (ARM_IS_THUMB (sym
))
6990 elf_symbol_type
* elf_sym
;
6992 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6993 bind
= ELF_ST_BIND (elf_sym
);
6995 /* If it's a .thumb_func, declare it as so,
6996 otherwise tag label as .code 16. */
6997 if (THUMB_IS_FUNC (sym
))
6998 elf_sym
->internal_elf_sym
.st_info
=
6999 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7001 elf_sym
->internal_elf_sym
.st_info
=
7002 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7011 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7013 *input_line_pointer
= '/';
7014 input_line_pointer
+= 5;
7015 *input_line_pointer
= 0;
7023 arm_canonicalize_symbol_name (name
)
7028 if (thumb_mode
&& (len
= strlen (name
)) > 5
7029 && streq (name
+ len
- 5, "/data"))
7030 *(name
+ len
- 5) = 0;
7036 arm_validate_fix (fixP
)
7039 /* If the destination of the branch is a defined symbol which does not have
7040 the THUMB_FUNC attribute, then we must be calling a function which has
7041 the (interfacearm) attribute. We look for the Thumb entry point to that
7042 function and change the branch to refer to that function instead. */
7043 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7044 && fixP
->fx_addsy
!= NULL
7045 && S_IS_DEFINED (fixP
->fx_addsy
)
7046 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7048 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7056 /* Relocations against Thumb function names must be left unadjusted,
7057 so that the linker can use this information to correctly set the
7058 bottom bit of their addresses. The MIPS version of this function
7059 also prevents relocations that are mips-16 specific, but I do not
7060 know why it does this.
7063 There is one other problem that ought to be addressed here, but
7064 which currently is not: Taking the address of a label (rather
7065 than a function) and then later jumping to that address. Such
7066 addresses also ought to have their bottom bit set (assuming that
7067 they reside in Thumb code), but at the moment they will not. */
7070 arm_fix_adjustable (fixP
)
7073 if (fixP
->fx_addsy
== NULL
)
7076 /* Prevent all adjustments to global symbols. */
7077 if (S_IS_EXTERN (fixP
->fx_addsy
))
7080 if (S_IS_WEAK (fixP
->fx_addsy
))
7083 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7084 && fixP
->fx_subsy
== NULL
)
7087 /* We need the symbol name for the VTABLE entries */
7088 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7089 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7096 elf32_arm_target_format ()
7098 if (target_big_endian
)
7100 return "elf32-bigarm-oabi";
7102 return "elf32-bigarm";
7105 return "elf32-littlearm-oabi";
7107 return "elf32-littlearm";
7111 armelf_frob_symbol (symp
, puntp
)
7115 elf_frob_symbol (symp
, puntp
);
7119 arm_force_relocation (fixp
)
7122 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7123 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7124 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7125 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7126 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7127 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7133 static bfd_reloc_code_real_type
7143 bfd_reloc_code_real_type reloc
;
7147 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7148 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7149 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7150 /* ScottB: Jan 30, 1998 */
7151 /* Added support for parsing "var(PLT)" branch instructions */
7152 /* generated by GCC for PLT relocs */
7153 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7154 { NULL
, 0, BFD_RELOC_UNUSED
}
7158 for (i
= 0, ip
= input_line_pointer
;
7159 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7161 id
[i
] = tolower (*ip
);
7163 for (i
= 0; reloc_map
[i
].str
; i
++)
7164 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7167 input_line_pointer
+= reloc_map
[i
].len
;
7169 return reloc_map
[i
].reloc
;
7173 s_arm_elf_cons (nbytes
)
7178 #ifdef md_flush_pending_output
7179 md_flush_pending_output ();
7182 if (is_it_end_of_statement ())
7184 demand_empty_rest_of_line ();
7188 #ifdef md_cons_align
7189 md_cons_align (nbytes
);
7194 bfd_reloc_code_real_type reloc
;
7198 if (exp
.X_op
== O_symbol
7199 && * input_line_pointer
== '('
7200 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7202 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7203 int size
= bfd_get_reloc_size (howto
);
7206 as_bad ("%s relocations do not fit in %d bytes",
7207 howto
->name
, nbytes
);
7210 register char * p
= frag_more ((int) nbytes
);
7211 int offset
= nbytes
- size
;
7213 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7218 emit_expr (& exp
, (unsigned int) nbytes
);
7220 while (*input_line_pointer
++ == ',');
7222 input_line_pointer
--; /* Put terminator back into stream. */
7223 demand_empty_rest_of_line ();
7226 #endif /* OBJ_ELF */