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;
388 #define SPSR_BIT (1 << 22) /* The bit that distnguishes CPSR and SPSR. */
389 #define PSR_SHIFT 16 /* How many bits to shift the PSR_xxx bits up by. */
391 #define PSR_c (1 << 0)
392 #define PSR_x (1 << 1)
393 #define PSR_s (1 << 2)
394 #define PSR_f (1 << 3)
396 static CONST
struct asm_psr psrs
[] =
398 {"CPSR", true, PSR_c
| PSR_f
},
399 {"CPSR_all", true, PSR_c
| PSR_f
},
400 {"SPSR", false, PSR_c
| PSR_f
},
401 {"SPSR_all", false, PSR_c
| PSR_f
},
402 {"CPSR_flg", true, PSR_f
},
403 {"CPSR_f", true, PSR_f
},
404 {"SPSR_flg", false, PSR_f
},
405 {"SPSR_f", false, PSR_f
},
406 {"CPSR_c", true, PSR_c
},
407 {"CPSR_ctl", true, PSR_c
},
408 {"SPSR_c", false, PSR_c
},
409 {"SPSR_ctl", false, PSR_c
},
410 {"CPSR_x", true, PSR_x
},
411 {"CPSR_s", true, PSR_s
},
412 {"SPSR_x", false, PSR_x
},
413 {"SPSR_s", false, PSR_s
},
414 /* For backwards compatability with older toolchain we also
415 support lower case versions of some of these flags. */
416 {"cpsr", true, PSR_c
| PSR_f
},
417 {"cpsr_all", true, PSR_c
| PSR_f
},
418 {"spsr", false, PSR_c
| PSR_f
},
419 {"spsr_all", false, PSR_c
| PSR_f
},
420 {"cpsr_flg", true, PSR_f
},
421 {"cpsr_f", true, PSR_f
},
422 {"spsr_flg", false, PSR_f
},
423 {"spsr_f", false, PSR_f
},
424 {"cpsr_c", true, PSR_c
},
425 {"cpsr_ctl", true, PSR_c
},
426 {"spsr_c", false, PSR_c
},
427 {"spsr_ctl", false, PSR_c
}
430 /* Functions called by parser. */
431 /* ARM instructions */
432 static void do_arit
PARAMS ((char *, unsigned long));
433 static void do_cmp
PARAMS ((char *, unsigned long));
434 static void do_mov
PARAMS ((char *, unsigned long));
435 static void do_ldst
PARAMS ((char *, unsigned long));
436 static void do_ldmstm
PARAMS ((char *, unsigned long));
437 static void do_branch
PARAMS ((char *, unsigned long));
438 static void do_swi
PARAMS ((char *, unsigned long));
439 /* Pseudo Op codes */
440 static void do_adr
PARAMS ((char *, unsigned long));
441 static void do_adrl
PARAMS ((char *, unsigned long));
442 static void do_nop
PARAMS ((char *, unsigned long));
444 static void do_mul
PARAMS ((char *, unsigned long));
445 static void do_mla
PARAMS ((char *, unsigned long));
447 static void do_swap
PARAMS ((char *, unsigned long));
449 static void do_msr
PARAMS ((char *, unsigned long));
450 static void do_mrs
PARAMS ((char *, unsigned long));
452 static void do_mull
PARAMS ((char *, unsigned long));
454 static void do_bx
PARAMS ((char *, unsigned long));
457 /* Coprocessor Instructions */
458 static void do_cdp
PARAMS ((char *, unsigned long));
459 static void do_lstc
PARAMS ((char *, unsigned long));
460 static void do_co_reg
PARAMS ((char *, unsigned long));
461 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
462 static void do_fp_ldst
PARAMS ((char *, unsigned long));
463 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
464 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
465 static void do_fp_monadic
PARAMS ((char *, unsigned long));
466 static void do_fp_cmp
PARAMS ((char *, unsigned long));
467 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
468 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
470 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
471 static int arm_reg_parse
PARAMS ((char **));
472 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
473 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
474 static int add_to_lit_pool
PARAMS ((void));
475 static unsigned validate_immediate
PARAMS ((unsigned));
476 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
477 static int validate_offset_imm
PARAMS ((unsigned int, int));
478 static void opcode_select
PARAMS ((int));
479 static void end_of_line
PARAMS ((char *));
480 static int reg_required_here
PARAMS ((char **, int));
481 static int psr_required_here
PARAMS ((char **));
482 static int co_proc_number
PARAMS ((char **));
483 static int cp_opc_expr
PARAMS ((char **, int, int));
484 static int cp_reg_required_here
PARAMS ((char **, int));
485 static int fp_reg_required_here
PARAMS ((char **, int));
486 static int cp_address_offset
PARAMS ((char **));
487 static int cp_address_required_here
PARAMS ((char **));
488 static int my_get_float_expression
PARAMS ((char **));
489 static int skip_past_comma
PARAMS ((char **));
490 static int walk_no_bignums
PARAMS ((symbolS
*));
491 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
492 static int data_op2
PARAMS ((char **));
493 static int fp_op2
PARAMS ((char **));
494 static long reg_list
PARAMS ((char **));
495 static void thumb_load_store
PARAMS ((char *, int, int));
496 static int decode_shift
PARAMS ((char **, int));
497 static int ldst_extend
PARAMS ((char **, int));
498 static void thumb_add_sub
PARAMS ((char *, int));
499 static void insert_reg
PARAMS ((int));
500 static void thumb_shift
PARAMS ((char *, int));
501 static void thumb_mov_compare
PARAMS ((char *, int));
502 static void set_constant_flonums
PARAMS ((void));
503 static valueT md_chars_to_number
PARAMS ((char *, int));
504 static void insert_reg_alias
PARAMS ((char *, int));
505 static void output_inst
PARAMS ((void));
507 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
510 /* ARM instructions take 4bytes in the object file, Thumb instructions
514 /* LONGEST_INST is the longest basic instruction name without conditions or
515 flags. ARM7M has 4 of length 5. */
517 #define LONGEST_INST 5
522 CONST
char * template; /* Basic string to match */
523 unsigned long value
; /* Basic instruction code */
525 /* Compulsory suffix that must follow conds. If "", then the
526 instruction is not conditional and must have no suffix. */
527 CONST
char * comp_suffix
;
529 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
530 unsigned long variants
; /* Which CPU variants this exists for */
531 /* Function to call to parse args */
532 void (* parms
) PARAMS ((char *, unsigned long));
535 static CONST
struct asm_opcode insns
[] =
537 /* ARM Instructions */
538 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
539 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
540 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
541 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
542 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
543 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
544 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
545 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
546 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
547 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
548 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
549 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
550 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
551 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
552 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
553 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
554 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
555 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
556 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
557 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
558 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
560 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
561 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
563 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
564 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
568 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
569 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
570 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
572 /* ARM 2 multiplies */
573 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
574 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
576 /* ARM 3 - swp instructions */
577 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
579 /* ARM 6 Coprocessor instructions */
580 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
581 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
582 /* ScottB: our code uses 0x0128f000 for msr.
583 NickC: but this is wrong because the bits 16 through 19 are
584 handled by the PSR_xxx defines above. */
586 /* ARM 7M long multiplies - need signed/unsigned flags! */
587 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
588 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
589 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
590 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
592 /* ARM THUMB interworking */
593 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
595 /* Floating point instructions */
596 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
597 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
598 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
599 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
600 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
601 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
602 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
603 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
604 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
605 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
607 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
608 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
609 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
610 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
611 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
612 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
613 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
614 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
615 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
616 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
617 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
618 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
619 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
620 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
621 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
622 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
623 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
624 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
625 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
626 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
627 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
628 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
629 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
630 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
631 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
632 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
633 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
634 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
635 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
636 be an optional suffix, but part of the instruction. To be compatible,
638 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
639 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
640 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
641 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
643 /* Generic copressor instructions. */
644 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
645 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
646 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
647 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
648 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
651 /* Defines for various bits that we will want to toggle. */
652 #define INST_IMMEDIATE 0x02000000
653 #define OFFSET_REG 0x02000000
654 #define HWOFFSET_IMM 0x00400000
655 #define SHIFT_BY_REG 0x00000010
656 #define PRE_INDEX 0x01000000
657 #define INDEX_UP 0x00800000
658 #define WRITE_BACK 0x00200000
659 #define LDM_TYPE_2_OR_3 0x00400000
661 #define LITERAL_MASK 0xf000f000
662 #define COND_MASK 0xf0000000
663 #define OPCODE_MASK 0xfe1fffff
664 #define DATA_OP_SHIFT 21
666 /* Codes to distinguish the arithmetic instructions. */
677 #define OPCODE_CMP 10
678 #define OPCODE_CMN 11
679 #define OPCODE_ORR 12
680 #define OPCODE_MOV 13
681 #define OPCODE_BIC 14
682 #define OPCODE_MVN 15
684 static void do_t_nop
PARAMS ((char *));
685 static void do_t_arit
PARAMS ((char *));
686 static void do_t_add
PARAMS ((char *));
687 static void do_t_asr
PARAMS ((char *));
688 static void do_t_branch9
PARAMS ((char *));
689 static void do_t_branch12
PARAMS ((char *));
690 static void do_t_branch23
PARAMS ((char *));
691 static void do_t_bx
PARAMS ((char *));
692 static void do_t_compare
PARAMS ((char *));
693 static void do_t_ldmstm
PARAMS ((char *));
694 static void do_t_ldr
PARAMS ((char *));
695 static void do_t_ldrb
PARAMS ((char *));
696 static void do_t_ldrh
PARAMS ((char *));
697 static void do_t_lds
PARAMS ((char *));
698 static void do_t_lsl
PARAMS ((char *));
699 static void do_t_lsr
PARAMS ((char *));
700 static void do_t_mov
PARAMS ((char *));
701 static void do_t_push_pop
PARAMS ((char *));
702 static void do_t_str
PARAMS ((char *));
703 static void do_t_strb
PARAMS ((char *));
704 static void do_t_strh
PARAMS ((char *));
705 static void do_t_sub
PARAMS ((char *));
706 static void do_t_swi
PARAMS ((char *));
707 static void do_t_adr
PARAMS ((char *));
709 #define T_OPCODE_MUL 0x4340
710 #define T_OPCODE_TST 0x4200
711 #define T_OPCODE_CMN 0x42c0
712 #define T_OPCODE_NEG 0x4240
713 #define T_OPCODE_MVN 0x43c0
715 #define T_OPCODE_ADD_R3 0x1800
716 #define T_OPCODE_SUB_R3 0x1a00
717 #define T_OPCODE_ADD_HI 0x4400
718 #define T_OPCODE_ADD_ST 0xb000
719 #define T_OPCODE_SUB_ST 0xb080
720 #define T_OPCODE_ADD_SP 0xa800
721 #define T_OPCODE_ADD_PC 0xa000
722 #define T_OPCODE_ADD_I8 0x3000
723 #define T_OPCODE_SUB_I8 0x3800
724 #define T_OPCODE_ADD_I3 0x1c00
725 #define T_OPCODE_SUB_I3 0x1e00
727 #define T_OPCODE_ASR_R 0x4100
728 #define T_OPCODE_LSL_R 0x4080
729 #define T_OPCODE_LSR_R 0x40c0
730 #define T_OPCODE_ASR_I 0x1000
731 #define T_OPCODE_LSL_I 0x0000
732 #define T_OPCODE_LSR_I 0x0800
734 #define T_OPCODE_MOV_I8 0x2000
735 #define T_OPCODE_CMP_I8 0x2800
736 #define T_OPCODE_CMP_LR 0x4280
737 #define T_OPCODE_MOV_HR 0x4600
738 #define T_OPCODE_CMP_HR 0x4500
740 #define T_OPCODE_LDR_PC 0x4800
741 #define T_OPCODE_LDR_SP 0x9800
742 #define T_OPCODE_STR_SP 0x9000
743 #define T_OPCODE_LDR_IW 0x6800
744 #define T_OPCODE_STR_IW 0x6000
745 #define T_OPCODE_LDR_IH 0x8800
746 #define T_OPCODE_STR_IH 0x8000
747 #define T_OPCODE_LDR_IB 0x7800
748 #define T_OPCODE_STR_IB 0x7000
749 #define T_OPCODE_LDR_RW 0x5800
750 #define T_OPCODE_STR_RW 0x5000
751 #define T_OPCODE_LDR_RH 0x5a00
752 #define T_OPCODE_STR_RH 0x5200
753 #define T_OPCODE_LDR_RB 0x5c00
754 #define T_OPCODE_STR_RB 0x5400
756 #define T_OPCODE_PUSH 0xb400
757 #define T_OPCODE_POP 0xbc00
759 #define T_OPCODE_BRANCH 0xe7fe
761 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
763 #define THUMB_SIZE 2 /* Size of thumb instruction. */
764 #define THUMB_REG_LO 0x1
765 #define THUMB_REG_HI 0x2
766 #define THUMB_REG_ANY 0x3
768 #define THUMB_H1 0x0080
769 #define THUMB_H2 0x0040
776 #define THUMB_COMPARE 1
779 #define THUMB_STORE 1
781 #define THUMB_PP_PC_LR 0x0100
783 /* These three are used for immediate shifts, do not alter. */
785 #define THUMB_HALFWORD 1
790 CONST
char * template; /* Basic string to match */
791 unsigned long value
; /* Basic instruction code */
793 unsigned long variants
; /* Which CPU variants this exists for */
794 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
797 static CONST
struct thumb_opcode tinsns
[] =
799 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
800 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
801 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
802 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
803 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
804 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
805 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
806 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
807 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
808 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
809 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
810 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
811 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
812 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
813 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
814 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
815 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
816 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
817 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
818 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
819 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
820 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
821 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
822 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
823 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
824 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
825 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
826 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
827 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
828 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
829 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
830 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
831 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
832 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
833 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
834 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
835 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
836 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
837 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
838 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
839 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
840 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
841 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
842 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
843 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
844 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
845 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
846 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
847 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
848 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
849 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
850 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
851 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
852 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
853 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
855 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
856 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
865 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
866 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
867 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
873 /* These are the standard names. Users can add aliases with .req */
874 static CONST
struct reg_entry reg_table
[] =
876 /* Processor Register Numbers. */
877 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
878 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
879 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
880 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
881 /* APCS conventions. */
882 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
883 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
884 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
885 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
886 /* ATPCS additions to APCS conventions. */
887 {"wr", 7}, {"v8", 11},
889 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
890 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
891 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
892 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
893 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
894 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
895 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
896 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
897 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
898 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
899 /* ATPCS additions to float register names. */
900 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
901 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
902 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
903 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
904 /* FIXME: At some point we need to add VFP register names. */
905 /* Array terminator. */
909 #define BAD_ARGS _("Bad arguments to instruction")
910 #define BAD_PC _("r15 not allowed here")
911 #define BAD_FLAGS _("Instruction should not have flags")
912 #define BAD_COND _("Instruction is not conditional")
914 static struct hash_control
* arm_ops_hsh
= NULL
;
915 static struct hash_control
* arm_tops_hsh
= NULL
;
916 static struct hash_control
* arm_cond_hsh
= NULL
;
917 static struct hash_control
* arm_shift_hsh
= NULL
;
918 static struct hash_control
* arm_reg_hsh
= NULL
;
919 static struct hash_control
* arm_psr_hsh
= NULL
;
921 /* This table describes all the machine specific pseudo-ops the assembler
922 has to support. The fields are:
923 pseudo-op name without dot
924 function to call to execute this pseudo-op
925 Integer arg to pass to the function. */
927 static void s_req
PARAMS ((int));
928 static void s_align
PARAMS ((int));
929 static void s_bss
PARAMS ((int));
930 static void s_even
PARAMS ((int));
931 static void s_ltorg
PARAMS ((int));
932 static void s_arm
PARAMS ((int));
933 static void s_thumb
PARAMS ((int));
934 static void s_code
PARAMS ((int));
935 static void s_force_thumb
PARAMS ((int));
936 static void s_thumb_func
PARAMS ((int));
937 static void s_thumb_set
PARAMS ((int));
938 static void arm_s_text
PARAMS ((int));
939 static void arm_s_data
PARAMS ((int));
941 static void arm_s_section
PARAMS ((int));
942 static void s_arm_elf_cons
PARAMS ((int));
945 static int my_get_expression
PARAMS ((expressionS
*, char **));
947 CONST pseudo_typeS md_pseudo_table
[] =
949 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
951 { "align", s_align
, 0 },
953 { "thumb", s_thumb
, 0 },
954 { "code", s_code
, 0 },
955 { "force_thumb", s_force_thumb
, 0 },
956 { "thumb_func", s_thumb_func
, 0 },
957 { "thumb_set", s_thumb_set
, 0 },
958 { "even", s_even
, 0 },
959 { "ltorg", s_ltorg
, 0 },
960 { "pool", s_ltorg
, 0 },
961 /* Allow for the effect of section changes. */
962 { "text", arm_s_text
, 0 },
963 { "data", arm_s_data
, 0 },
965 { "section", arm_s_section
, 0 },
966 { "section.s", arm_s_section
, 0 },
967 { "sect", arm_s_section
, 0 },
968 { "sect.s", arm_s_section
, 0 },
969 { "word", s_arm_elf_cons
, 4 },
970 { "long", s_arm_elf_cons
, 4 },
974 { "extend", float_cons
, 'x' },
975 { "ldouble", float_cons
, 'x' },
976 { "packed", float_cons
, 'p' },
980 /* Stuff needed to resolve the label ambiguity
990 symbolS
* last_label_seen
;
991 static int label_is_thumb_function_name
= false;
995 #define MAX_LITERAL_POOL_SIZE 1024
997 typedef struct literalS
999 struct expressionS exp
;
1000 struct arm_it
* inst
;
1003 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1004 int next_literal_pool_place
= 0; /* Next free entry in the pool */
1005 int lit_pool_num
= 1; /* Next literal pool number */
1006 symbolS
* current_poolP
= NULL
;
1013 if (current_poolP
== NULL
)
1014 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1015 (valueT
) 0, &zero_address_frag
);
1017 /* Check if this literal value is already in the pool: */
1018 while (lit_count
< next_literal_pool_place
)
1020 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1021 && inst
.reloc
.exp
.X_op
== O_constant
1022 && literals
[lit_count
].exp
.X_add_number
1023 == inst
.reloc
.exp
.X_add_number
1024 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1029 if (lit_count
== next_literal_pool_place
) /* new entry */
1031 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1033 inst
.error
= _("Literal Pool Overflow");
1037 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1038 lit_count
= next_literal_pool_place
++;
1041 inst
.reloc
.exp
.X_op
= O_symbol
;
1042 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1043 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1048 /* Can't use symbol_new here, so have to create a symbol and then at
1049 a later date assign it a value. Thats what these functions do. */
1051 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1053 CONST
char * name
; /* It is copied, the caller can modify */
1054 segT segment
; /* Segment identifier (SEG_<something>) */
1055 valueT valu
; /* Symbol value */
1056 fragS
* frag
; /* Associated fragment */
1058 unsigned int name_length
;
1059 char * preserved_copy_of_name
;
1061 name_length
= strlen (name
) + 1; /* +1 for \0 */
1062 obstack_grow (¬es
, name
, name_length
);
1063 preserved_copy_of_name
= obstack_finish (¬es
);
1064 #ifdef STRIP_UNDERSCORE
1065 if (preserved_copy_of_name
[0] == '_')
1066 preserved_copy_of_name
++;
1069 #ifdef tc_canonicalize_symbol_name
1070 preserved_copy_of_name
=
1071 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1074 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1076 S_SET_SEGMENT (symbolP
, segment
);
1077 S_SET_VALUE (symbolP
, valu
);
1078 symbol_clear_list_pointers(symbolP
);
1080 symbol_set_frag (symbolP
, frag
);
1082 /* Link to end of symbol chain. */
1084 extern int symbol_table_frozen
;
1085 if (symbol_table_frozen
)
1089 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1091 obj_symbol_new_hook (symbolP
);
1093 #ifdef tc_symbol_new_hook
1094 tc_symbol_new_hook (symbolP
);
1098 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1099 #endif /* DEBUG_SYMS */
1102 /* Check that an immediate is valid, and if so,
1103 convert it to the right format. */
1105 validate_immediate (val
)
1111 #define rotate_left(v, n) (v << n | v >> (32 - n))
1113 for (i
= 0; i
< 32; i
+= 2)
1114 if ((a
= rotate_left (val
, i
)) <= 0xff)
1115 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1120 /* Check to see if an immediate can be computed as two seperate immediate
1121 values, added together. We already know that this value cannot be
1122 computed by just one ARM instruction. */
1124 validate_immediate_twopart (val
, highpart
)
1126 unsigned int * highpart
;
1131 for (i
= 0; i
< 32; i
+= 2)
1132 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1138 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1140 else if (a
& 0xff0000)
1145 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1149 assert (a
& 0xff000000);
1151 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1154 return (a
& 0xff) | (i
<< 7);
1161 validate_offset_imm (val
, hwse
)
1165 if ((hwse
&& val
> 255) || val
> 4095)
1173 int a ATTRIBUTE_UNUSED
;
1175 as_bad (_("Invalid syntax for .req directive."));
1180 int ignore ATTRIBUTE_UNUSED
;
1182 /* We don't support putting frags in the BSS segment, we fake it by
1183 marking in_bss, then looking at s_skip for clues?.. */
1184 subseg_set (bss_section
, 0);
1185 demand_empty_rest_of_line ();
1190 int ignore ATTRIBUTE_UNUSED
;
1192 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1193 frag_align (1, 0, 0);
1195 record_alignment (now_seg
, 1);
1197 demand_empty_rest_of_line ();
1202 int ignored ATTRIBUTE_UNUSED
;
1207 if (current_poolP
== NULL
)
1210 /* Align pool as you have word accesses */
1211 /* Only make a frag if we have to ... */
1213 frag_align (2, 0, 0);
1215 record_alignment (now_seg
, 2);
1217 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1219 symbol_locate (current_poolP
, sym_name
, now_seg
,
1220 (valueT
) frag_now_fix (), frag_now
);
1221 symbol_table_insert (current_poolP
);
1223 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1225 #if defined OBJ_COFF || defined OBJ_ELF
1226 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1229 while (lit_count
< next_literal_pool_place
)
1230 /* First output the expression in the instruction to the pool. */
1231 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1233 next_literal_pool_place
= 0;
1234 current_poolP
= NULL
;
1238 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1239 int unused ATTRIBUTE_UNUSED
;
1242 register long temp_fill
;
1243 long max_alignment
= 15;
1245 temp
= get_absolute_expression ();
1246 if (temp
> max_alignment
)
1247 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1250 as_bad (_("Alignment negative. 0 assumed."));
1254 if (*input_line_pointer
== ',')
1256 input_line_pointer
++;
1257 temp_fill
= get_absolute_expression ();
1265 /* Only make a frag if we HAVE to. . . */
1266 if (temp
&& !need_pass_2
)
1267 frag_align (temp
, (int) temp_fill
, 0);
1268 demand_empty_rest_of_line ();
1270 record_alignment (now_seg
, temp
);
1274 s_force_thumb (ignore
)
1275 int ignore ATTRIBUTE_UNUSED
;
1277 /* If we are not already in thumb mode go into it, EVEN if
1278 the target processor does not support thumb instructions.
1279 This is used by gcc/config/arm/lib1funcs.asm for example
1280 to compile interworking support functions even if the
1281 target processor should not support interworking. */
1287 record_alignment (now_seg
, 1);
1290 demand_empty_rest_of_line ();
1294 s_thumb_func (ignore
)
1295 int ignore ATTRIBUTE_UNUSED
;
1297 /* The following label is the name/address of the start of a Thumb function.
1298 We need to know this for the interworking support. */
1300 label_is_thumb_function_name
= true;
1302 demand_empty_rest_of_line ();
1305 /* Perform a .set directive, but also mark the alias as
1306 being a thumb function. */
1312 /* XXX the following is a duplicate of the code for s_set() in read.c
1313 We cannot just call that code as we need to get at the symbol that
1315 register char * name
;
1316 register char delim
;
1317 register char * end_name
;
1318 register symbolS
* symbolP
;
1321 * Especial apologies for the random logic:
1322 * this just grew, and could be parsed much more simply!
1325 name
= input_line_pointer
;
1326 delim
= get_symbol_end ();
1327 end_name
= input_line_pointer
;
1332 if (*input_line_pointer
!= ',')
1335 as_bad (_("Expected comma after name \"%s\""), name
);
1337 ignore_rest_of_line ();
1341 input_line_pointer
++;
1344 if (name
[0] == '.' && name
[1] == '\0')
1346 /* XXX - this should not happen to .thumb_set */
1350 if ((symbolP
= symbol_find (name
)) == NULL
1351 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1354 /* When doing symbol listings, play games with dummy fragments living
1355 outside the normal fragment chain to record the file and line info
1357 if (listing
& LISTING_SYMBOLS
)
1359 extern struct list_info_struct
* listing_tail
;
1360 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1361 memset (dummy_frag
, 0, sizeof(fragS
));
1362 dummy_frag
->fr_type
= rs_fill
;
1363 dummy_frag
->line
= listing_tail
;
1364 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1365 dummy_frag
->fr_symbol
= symbolP
;
1369 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1372 /* "set" symbols are local unless otherwise specified. */
1373 SF_SET_LOCAL (symbolP
);
1374 #endif /* OBJ_COFF */
1375 } /* make a new symbol */
1377 symbol_table_insert (symbolP
);
1382 && S_IS_DEFINED (symbolP
)
1383 && S_GET_SEGMENT (symbolP
) != reg_section
)
1384 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1386 pseudo_set (symbolP
);
1388 demand_empty_rest_of_line ();
1390 /* XXX Now we come to the Thumb specific bit of code. */
1392 THUMB_SET_FUNC (symbolP
, 1);
1393 ARM_SET_THUMB (symbolP
, 1);
1394 #if defined OBJ_ELF || defined OBJ_COFF
1395 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1399 /* If we change section we must dump the literal pool first. */
1404 if (now_seg
!= text_section
)
1408 obj_elf_text (ignore
);
1418 if (flag_readonly_data_in_text
)
1420 if (now_seg
!= text_section
)
1423 else if (now_seg
!= data_section
)
1427 obj_elf_data (ignore
);
1435 arm_s_section (ignore
)
1440 obj_elf_section (ignore
);
1445 opcode_select (width
)
1453 if (! (cpu_variant
& ARM_THUMB
))
1454 as_bad (_("selected processor does not support THUMB opcodes"));
1456 /* No need to force the alignment, since we will have been
1457 coming from ARM mode, which is word-aligned. */
1458 record_alignment (now_seg
, 1);
1465 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1466 as_bad (_("selected processor does not support ARM opcodes"));
1469 frag_align (2, 0, 0);
1470 record_alignment (now_seg
, 1);
1475 as_bad (_("invalid instruction size selected (%d)"), width
);
1481 int ignore ATTRIBUTE_UNUSED
;
1484 demand_empty_rest_of_line ();
1489 int ignore ATTRIBUTE_UNUSED
;
1492 demand_empty_rest_of_line ();
1497 int unused ATTRIBUTE_UNUSED
;
1501 temp
= get_absolute_expression ();
1506 opcode_select (temp
);
1510 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1518 skip_whitespace (str
);
1521 inst
.error
= _("Garbage following instruction");
1525 skip_past_comma (str
)
1531 while ((c
= *p
) == ' ' || c
== ',')
1534 if (c
== ',' && comma
++)
1542 return comma
? SUCCESS
: FAIL
;
1545 /* A standard register must be given at this point.
1546 Shift is the place to put it in inst.instruction.
1547 Restores input start point on err.
1548 Returns the reg#, or FAIL. */
1550 reg_required_here (str
, shift
)
1554 static char buff
[128]; /* XXX */
1556 char * start
= *str
;
1558 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1561 inst
.instruction
|= reg
<< shift
;
1565 /* Restore the start point, we may have got a reg of the wrong class. */
1568 /* In the few cases where we might be able to accept something else
1569 this error can be overridden. */
1570 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1576 static CONST
struct asm_psr
*
1578 register char ** ccp
;
1580 char * start
= * ccp
;
1583 CONST
struct asm_psr
* psr
;
1587 /* Skip to the end of the next word in the input stream. */
1592 while (isalpha (c
) || c
== '_');
1594 /* Terminate the word. */
1597 /* Now locate the word in the psr hash table. */
1598 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1600 /* Restore the input stream. */
1603 /* If we found a valid match, advance the
1604 stream pointer past the end of the word. */
1610 /* Parse the input looking for a PSR flag. */
1612 psr_required_here (str
)
1615 char * start
= *str
;
1616 CONST
struct asm_psr
* psr
;
1618 psr
= arm_psr_parse (str
);
1622 /* If this is the SPSR that is being modified, set the R bit. */
1624 inst
.instruction
|= SPSR_BIT
;
1626 /* Set the psr flags in the MSR instruction. */
1627 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1632 /* In the few cases where we might be able to accept
1633 something else this error can be overridden. */
1634 inst
.error
= _("flag for {c}psr instruction expected");
1636 /* Restore the start point. */
1642 co_proc_number (str
)
1645 int processor
, pchar
;
1647 skip_whitespace (* str
);
1649 /* The data sheet seems to imply that just a number on its own is valid
1650 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1652 if (**str
== 'p' || **str
== 'P')
1656 if (pchar
>= '0' && pchar
<= '9')
1658 processor
= pchar
- '0';
1659 if (**str
>= '0' && **str
<= '9')
1661 processor
= processor
* 10 + *(*str
)++ - '0';
1664 inst
.error
= _("Illegal co-processor number");
1671 inst
.error
= _("Bad or missing co-processor number");
1675 inst
.instruction
|= processor
<< 8;
1680 cp_opc_expr (str
, where
, length
)
1687 skip_whitespace (* str
);
1689 memset (&expr
, '\0', sizeof (expr
));
1691 if (my_get_expression (&expr
, str
))
1693 if (expr
.X_op
!= O_constant
)
1695 inst
.error
= _("bad or missing expression");
1699 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1701 inst
.error
= _("immediate co-processor expression too large");
1705 inst
.instruction
|= expr
.X_add_number
<< where
;
1710 cp_reg_required_here (str
, where
)
1715 char * start
= *str
;
1717 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1720 inst
.instruction
|= reg
<< where
;
1724 /* In the few cases where we might be able to accept something else
1725 this error can be overridden. */
1726 inst
.error
= _("Co-processor register expected");
1728 /* Restore the start point. */
1734 fp_reg_required_here (str
, where
)
1739 char * start
= *str
;
1741 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1744 inst
.instruction
|= reg
<< where
;
1748 /* In the few cases where we might be able to accept something else
1749 this error can be overridden. */
1750 inst
.error
= _("Floating point register expected");
1752 /* Restore the start point. */
1758 cp_address_offset (str
)
1763 skip_whitespace (* str
);
1765 if (! is_immediate_prefix (**str
))
1767 inst
.error
= _("immediate expression expected");
1773 if (my_get_expression (& inst
.reloc
.exp
, str
))
1776 if (inst
.reloc
.exp
.X_op
== O_constant
)
1778 offset
= inst
.reloc
.exp
.X_add_number
;
1782 inst
.error
= _("co-processor address must be word aligned");
1786 if (offset
> 1023 || offset
< -1023)
1788 inst
.error
= _("offset too large");
1793 inst
.instruction
|= INDEX_UP
;
1797 inst
.instruction
|= offset
>> 2;
1800 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1806 cp_address_required_here (str
)
1818 skip_whitespace (p
);
1820 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1823 skip_whitespace (p
);
1829 if (skip_past_comma (& p
) == SUCCESS
)
1832 write_back
= WRITE_BACK
;
1836 inst
.error
= _("pc may not be used in post-increment");
1840 if (cp_address_offset (& p
) == FAIL
)
1844 pre_inc
= PRE_INDEX
| INDEX_UP
;
1848 /* '['Rn, #expr']'[!] */
1850 if (skip_past_comma (& p
) == FAIL
)
1852 inst
.error
= _("pre-indexed expression expected");
1856 pre_inc
= PRE_INDEX
;
1858 if (cp_address_offset (& p
) == FAIL
)
1861 skip_whitespace (p
);
1865 inst
.error
= _("missing ]");
1869 skip_whitespace (p
);
1875 inst
.error
= _("pc may not be used with write-back");
1880 write_back
= WRITE_BACK
;
1886 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1889 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1890 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1891 inst
.reloc
.pc_rel
= 1;
1892 inst
.instruction
|= (REG_PC
<< 16);
1893 pre_inc
= PRE_INDEX
;
1896 inst
.instruction
|= write_back
| pre_inc
;
1904 unsigned long flags
;
1906 /* Do nothing really. */
1907 inst
.instruction
|= flags
; /* This is pointless. */
1915 unsigned long flags
;
1919 /* Only one syntax. */
1920 skip_whitespace (str
);
1922 if (reg_required_here (&str
, 12) == FAIL
)
1924 inst
.error
= BAD_ARGS
;
1928 if (skip_past_comma (&str
) == FAIL
)
1930 inst
.error
= _("comma expected after register name");
1934 skip_whitespace (str
);
1936 if ( strcmp (str
, "CPSR") == 0
1937 || strcmp (str
, "SPSR") == 0
1938 /* Lower case versions for backwards compatability. */
1939 || strcmp (str
, "cpsr") == 0
1940 || strcmp (str
, "spsr") == 0)
1942 /* This is for backwards compatability with older toolchains. */
1943 else if (strcmp (str
, "cpsr_all") == 0
1944 || strcmp (str
, "spsr_all") == 0)
1948 inst
.error
= _("{C|S}PSR expected");
1952 if (* str
== 's' || * str
== 'S')
1953 inst
.instruction
|= SPSR_BIT
;
1956 inst
.instruction
|= flags
;
1960 /* Two possible forms:
1961 "{C|S}PSR_<field>, Rm",
1962 "{C|S}PSR_f, #expression". */
1966 unsigned long flags
;
1968 skip_whitespace (str
);
1970 if (psr_required_here (& str
) == FAIL
)
1973 if (skip_past_comma (& str
) == FAIL
)
1975 inst
.error
= _("comma missing after psr flags");
1979 skip_whitespace (str
);
1981 if (reg_required_here (& str
, 0) != FAIL
)
1984 inst
.instruction
|= flags
;
1989 if (! is_immediate_prefix (* str
))
1991 inst
.error
= _("only a register or immediate value can follow a psr flag");
1998 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2000 inst
.error
= _("only a register or immediate value can follow a psr flag");
2004 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2006 inst
.error
= _("can only set flag field with immediate value");
2010 flags
|= INST_IMMEDIATE
;
2012 if (inst
.reloc
.exp
.X_add_symbol
)
2014 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2015 inst
.reloc
.pc_rel
= 0;
2019 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2021 if (value
== (unsigned) FAIL
)
2023 inst
.error
= _("Invalid constant");
2027 inst
.instruction
|= value
;
2031 inst
.instruction
|= flags
;
2035 /* Long Multiply Parser
2036 UMULL RdLo, RdHi, Rm, Rs
2037 SMULL RdLo, RdHi, Rm, Rs
2038 UMLAL RdLo, RdHi, Rm, Rs
2039 SMLAL RdLo, RdHi, Rm, Rs
2042 do_mull (str
, flags
)
2044 unsigned long flags
;
2046 int rdlo
, rdhi
, rm
, rs
;
2048 /* Only one format "rdlo, rdhi, rm, rs" */
2049 skip_whitespace (str
);
2051 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2053 inst
.error
= BAD_ARGS
;
2057 if (skip_past_comma (&str
) == FAIL
2058 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2060 inst
.error
= BAD_ARGS
;
2064 if (skip_past_comma (&str
) == FAIL
2065 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2067 inst
.error
= BAD_ARGS
;
2071 /* rdhi, rdlo and rm must all be different */
2072 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2073 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2075 if (skip_past_comma (&str
) == FAIL
2076 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2078 inst
.error
= BAD_ARGS
;
2082 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2084 inst
.error
= BAD_PC
;
2088 inst
.instruction
|= flags
;
2096 unsigned long flags
;
2100 /* Only one format "rd, rm, rs" */
2101 skip_whitespace (str
);
2103 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2105 inst
.error
= BAD_ARGS
;
2111 inst
.error
= BAD_PC
;
2115 if (skip_past_comma (&str
) == FAIL
2116 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2118 inst
.error
= BAD_ARGS
;
2124 inst
.error
= BAD_PC
;
2129 as_tsktsk (_("rd and rm should be different in mul"));
2131 if (skip_past_comma (&str
) == FAIL
2132 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2134 inst
.error
= BAD_ARGS
;
2140 inst
.error
= BAD_PC
;
2144 inst
.instruction
|= flags
;
2152 unsigned long flags
;
2156 /* Only one format "rd, rm, rs, rn" */
2157 skip_whitespace (str
);
2159 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2161 inst
.error
= BAD_ARGS
;
2167 inst
.error
= BAD_PC
;
2171 if (skip_past_comma (&str
) == FAIL
2172 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2174 inst
.error
= BAD_ARGS
;
2180 inst
.error
= BAD_PC
;
2185 as_tsktsk (_("rd and rm should be different in mla"));
2187 if (skip_past_comma (&str
) == FAIL
2188 || (rd
= reg_required_here (&str
, 8)) == FAIL
2189 || skip_past_comma (&str
) == FAIL
2190 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2192 inst
.error
= BAD_ARGS
;
2196 if (rd
== REG_PC
|| rm
== REG_PC
)
2198 inst
.error
= BAD_PC
;
2202 inst
.instruction
|= flags
;
2207 /* Returns the index into fp_values of a floating point number, or -1 if
2208 not in the table. */
2210 my_get_float_expression (str
)
2213 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2219 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2220 /* Look for a raw floating point number */
2221 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2222 && is_end_of_line
[(unsigned char) *save_in
])
2224 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2226 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2228 if (words
[j
] != fp_values
[i
][j
])
2232 if (j
== MAX_LITTLENUMS
)
2240 /* Try and parse a more complex expression, this will probably fail
2241 unless the code uses a floating point prefix (eg "0f") */
2242 save_in
= input_line_pointer
;
2243 input_line_pointer
= *str
;
2244 if (expression (&exp
) == absolute_section
2245 && exp
.X_op
== O_big
2246 && exp
.X_add_number
< 0)
2248 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2250 if (gen_to_words (words
, 5, (long)15) == 0)
2252 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2254 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2256 if (words
[j
] != fp_values
[i
][j
])
2260 if (j
== MAX_LITTLENUMS
)
2262 *str
= input_line_pointer
;
2263 input_line_pointer
= save_in
;
2270 *str
= input_line_pointer
;
2271 input_line_pointer
= save_in
;
2275 /* Return true if anything in the expression is a bignum */
2277 walk_no_bignums (sp
)
2280 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2283 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2285 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2286 || (symbol_get_value_expression (sp
)->X_op_symbol
2287 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2294 my_get_expression (ep
, str
)
2301 save_in
= input_line_pointer
;
2302 input_line_pointer
= *str
;
2303 seg
= expression (ep
);
2306 if (seg
!= absolute_section
2307 && seg
!= text_section
2308 && seg
!= data_section
2309 && seg
!= bss_section
2310 && seg
!= undefined_section
)
2312 inst
.error
= _("bad_segment");
2313 *str
= input_line_pointer
;
2314 input_line_pointer
= save_in
;
2319 /* Get rid of any bignums now, so that we don't generate an error for which
2320 we can't establish a line number later on. Big numbers are never valid
2321 in instructions, which is where this routine is always called. */
2322 if (ep
->X_op
== O_big
2323 || (ep
->X_add_symbol
2324 && (walk_no_bignums (ep
->X_add_symbol
)
2326 && walk_no_bignums (ep
->X_op_symbol
)))))
2328 inst
.error
= _("Invalid constant");
2329 *str
= input_line_pointer
;
2330 input_line_pointer
= save_in
;
2334 *str
= input_line_pointer
;
2335 input_line_pointer
= save_in
;
2339 /* unrestrict should be one if <shift> <register> is permitted for this
2343 decode_shift (str
, unrestrict
)
2347 struct asm_shift
* shft
;
2351 skip_whitespace (* str
);
2353 for (p
= *str
; isalpha (*p
); p
++)
2358 inst
.error
= _("Shift expression expected");
2364 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2368 if (!strncmp (*str
, "rrx", 3)
2369 || !strncmp (*str
, "RRX", 3))
2372 inst
.instruction
|= shft
->value
;
2376 skip_whitespace (p
);
2378 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2380 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2384 else if (is_immediate_prefix (* p
))
2388 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2391 /* Validate some simple #expressions */
2392 if (inst
.reloc
.exp
.X_op
== O_constant
)
2394 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2396 /* Reject operations greater than 32, or lsl #32 */
2397 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2399 inst
.error
= _("Invalid immediate shift");
2403 /* Shifts of zero should be converted to lsl (which is zero)*/
2410 /* Shifts of 32 are encoded as 0, for those shifts that
2415 inst
.instruction
|= (num
<< 7) | shft
->value
;
2420 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2421 inst
.reloc
.pc_rel
= 0;
2422 inst
.instruction
|= shft
->value
;
2428 inst
.error
= unrestrict
? _("shift requires register or #expression")
2429 : _("shift requires #expression");
2435 inst
.error
= _("Shift expression expected");
2439 /* Do those data_ops which can take a negative immediate constant */
2440 /* by altering the instuction. A bit of a hack really */
2444 by inverting the second operand, and
2447 by negating the second operand.
2450 negate_data_op (instruction
, value
)
2451 unsigned long * instruction
;
2452 unsigned long value
;
2455 unsigned long negated
, inverted
;
2457 negated
= validate_immediate (-value
);
2458 inverted
= validate_immediate (~value
);
2460 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2464 case OPCODE_SUB
: /* ADD <-> SUB */
2465 new_inst
= OPCODE_ADD
;
2470 new_inst
= OPCODE_SUB
;
2474 case OPCODE_CMP
: /* CMP <-> CMN */
2475 new_inst
= OPCODE_CMN
;
2480 new_inst
= OPCODE_CMP
;
2484 /* Now Inverted ops */
2485 case OPCODE_MOV
: /* MOV <-> MVN */
2486 new_inst
= OPCODE_MVN
;
2491 new_inst
= OPCODE_MOV
;
2495 case OPCODE_AND
: /* AND <-> BIC */
2496 new_inst
= OPCODE_BIC
;
2501 new_inst
= OPCODE_AND
;
2505 case OPCODE_ADC
: /* ADC <-> SBC */
2506 new_inst
= OPCODE_SBC
;
2511 new_inst
= OPCODE_ADC
;
2515 /* We cannot do anything */
2520 if (value
== (unsigned) FAIL
)
2523 *instruction
&= OPCODE_MASK
;
2524 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2535 skip_whitespace (* str
);
2537 if (reg_required_here (str
, 0) != FAIL
)
2539 if (skip_past_comma (str
) == SUCCESS
)
2540 /* Shift operation on register. */
2541 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2547 /* Immediate expression */
2548 if (is_immediate_prefix (**str
))
2553 if (my_get_expression (&inst
.reloc
.exp
, str
))
2556 if (inst
.reloc
.exp
.X_add_symbol
)
2558 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2559 inst
.reloc
.pc_rel
= 0;
2563 if (skip_past_comma (str
) == SUCCESS
)
2565 /* #x, y -- ie explicit rotation by Y */
2566 if (my_get_expression (&expr
, str
))
2569 if (expr
.X_op
!= O_constant
)
2571 inst
.error
= _("Constant expression expected");
2575 /* Rotate must be a multiple of 2 */
2576 if (((unsigned) expr
.X_add_number
) > 30
2577 || (expr
.X_add_number
& 1) != 0
2578 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2580 inst
.error
= _("Invalid constant");
2583 inst
.instruction
|= INST_IMMEDIATE
;
2584 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2585 inst
.instruction
|= expr
.X_add_number
<< 7;
2589 /* Implicit rotation, select a suitable one */
2590 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2594 /* Can't be done, perhaps the code reads something like
2595 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2596 if ((value
= negate_data_op (&inst
.instruction
,
2597 inst
.reloc
.exp
.X_add_number
))
2600 inst
.error
= _("Invalid constant");
2605 inst
.instruction
|= value
;
2608 inst
.instruction
|= INST_IMMEDIATE
;
2613 inst
.error
= _("Register or shift expression expected");
2622 skip_whitespace (* str
);
2624 if (fp_reg_required_here (str
, 0) != FAIL
)
2628 /* Immediate expression */
2629 if (*((*str
)++) == '#')
2635 skip_whitespace (* str
);
2637 /* First try and match exact strings, this is to guarantee that
2638 some formats will work even for cross assembly */
2640 for (i
= 0; fp_const
[i
]; i
++)
2642 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2646 *str
+= strlen (fp_const
[i
]);
2647 if (is_end_of_line
[(unsigned char) **str
])
2649 inst
.instruction
|= i
+ 8;
2656 /* Just because we didn't get a match doesn't mean that the
2657 constant isn't valid, just that it is in a format that we
2658 don't automatically recognize. Try parsing it with
2659 the standard expression routines. */
2660 if ((i
= my_get_float_expression (str
)) >= 0)
2662 inst
.instruction
|= i
+ 8;
2666 inst
.error
= _("Invalid floating point immediate expression");
2669 inst
.error
= _("Floating point register or immediate expression expected");
2675 do_arit (str
, flags
)
2677 unsigned long flags
;
2679 skip_whitespace (str
);
2681 if (reg_required_here (&str
, 12) == FAIL
2682 || skip_past_comma (&str
) == FAIL
2683 || reg_required_here (&str
, 16) == FAIL
2684 || skip_past_comma (&str
) == FAIL
2685 || data_op2 (&str
) == FAIL
)
2688 inst
.error
= BAD_ARGS
;
2692 inst
.instruction
|= flags
;
2700 unsigned long flags
;
2702 /* This is a pseudo-op of the form "adr rd, label" to be converted
2703 into a relative address of the form "add rd, pc, #label-.-8". */
2704 skip_whitespace (str
);
2706 if (reg_required_here (&str
, 12) == FAIL
2707 || skip_past_comma (&str
) == FAIL
2708 || my_get_expression (&inst
.reloc
.exp
, &str
))
2711 inst
.error
= BAD_ARGS
;
2715 /* Frag hacking will turn this into a sub instruction if the offset turns
2716 out to be negative. */
2717 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2718 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2719 inst
.reloc
.pc_rel
= 1;
2720 inst
.instruction
|= flags
;
2726 do_adrl (str
, flags
)
2728 unsigned long flags
;
2730 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2731 into a relative address of the form:
2732 add rd, pc, #low(label-.-8)"
2733 add rd, rd, #high(label-.-8)" */
2735 skip_whitespace (str
);
2737 if (reg_required_here (& str
, 12) == FAIL
2738 || skip_past_comma (& str
) == FAIL
2739 || my_get_expression (& inst
.reloc
.exp
, & str
))
2742 inst
.error
= BAD_ARGS
;
2748 /* Frag hacking will turn this into a sub instruction if the offset turns
2749 out to be negative. */
2750 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2751 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2752 inst
.reloc
.pc_rel
= 1;
2753 inst
.instruction
|= flags
;
2754 inst
.size
= INSN_SIZE
* 2;
2762 unsigned long flags
;
2764 skip_whitespace (str
);
2766 if (reg_required_here (&str
, 16) == FAIL
)
2769 inst
.error
= BAD_ARGS
;
2773 if (skip_past_comma (&str
) == FAIL
2774 || data_op2 (&str
) == FAIL
)
2777 inst
.error
= BAD_ARGS
;
2781 inst
.instruction
|= flags
;
2782 if ((flags
& 0x0000f000) == 0)
2783 inst
.instruction
|= CONDS_BIT
;
2792 unsigned long flags
;
2794 skip_whitespace (str
);
2796 if (reg_required_here (&str
, 12) == FAIL
)
2799 inst
.error
= BAD_ARGS
;
2803 if (skip_past_comma (&str
) == FAIL
2804 || data_op2 (&str
) == FAIL
)
2807 inst
.error
= BAD_ARGS
;
2811 inst
.instruction
|= flags
;
2817 ldst_extend (str
, hwse
)
2828 if (my_get_expression (& inst
.reloc
.exp
, str
))
2831 if (inst
.reloc
.exp
.X_op
== O_constant
)
2833 int value
= inst
.reloc
.exp
.X_add_number
;
2835 if ((hwse
&& (value
< -255 || value
> 255))
2836 || (value
< -4095 || value
> 4095))
2838 inst
.error
= _("address offset too large");
2848 /* Halfword and signextension instructions have the
2849 immediate value split across bits 11..8 and bits 3..0 */
2851 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2853 inst
.instruction
|= add
| value
;
2859 inst
.instruction
|= HWOFFSET_IMM
;
2860 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2863 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2864 inst
.reloc
.pc_rel
= 0;
2869 add
= 0; /* and fall through */
2871 (*str
)++; /* and fall through */
2873 if (reg_required_here (str
, 0) == FAIL
)
2877 inst
.instruction
|= add
;
2880 inst
.instruction
|= add
| OFFSET_REG
;
2881 if (skip_past_comma (str
) == SUCCESS
)
2882 return decode_shift (str
, SHIFT_RESTRICT
);
2890 do_ldst (str
, flags
)
2892 unsigned long flags
;
2899 /* This is not ideal, but it is the simplest way of dealing with the
2900 ARM7T halfword instructions (since they use a different
2901 encoding, but the same mnemonic): */
2902 halfword
= (flags
& 0x80000000) != 0;
2905 /* This is actually a load/store of a halfword, or a
2906 signed-extension load */
2907 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2910 = _("Processor does not support halfwords or signed bytes");
2914 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2915 | (flags
& ~COND_MASK
);
2920 skip_whitespace (str
);
2922 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2925 inst
.error
= BAD_ARGS
;
2929 if (skip_past_comma (& str
) == FAIL
)
2931 inst
.error
= _("Address expected");
2941 skip_whitespace (str
);
2943 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2946 /* Conflicts can occur on stores as well as loads. */
2947 conflict_reg
= (conflict_reg
== reg
);
2949 skip_whitespace (str
);
2955 if (skip_past_comma (&str
) == SUCCESS
)
2957 /* [Rn],... (post inc) */
2958 if (ldst_extend (&str
, halfword
) == FAIL
)
2961 as_warn (_("%s register same as write-back base"),
2962 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2968 inst
.instruction
|= HWOFFSET_IMM
;
2970 skip_whitespace (str
);
2975 as_warn (_("%s register same as write-back base"),
2976 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2978 inst
.instruction
|= WRITE_BACK
;
2982 if (! (flags
& TRANS_BIT
))
2989 if (skip_past_comma (&str
) == FAIL
)
2991 inst
.error
= _("pre-indexed expression expected");
2996 if (ldst_extend (&str
, halfword
) == FAIL
)
2999 skip_whitespace (str
);
3003 inst
.error
= _("missing ]");
3007 skip_whitespace (str
);
3012 as_warn (_("%s register same as write-back base"),
3013 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
3015 inst
.instruction
|= WRITE_BACK
;
3019 else if (*str
== '=')
3021 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3024 skip_whitespace (str
);
3026 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3029 if (inst
.reloc
.exp
.X_op
!= O_constant
3030 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3032 inst
.error
= _("Constant expression expected");
3036 if (inst
.reloc
.exp
.X_op
== O_constant
3037 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3039 /* This can be done with a mov instruction */
3040 inst
.instruction
&= LITERAL_MASK
;
3041 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3042 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3048 /* Insert into literal pool */
3049 if (add_to_lit_pool () == FAIL
)
3052 inst
.error
= _("literal pool insertion failed");
3056 /* Change the instruction exp to point to the pool */
3059 inst
.instruction
|= HWOFFSET_IMM
;
3060 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3063 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3064 inst
.reloc
.pc_rel
= 1;
3065 inst
.instruction
|= (REG_PC
<< 16);
3071 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3076 inst
.instruction
|= HWOFFSET_IMM
;
3077 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3080 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3082 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3084 inst
.reloc
.pc_rel
= 1;
3085 inst
.instruction
|= (REG_PC
<< 16);
3089 if (pre_inc
&& (flags
& TRANS_BIT
))
3090 inst
.error
= _("Pre-increment instruction with translate");
3092 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3105 /* We come back here if we get ranges concatenated by '+' or '|' */
3120 skip_whitespace (str
);
3122 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3131 inst
.error
= _("Bad range in register list");
3135 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3137 if (range
& (1 << i
))
3139 (_("Warning: Duplicated register (r%d) in register list"),
3147 if (range
& (1 << reg
))
3148 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3150 else if (reg
<= cur_reg
)
3151 as_tsktsk (_("Warning: Register range not in ascending order"));
3155 } while (skip_past_comma (&str
) != FAIL
3156 || (in_range
= 1, *str
++ == '-'));
3158 skip_whitespace (str
);
3162 inst
.error
= _("Missing `}'");
3170 if (my_get_expression (&expr
, &str
))
3173 if (expr
.X_op
== O_constant
)
3175 if (expr
.X_add_number
3176 != (expr
.X_add_number
& 0x0000ffff))
3178 inst
.error
= _("invalid register mask");
3182 if ((range
& expr
.X_add_number
) != 0)
3184 int regno
= range
& expr
.X_add_number
;
3187 regno
= (1 << regno
) - 1;
3189 (_("Warning: Duplicated register (r%d) in register list"),
3193 range
|= expr
.X_add_number
;
3197 if (inst
.reloc
.type
!= 0)
3199 inst
.error
= _("expression too complex");
3203 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3204 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3205 inst
.reloc
.pc_rel
= 0;
3209 skip_whitespace (str
);
3211 if (*str
== '|' || *str
== '+')
3216 } while (another_range
);
3223 do_ldmstm (str
, flags
)
3225 unsigned long flags
;
3230 skip_whitespace (str
);
3232 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3235 if (base_reg
== REG_PC
)
3237 inst
.error
= _("r15 not allowed as base register");
3241 skip_whitespace (str
);
3245 flags
|= WRITE_BACK
;
3249 if (skip_past_comma (&str
) == FAIL
3250 || (range
= reg_list (&str
)) == FAIL
)
3253 inst
.error
= BAD_ARGS
;
3260 flags
|= LDM_TYPE_2_OR_3
;
3263 inst
.instruction
|= flags
| range
;
3271 unsigned long flags
;
3273 skip_whitespace (str
);
3275 /* Allow optional leading '#'. */
3276 if (is_immediate_prefix (*str
))
3279 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3282 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3283 inst
.reloc
.pc_rel
= 0;
3284 inst
.instruction
|= flags
;
3292 do_swap (str
, flags
)
3294 unsigned long flags
;
3298 skip_whitespace (str
);
3300 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3305 inst
.error
= _("r15 not allowed in swap");
3309 if (skip_past_comma (&str
) == FAIL
3310 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3313 inst
.error
= BAD_ARGS
;
3319 inst
.error
= _("r15 not allowed in swap");
3323 if (skip_past_comma (&str
) == FAIL
3326 inst
.error
= BAD_ARGS
;
3330 skip_whitespace (str
);
3332 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3337 inst
.error
= BAD_PC
;
3341 skip_whitespace (str
);
3345 inst
.error
= _("missing ]");
3349 inst
.instruction
|= flags
;
3355 do_branch (str
, flags
)
3357 unsigned long flags ATTRIBUTE_UNUSED
;
3359 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3366 /* ScottB: February 5, 1998 */
3367 /* Check to see of PLT32 reloc required for the instruction. */
3369 /* arm_parse_reloc() works on input_line_pointer.
3370 We actually want to parse the operands to the branch instruction
3371 passed in 'str'. Save the input pointer and restore it later. */
3372 save_in
= input_line_pointer
;
3373 input_line_pointer
= str
;
3374 if (inst
.reloc
.exp
.X_op
== O_symbol
3376 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3378 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3379 inst
.reloc
.pc_rel
= 0;
3380 /* Modify str to point to after parsed operands, otherwise
3381 end_of_line() will complain about the (PLT) left in str. */
3382 str
= input_line_pointer
;
3386 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3387 inst
.reloc
.pc_rel
= 1;
3389 input_line_pointer
= save_in
;
3392 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3393 inst
.reloc
.pc_rel
= 1;
3394 #endif /* OBJ_ELF */
3403 unsigned long flags ATTRIBUTE_UNUSED
;
3407 skip_whitespace (str
);
3409 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3411 inst
.error
= BAD_ARGS
;
3416 inst
.error
= BAD_PC
;
3424 unsigned long flags ATTRIBUTE_UNUSED
;
3426 /* Co-processor data operation.
3427 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3428 skip_whitespace (str
);
3430 if (co_proc_number (&str
) == FAIL
)
3433 inst
.error
= BAD_ARGS
;
3437 if (skip_past_comma (&str
) == FAIL
3438 || cp_opc_expr (&str
, 20,4) == FAIL
)
3441 inst
.error
= BAD_ARGS
;
3445 if (skip_past_comma (&str
) == FAIL
3446 || cp_reg_required_here (&str
, 12) == FAIL
)
3449 inst
.error
= BAD_ARGS
;
3453 if (skip_past_comma (&str
) == FAIL
3454 || cp_reg_required_here (&str
, 16) == FAIL
)
3457 inst
.error
= BAD_ARGS
;
3461 if (skip_past_comma (&str
) == FAIL
3462 || cp_reg_required_here (&str
, 0) == FAIL
)
3465 inst
.error
= BAD_ARGS
;
3469 if (skip_past_comma (&str
) == SUCCESS
)
3471 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3474 inst
.error
= BAD_ARGS
;
3484 do_lstc (str
, flags
)
3486 unsigned long flags
;
3488 /* Co-processor register load/store.
3489 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3491 skip_whitespace (str
);
3493 if (co_proc_number (&str
) == FAIL
)
3496 inst
.error
= BAD_ARGS
;
3500 if (skip_past_comma (&str
) == FAIL
3501 || cp_reg_required_here (&str
, 12) == FAIL
)
3504 inst
.error
= BAD_ARGS
;
3508 if (skip_past_comma (&str
) == FAIL
3509 || cp_address_required_here (&str
) == FAIL
)
3512 inst
.error
= BAD_ARGS
;
3516 inst
.instruction
|= flags
;
3522 do_co_reg (str
, flags
)
3524 unsigned long flags
;
3526 /* Co-processor register transfer.
3527 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3529 skip_whitespace (str
);
3531 if (co_proc_number (&str
) == FAIL
)
3534 inst
.error
= BAD_ARGS
;
3538 if (skip_past_comma (&str
) == FAIL
3539 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3542 inst
.error
= BAD_ARGS
;
3546 if (skip_past_comma (&str
) == FAIL
3547 || reg_required_here (&str
, 12) == FAIL
)
3550 inst
.error
= BAD_ARGS
;
3554 if (skip_past_comma (&str
) == FAIL
3555 || cp_reg_required_here (&str
, 16) == FAIL
)
3558 inst
.error
= BAD_ARGS
;
3562 if (skip_past_comma (&str
) == FAIL
3563 || cp_reg_required_here (&str
, 0) == FAIL
)
3566 inst
.error
= BAD_ARGS
;
3570 if (skip_past_comma (&str
) == SUCCESS
)
3572 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3575 inst
.error
= BAD_ARGS
;
3581 inst
.error
= BAD_COND
;
3589 do_fp_ctrl (str
, flags
)
3591 unsigned long flags ATTRIBUTE_UNUSED
;
3593 /* FP control registers.
3594 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3596 skip_whitespace (str
);
3598 if (reg_required_here (&str
, 12) == FAIL
)
3601 inst
.error
= BAD_ARGS
;
3610 do_fp_ldst (str
, flags
)
3612 unsigned long flags ATTRIBUTE_UNUSED
;
3614 skip_whitespace (str
);
3616 switch (inst
.suffix
)
3621 inst
.instruction
|= CP_T_X
;
3624 inst
.instruction
|= CP_T_Y
;
3627 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3633 if (fp_reg_required_here (&str
, 12) == FAIL
)
3636 inst
.error
= BAD_ARGS
;
3640 if (skip_past_comma (&str
) == FAIL
3641 || cp_address_required_here (&str
) == FAIL
)
3644 inst
.error
= BAD_ARGS
;
3652 do_fp_ldmstm (str
, flags
)
3654 unsigned long flags
;
3658 skip_whitespace (str
);
3660 if (fp_reg_required_here (&str
, 12) == FAIL
)
3663 inst
.error
= BAD_ARGS
;
3667 /* Get Number of registers to transfer */
3668 if (skip_past_comma (&str
) == FAIL
3669 || my_get_expression (&inst
.reloc
.exp
, &str
))
3672 inst
.error
= _("constant expression expected");
3676 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3678 inst
.error
= _("Constant value required for number of registers");
3682 num_regs
= inst
.reloc
.exp
.X_add_number
;
3684 if (num_regs
< 1 || num_regs
> 4)
3686 inst
.error
= _("number of registers must be in the range [1:4]");
3693 inst
.instruction
|= CP_T_X
;
3696 inst
.instruction
|= CP_T_Y
;
3699 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3713 /* The instruction specified "ea" or "fd", so we can only accept
3714 [Rn]{!}. The instruction does not really support stacking or
3715 unstacking, so we have to emulate these by setting appropriate
3716 bits and offsets. */
3717 if (skip_past_comma (&str
) == FAIL
3721 inst
.error
= BAD_ARGS
;
3726 skip_whitespace (str
);
3728 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3731 skip_whitespace (str
);
3735 inst
.error
= BAD_ARGS
;
3746 inst
.error
= _("R15 not allowed as base register with write-back");
3753 if (flags
& CP_T_Pre
)
3756 offset
= 3 * num_regs
;
3762 /* Post-increment */
3766 offset
= 3 * num_regs
;
3770 /* No write-back, so convert this into a standard pre-increment
3771 instruction -- aesthetically more pleasing. */
3772 flags
= CP_T_Pre
| CP_T_UD
;
3777 inst
.instruction
|= flags
| offset
;
3779 else if (skip_past_comma (&str
) == FAIL
3780 || cp_address_required_here (&str
) == FAIL
)
3783 inst
.error
= BAD_ARGS
;
3791 do_fp_dyadic (str
, flags
)
3793 unsigned long flags
;
3795 skip_whitespace (str
);
3797 switch (inst
.suffix
)
3802 inst
.instruction
|= 0x00000080;
3805 inst
.instruction
|= 0x00080000;
3811 if (fp_reg_required_here (&str
, 12) == FAIL
)
3814 inst
.error
= BAD_ARGS
;
3818 if (skip_past_comma (&str
) == FAIL
3819 || fp_reg_required_here (&str
, 16) == FAIL
)
3822 inst
.error
= BAD_ARGS
;
3826 if (skip_past_comma (&str
) == FAIL
3827 || fp_op2 (&str
) == FAIL
)
3830 inst
.error
= BAD_ARGS
;
3834 inst
.instruction
|= flags
;
3840 do_fp_monadic (str
, flags
)
3842 unsigned long flags
;
3844 skip_whitespace (str
);
3846 switch (inst
.suffix
)
3851 inst
.instruction
|= 0x00000080;
3854 inst
.instruction
|= 0x00080000;
3860 if (fp_reg_required_here (&str
, 12) == FAIL
)
3863 inst
.error
= BAD_ARGS
;
3867 if (skip_past_comma (&str
) == FAIL
3868 || fp_op2 (&str
) == FAIL
)
3871 inst
.error
= BAD_ARGS
;
3875 inst
.instruction
|= flags
;
3881 do_fp_cmp (str
, flags
)
3883 unsigned long flags
;
3885 skip_whitespace (str
);
3887 if (fp_reg_required_here (&str
, 16) == FAIL
)
3890 inst
.error
= BAD_ARGS
;
3894 if (skip_past_comma (&str
) == FAIL
3895 || fp_op2 (&str
) == FAIL
)
3898 inst
.error
= BAD_ARGS
;
3902 inst
.instruction
|= flags
;
3908 do_fp_from_reg (str
, flags
)
3910 unsigned long flags
;
3912 skip_whitespace (str
);
3914 switch (inst
.suffix
)
3919 inst
.instruction
|= 0x00000080;
3922 inst
.instruction
|= 0x00080000;
3928 if (fp_reg_required_here (&str
, 16) == FAIL
)
3931 inst
.error
= BAD_ARGS
;
3935 if (skip_past_comma (&str
) == FAIL
3936 || reg_required_here (&str
, 12) == FAIL
)
3939 inst
.error
= BAD_ARGS
;
3943 inst
.instruction
|= flags
;
3949 do_fp_to_reg (str
, flags
)
3951 unsigned long flags
;
3953 skip_whitespace (str
);
3955 if (reg_required_here (&str
, 12) == FAIL
)
3958 if (skip_past_comma (&str
) == FAIL
3959 || fp_reg_required_here (&str
, 0) == FAIL
)
3962 inst
.error
= BAD_ARGS
;
3966 inst
.instruction
|= flags
;
3971 /* Thumb specific routines */
3973 /* Parse and validate that a register is of the right form, this saves
3974 repeated checking of this information in many similar cases.
3975 Unlike the 32-bit case we do not insert the register into the opcode
3976 here, since the position is often unknown until the full instruction
3979 thumb_reg (strp
, hi_lo
)
3985 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3993 inst
.error
= _("lo register required");
4001 inst
.error
= _("hi register required");
4013 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4016 thumb_add_sub (str
, subtract
)
4020 int Rd
, Rs
, Rn
= FAIL
;
4022 skip_whitespace (str
);
4024 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4025 || skip_past_comma (&str
) == FAIL
)
4028 inst
.error
= BAD_ARGS
;
4032 if (is_immediate_prefix (*str
))
4036 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4041 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4044 if (skip_past_comma (&str
) == FAIL
)
4046 /* Two operand format, shuffle the registers and pretend there
4051 else if (is_immediate_prefix (*str
))
4054 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4057 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4061 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4062 for the latter case, EXPR contains the immediate that was found. */
4065 /* All register format. */
4066 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4070 inst
.error
= _("dest and source1 must be the same register");
4074 /* Can't do this for SUB */
4077 inst
.error
= _("subtract valid only on lo regs");
4081 inst
.instruction
= (T_OPCODE_ADD_HI
4082 | (Rd
> 7 ? THUMB_H1
: 0)
4083 | (Rn
> 7 ? THUMB_H2
: 0));
4084 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4088 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4089 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4094 /* Immediate expression, now things start to get nasty. */
4096 /* First deal with HI regs, only very restricted cases allowed:
4097 Adjusting SP, and using PC or SP to get an address. */
4098 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4099 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4101 inst
.error
= _("invalid Hi register with immediate");
4105 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4107 /* Value isn't known yet, all we can do is store all the fragments
4108 we know about in the instruction and let the reloc hacking
4110 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4111 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4115 int offset
= inst
.reloc
.exp
.X_add_number
;
4125 /* Quick check, in case offset is MIN_INT */
4128 inst
.error
= _("immediate value out of range");
4137 if (offset
& ~0x1fc)
4139 inst
.error
= _("invalid immediate value for stack adjust");
4142 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4143 inst
.instruction
|= offset
>> 2;
4145 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4148 || (offset
& ~0x3fc))
4150 inst
.error
= _("invalid immediate for address calculation");
4153 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4155 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4161 inst
.error
= _("immediate value out of range");
4164 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4165 inst
.instruction
|= (Rd
<< 8) | offset
;
4171 inst
.error
= _("immediate value out of range");
4174 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4175 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4184 thumb_shift (str
, shift
)
4188 int Rd
, Rs
, Rn
= FAIL
;
4190 skip_whitespace (str
);
4192 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4193 || skip_past_comma (&str
) == FAIL
)
4196 inst
.error
= BAD_ARGS
;
4200 if (is_immediate_prefix (*str
))
4202 /* Two operand immediate format, set Rs to Rd. */
4205 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4210 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4213 if (skip_past_comma (&str
) == FAIL
)
4215 /* Two operand format, shuffle the registers and pretend there
4220 else if (is_immediate_prefix (*str
))
4223 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4226 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4230 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4231 for the latter case, EXPR contains the immediate that was found. */
4237 inst
.error
= _("source1 and dest must be same register");
4243 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4244 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4245 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4248 inst
.instruction
|= Rd
| (Rn
<< 3);
4254 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4255 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4256 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4259 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4261 /* Value isn't known yet, create a dummy reloc and let reloc
4262 hacking fix it up */
4264 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4268 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4270 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4272 inst
.error
= _("Invalid immediate for shift");
4276 /* Shifts of zero are handled by converting to LSL */
4277 if (shift_value
== 0)
4278 inst
.instruction
= T_OPCODE_LSL_I
;
4280 /* Shifts of 32 are encoded as a shift of zero */
4281 if (shift_value
== 32)
4284 inst
.instruction
|= shift_value
<< 6;
4287 inst
.instruction
|= Rd
| (Rs
<< 3);
4294 thumb_mov_compare (str
, move
)
4300 skip_whitespace (str
);
4302 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4303 || skip_past_comma (&str
) == FAIL
)
4306 inst
.error
= BAD_ARGS
;
4310 if (is_immediate_prefix (*str
))
4313 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4316 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4321 if (Rs
< 8 && Rd
< 8)
4323 if (move
== THUMB_MOVE
)
4324 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4325 since a MOV instruction produces unpredictable results */
4326 inst
.instruction
= T_OPCODE_ADD_I3
;
4328 inst
.instruction
= T_OPCODE_CMP_LR
;
4329 inst
.instruction
|= Rd
| (Rs
<< 3);
4333 if (move
== THUMB_MOVE
)
4334 inst
.instruction
= T_OPCODE_MOV_HR
;
4336 inst
.instruction
= T_OPCODE_CMP_HR
;
4339 inst
.instruction
|= THUMB_H1
;
4342 inst
.instruction
|= THUMB_H2
;
4344 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4351 inst
.error
= _("only lo regs allowed with immediate");
4355 if (move
== THUMB_MOVE
)
4356 inst
.instruction
= T_OPCODE_MOV_I8
;
4358 inst
.instruction
= T_OPCODE_CMP_I8
;
4360 inst
.instruction
|= Rd
<< 8;
4362 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4363 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4366 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4370 inst
.error
= _("invalid immediate");
4374 inst
.instruction
|= value
;
4382 thumb_load_store (str
, load_store
, size
)
4387 int Rd
, Rb
, Ro
= FAIL
;
4389 skip_whitespace (str
);
4391 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4392 || skip_past_comma (&str
) == FAIL
)
4395 inst
.error
= BAD_ARGS
;
4402 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4405 if (skip_past_comma (&str
) != FAIL
)
4407 if (is_immediate_prefix (*str
))
4410 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4413 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4418 inst
.reloc
.exp
.X_op
= O_constant
;
4419 inst
.reloc
.exp
.X_add_number
= 0;
4424 inst
.error
= _("expected ']'");
4429 else if (*str
== '=')
4431 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4434 skip_whitespace (str
);
4436 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4441 if ( inst
.reloc
.exp
.X_op
!= O_constant
4442 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4444 inst
.error
= "Constant expression expected";
4448 if (inst
.reloc
.exp
.X_op
== O_constant
4449 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4451 /* This can be done with a mov instruction */
4453 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4454 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4458 /* Insert into literal pool */
4459 if (add_to_lit_pool () == FAIL
)
4462 inst
.error
= "literal pool insertion failed";
4466 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4467 inst
.reloc
.pc_rel
= 1;
4468 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4469 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4475 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4478 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4479 inst
.reloc
.pc_rel
= 1;
4480 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4481 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4486 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4488 if (size
!= THUMB_WORD
)
4490 inst
.error
= _("byte or halfword not valid for base register");
4493 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4495 inst
.error
= _("R15 based store not allowed");
4498 else if (Ro
!= FAIL
)
4500 inst
.error
= _("Invalid base register for register offset");
4505 inst
.instruction
= T_OPCODE_LDR_PC
;
4506 else if (load_store
== THUMB_LOAD
)
4507 inst
.instruction
= T_OPCODE_LDR_SP
;
4509 inst
.instruction
= T_OPCODE_STR_SP
;
4511 inst
.instruction
|= Rd
<< 8;
4512 if (inst
.reloc
.exp
.X_op
== O_constant
)
4514 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4516 if (offset
& ~0x3fc)
4518 inst
.error
= _("invalid offset");
4522 inst
.instruction
|= offset
>> 2;
4525 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4529 inst
.error
= _("invalid base register in load/store");
4532 else if (Ro
== FAIL
)
4534 /* Immediate offset */
4535 if (size
== THUMB_WORD
)
4536 inst
.instruction
= (load_store
== THUMB_LOAD
4537 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4538 else if (size
== THUMB_HALFWORD
)
4539 inst
.instruction
= (load_store
== THUMB_LOAD
4540 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4542 inst
.instruction
= (load_store
== THUMB_LOAD
4543 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4545 inst
.instruction
|= Rd
| (Rb
<< 3);
4547 if (inst
.reloc
.exp
.X_op
== O_constant
)
4549 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4551 if (offset
& ~(0x1f << size
))
4553 inst
.error
= _("Invalid offset");
4556 inst
.instruction
|= (offset
>> size
) << 6;
4559 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4563 /* Register offset */
4564 if (size
== THUMB_WORD
)
4565 inst
.instruction
= (load_store
== THUMB_LOAD
4566 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4567 else if (size
== THUMB_HALFWORD
)
4568 inst
.instruction
= (load_store
== THUMB_LOAD
4569 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4571 inst
.instruction
= (load_store
== THUMB_LOAD
4572 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4574 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4589 /* Handle the Format 4 instructions that do not have equivalents in other
4590 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4598 skip_whitespace (str
);
4600 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4601 || skip_past_comma (&str
) == FAIL
4602 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4604 inst
.error
= BAD_ARGS
;
4608 if (skip_past_comma (&str
) != FAIL
)
4610 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4611 (It isn't allowed for CMP either, but that isn't handled by this
4613 if (inst
.instruction
== T_OPCODE_TST
4614 || inst
.instruction
== T_OPCODE_CMN
4615 || inst
.instruction
== T_OPCODE_NEG
4616 || inst
.instruction
== T_OPCODE_MVN
)
4618 inst
.error
= BAD_ARGS
;
4622 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4627 inst
.error
= _("dest and source1 one must be the same register");
4633 if (inst
.instruction
== T_OPCODE_MUL
4635 as_tsktsk (_("Rs and Rd must be different in MUL"));
4637 inst
.instruction
|= Rd
| (Rs
<< 3);
4645 thumb_add_sub (str
, 0);
4652 thumb_shift (str
, THUMB_ASR
);
4659 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4661 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4662 inst
.reloc
.pc_rel
= 1;
4670 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4672 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4673 inst
.reloc
.pc_rel
= 1;
4677 /* Find the real, Thumb encoded start of a Thumb function. */
4680 find_real_start (symbolP
)
4684 const char * name
= S_GET_NAME (symbolP
);
4685 symbolS
* new_target
;
4687 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4688 #define STUB_NAME ".real_start_of"
4693 /* Names that start with '.' are local labels, not function entry points.
4694 The compiler may generate BL instructions to these labels because it
4695 needs to perform a branch to a far away location. */
4699 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4700 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4702 new_target
= symbol_find (real_start
);
4704 if (new_target
== NULL
)
4706 as_warn ("Failed to find real start of function: %s\n", name
);
4707 new_target
= symbolP
;
4720 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4723 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4724 inst
.reloc
.pc_rel
= 1;
4727 /* If the destination of the branch is a defined symbol which does not have
4728 the THUMB_FUNC attribute, then we must be calling a function which has
4729 the (interfacearm) attribute. We look for the Thumb entry point to that
4730 function and change the branch to refer to that function instead. */
4731 if ( inst
.reloc
.exp
.X_op
== O_symbol
4732 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4733 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4734 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4735 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4744 skip_whitespace (str
);
4746 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4749 /* This sets THUMB_H2 from the top bit of reg. */
4750 inst
.instruction
|= reg
<< 3;
4752 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4753 should cause the alignment to be checked once it is known. This is
4754 because BX PC only works if the instruction is word aligned. */
4763 thumb_mov_compare (str
, THUMB_COMPARE
);
4773 skip_whitespace (str
);
4775 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4779 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4783 if (skip_past_comma (&str
) == FAIL
4784 || (range
= reg_list (&str
)) == FAIL
)
4787 inst
.error
= BAD_ARGS
;
4791 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4793 /* This really doesn't seem worth it. */
4794 inst
.reloc
.type
= BFD_RELOC_NONE
;
4795 inst
.error
= _("Expression too complex");
4801 inst
.error
= _("only lo-regs valid in load/store multiple");
4805 inst
.instruction
|= (Rb
<< 8) | range
;
4813 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4820 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4827 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4836 skip_whitespace (str
);
4838 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4839 || skip_past_comma (&str
) == FAIL
4841 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4842 || skip_past_comma (&str
) == FAIL
4843 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4847 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4851 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4859 thumb_shift (str
, THUMB_LSL
);
4866 thumb_shift (str
, THUMB_LSR
);
4873 thumb_mov_compare (str
, THUMB_MOVE
);
4882 skip_whitespace (str
);
4884 if ((range
= reg_list (&str
)) == FAIL
)
4887 inst
.error
= BAD_ARGS
;
4891 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4893 /* This really doesn't seem worth it. */
4894 inst
.reloc
.type
= BFD_RELOC_NONE
;
4895 inst
.error
= _("Expression too complex");
4901 if ((inst
.instruction
== T_OPCODE_PUSH
4902 && (range
& ~0xff) == 1 << REG_LR
)
4903 || (inst
.instruction
== T_OPCODE_POP
4904 && (range
& ~0xff) == 1 << REG_PC
))
4906 inst
.instruction
|= THUMB_PP_PC_LR
;
4911 inst
.error
= _("invalid register list to push/pop instruction");
4916 inst
.instruction
|= range
;
4924 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4931 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4938 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4945 thumb_add_sub (str
, 1);
4952 skip_whitespace (str
);
4954 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4957 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4968 /* This is a pseudo-op of the form "adr rd, label" to be converted
4969 into a relative address of the form "add rd, pc, #label-.-4". */
4970 skip_whitespace (str
);
4972 /* Store Rd in temporary location inside instruction. */
4973 if ((reg
= reg_required_here (&str
, 4)) == FAIL
4974 || (reg
> 7) /* For Thumb reg must be r0..r7. */
4975 || skip_past_comma (&str
) == FAIL
4976 || my_get_expression (&inst
.reloc
.exp
, &str
))
4979 inst
.error
= BAD_ARGS
;
4983 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4984 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
4985 inst
.reloc
.pc_rel
= 1;
4986 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
4995 int len
= strlen (reg_table
[entry
].name
) + 2;
4996 char * buf
= (char *) xmalloc (len
);
4997 char * buf2
= (char *) xmalloc (len
);
5000 #ifdef REGISTER_PREFIX
5001 buf
[i
++] = REGISTER_PREFIX
;
5004 strcpy (buf
+ i
, reg_table
[entry
].name
);
5006 for (i
= 0; buf
[i
]; i
++)
5007 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5011 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
5012 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
5016 insert_reg_alias (str
, regnum
)
5020 struct reg_entry
*new =
5021 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
5022 char *name
= xmalloc (strlen (str
) + 1);
5026 new->number
= regnum
;
5028 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5032 set_constant_flonums ()
5036 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5037 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5047 if ( (arm_ops_hsh
= hash_new ()) == NULL
5048 || (arm_tops_hsh
= hash_new ()) == NULL
5049 || (arm_cond_hsh
= hash_new ()) == NULL
5050 || (arm_shift_hsh
= hash_new ()) == NULL
5051 || (arm_reg_hsh
= hash_new ()) == NULL
5052 || (arm_psr_hsh
= hash_new ()) == NULL
)
5053 as_fatal (_("Virtual memory exhausted"));
5055 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5056 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5057 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5058 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5059 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5060 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5061 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
5062 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
5063 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5064 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5066 for (i
= 0; reg_table
[i
].name
; i
++)
5069 set_constant_flonums ();
5071 #if defined OBJ_COFF || defined OBJ_ELF
5073 unsigned int flags
= 0;
5075 /* Set the flags in the private structure. */
5076 if (uses_apcs_26
) flags
|= F_APCS26
;
5077 if (support_interwork
) flags
|= F_INTERWORK
;
5078 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5079 if (pic_code
) flags
|= F_PIC
;
5080 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5082 bfd_set_private_flags (stdoutput
, flags
);
5086 /* Record the CPU type as well. */
5087 switch (cpu_variant
& ARM_CPU_MASK
)
5090 mach
= bfd_mach_arm_2
;
5093 case ARM_3
: /* Also ARM_250. */
5094 mach
= bfd_mach_arm_2a
;
5098 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5099 mach
= bfd_mach_arm_4
;
5102 case ARM_7
: /* Also ARM_6. */
5103 mach
= bfd_mach_arm_3
;
5107 /* Catch special cases. */
5108 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5110 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5111 mach
= bfd_mach_arm_5T
;
5112 else if (cpu_variant
& ARM_EXT_V5
)
5113 mach
= bfd_mach_arm_5
;
5114 else if (cpu_variant
& ARM_THUMB
)
5115 mach
= bfd_mach_arm_4T
;
5116 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5117 mach
= bfd_mach_arm_4
;
5118 else if (cpu_variant
& ARM_LONGMUL
)
5119 mach
= bfd_mach_arm_3M
;
5122 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5125 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5126 for use in the a.out file, and stores them in the array pointed to by buf.
5127 This knows about the endian-ness of the target machine and does
5128 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5129 2 (short) and 4 (long) Floating numbers are put out as a series of
5130 LITTLENUMS (shorts, here at least). */
5132 md_number_to_chars (buf
, val
, n
)
5137 if (target_big_endian
)
5138 number_to_chars_bigendian (buf
, val
, n
);
5140 number_to_chars_littleendian (buf
, val
, n
);
5144 md_chars_to_number (buf
, n
)
5149 unsigned char * where
= (unsigned char *) buf
;
5151 if (target_big_endian
)
5156 result
|= (*where
++ & 255);
5164 result
|= (where
[n
] & 255);
5171 /* Turn a string in input_line_pointer into a floating point constant
5172 of type TYPE, and store the appropriate bytes in *litP. The number
5173 of LITTLENUMS emitted is stored in *sizeP . An error message is
5174 returned, or NULL on OK.
5176 Note that fp constants aren't represent in the normal way on the ARM.
5177 In big endian mode, things are as expected. However, in little endian
5178 mode fp constants are big-endian word-wise, and little-endian byte-wise
5179 within the words. For example, (double) 1.1 in big endian mode is
5180 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5181 the byte sequence 99 99 f1 3f 9a 99 99 99.
5183 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5186 md_atof (type
, litP
, sizeP
)
5192 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5224 return _("Bad call to MD_ATOF()");
5227 t
= atof_ieee (input_line_pointer
, type
, words
);
5229 input_line_pointer
= t
;
5232 if (target_big_endian
)
5234 for (i
= 0; i
< prec
; i
++)
5236 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5242 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5243 8 byte float the order is 1 0 3 2. */
5244 for (i
= 0; i
< prec
; i
+= 2)
5246 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5247 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5255 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5257 md_pcrel_from (fixP
)
5261 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5262 && fixP
->fx_subsy
== NULL
)
5265 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5267 /* PC relative addressing on the Thumb is slightly odd
5268 as the bottom two bits of the PC are forced to zero
5269 for the calculation. */
5270 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5274 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5275 so we un-adjust here to compensate for the accomodation. */
5276 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5278 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5282 /* Round up a section size to the appropriate boundary. */
5284 md_section_align (segment
, size
)
5285 segT segment ATTRIBUTE_UNUSED
;
5291 /* Round all sects to multiple of 4 */
5292 return (size
+ 3) & ~3;
5296 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5297 we have no need to default values of symbols. */
5301 md_undefined_symbol (name
)
5302 char * name ATTRIBUTE_UNUSED
;
5305 if (name
[0] == '_' && name
[1] == 'G'
5306 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5310 if (symbol_find (name
))
5311 as_bad ("GOT already in the symbol table");
5313 GOT_symbol
= symbol_new (name
, undefined_section
,
5314 (valueT
)0, & zero_address_frag
);
5324 /* arm_reg_parse () := if it looks like a register, return its token and
5325 advance the pointer. */
5329 register char ** ccp
;
5331 char * start
= * ccp
;
5334 struct reg_entry
* reg
;
5336 #ifdef REGISTER_PREFIX
5337 if (*start
!= REGISTER_PREFIX
)
5342 #ifdef OPTIONAL_REGISTER_PREFIX
5343 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5347 if (!isalpha (*p
) || !is_name_beginner (*p
))
5351 while (isalpha (c
) || isdigit (c
) || c
== '_')
5355 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5368 md_apply_fix3 (fixP
, val
, seg
)
5373 offsetT value
= * val
;
5375 unsigned int newimm
;
5378 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5379 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5381 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5383 /* Note whether this will delete the relocation. */
5384 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5385 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5388 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5392 /* If this symbol is in a different section then we need to leave it for
5393 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5394 so we have to undo it's effects here. */
5397 if (fixP
->fx_addsy
!= NULL
5398 && S_IS_DEFINED (fixP
->fx_addsy
)
5399 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5402 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5403 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5407 value
+= md_pcrel_from (fixP
);
5411 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5413 switch (fixP
->fx_r_type
)
5415 case BFD_RELOC_ARM_IMMEDIATE
:
5416 newimm
= validate_immediate (value
);
5417 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5419 /* If the instruction will fail, see if we can fix things up by
5420 changing the opcode. */
5421 if (newimm
== (unsigned int) FAIL
5422 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5424 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5425 _("invalid constant (%lx) after fixup"),
5426 (unsigned long) value
);
5430 newimm
|= (temp
& 0xfffff000);
5431 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5434 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5436 unsigned int highpart
= 0;
5437 unsigned int newinsn
= 0xe1a00000; /* nop */
5438 newimm
= validate_immediate (value
);
5439 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5441 /* If the instruction will fail, see if we can fix things up by
5442 changing the opcode. */
5443 if (newimm
== (unsigned int) FAIL
5444 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5446 /* No ? OK - try using two ADD instructions to generate the value. */
5447 newimm
= validate_immediate_twopart (value
, & highpart
);
5449 /* Yes - then make sure that the second instruction is also an add. */
5450 if (newimm
!= (unsigned int) FAIL
)
5452 /* Still No ? Try using a negated value. */
5453 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5454 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5455 /* Otherwise - give up. */
5458 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5459 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5463 /* Replace the first operand in the 2nd instruction (which is the PC)
5464 with the destination register. We have already added in the PC in the
5465 first instruction and we do not want to do it again. */
5466 newinsn
&= ~ 0xf0000;
5467 newinsn
|= ((newinsn
& 0x0f000) << 4);
5470 newimm
|= (temp
& 0xfffff000);
5471 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5473 highpart
|= (newinsn
& 0xfffff000);
5474 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5478 case BFD_RELOC_ARM_OFFSET_IMM
:
5484 if (validate_offset_imm (value
, 0) == FAIL
)
5486 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5487 _("bad immediate value for offset (%ld)"), (long) value
);
5491 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5492 newval
&= 0xff7ff000;
5493 newval
|= value
| (sign
? INDEX_UP
: 0);
5494 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5497 case BFD_RELOC_ARM_OFFSET_IMM8
:
5498 case BFD_RELOC_ARM_HWLITERAL
:
5504 if (validate_offset_imm (value
, 1) == FAIL
)
5506 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5507 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5508 _("invalid literal constant: pool needs to be closer"));
5510 as_bad (_("bad immediate value for half-word offset (%ld)"),
5515 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5516 newval
&= 0xff7ff0f0;
5517 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5518 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5521 case BFD_RELOC_ARM_LITERAL
:
5527 if (validate_offset_imm (value
, 0) == FAIL
)
5529 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5530 _("invalid literal constant: pool needs to be closer"));
5534 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5535 newval
&= 0xff7ff000;
5536 newval
|= value
| (sign
? INDEX_UP
: 0);
5537 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5540 case BFD_RELOC_ARM_SHIFT_IMM
:
5541 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5542 if (((unsigned long) value
) > 32
5544 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5546 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5547 _("shift expression is too large"));
5552 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5553 else if (value
== 32)
5555 newval
&= 0xfffff07f;
5556 newval
|= (value
& 0x1f) << 7;
5557 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5560 case BFD_RELOC_ARM_SWI
:
5561 if (arm_data
->thumb_mode
)
5563 if (((unsigned long) value
) > 0xff)
5564 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5565 _("Invalid swi expression"));
5566 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5568 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5572 if (((unsigned long) value
) > 0x00ffffff)
5573 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5574 _("Invalid swi expression"));
5575 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5577 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5581 case BFD_RELOC_ARM_MULTI
:
5582 if (((unsigned long) value
) > 0xffff)
5583 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5584 _("Invalid expression in load/store multiple"));
5585 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5586 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5589 case BFD_RELOC_ARM_PCREL_BRANCH
:
5590 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5592 /* Sign-extend a 24-bit number. */
5593 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5597 value
= fixP
->fx_offset
;
5600 /* We are going to store value (shifted right by two) in the
5601 instruction, in a 24 bit, signed field. Thus we need to check
5602 that none of the top 8 bits of the shifted value (top 7 bits of
5603 the unshifted, unsigned value) are set, or that they are all set. */
5604 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5605 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5608 /* Normally we would be stuck at this point, since we cannot store
5609 the absolute address that is the destination of the branch in the
5610 24 bits of the branch instruction. If however, we happen to know
5611 that the destination of the branch is in the same section as the
5612 branch instruciton itself, then we can compute the relocation for
5613 ourselves and not have to bother the linker with it.
5615 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5616 because I have not worked out how to do this for OBJ_COFF or
5619 && fixP
->fx_addsy
!= NULL
5620 && S_IS_DEFINED (fixP
->fx_addsy
)
5621 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5623 /* Get pc relative value to go into the branch. */
5626 /* Permit a backward branch provided that enough bits are set.
5627 Allow a forwards branch, provided that enough bits are clear. */
5628 if ((value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5629 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5633 if (! fixP
->fx_done
)
5635 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5636 _("gas can't handle same-section branch dest >= 0x04000000"));
5640 value
+= SEXT24 (newval
);
5642 if ((value
& ~ ((offsetT
) 0xffffff)) != 0
5643 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5644 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5645 _("out of range branch"));
5647 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5648 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5651 case BFD_RELOC_ARM_PCREL_BLX
:
5654 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5658 value
= fixP
->fx_offset
;
5660 hbit
= (value
>> 1) & 1;
5661 value
= (value
>> 2) & 0x00ffffff;
5662 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5663 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5664 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5668 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5669 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5671 addressT diff
= (newval
& 0xff) << 1;
5676 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5678 _("Branch out of range"));
5679 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5681 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5684 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5685 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5687 addressT diff
= (newval
& 0x7ff) << 1;
5692 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5694 _("Branch out of range"));
5695 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5697 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5700 case BFD_RELOC_THUMB_PCREL_BLX
:
5701 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5706 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5707 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5708 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5709 if (diff
& 0x400000)
5712 value
= fixP
->fx_offset
;
5715 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5716 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5717 _("Branch with link out of range"));
5719 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5720 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5721 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5722 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5727 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5728 md_number_to_chars (buf
, value
, 1);
5730 else if (!target_oabi
)
5732 value
= fixP
->fx_offset
;
5733 md_number_to_chars (buf
, value
, 1);
5739 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5740 md_number_to_chars (buf
, value
, 2);
5742 else if (!target_oabi
)
5744 value
= fixP
->fx_offset
;
5745 md_number_to_chars (buf
, value
, 2);
5751 case BFD_RELOC_ARM_GOT32
:
5752 case BFD_RELOC_ARM_GOTOFF
:
5753 md_number_to_chars (buf
, 0, 4);
5759 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5760 md_number_to_chars (buf
, value
, 4);
5762 else if (!target_oabi
)
5764 value
= fixP
->fx_offset
;
5765 md_number_to_chars (buf
, value
, 4);
5771 case BFD_RELOC_ARM_PLT32
:
5772 /* It appears the instruction is fully prepared at this point. */
5776 case BFD_RELOC_ARM_GOTPC
:
5777 md_number_to_chars (buf
, value
, 4);
5780 case BFD_RELOC_ARM_CP_OFF_IMM
:
5782 if (value
< -1023 || value
> 1023 || (value
& 3))
5783 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5784 _("Illegal value for co-processor offset"));
5787 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5788 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5789 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5792 case BFD_RELOC_ARM_THUMB_OFFSET
:
5793 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5794 /* Exactly what ranges, and where the offset is inserted depends on
5795 the type of instruction, we can establish this from the top 4 bits */
5796 switch (newval
>> 12)
5798 case 4: /* PC load */
5799 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5800 forced to zero for these loads, so we will need to round
5801 up the offset if the instruction address is not word
5802 aligned (since the final address produced must be, and
5803 we can only describe word-aligned immediate offsets). */
5805 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5806 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5807 _("Invalid offset, target not word aligned (0x%08X)"),
5808 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5810 if ((value
+ 2) & ~0x3fe)
5811 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5812 _("Invalid offset, value too big (0x%08X)"), value
);
5814 /* Round up, since pc will be rounded down. */
5815 newval
|= (value
+ 2) >> 2;
5818 case 9: /* SP load/store */
5820 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5821 _("Invalid offset, value too big (0x%08X)"), value
);
5822 newval
|= value
>> 2;
5825 case 6: /* Word load/store */
5827 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5828 _("Invalid offset, value too big (0x%08X)"), value
);
5829 newval
|= value
<< 4; /* 6 - 2 */
5832 case 7: /* Byte load/store */
5834 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5835 _("Invalid offset, value too big (0x%08X)"), value
);
5836 newval
|= value
<< 6;
5839 case 8: /* Halfword load/store */
5841 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5842 _("Invalid offset, value too big (0x%08X)"), value
);
5843 newval
|= value
<< 5; /* 6 - 1 */
5847 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5848 "Unable to process relocation for thumb opcode: %lx",
5849 (unsigned long) newval
);
5852 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5855 case BFD_RELOC_ARM_THUMB_ADD
:
5856 /* This is a complicated relocation, since we use it for all of
5857 the following immediate relocations:
5860 9bit ADD/SUB SP word-aligned
5861 10bit ADD PC/SP word-aligned
5863 The type of instruction being processed is encoded in the
5869 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5871 int rd
= (newval
>> 4) & 0xf;
5872 int rs
= newval
& 0xf;
5873 int subtract
= newval
& 0x8000;
5878 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5879 _("Invalid immediate for stack address calculation"));
5880 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5881 newval
|= value
>> 2;
5883 else if (rs
== REG_PC
|| rs
== REG_SP
)
5887 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5888 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5889 (unsigned long) value
);
5890 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5892 newval
|= value
>> 2;
5897 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5898 _("Invalid 8bit immediate"));
5899 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5900 newval
|= (rd
<< 8) | value
;
5905 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5906 _("Invalid 3bit immediate"));
5907 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5908 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5911 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5914 case BFD_RELOC_ARM_THUMB_IMM
:
5915 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5916 switch (newval
>> 11)
5918 case 0x04: /* 8bit immediate MOV */
5919 case 0x05: /* 8bit immediate CMP */
5920 if (value
< 0 || value
> 255)
5921 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5922 _("Invalid immediate: %ld is too large"),
5930 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5933 case BFD_RELOC_ARM_THUMB_SHIFT
:
5934 /* 5bit shift value (0..31) */
5935 if (value
< 0 || value
> 31)
5936 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5937 _("Illegal Thumb shift value: %ld"), (long) value
);
5938 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5939 newval
|= value
<< 6;
5940 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5943 case BFD_RELOC_VTABLE_INHERIT
:
5944 case BFD_RELOC_VTABLE_ENTRY
:
5948 case BFD_RELOC_NONE
:
5950 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5951 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5957 /* Translate internal representation of relocation info to BFD target
5960 tc_gen_reloc (section
, fixp
)
5961 asection
* section ATTRIBUTE_UNUSED
;
5965 bfd_reloc_code_real_type code
;
5967 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5969 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5970 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5971 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5973 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5975 if (fixp
->fx_pcrel
== 0)
5976 reloc
->addend
= fixp
->fx_offset
;
5978 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5980 reloc
->addend
= fixp
->fx_offset
;
5983 switch (fixp
->fx_r_type
)
5988 code
= BFD_RELOC_8_PCREL
;
5995 code
= BFD_RELOC_16_PCREL
;
6002 code
= BFD_RELOC_32_PCREL
;
6006 case BFD_RELOC_ARM_PCREL_BRANCH
:
6007 case BFD_RELOC_ARM_PCREL_BLX
:
6009 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6010 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6011 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6012 case BFD_RELOC_THUMB_PCREL_BLX
:
6013 case BFD_RELOC_VTABLE_ENTRY
:
6014 case BFD_RELOC_VTABLE_INHERIT
:
6015 code
= fixp
->fx_r_type
;
6018 case BFD_RELOC_ARM_LITERAL
:
6019 case BFD_RELOC_ARM_HWLITERAL
:
6020 /* If this is called then the a literal has been referenced across
6021 a section boundary - possibly due to an implicit dump */
6022 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6023 _("Literal referenced across section boundary (Implicit dump?)"));
6027 case BFD_RELOC_ARM_GOT32
:
6028 case BFD_RELOC_ARM_GOTOFF
:
6029 case BFD_RELOC_ARM_PLT32
:
6030 code
= fixp
->fx_r_type
;
6034 case BFD_RELOC_ARM_IMMEDIATE
:
6035 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6036 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6040 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6041 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6042 _("ADRL used for a symbol not defined in the same file"),
6046 case BFD_RELOC_ARM_OFFSET_IMM
:
6047 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6048 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6055 switch (fixp
->fx_r_type
)
6057 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6058 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6059 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6060 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6061 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6062 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6063 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6064 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6065 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6066 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6067 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6068 default: type
= _("<unknown>"); break;
6070 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6071 _("Can not represent %s relocation in this object file format (%d)"),
6072 type
, fixp
->fx_pcrel
);
6078 if (code
== BFD_RELOC_32_PCREL
6080 && fixp
->fx_addsy
== GOT_symbol
)
6082 code
= BFD_RELOC_ARM_GOTPC
;
6083 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6087 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6089 if (reloc
->howto
== NULL
)
6091 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6092 _("Can not represent %s relocation in this object file format"),
6093 bfd_get_reloc_code_name (code
));
6097 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6098 vtable entry to be used in the relocation's section offset. */
6099 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6100 reloc
->address
= fixp
->fx_offset
;
6106 md_estimate_size_before_relax (fragP
, segtype
)
6107 fragS
* fragP ATTRIBUTE_UNUSED
;
6108 segT segtype ATTRIBUTE_UNUSED
;
6110 as_fatal (_("md_estimate_size_before_relax\n"));
6115 output_inst
PARAMS ((void))
6121 as_bad (inst
.error
);
6125 to
= frag_more (inst
.size
);
6127 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6129 assert (inst
.size
== (2 * THUMB_SIZE
));
6130 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6131 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6133 else if (inst
.size
> INSN_SIZE
)
6135 assert (inst
.size
== (2 * INSN_SIZE
));
6136 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6137 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6140 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6142 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6143 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6144 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6159 /* Align the instruction.
6160 This may not be the right thing to do but ... */
6161 /* arm_align (2, 0); */
6162 listing_prev_line (); /* Defined in listing.h */
6164 /* Align the previous label if needed. */
6165 if (last_label_seen
!= NULL
)
6167 symbol_set_frag (last_label_seen
, frag_now
);
6168 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6169 S_SET_SEGMENT (last_label_seen
, now_seg
);
6172 memset (&inst
, '\0', sizeof (inst
));
6173 inst
.reloc
.type
= BFD_RELOC_NONE
;
6175 skip_whitespace (str
);
6177 /* Scan up to the end of the op-code, which must end in white space or
6179 for (start
= p
= str
; *p
!= '\0'; p
++)
6185 as_bad (_("No operator -- statement `%s'\n"), str
);
6191 CONST
struct thumb_opcode
* opcode
;
6195 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6200 /* Check that this instruction is supported for this CPU. */
6201 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6203 as_bad (_("selected processor does not support this opcode"));
6207 inst
.instruction
= opcode
->value
;
6208 inst
.size
= opcode
->size
;
6209 (*opcode
->parms
)(p
);
6216 CONST
struct asm_opcode
* opcode
;
6217 unsigned long cond_code
;
6219 inst
.size
= INSN_SIZE
;
6220 /* p now points to the end of the opcode, probably white space, but we
6221 have to break the opcode up in case it contains condionals and flags;
6222 keep trying with progressively smaller basic instructions until one
6223 matches, or we run out of opcode. */
6224 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6226 for (; q
!= str
; q
--)
6231 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6234 if (opcode
&& opcode
->template)
6236 unsigned long flag_bits
= 0;
6239 /* Check that this instruction is supported for this CPU. */
6240 if ((opcode
->variants
& cpu_variant
) == 0)
6243 inst
.instruction
= opcode
->value
;
6244 if (q
== p
) /* Just a simple opcode. */
6246 if (opcode
->comp_suffix
)
6248 if (*opcode
->comp_suffix
!= '\0')
6249 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6250 str
, opcode
->comp_suffix
);
6252 /* Not a conditional instruction. */
6253 (*opcode
->parms
)(q
, 0);
6257 /* A conditional instruction with default condition. */
6258 inst
.instruction
|= COND_ALWAYS
;
6259 (*opcode
->parms
)(q
, 0);
6265 /* Not just a simple opcode. Check if extra is a conditional. */
6269 CONST
struct asm_cond
*cond
;
6273 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6277 if (cond
->value
== 0xf0000000)
6279 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6281 cond_code
= cond
->value
;
6285 cond_code
= COND_ALWAYS
;
6288 cond_code
= COND_ALWAYS
;
6290 /* Apply the conditional, or complain it's not allowed. */
6291 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6293 /* Instruction isn't conditional */
6294 if (cond_code
!= COND_ALWAYS
)
6296 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6301 /* Instruction is conditional: set the condition into it. */
6302 inst
.instruction
|= cond_code
;
6305 /* If there is a compulsory suffix, it should come here, before
6306 any optional flags. */
6307 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6309 CONST
char *s
= opcode
->comp_suffix
;
6321 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6322 opcode
->comp_suffix
);
6329 /* The remainder, if any should now be flags for the instruction;
6330 Scan these checking each one found with the opcode. */
6334 CONST
struct asm_flg
*flag
= opcode
->flags
;
6343 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6345 if (streq (r
, flag
[flagno
].template))
6347 flag_bits
|= flag
[flagno
].set_bits
;
6353 if (! flag
[flagno
].template)
6360 (*opcode
->parms
) (p
, flag_bits
);
6370 /* It wasn't an instruction, but it might be a register alias of the form
6373 skip_whitespace (q
);
6378 if (*q
&& !strncmp (q
, ".req ", 4))
6381 char * copy_of_str
= str
;
6385 skip_whitespace (q
);
6387 for (r
= q
; *r
!= '\0'; r
++)
6397 regnum
= arm_reg_parse (& q
);
6400 reg
= arm_reg_parse (& str
);
6405 insert_reg_alias (str
, regnum
);
6407 as_warn (_("register '%s' does not exist\n"), q
);
6409 else if (regnum
!= FAIL
)
6412 as_warn (_("ignoring redefinition of register alias '%s'"),
6415 /* Do not warn about redefinitions to the same alias. */
6418 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6422 as_warn (_("ignoring incomplete .req pseuso op"));
6429 as_bad (_("bad instruction `%s'"), start
);
6434 * Invocation line includes a switch not recognized by the base assembler.
6435 * See if it's a processor-specific option. These are:
6436 * Cpu variants, the arm part is optional:
6437 * -m[arm]1 Currently not supported.
6438 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6439 * -m[arm]3 Arm 3 processor
6440 * -m[arm]6[xx], Arm 6 processors
6441 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6442 * -m[arm]8[10] Arm 8 processors
6443 * -m[arm]9[20][tdmi] Arm 9 processors
6444 * -mstrongarm[110[0]] StrongARM processors
6445 * -m[arm]v[2345[t]] Arm architectures
6446 * -mall All (except the ARM1)
6448 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6449 * -mfpe-old (No float load/store multiples)
6450 * -mno-fpu Disable all floating point instructions
6451 * Run-time endian selection:
6452 * -EB big endian cpu
6453 * -EL little endian cpu
6454 * ARM Procedure Calling Standard:
6455 * -mapcs-32 32 bit APCS
6456 * -mapcs-26 26 bit APCS
6457 * -mapcs-float Pass floats in float regs
6458 * -mapcs-reentrant Position independent code
6459 * -mthumb-interwork Code supports Arm/Thumb interworking
6460 * -moabi Old ELF ABI
6463 CONST
char * md_shortopts
= "m:k";
6464 struct option md_longopts
[] =
6466 #ifdef ARM_BI_ENDIAN
6467 #define OPTION_EB (OPTION_MD_BASE + 0)
6468 {"EB", no_argument
, NULL
, OPTION_EB
},
6469 #define OPTION_EL (OPTION_MD_BASE + 1)
6470 {"EL", no_argument
, NULL
, OPTION_EL
},
6472 #define OPTION_OABI (OPTION_MD_BASE +2)
6473 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6476 {NULL
, no_argument
, NULL
, 0}
6478 size_t md_longopts_size
= sizeof (md_longopts
);
6481 md_parse_option (c
, arg
)
6489 #ifdef ARM_BI_ENDIAN
6491 target_big_endian
= 1;
6494 target_big_endian
= 0;
6502 if (streq (str
, "fpa10"))
6503 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6504 else if (streq (str
, "fpa11"))
6505 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6506 else if (streq (str
, "fpe-old"))
6507 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6513 if (streq (str
, "no-fpu"))
6514 cpu_variant
&= ~FPU_ALL
;
6519 if (streq (str
, "oabi"))
6525 /* Limit assembler to generating only Thumb instructions: */
6526 if (streq (str
, "thumb"))
6528 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6529 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6532 else if (streq (str
, "thumb-interwork"))
6534 if ((cpu_variant
& ARM_THUMB
) == 0)
6535 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6536 #if defined OBJ_COFF || defined OBJ_ELF
6537 support_interwork
= true;
6545 if (streq (str
, "all"))
6547 cpu_variant
= ARM_ALL
| FPU_ALL
;
6550 #if defined OBJ_COFF || defined OBJ_ELF
6551 if (! strncmp (str
, "apcs-", 5))
6553 /* GCC passes on all command line options starting "-mapcs-..."
6554 to us, so we must parse them here. */
6558 if (streq (str
, "32"))
6560 uses_apcs_26
= false;
6563 else if (streq (str
, "26"))
6565 uses_apcs_26
= true;
6568 else if (streq (str
, "frame"))
6570 /* Stack frames are being generated - does not affect
6574 else if (streq (str
, "stack-check"))
6576 /* Stack checking is being performed - does not affect
6577 linkage, but does require that the functions
6578 __rt_stkovf_split_small and __rt_stkovf_split_big be
6579 present in the final link. */
6583 else if (streq (str
, "float"))
6585 /* Floating point arguments are being passed in the floating
6586 point registers. This does affect linking, since this
6587 version of the APCS is incompatible with the version that
6588 passes floating points in the integer registers. */
6590 uses_apcs_float
= true;
6593 else if (streq (str
, "reentrant"))
6595 /* Reentrant code has been generated. This does affect
6596 linking, since there is no point in linking reentrant/
6597 position independent code with absolute position code. */
6602 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6606 /* Strip off optional "arm" */
6607 if (! strncmp (str
, "arm", 3))
6613 if (streq (str
, "1"))
6614 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6620 if (streq (str
, "2"))
6621 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6622 else if (streq (str
, "250"))
6623 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6629 if (streq (str
, "3"))
6630 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6636 switch (strtol (str
, NULL
, 10))
6643 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6651 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6664 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6670 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6674 cpu_variant
|= ARM_LONGMUL
;
6677 case 'f': /* fe => fp enabled cpu. */
6683 case 'c': /* Left over from 710c processor name. */
6684 case 'd': /* Debug */
6685 case 'i': /* Embedded ICE */
6686 /* Included for completeness in ARM processor naming. */
6696 if (streq (str
, "8") || streq (str
, "810"))
6697 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6698 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6704 if (streq (str
, "9"))
6705 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6706 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6707 else if (streq (str
, "920"))
6708 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6709 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6710 else if (streq (str
, "920t"))
6711 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6712 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6713 else if (streq (str
, "9tdmi"))
6714 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6715 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6722 if (streq (str
, "strongarm")
6723 || streq (str
, "strongarm110")
6724 || streq (str
, "strongarm1100"))
6725 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6726 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6732 /* Select variant based on architecture rather than processor. */
6739 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6742 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6745 as_bad (_("Invalid architecture variant -m%s"), arg
);
6751 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6755 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6758 as_bad (_("Invalid architecture variant -m%s"), arg
);
6764 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6768 case 't': cpu_variant
|= ARM_THUMB
; break;
6771 as_bad (_("Invalid architecture variant -m%s"), arg
);
6777 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6780 case 't': cpu_variant
|= ARM_THUMB
; break;
6783 as_bad (_("Invalid architecture variant -m%s"), arg
);
6789 as_bad (_("Invalid architecture variant -m%s"), arg
);
6796 as_bad (_("Invalid processor variant -m%s"), arg
);
6802 #if defined OBJ_ELF || defined OBJ_COFF
6820 ARM Specific Assembler Options:\n\
6821 -m[arm][<processor name>] select processor variant\n\
6822 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6823 -mthumb only allow Thumb instructions\n\
6824 -mthumb-interwork mark the assembled code as supporting interworking\n\
6825 -mall allow any instruction\n\
6826 -mfpa10, -mfpa11 select floating point architecture\n\
6827 -mfpe-old don't allow floating-point multiple instructions\n\
6828 -mno-fpu don't allow any floating-point instructions.\n\
6829 -k generate PIC code.\n"));
6830 #if defined OBJ_COFF || defined OBJ_ELF
6832 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6833 -mapcs-float floating point args are passed in FP regs\n\
6834 -mapcs-reentrant the code is position independent/reentrant\n"));
6838 -moabi support the old ELF ABI\n"));
6840 #ifdef ARM_BI_ENDIAN
6842 -EB assemble code for a big endian cpu\n\
6843 -EL assemble code for a little endian cpu\n"));
6847 /* We need to be able to fix up arbitrary expressions in some statements.
6848 This is so that we can handle symbols that are an arbitrary distance from
6849 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6850 which returns part of an address in a form which will be valid for
6851 a data instruction. We do this by pushing the expression into a symbol
6852 in the expr_section, and creating a fix for that. */
6855 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6864 arm_fix_data
* arm_data
;
6872 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6876 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6881 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6882 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6883 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6884 arm_data
->thumb_mode
= thumb_mode
;
6890 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6892 cons_fix_new_arm (frag
, where
, size
, exp
)
6898 bfd_reloc_code_real_type type
;
6903 * @@ Should look at CPU word size.
6908 type
= BFD_RELOC_16
;
6912 type
= BFD_RELOC_32
;
6915 type
= BFD_RELOC_64
;
6919 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6922 /* A good place to do this, although this was probably not intended
6923 for this kind of use. We need to dump the literal pool before
6924 references are made to a null symbol pointer. */
6928 if (current_poolP
== NULL
)
6931 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6933 listing_prev_line ();
6937 arm_start_line_hook ()
6939 last_label_seen
= NULL
;
6943 arm_frob_label (sym
)
6946 last_label_seen
= sym
;
6948 ARM_SET_THUMB (sym
, thumb_mode
);
6950 #if defined OBJ_COFF || defined OBJ_ELF
6951 ARM_SET_INTERWORK (sym
, support_interwork
);
6954 if (label_is_thumb_function_name
)
6956 /* When the address of a Thumb function is taken the bottom
6957 bit of that address should be set. This will allow
6958 interworking between Arm and Thumb functions to work
6961 THUMB_SET_FUNC (sym
, 1);
6963 label_is_thumb_function_name
= false;
6967 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6971 arm_adjust_symtab ()
6976 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6978 if (ARM_IS_THUMB (sym
))
6980 if (THUMB_IS_FUNC (sym
))
6982 /* Mark the symbol as a Thumb function. */
6983 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6984 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6985 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6987 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6988 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6990 as_bad (_("%s: unexpected function type: %d"),
6991 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6993 else switch (S_GET_STORAGE_CLASS (sym
))
6996 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6999 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7002 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7004 default: /* do nothing */
7009 if (ARM_IS_INTERWORK (sym
))
7010 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7017 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7019 if (ARM_IS_THUMB (sym
))
7021 elf_symbol_type
* elf_sym
;
7023 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7024 bind
= ELF_ST_BIND (elf_sym
);
7026 /* If it's a .thumb_func, declare it as so,
7027 otherwise tag label as .code 16. */
7028 if (THUMB_IS_FUNC (sym
))
7029 elf_sym
->internal_elf_sym
.st_info
=
7030 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7032 elf_sym
->internal_elf_sym
.st_info
=
7033 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7042 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7044 *input_line_pointer
= '/';
7045 input_line_pointer
+= 5;
7046 *input_line_pointer
= 0;
7054 arm_canonicalize_symbol_name (name
)
7059 if (thumb_mode
&& (len
= strlen (name
)) > 5
7060 && streq (name
+ len
- 5, "/data"))
7061 *(name
+ len
- 5) = 0;
7067 arm_validate_fix (fixP
)
7070 /* If the destination of the branch is a defined symbol which does not have
7071 the THUMB_FUNC attribute, then we must be calling a function which has
7072 the (interfacearm) attribute. We look for the Thumb entry point to that
7073 function and change the branch to refer to that function instead. */
7074 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7075 && fixP
->fx_addsy
!= NULL
7076 && S_IS_DEFINED (fixP
->fx_addsy
)
7077 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7079 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7087 /* Relocations against Thumb function names must be left unadjusted,
7088 so that the linker can use this information to correctly set the
7089 bottom bit of their addresses. The MIPS version of this function
7090 also prevents relocations that are mips-16 specific, but I do not
7091 know why it does this.
7094 There is one other problem that ought to be addressed here, but
7095 which currently is not: Taking the address of a label (rather
7096 than a function) and then later jumping to that address. Such
7097 addresses also ought to have their bottom bit set (assuming that
7098 they reside in Thumb code), but at the moment they will not. */
7101 arm_fix_adjustable (fixP
)
7104 if (fixP
->fx_addsy
== NULL
)
7107 /* Prevent all adjustments to global symbols. */
7108 if (S_IS_EXTERN (fixP
->fx_addsy
))
7111 if (S_IS_WEAK (fixP
->fx_addsy
))
7114 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7115 && fixP
->fx_subsy
== NULL
)
7118 /* We need the symbol name for the VTABLE entries */
7119 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7120 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7127 elf32_arm_target_format ()
7129 if (target_big_endian
)
7131 return "elf32-bigarm-oabi";
7133 return "elf32-bigarm";
7136 return "elf32-littlearm-oabi";
7138 return "elf32-littlearm";
7142 armelf_frob_symbol (symp
, puntp
)
7146 elf_frob_symbol (symp
, puntp
);
7150 arm_force_relocation (fixp
)
7153 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7154 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7155 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7156 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7157 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7158 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7164 static bfd_reloc_code_real_type
7174 bfd_reloc_code_real_type reloc
;
7178 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7179 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7180 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7181 /* ScottB: Jan 30, 1998 */
7182 /* Added support for parsing "var(PLT)" branch instructions */
7183 /* generated by GCC for PLT relocs */
7184 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7185 { NULL
, 0, BFD_RELOC_UNUSED
}
7189 for (i
= 0, ip
= input_line_pointer
;
7190 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7192 id
[i
] = tolower (*ip
);
7194 for (i
= 0; reloc_map
[i
].str
; i
++)
7195 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7198 input_line_pointer
+= reloc_map
[i
].len
;
7200 return reloc_map
[i
].reloc
;
7204 s_arm_elf_cons (nbytes
)
7209 #ifdef md_flush_pending_output
7210 md_flush_pending_output ();
7213 if (is_it_end_of_statement ())
7215 demand_empty_rest_of_line ();
7219 #ifdef md_cons_align
7220 md_cons_align (nbytes
);
7225 bfd_reloc_code_real_type reloc
;
7229 if (exp
.X_op
== O_symbol
7230 && * input_line_pointer
== '('
7231 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7233 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7234 int size
= bfd_get_reloc_size (howto
);
7237 as_bad ("%s relocations do not fit in %d bytes",
7238 howto
->name
, nbytes
);
7241 register char * p
= frag_more ((int) nbytes
);
7242 int offset
= nbytes
- size
;
7244 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7249 emit_expr (& exp
, (unsigned int) nbytes
);
7251 while (*input_line_pointer
++ == ',');
7253 input_line_pointer
--; /* Put terminator back into stream. */
7254 demand_empty_rest_of_line ();
7257 #endif /* OBJ_ELF */